Browse Source

deploy

master
Soleilw 1 year ago
parent
commit
df3dd1b87f
100 changed files with 9226 additions and 10430 deletions
  1. 3
    0
      .gitignore
  2. 3
    0
      .vscode/extensions.json
  3. 18
    0
      README.md
  4. 0
    613
      dist/assets/index-63zZrvj6.js
  5. 0
    613
      dist/assets/index-D4KoYBnD.js
  6. 0
    613
      dist/assets/index-EllxiTMp.js
  7. 0
    1
      dist/assets/index-HJRtI44_.css
  8. 0
    613
      dist/assets/index-HmaFEaIr.js
  9. 0
    613
      dist/assets/index-I_tDribN.js
  10. 0
    613
      dist/assets/index-O0x34dq3.js
  11. 0
    613
      dist/assets/index-RQ7vbfo_.js
  12. 0
    613
      dist/assets/index-SN7BLKOz.js
  13. 0
    613
      dist/assets/index-Sp6Dw8Fn.js
  14. 0
    1
      dist/assets/index-UPhkh_vR.css
  15. 0
    613
      dist/assets/index-Z9jEIHgQ.js
  16. 0
    613
      dist/assets/index-aDbTtbEs.js
  17. 0
    1
      dist/assets/index-b4vyUPn9.css
  18. 0
    613
      dist/assets/index-cW64lgls.js
  19. 0
    613
      dist/assets/index-ermjgwUQ.js
  20. 0
    613
      dist/assets/index-gVPLuavq.js
  21. 0
    1
      dist/assets/index-hAmyWmmA.css
  22. 0
    1
      dist/assets/index-laIhE6cV.css
  23. 0
    613
      dist/assets/index-rDo0GekC.js
  24. 0
    1
      dist/assets/index-rkekJApM.css
  25. 0
    613
      dist/assets/index-sNKAfmqp.js
  26. 0
    1
      dist/assets/index-wB3lG_Ne.css
  27. 0
    613
      dist/assets/index-xaHG-CY6.js
  28. 0
    1
      dist/assets/index-ybOV3saj.css
  29. 1
    1
      dist/index.html
  30. 13
    0
      index.html
  31. 5409
    0
      package-lock.json
  32. 38
    0
      package.json
  33. BIN
      public/logo_1.jpg
  34. 13
    0
      src/App.vue
  35. 88
    0
      src/apis/index.ts
  36. 203
    0
      src/apis/models/index.ts
  37. 9
    0
      src/apis/types/role.d.ts
  38. 9
    0
      src/apis/types/search.d.ts
  39. 188
    0
      src/apis/types/url.d.ts
  40. 193
    0
      src/apis/url.ts
  41. BIN
      src/assets/buy.png
  42. BIN
      src/assets/logo.png
  43. 1
    0
      src/assets/vue.svg
  44. 39
    0
      src/components/cCascader/cascader.vue
  45. 52
    0
      src/components/cEchart/cPie.vue
  46. 50
    0
      src/components/cOperation/cOperation.vue
  47. 103
    0
      src/components/cPermission/cPermission.vue
  48. 200
    0
      src/components/cResume/basic.vue
  49. 52
    0
      src/components/cResume/contact.vue
  50. 32
    0
      src/components/cResume/credential.vue
  51. 54
    0
      src/components/cResume/experience.vue
  52. 145
    0
      src/components/cResume/intention.vue
  53. 34
    0
      src/components/cResume/introduction.vue
  54. 68
    0
      src/components/cResume/skill.vue
  55. 64
    0
      src/components/cResume/train.vue
  56. 17
    0
      src/components/cSearch/search.vue
  57. 37
    0
      src/components/cSelect/common.vue
  58. 40
    0
      src/components/cSelect/select.vue
  59. 38
    0
      src/components/cSelect/xuanze.vue
  60. 90
    0
      src/components/cTable/cTable.vue
  61. 61
    0
      src/components/form/search-select.vue
  62. 43
    0
      src/components/form/shujilian.vue
  63. 0
    0
      src/components/layout/header/aHeader.less
  64. 103
    0
      src/components/layout/header/aHeader.vue
  65. 60
    0
      src/components/layout/index.vue
  66. 0
    0
      src/components/layout/sider/aSider.less
  67. 74
    0
      src/components/layout/sider/aSider.vue
  68. 58
    0
      src/components/map/map-iframe.vue
  69. 72
    0
      src/components/statistics/resume/major/index.vue
  70. 57
    0
      src/components/statistics/resume/major/search/index.vue
  71. 157
    0
      src/components/upload/one.vue
  72. 35
    0
      src/hooks/common.d.ts
  73. 0
    0
      src/hooks/index.ts
  74. 44
    0
      src/hooks/useAsRouter.ts
  75. 149
    0
      src/hooks/useCommon.ts
  76. 26
    0
      src/hooks/useMenu.ts
  77. 66
    0
      src/main.ts
  78. 326
    0
      src/router/dynamic.ts
  79. 8
    0
      src/router/index.ts
  80. 80
    0
      src/router/routerList.ts
  81. 37
    0
      src/router/routes.ts
  82. 12
    0
      src/router/types.ts
  83. BIN
      src/static/images/logo.jpg
  84. BIN
      src/static/images/logo.png
  85. BIN
      src/static/images/logo_1.jpg
  86. 13
    0
      src/store/index.ts
  87. 49
    0
      src/store/mutations.ts
  88. 12
    0
      src/store/state.ts
  89. 10
    0
      src/store/types.ts
  90. 78
    0
      src/store/usePermissionStore.ts
  91. 79
    0
      src/style.css
  92. 7
    0
      src/types/column.d.ts
  93. 52
    0
      src/utils/dataHelper.ts
  94. 6
    0
      src/utils/imageHelper.ts
  95. 30
    0
      src/utils/reqHelper.ts
  96. 51
    0
      src/utils/timeHelper.ts
  97. 15
    0
      src/utils/toastHelper.ts
  98. 9
    0
      src/utils/typeHelper.ts
  99. 43
    0
      src/views/activity/address/add/add.d.ts
  100. 0
    0
      src/views/activity/address/add/add.vue

+ 3
- 0
.gitignore View File

@@ -0,0 +1,3 @@
node_modules
dist
dist-ssr

+ 3
- 0
.vscode/extensions.json View File

@@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

+ 18
- 0
README.md View File

@@ -0,0 +1,18 @@
# Vue 3 + TypeScript + Vite

This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.

## Recommended IDE Setup

- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).

## Type Support For `.vue` Imports in TS

TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.

If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:

1. Disable the built-in TypeScript Extension
1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.

+ 0
- 613
dist/assets/index-63zZrvj6.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-D4KoYBnD.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-EllxiTMp.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-HJRtI44_.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-HmaFEaIr.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-I_tDribN.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-O0x34dq3.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-RQ7vbfo_.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-SN7BLKOz.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-Sp6Dw8Fn.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-UPhkh_vR.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-Z9jEIHgQ.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-aDbTtbEs.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-b4vyUPn9.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-cW64lgls.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-ermjgwUQ.js
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-gVPLuavq.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-hAmyWmmA.css
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-laIhE6cV.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-rDo0GekC.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-rkekJApM.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-sNKAfmqp.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-wB3lG_Ne.css
File diff suppressed because it is too large
View File


+ 0
- 613
dist/assets/index-xaHG-CY6.js
File diff suppressed because it is too large
View File


+ 0
- 1
dist/assets/index-ybOV3saj.css
File diff suppressed because it is too large
View File


+ 1
- 1
dist/index.html View File

@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/logo_1.jpg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>后台管理系统</title>
<script type="module" crossorigin src="/assets/index-gVPLuavq.js"></script>
<script type="module" crossorigin src="/assets/index-uU_dXTTD.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-ioYE9aJh.css">
</head>
<body>

+ 13
- 0
index.html View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo_1.jpg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>后台管理系统</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

+ 5409
- 0
package-lock.json
File diff suppressed because it is too large
View File


+ 38
- 0
package.json View File

@@ -0,0 +1,38 @@
{
"name": "job-master",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"@vueup/vue-quill": "^1.2.0",
"ant-design-vue": "^4.0.7",
"axios": "^1.6.2",
"dayjs": "^1.11.10",
"echarts": "^5.4.3",
"moment": "^2.30.1",
"vue": "^3.2.36",
"vue-router": "^4.2.5",
"vuex": "^4.1.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.5.0",
"less": "^4.2.0",
"less-loader": "^11.1.3",
"typescript": "^5.2.2",
"vite": "^5.0.0",
"vue-tsc": "^1.8.22"
},
"description": "This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://gitee.com/soleilw/job-master.git"
},
"author": "",
"license": "ISC"
}

BIN
public/logo_1.jpg View File


+ 13
- 0
src/App.vue View File

@@ -0,0 +1,13 @@
<script setup lang="ts">
import zhCN from 'ant-design-vue/es/locale/zh_CN';
</script>

<template>
<a-config-provider :locale="zhCN">
<router-view></router-view>
</a-config-provider>
</template>

<style scoped>

</style>

+ 88
- 0
src/apis/index.ts View File

@@ -0,0 +1,88 @@
import axios from 'axios';
import * as typeHelper from '@/utils/typeHelper';
import { message } from 'ant-design-vue';
import { router } from '@/router';

const instance = axios.create({
// baseURL: 'http://114.132.85.7:8889',
baseURL: 'https://rcsc-test.jcjob.cn/api',
timeout: 30000,
headers: {
'Content-Type': 'application/json'
},
withCredentials: false,
})
// 请求拦截
// 添加请求拦截器
instance.interceptors.request.use(function (config) {
sessionStorage.getItem('token') ? config.headers.Authorization = sessionStorage.getItem('token') : '';
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});

// 添加响应拦截器
instance.interceptors.response.use(function (response) {
switch (response.data.code) {
case -1:
message.warning(response.data.msg);
break;
case 0:

break;
case 1:
return response;
break;
case 401:
message.warning(response.data.msg);
sessionStorage.clear();
window.location.reload();
router.replace('/login');
case 403:
message.warning(response.data.msg);
break;
case 600:
if(response.data.errors) {
response.data.errors.forEach((item:String) => {
message.warning(item);
})
} else {
message.warning(response.data.msg);
}
break;
default:
console.log(response)

}
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
console.log(error)
return Promise.reject(error);
});

export const httpGet : Function = (url : string, data : object, cb : Function) => {
instance.get(url, {
params: data
}).then(res => {
const resData = res;
typeHelper.isFunction(cb) && cb(resData);
}).catch(err => {
cb(err.response)
})
}

export const httpPost : Function = (url : string, data : object, cb : Function) => {
instance.post(url, data).then(res => {
const resData = res;
typeHelper.isFunction(cb) && cb(resData);
}).catch(err => {
console.log(err)
// cb(err.response)
})
}

+ 203
- 0
src/apis/models/index.ts View File

@@ -0,0 +1,203 @@
import { postModel, getModel } from '@/utils/reqHelper'
import { url } from '../url'

export const Login = postModel(url.userLogin);
export const GetUserMenulist = getModel(url.UserMenulist);

// 角色
export const PostRoleAdd = postModel(url.RoleAdd);
export const PostRoleDel = postModel(url.RoleDel);
export const PostRoleEdit = postModel(url.RoleEdit);
export const GetRoleList = getModel(url.RoleList);
export const PostRoleAddpermission = postModel(url.RoleAddpermission);
export const getRoleGetpermissions = getModel(url.RoleGetpermissions);
export const PostRoleDelpermission = postModel(url.RoleDelpermission);

// 权限
export const addPermission = postModel(url.permissionAdd);
export const getPermission = getModel(url.permissionList);
export const updatePermission = postModel(url.permissionUpdate);
export const getPermissionListWithchilds = getModel(url.permissionListWithchilds);

// 账号
export const addAccount = postModel(url.accountAdd);
export const getAccount = getModel(url.accountList);
export const updateAccount = postModel(url.accountUpdate);

// 企业
export const addCompany = postModel(url.companyAdd);
export const getCompanyList = getModel(url.companyList);
export const updateCompany = postModel(url.companyEdit);
// VIP
export const PostCompanyVipmanage = postModel(url.companyVipmanage);
export const GetCompanyInfo = getModel(url.companyInfo);
export const GetCompanyVipInfo = getModel(url.companyVipInfo);
export const PostCompanyMultiClose = postModel(url.companyMultiClose);
export const PostCompanyMultiOpen = postModel(url.companyMultiOpen);

export const PostCompanyEdit = postModel(url.companyEdit);
export const PostCompanyViplist = getModel(url.companyViplist);
export const PostCompanyJobAdd = postModel(url.companyJobAdd);
export const PostCompanyJobEdit = postModel(url.companyJobEdit);
export const GetCompanyJobList = getModel(url.companyJobList);
export const PostCompanyJobInfo = getModel(url.companyJobInfo);
export const PostCompanyDepartmentAdd = postModel(url.companyDepartmentAdd);
export const PostCompanyDepartmentEdit = postModel(url.companyDepartmentEdit);
export const GetCompanyDepartmentList = getModel(url.CompanyDepartmentList);
export const GetCompanyDepartmentInfo = getModel(url.companyDepartmentInfo);

// 类型
export const PostHousekeepingtypeAdd = postModel(url.HousekeepingtypeAdd);
export const PostHousekeepingtypeDel = postModel(url.HousekeepingtypeDel);
export const PostHousekeepingtypeUpdate = postModel(url.HousekeepingtypeUpdate);
export const GetHousekeepingtypeList = getModel(url.HousekeepingtypeList);
export const GetHousekeepingtypeDetail = getModel(url.HousekeepingtypeDetail);

// 职位
export const PostHousekeepingapplyAdd = postModel(url.HousekeepingapplyAdd);
export const PostHousekeepingapplyDel = postModel(url.HousekeepingapplyDel);
export const PostHousekeepingapplyUpdate = postModel(url.HousekeepingapplyUpdate);
export const GetHousekeepingapplyList = getModel(url.HousekeepingapplyList);
export const GetHousekeepingapplyDetail = getModel(url.HousekeepingapplyDetail);

// 需求
export const PostHousekeepingAdd = postModel(url.HousekeepingAdd);
export const PostHousekeepingDel = postModel(url.HousekeepingDel);
export const PostHousekeepingUpdate = postModel(url.HousekeepingUpdate);
export const GetHousekeepingList = getModel(url.HousekeepingList);
export const GetHousekeepingDetail = getModel(url.HousekeepingDetail);

// 预定
export const PostHousekeepingappointmentAdd = postModel(url.HousekeepingappointmentAdd);
export const PostHousekeepingappointmentDel = postModel(url.HousekeepingappointmentDel);
export const PostHousekeepingappointmentUpdate = postModel(url.HousekeepingappointmentUpdate);
export const GetHousekeepingappointmentList = getModel(url.HousekeepingappointmentList);
export const GetHousekeepingappointmentDetail = getModel(url.HousekeepingappointmentDetail);


// 招聘会
export const PostRecruitmentAdd = postModel(url.RecruitmentAdd);
export const PostRecruitmentDel = postModel(url.RecruitmentDel);
export const PostRecruitmentUpdate = postModel(url.RecruitmentUpdate);
export const listRecruitment = getModel(url.recruitmentList);
export const GetRecruitmentDetail = getModel(url.RecruitmentDetail);

// 招聘会企业
export const PostRecruitmentBookAdd = postModel(url.RecruitmentBookAdd);
export const PostRecruitmentBookDel = postModel(url.RecruitmentBookDel);
export const PostRecruitmentBookUpdate = postModel(url.RecruitmentBookUpdate);
export const GetRecruitmentBookList = getModel(url.RecruitmentBookList);

// 文章栏目
export const addSection = postModel(url.sectionAdd);
export const delSection = postModel(url.sectionDel);
export const updateSection = postModel(url.sectionUpdate);
export const listSection = getModel(url.sectionList);

// 文章
export const addArticle = postModel(url.articleAdd);
export const delArticle = postModel(url.articleDel);
export const updateArticle = postModel(url.articleUpdate);
export const listArticle = getModel(url.articleList);

// 广告
export const PostAdvertareaAdd = postModel(url.advertareaAdd);
export const PostAdvertareaDel = postModel(url.advertareaDel);
export const PostAdvertareaUpdate = postModel(url.advertareaUpdate);
export const GetAdvertareaList = getModel(url.advertareaList);
export const GetAdvertareaDetail = getModel(url.advertareaDetail);
// 投放
export const PostAdvertscheduleAdd = postModel(url.advertscheduleAdd);
export const PostAdvertscheduleDel = postModel(url.advertscheduleDel);
export const PostAdvertscheduleUpdate = postModel(url.advertscheduleUpdate);
export const GetAdvertscheduleList = getModel(url.advertscheduleList);
export const GetAdvertscheduleDetail = getModel(url.advertscheduleDetail);

// 活动
export const PostActivityExportUsers = postModel(url.activityExportUsers);
export const PostActivityaddressAdd = postModel(url.activityaddressAdd);
export const PostActivityaddressDel = postModel(url.activityaddressDel);
export const PostActivityaddressUpdate = postModel(url.activityaddressUpdate);
export const GetActivityaddressList = getModel(url.activityaddressList);
export const GetActivityaddressDetail = getModel(url.activityaddressDetail);
export const GetActivityaddressCate = getModel(url.activityaddressCate);


// 字典数据
export const GetDictTree = getModel(url.dictTree);
export const PostImageUpload = postModel(url.ImageUpload);

// 简历
// 列表
export const PostJobseekerList = postModel(url.JobseekerList);
export const GetJobseekerDetail = getModel(url.JobseekerDetail);
// 基本资料
export const PostJobapplicantAdd = postModel(url.JobapplicantAdd);
export const PostJobapplicantDel = postModel(url.JobapplicantDel);
export const PostJobapplicantUpdate = postModel(url.JobapplicantUpdate);
export const GetJobapplicantList = getModel(url.JobapplicantList);
export const GetJobapplicantDetail = getModel(url.JobapplicantDetail);
// 联系方式
export const PostJobapplicantAddcontact = postModel(url.JobapplicantAddcontact);
export const PostJobapplicantDelcontact = postModel(url.JobapplicantDelcontact);
export const PostJobapplicantUpdatecontact = postModel(url.JobapplicantUpdatecontact);
export const PostJobapplicantListcontact = getModel(url.JobapplicantListcontact);
export const PostJobapplicantContactdetail = getModel(url.JobapplicantContactdetail);
// 证书技能
export const PostJobapplicantAddskill = postModel(url.JobapplicantAddskill);
export const PostJobapplicantDelskill = postModel(url.JobapplicantDelskill);
export const PostJobapplicantUpdateskill = postModel(url.JobapplicantUpdateskill);
export const PostJobapplicantListskill = getModel(url.JobapplicantListskill);
export const PostJobapplicantSkilldetail = getModel(url.JobapplicantSkilldetail);
// 培训经历
export const PostJobapplicantAddtraining = postModel(url.JobapplicantAddtraining);
export const PostJobapplicantDeltraining = postModel(url.JobapplicantDeltraining);
export const PostJobapplicantUpdatetraining = postModel(url.JobapplicantUpdatetraining);
export const PostJobapplicantListtraining = getModel(url.JobapplicantListtraining);
export const PostJobapplicantTrainingdetail = getModel(url.JobapplicantTrainingdetail);
// 求职意向-基本
export const PostJobapplicantAdddesirebase = postModel(url.JobapplicantAdddesirebase);
export const PostJobapplicantDeldesirebase = postModel(url.JobapplicantDeldesirebase);
export const PostJobapplicantUpdatedesirebase = postModel(url.JobapplicantUpdatedesirebase);
export const PostJobapplicantListdesirebase = getModel(url.JobapplicantListdesirebase);
export const PostJobapplicantDesirebasedetail = getModel(url.JobapplicantDesirebasedetail);
// 求职意向-地区
export const PostJobapplicantAdddesirearea = postModel(url.JobapplicantAdddesirearea);
export const PostJobapplicantDeldesirearea = postModel(url.JobapplicantDeldesirearea);
export const PostJobapplicantUpdatedesirearea = postModel(url.JobapplicantUpdatedesirearea);
export const PostJobapplicantListdesirearea = getModel(url.JobapplicantListdesirearea);
export const PostJobapplicantDesireareadetail = getModel(url.JobapplicantDesireareadetail);
// 求职意向-职位
export const PostJobapplicantAdddesireindustry = postModel(url.JobapplicantAdddesireindustry);
export const PostJobapplicantDeldesireindustry = postModel(url.JobapplicantDeldesireindustry);
export const PostJobapplicantUpdatedesireindustry = postModel(url.JobapplicantUpdatedesireindustry);
export const PostJobapplicantListdesireindustry = getModel(url.JobapplicantListdesireindustry);
export const PostJobapplicantDesireindustrydetail = getModel(url.JobapplicantDesireindustrydetail);
// 工作经历
export const PostJobapplicantAddexperience = postModel(url.JobapplicantAddexperience);
export const PostJobapplicantDelexperience = postModel(url.JobapplicantDelexperience);
export const PostJobapplicantUpdateexperience = postModel(url.JobapplicantUpdateexperience);
export const PostJobapplicantListexperience = getModel(url.JobapplicantListexperience);
export const PostJobapplicantExperiencedetail = getModel(url.JobapplicantExperiencedetail);
// 证书
export const PostJobapplicantAddcertificate = postModel(url.JobapplicantAddcertificate);
export const PostJobapplicantUpdatecertificate = postModel(url.JobapplicantUpdatecertificate);
export const PostJobapplicantListcertificate = getModel(url.JobapplicantListcertificate);
export const PostJobapplicantCertificatedetail = getModel(url.JobapplicantCertificatedetail);



export const PostJobapplicantAddintroduction = postModel(url.JobapplicantAddintroduction); // 个人介绍
export const PostJobapplicantDelintroduction = postModel(url.JobapplicantDelintroduction); // 个人介绍
export const PostJobapplicantUpdateintroduction = postModel(url.JobapplicantUpdateintroduction); // 个人介绍
export const GetJobapplicantListintroduction = getModel(url.JobapplicantListintroduction); // 个人介绍
export const GetJobapplicantIntroductiondetail = getModel(url.JobapplicantIntroductiondetail); // 个人详情

// 统计
export const GetStatsMajor= getModel(url.StatsMajor);
export const GetStatsCertificate= getModel(url.StatsCertificate);
export const GetStatsWorkExperience= getModel(url.StatsWorkExperience);
export const GetStatsHa= getModel(url.StatsHa);
export const GetStatsAgeandgender= getModel(url.StatsAgeandgender);
export const GetStatsEducation= getModel(url.StatsEducation);
export const GetStatsPosition= getModel(url.StatsPosition);

+ 9
- 0
src/apis/types/role.d.ts View File

@@ -0,0 +1,9 @@
declare namespace roleType {
type addRoleType = {
id ?: string,
name: string,
code: string,
description: string
}

}

+ 9
- 0
src/apis/types/search.d.ts View File

@@ -0,0 +1,9 @@
declare namespace searchType {
type searchParams = {
page : string,
pagesize : string,
sort : string,
sortby : string,
keyword ?: string
}
}

+ 188
- 0
src/apis/types/url.d.ts View File

@@ -0,0 +1,188 @@
declare namespace urlType {
type url = {
userLogin : String,
UserMenulist : String,
RoleAdd : String,
RoleList : String,
RoleDel : String,
RoleEdit : String,
RoleAddpermission : String,
RoleGetpermissions : String,
RoleDelpermission : String,
permissionAdd : String,
permissionList : String,
permissionUpdate : String,
permissionListWithchilds : String,
accountAdd : String,
accountList : String,
accountUpdate : String,
companyAdd : String,
companyList : String,
companyEdit : String,

companyInfo : String,
companyVipInfo : String,
companyMultiClose : String,
companyMultiOpen : String,

companyEdit : String,
companyVipmanage : String,
companyViplist : String,

companyJobAdd : String,
companyJobEdit : String,
companyJobList : String,
companyJobInfo : String,

companyDepartmentAdd : String,
companyDepartmentEdit : String,
CompanyDepartmentList : String,
companyDepartmentInfo : String,

// 类型
HousekeepingtypeAdd : String,
HousekeepingtypeDel : String,
HousekeepingtypeUpdate : String,
HousekeepingtypeList : String,
HousekeepingtypeDetail : String,
// 职位
HousekeepingapplyAdd : String,
HousekeepingapplyDel : String,
HousekeepingapplyUpdate : String,
HousekeepingapplyList : String,
HousekeepingapplyDetail : String,
// 需求
HousekeepingAdd : String,
HousekeepingDel : String,
HousekeepingUpdate : String,
HousekeepingList : String,
HousekeepingDetail : String,
// 预定
HousekeepingappointmentAdd : String,
HousekeepingappointmentDel : String,
HousekeepingappointmentUpdate : String,
HousekeepingappointmentList : String,
HousekeepingappointmentDetail : String,


RecruitmentAdd : String,
RecruitmentDel : String,
RecruitmentUpdate : String,
recruitmentList : String,
RecruitmentDetail : String,
RecruitmentBookAdd : String,
RecruitmentBookDel : String,
RecruitmentBookUpdate : String,
RecruitmentBookList : String,


sectionAdd : String,
sectionDel : String,
sectionUpdate : String,
sectionList : String,
// 文章
articleAdd : String,
articleDel : String,
articleUpdate : String,
articleList : String,

dictTree : String,
ImageUpload : String,
advertareaAdd : String,
advertareaDel : String,
advertareaUpdate : String,
advertareaList : String,
advertareaDetail : String,
advertscheduleAdd : String,
advertscheduleDel : String,
advertscheduleUpdate : String,
advertscheduleList : String,
advertscheduleDetail : String,
// 活动
activityExportUsers: String,
activityaddressAdd: String,
activityaddressDel: String,
activityaddressUpdate: String,
activityaddressList: String,
activityaddressDetail: String,
activityaddressCate: String,
// 简历
// 列表
'JobseekerList' : String, // 查看
'JobseekerDetail' : String, // 详情
// 基本资料
'JobapplicantAdd' : String, // 添加
'JobapplicantDel' : String, // 删除
'JobapplicantUpdate' : String, // 修改
'JobapplicantList' : String, // 查看
'JobapplicantDetail' : String, // 详情
// 个人介绍
'JobapplicantAddintroduction' : String,
'JobapplicantDelintroduction' : String,
'JobapplicantUpdateintroduction' : String,
'JobapplicantListintroduction' : String,
'JobapplicantIntroductiondetail' : String,
// 联系信息
'JobapplicantAddcontact' : String,
'JobapplicantDelcontact' : String,
'JobapplicantUpdatecontact' : String,
'JobapplicantListcontact' : String,
'JobapplicantContactdetail' : String,
// 专业技能
'JobapplicantAddskill' : String,
'JobapplicantDelskill' : String,
'JobapplicantUpdateskill' : String,
'JobapplicantListskill' : String,
'JobapplicantSkilldetail' : String,
// 培训经历
'JobapplicantAddtraining' : String,
'JobapplicantDeltraining' : String,
'JobapplicantUpdatetraining' : String,
'JobapplicantListtraining' : String,
'JobapplicantTrainingdetail' : String,
// 求职意向-基本
'JobapplicantAdddesirebase' : String,
'JobapplicantDeldesirebase' : String,
'JobapplicantUpdatedesirebase' : String,
'JobapplicantDesirebasedetail' : String,
// 求职意向-地区
'JobapplicantAdddesirearea' : String,
'JobapplicantDeldesirearea' : String,
'JobapplicantUpdatedesirearea' : String,
'JobapplicantListdesirearea' : String,
'JobapplicantDesireareadetail' : String,
// 求职意向-职位
'JobapplicantAdddesireindustry' : String,
'JobapplicantDeldesireindustry' : String,
'JobapplicantUpdatedesireindustry' : String,
'JobapplicantListdesireindustry' : String,
'JobapplicantDesireindustrydetail' : String,
// 证书
'JobapplicantAddcertificate' : String,
'JobapplicantDelcertificate' : String,
'JobapplicantUpdatecertificate' : String,
'JobapplicantListcertificate' : String,
'JobapplicantCertificatedetail' : String,
// 工作经历
'JobapplicantAddexperience' : String,
'JobapplicantDelexperience' : String,
'JobapplicantUpdateexperience' : String,
'JobapplicantListexperience' : String,
'JobapplicantExperiencedetail' : String,
// 统计
StatsMajor: String,
StatsCertificate: String,
StatsWorkExperience: String,
StatsHa: String,
StatsAgeandgender: String,
StatsEducation: String,
StatsPosition: String,



}
}

+ 193
- 0
src/apis/url.ts View File

@@ -0,0 +1,193 @@
let admin : string = '/admin';
let common : string = '/common';
// 角色
export const url : urlType.url = {
userLogin: admin + '/user/login',
UserMenulist: admin + '/user/menulist',
// 角色
RoleAdd: admin + '/role/add',
RoleList: admin + '/role/list',
RoleDel: admin + '/role/del',
RoleEdit: admin + '/role/update',
RoleAddpermission: admin + '/role/addpermission',
RoleGetpermissions: admin + '/role/getpermissions',
RoleDelpermission: admin + '/role/delpermission',
permissionAdd: admin + '/permission/add',
permissionList: admin + '/permission/list',
permissionUpdate: admin + '/permission/update',
permissionListWithchilds: admin + '/permission/listwithchilds',
accountAdd: admin + '/user/add',
accountList: admin + '/user/list',
accountUpdate: admin + '/user/update',
companyAdd: admin + '/company/add',
companyList: admin + '/company/list',
companyInfo: admin + '/company/info',
companyVipInfo: admin + '/company/vipinfo',
companyMultiClose: admin + '/company/multiclose',
companyMultiOpen: admin + '/company/multiopen',

companyEdit: admin + '/company/edit',
companyVipmanage: admin + '/company/vipmanage',
companyViplist: admin + '/company/viplist',

companyJobAdd: admin + '/company/job_add',
companyJobEdit: admin + '/company/job_edit',
companyJobList: admin + '/company/job_list',
companyJobInfo: admin + '/company/job_info',

companyDepartmentAdd: admin + '/company/department_add',
companyDepartmentEdit: admin + '/company/department_edit',
CompanyDepartmentList: admin + '/company/department_list',
companyDepartmentInfo: admin + '/company/department_info',

// 家政
// 类型
HousekeepingtypeAdd: admin + '/housekeepingtype/add',
HousekeepingtypeDel: admin + '/housekeepingtype/del',
HousekeepingtypeUpdate: admin + '/housekeepingtype/update',
HousekeepingtypeList: admin + '/housekeepingtype/list',
HousekeepingtypeDetail: admin + '/housekeepingtype/detail',
// 职位
HousekeepingapplyAdd: admin + '/housekeepingapply/add',
HousekeepingapplyDel: admin + '/housekeepingapply/del',
HousekeepingapplyUpdate: admin + '/housekeepingapply/update',
HousekeepingapplyList: admin + '/housekeepingapply/list',
HousekeepingapplyDetail: admin + '/housekeepingapply/detail',
// 需求
HousekeepingAdd: admin + '/housekeeping/add',
HousekeepingDel: admin + '/housekeeping/del',
HousekeepingUpdate: admin + '/housekeeping/update',
HousekeepingList: admin + '/housekeeping/list',
HousekeepingDetail: admin + '/housekeeping/detail',
// 预定
HousekeepingappointmentAdd: admin + '/housekeepingappointment/add',
HousekeepingappointmentDel: admin + '/housekeepingappointment/del',
HousekeepingappointmentUpdate: admin + '/housekeepingappointment/update',
HousekeepingappointmentList: admin + '/housekeepingappointment/list',
HousekeepingappointmentDetail: admin + '/housekeepingappointment/detail',

// 招聘会
RecruitmentAdd: admin + '/recruitment/add',
RecruitmentDel: admin + '/recruitment/del',
RecruitmentUpdate: admin + '/recruitment/update',
recruitmentList: admin + '/recruitment/list',
RecruitmentDetail: admin + '/recruitment/detail',

// 招聘参与企业
RecruitmentBookAdd: admin + '/recruitmentbook/add',
RecruitmentBookDel: admin + '/recruitmentbook/del',
RecruitmentBookUpdate: admin + '/recruitmentbook/update',
RecruitmentBookList: admin + '/recruitmentbook/list',

// 文章栏目
sectionAdd: admin + '/section/add',
sectionDel: admin + '/section/del',
sectionUpdate: admin + '/section/update',
sectionList: admin + '/section/list',

// 文章
articleAdd: admin + '/article/add',
articleDel: admin + '/article/del',
articleUpdate: admin + '/article/update',
articleList: admin + '/article/list',
// 字典
dictTree: common + '/dict/tree',
ImageUpload: common + '/image/upload?imgtype=1',

// 广告
// 广告列表
advertareaAdd: admin + '/advertarea/add',
advertareaDel: admin + '/advertarea/del',
advertareaUpdate: admin + '/advertarea/update',
advertareaList: admin + '/advertarea/list',
advertareaDetail: admin + '/advertarea/detail',
// 投放
advertscheduleAdd: admin + '/advertschedule/add',
advertscheduleDel: admin + '/advertschedule/del',
advertscheduleUpdate: admin + '/advertschedule/update',
advertscheduleList: admin + '/advertschedule/list',
advertscheduleDetail: admin + '/advertarea/detail',

// 活动管理
activityExportUsers: admin + '/activity/export_users', // 导出参加活动用户
// 活动地址
activityaddressAdd: admin + '/activityaddress/add',
activityaddressDel: admin + '/activityaddress/del',
activityaddressUpdate: admin + '/activityaddress/update',
activityaddressList: admin + '/activityaddress/list',
activityaddressDetail: admin + '/activityaddress/detail',
activityaddressCate: admin + '/activityaddress/cate', // 地址分类

// 简历
// 列表
'JobseekerList': admin + '/jobseeker/list', // 查看
'JobseekerDetail': admin + '/jobseeker/detail', // 详情
// 基本资料
'JobapplicantAdd': admin + '/jobapplicant/add', // 添加
'JobapplicantDel': admin + '/jobapplicant/del', // 删除
'JobapplicantUpdate': admin + '/jobapplicant/update', // 修改
'JobapplicantList': admin + '/jobapplicant/list', // 查看
'JobapplicantDetail': admin + '/jobapplicant/detail', // 详情
// 个人介绍
'JobapplicantAddintroduction': '/admin/jobapplicant/addintroduction',
'JobapplicantDelintroduction': admin + '/jobapplicant/delintroduction', // 删除
'JobapplicantUpdateintroduction': admin + '/jobapplicant/updateintroduction', // 修改
'JobapplicantListintroduction': '/admin/jobapplicant/listintroduction',
'JobapplicantIntroductiondetail': '/admin/jobapplicant/introductiondetail',
// 联系信息
'JobapplicantAddcontact': admin + '/jobapplicant/addcontact', // 添加
'JobapplicantDelcontact': admin + '/jobapplicant/delcontact', // 删除
'JobapplicantUpdatecontact': admin + '/jobapplicant/updatecontact', // 修改
'JobapplicantListcontact': admin + '/jobapplicant/listcontact', // 查看
'JobapplicantContactdetail': admin + '/jobapplicant/contactdetail', // 详情
// 专业技能
'JobapplicantAddskill': admin + '/jobapplicant/addskill', // 添加
'JobapplicantDelskill': admin + '/jobapplicant/delskill', // 删除
'JobapplicantUpdateskill': admin + '/jobapplicant/updateskill', // 修改
'JobapplicantListskill': admin + '/jobapplicant/listskill', // 查看
'JobapplicantSkilldetail': admin + '/jobapplicant/skilldetail', // 详情
// 培训经历
'JobapplicantAddtraining': admin + '/jobapplicant/addtraining', // 添加
'JobapplicantDeltraining': admin + '/jobapplicant/deltraining', // 删除
'JobapplicantUpdatetraining': admin + '/jobapplicant/updatetraining', // 修改
'JobapplicantListtraining': admin + '/jobapplicant/listtraining', // 查看
'JobapplicantTrainingdetail': admin + '/jobapplicant/trainingdetail', // 详情
// 求职意向-基本
'JobapplicantAdddesirebase': '/admin/jobapplicant/adddesirebase', // 添加
'JobapplicantDeldesirebase': '/admin/jobapplicant/deldesirebase', // 删除
'JobapplicantUpdatedesirebase': '/admin/jobapplicant/updatedesirebase', // 修改
'JobapplicantDesirebasedetail': '/admin/jobapplicant/desirebasedetail', // 详情
// 求职意向-地区
'JobapplicantAdddesirearea': admin + '/jobapplicant/adddesirearea', // 添加
'JobapplicantDeldesirearea': admin + '/jobapplicant/deldesirearea', // 删除
'JobapplicantUpdatedesirearea': admin + '/jobapplicant/updatedesirearea', // 修改
'JobapplicantListdesirearea': admin + '/jobapplicant/listdesirearea', // 查看
'JobapplicantDesireareadetail': admin + '/jobapplicant/desireareadetail', // 详情
// 求职意向-职位
'JobapplicantAdddesireindustry': admin + '/jobapplicant/adddesireindustry', // 添加
'JobapplicantDeldesireindustry': admin + '/jobapplicant/deldesireindustry', // 删除
'JobapplicantUpdatedesireindustry': admin + '/jobapplicant/updatedesireindustry', // 修改
'JobapplicantListdesireindustry': admin + '/jobapplicant/listdesireindustry', // 查看
'JobapplicantDesireindustrydetail': admin + '/jobapplicant/desireindustrydetail', // 详情
// 证书
'JobapplicantAddcertificate': admin + '/jobapplicant/addcertificate', // 添加
'JobapplicantDelcertificate': admin + '/jobapplicant/delcertificate', // 删除
'JobapplicantUpdatecertificate': admin + '/jobapplicant/updatecertificate', // 修改
'JobapplicantListcertificate': admin + '/jobapplicant/listcertificate', // 查看
'JobapplicantCertificatedetail': admin + '/jobapplicant/certificatedetail', // 详情
// 工作经历
'JobapplicantAddexperience': admin + '/jobapplicant/addexperience', // 添加
'JobapplicantDelexperience': admin + '/jobapplicant/delexperience', // 删除
'JobapplicantUpdateexperience': admin + '/jobapplicant/updateexperience', // 修改
'JobapplicantListexperience': admin + '/jobapplicant/listexperience', // 查看
'JobapplicantExperiencedetail': admin + '/jobapplicant/experiencedetail', // 详情

// 统计
StatsMajor: admin + '/stats/major', // 求职者专业统计
StatsCertificate: admin + '/stats/certificate', // 求职者技能证书统计
StatsWorkExperience: admin + '/stats/work_experience', // 求职者工作经验统计
StatsHa: admin + '/stats/ha', // 求职者节假日与食宿统计
StatsAgeandgender: admin + '/stats/ageandgender', // 求职者年龄与性别统计
StatsEducation: admin + '/stats/education', // 求职者学历统计
StatsPosition: admin + '/stats/position', // 求职者求职意向统计
}

BIN
src/assets/buy.png View File


BIN
src/assets/logo.png View File


+ 1
- 0
src/assets/vue.svg View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>

+ 39
- 0
src/components/cCascader/cascader.vue View File

@@ -0,0 +1,39 @@
<template>
<a-cascader v-model:value="cascaderParentId" @change="parentChange" :options="listOptions"
:fieldNames="listFieldNames" :changeOnSelect="true" :placeholder="placeholder" style="width: 100%" change-on-select/>
</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits } from 'vue';
import { GetDictTree } from '@/apis/models';
const props = defineProps(['dict', 'placeholder', 'cascader_content']);
let listOptions = ref([]);
let cascaderParentId = ref<String>([]);
const listFieldNames = ref({ label: 'name', value: 'id', children: 'children' });
let placeholder = ref('请选择');
placeholder.value = props.placeholder
watch(() => [props.dict, props.cascader_content],
(newVal, oldVal) => {
GetDictTree({
code: newVal[0]
}).then(res => {
listOptions.value = res.data.dicts
})
cascaderParentId.value = newVal[1]
})

onMounted(() => {
GetDictTree({
code: props.dict
}).then(res => {
listOptions.value = res.data.dicts
})
})
const emit = defineEmits();
const parentChange = (val, selectedOptions) => {
emit('saveCascader', {arr1: val, arr2: selectedOptions});
}
</script>

<style>
</style>

+ 52
- 0
src/components/cEchart/cPie.vue View File

@@ -0,0 +1,52 @@
<template>
<div ref="pie" style="width: 100%; height: 240px;"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { init } from 'echarts';

const pie = ref(null);

// 设置环形图的数据
const ageData = [
{ name: '0-18岁', value: 20 },
{ name: '19-30岁', value: 30 },
{ name: '31-45岁', value: 40 },
{ name: '46岁以上', value: 10 },
];

// 使用setup函数创建环形图
onMounted(() => {
console.log(pie)
const aa = init(pie.value)
const option = {
legend: {
orient: 'vertical',
top: '10%',
left: 'left'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)',
},
series: [
{
name: '年龄分布',
type: 'pie',
radius: ['40%', '70%'],
center: ['50%', '50%'],
data: ageData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
},
],
};
aa.setOption(option)
});
</script>

+ 50
- 0
src/components/cOperation/cOperation.vue View File

@@ -0,0 +1,50 @@
<template>
<a-row :gutter="16" style="margin-bottom: 16px;">
<a-col v-if="needAdd">
<a-button type="primary" @click="showModal">
<template #icon>
<PlusOutlined />
</template>
新建
</a-button>
</a-col>
<a-col>
<a-button type="primary" @click="refreshTable">
<template #icon>
<SyncOutlined />
</template>
刷新
</a-button>
</a-col>
<a-col>
<a-button type="primary" @click="showSearch">
<template #icon>
<SearchOutlined />
</template>
搜索
</a-button>
</a-col>
<slot></slot>
</a-row>
</template>

<script setup lang="ts">
import { ref, defineProps, computed, watch, defineEmits } from 'vue';
import { SyncOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { useCommon } from '@/hooks/useCommon';
let { showModal, showSearch } = useCommon();
let props = defineProps({
need_add: {
type: Boolean,
default: true
}
});
let needAdd = ref<Boolean>(props.need_add)
const emit = defineEmits();
const refreshTable = () => {
emit('refresh');
}
</script>

<style>
</style>

+ 103
- 0
src/components/cPermission/cPermission.vue View File

@@ -0,0 +1,103 @@
<template>
<div>
<template v-for="(item, index) in permissionList">
<a-row class="a-row" align="middle">
<a-col span="6" class="a-col">
<a-checkbox v-model:checked="item.checked" @change="one($event, index, item)"
:label="item.name">{{item.name}}</a-checkbox>
</a-col>
<a-col span="18" class="a-col">
<template v-if="item.childs">
<a-row align="middle">
<template v-for="(childItem, childIndex) in item.childs">
<a-col span="6" class="a-col"><a-checkbox v-model:checked="childItem.checked"
@change="one($event, index, childItem)"
:label="childItem.name">{{childItem.name}}</a-checkbox></a-col>
<a-col span="18" class="a-col">
<template v-if="childItem.childs">
<a-row align="middle">
<template v-for="(thirdItem, thirdIndex) in childItem.childs">
<a-col span="6"><a-checkbox v-model:checked="thirdItem.checked"
@change="one($event, index, thirdItem)"
:label="thirdItem.name">{{thirdItem.name}}</a-checkbox></a-col>
</template>
</a-row>
</template>
</a-col>
</template>
</a-row>
</template>
</a-col>
</a-row>
</template>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted, defineProps, watch } from 'vue';
import { getPermissionListWithchilds, getRoleGetpermissions, PostRoleAddpermission } from '@/apis/models';
import { message } from 'ant-design-vue';
const emit = defineEmits();
let permissionList = ref<object[]>([])
let props = defineProps(['roleId', 'roleName']);

onMounted(async () => {
let res = await getPermissionListWithchilds({ page: 1, pagesize: 10, sort: 'id', sortby: "asc", keyword: "" });
permissionList.value = res.data.permissions;
let res1 = await getRoleGetpermissions({ ids: props.roleId.toString() });
emit('detailTitle', { title: props.roleName, length: res1.data.permissions.length });
permissionList.value = markChecked(permissionList.value, res1.data.permissions);
})


const one = (e, index, item) => {
PostRoleAddpermission({ role_id: props.roleId, permission_id: item.id }).then(res => {
message.success('为角色新增菜单/权限成功');
getOneRole();
})
}

// 获取角色的权限
const getOneRole = () => {
getRoleGetpermissions({ ids: props.roleId.toString() }).then(res => {
permissionList.value = markChecked(permissionList.value, res.data.permissions);
});
}

const markChecked = (arr1, arr2) => {
arr1.forEach((itemA : Object) => {
const matchingItem = arr2.find(itemB => itemB.id === itemA.id);
if (matchingItem) {
itemA.checked = true;
}
if (itemA.childs && itemA.childs.length) {
debugger
markChecked(itemA.childs, arr2);
}
});
return arr1;
}
</script>

<style lang="less" scoped>
.a-row:first-child {
border-bottom: none;
border-radius: 10px 10px 0 0;
}

.a-row:last-child {
border-radius: 0 0 10px 10px;
}

.a-row {
padding: 6px;
border: 1px #f0f0f0 solid;

.a-col:first-child {}
}

.a-col {
padding: 6px;
// padding-top: 6px;
}
</style>

+ 200
- 0
src/components/cResume/basic.vue View File

@@ -0,0 +1,200 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item required label="简历是否可见" name="简历是否可见">
<a-radio-group v-model:value="createForm.hide_resume" button-style="solid">
<a-radio-button value="1">是</a-radio-button>
<a-radio-button value="2">否</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item required label="家政版块是否可见" name="createForm.house_keeping_status">
<a-radio-group v-model:value="createForm.house_keeping_status" button-style="solid">
<a-radio-button value="1">是</a-radio-button>
<a-radio-button value="2">否</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item required label="姓名" name="name">
<a-input v-model:value="createForm.name" placeholder="请输入姓名" />
</a-form-item>
<a-form-item required label="身份证" name="id_number">
<a-input v-model:value="createForm.id_number" placeholder="请输入身份证" />
</a-form-item>
<a-form-item required label="性别" name="createForm.gender">
<a-radio-group v-model:value="createForm.gender" button-style="solid">
<a-radio-button value="男">男</a-radio-button>
<a-radio-button value="女">女</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item required label="出生日期" name="dob">
<a-date-picker v-model:value="createForm.dob" :locale="locale" :format="dateFormat" @panelChange="dobChange"/>
</a-form-item>
<a-form-item required label="工作经验(年)" name="work_experience">
<a-input v-model:value="createForm.work_experience" placeholder="请输入工作经验" />
</a-form-item>
<a-form-item label="学历" name="education">
<a-c-select :dict="2006" :placeholder="educationPlaceholder" @saveSelect="saveEducation"></a-c-select>
</a-form-item>
<a-form-item label="户口所在地">
<a-c-cascader :dict="2009" @saveCascader="regLevelSave" placeholder="请选择户口所在地" ></a-c-cascader>
</a-form-item>
<a-form-item label="现居地">
<a-c-cascader :dict="2009" @saveCascader="nowLevelSave" placeholder="请选择现居地" ></a-c-cascader>
</a-form-item>
<a-form-item label="职称">
<a-c-select :dict="2014" :placeholder="titlePlaceholder" @saveSelect="saveTitle"></a-c-select>
</a-form-item>
<a-form-item label="婚姻状况">
<a-c-select :dict="2011" :placeholder="maritalStatusPlaceholder"
@saveSelect="saveMaritalStatus"></a-c-select>
</a-form-item>
<a-form-item label="民族">
<a-c-select :dict="2012" :placeholder="ethnicityPlaceholder" @saveSelect="saveEthnicity"></a-c-select>
</a-form-item>
<a-form-item label="身高(厘米cm)">
<a-input-number :min="0" type="number" v-model:value="createForm.height" placeholder="请输入身高" />
</a-form-item>
<a-form-item label="体重(千克kg)">
<a-input-number :min="0" type="number" v-model:value="createForm.weight" placeholder="请输入体重" />
</a-form-item>
<a-form-item label="政治面貌">
<a-c-select :dict="2010" :placeholder="politicalStatusPlaceholder"
@saveSelect="savePoliticalStatus"></a-c-select>
</a-form-item>
<a-form-item label="籍贯">
<a-c-cascader :dict="2009" @saveCascader="nativePlaceSave" placeholder="请选择籍贯"></a-c-cascader>
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px">重置</a-button>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
import moment, { Moment } from 'moment';
import 'moment/dist/locale/zh-cn';
import locale from "ant-design-vue/es/date-picker/locale/zh_CN";
let createForm = ref({
hide_resume: 0,
house_keeping_status: 0,
photo: 'aaa.jpg',
name: '',
id_number: '',
gender: "女",
dob: ref<Moment>(),
work_experience: '',
education: 0,
reg_level1: 0,
reg_level2: 0,
reg_level3: 0,
reg_level4: 0,
now_level1: 0,
now_level2: 0,
now_level3: 0,
now_level4: 0,
title: 0,
marital_status: 0,
ethnicity: 0,
height: '',
weight: '',
political_status: 0,
native_place: 0
})

const onSubmit = () => {
console.log(createForm.value)
}

const resetForm = () => {
createForm.value = {
hide_resume: 0,
house_keeping_status: 0,
photo: 'aaa.jpg',
name: '',
id_number: '',
gender: "女",
dob: ref<Moment>(),
work_experience: '',
education: 0,
reg_level1: 0,
reg_level2: 0,
reg_level3: 0,
reg_level4: 0,
now_level1: 0,
now_level2: 0,
now_level3: 0,
now_level4: 0,
title: 0,
marital_status: 0,
ethnicity: 0,
height: '',
weight: '',
political_status: 0,
native_place: 0
}
}
// 出生日期
const dateFormat = ref('YYYY-MM-DD');
const dobChange = (val) => {
moment(val, 'YYYY-MM-DD');
console.log(val)
}
// 学历
const educationPlaceholder = ref('请选择学历');
const saveEducation = (data) => {
createForm.value.education = data.val;
}

// 职称
const titlePlaceholder = ref('请选择职称')
const saveTitle = (data) => {
createForm.value.title = data.val;
}

// 婚姻状态
const maritalStatusPlaceholder = ref('请选择婚姻状态')
const saveMaritalStatus = (data) => {
createForm.value.marital_status = data.val;
}

// 民族
const ethnicityPlaceholder = ref('请选择民族')
const saveEthnicity = (data) => {
createForm.value.ethnicity = data.val;
}

// 政治面貌
const politicalStatusPlaceholder = ref('请选择政治面貌')
const savePoliticalStatus = (data) => {
createForm.value.political_status = data.val;
}


// 户口所在地
const regLevelSave = (data) => {
for (let i = 0; i < 4; i++) {
createForm.value[`reg_level${i + 1}`] = data.arr1[i] || 0;
}
}

// 户口所在地
const nowLevelSave = (data) => {
for (let i = 0; i < 4; i++) {
createForm.value[`now_level${i + 1}`] = data.arr1[i] || 0;
}
}

// 户口所在地
const nativePlaceSave = (data) => {
if (data.arr1.length == 1) {
return false;
} else {
createForm.value.native_place = data.arr1[1];
}
}
</script>

<style>
</style>

+ 52
- 0
src/components/cResume/contact.vue View File

@@ -0,0 +1,52 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item label="固话" name="landline">
<a-input v-model:value="createForm.landline" placeholder="请输入固话" />
</a-form-item>
<a-form-item required label="移动电话" name="mobile">
<a-input v-model:value="createForm.mobile" placeholder="请输入移动电话" />
</a-form-item>
<a-form-item label="QQ" name="qq">
<a-input v-model:value="createForm.qq" placeholder="请输入QQ" />
</a-form-item>
<a-form-item label="个人网站" name="personal_website">
<a-input v-model:value="createForm.personal_website" placeholder="请输入个人网站" />
</a-form-item>
<a-form-item label="通信地址" name="mailing_address">
<a-input v-model:value="createForm.mailing_address" placeholder="请输入通信地址" />
</a-form-item>
<a-form-item label="邮编" name="postal_code">
<a-input v-model:value="createForm.postal_code" placeholder="请输入邮编" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px">重置</a-button>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
landline: '',
mobile: '',
qq: '',
personal_website: '',
mailing_address: '',
postal_code: '',
})

const resetForm = () => {
createForm.value = {
landline: '',
mobile: '',
qq: '',
personal_website: '',
mailing_address: '',
postal_code: '',
}
}
</script>

<style>
</style>

+ 32
- 0
src/components/cResume/credential.vue View File

@@ -0,0 +1,32 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item label="证书名称" name="name">
<a-input v-model:value="createForm.name" placeholder="请输入证书名称" />
</a-form-item>
<a-form-item required label="证书描述" name="description">
<a-input v-model:value="createForm.description" placeholder="请输入证书描述" />
</a-form-item>


</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
name: '',
description: '',
certificate_photo: '',
})

const resetForm = () => {
createForm.value = {
name: '',
description: '',
certificate_photo: '',
}
}
</script>

<style>
</style>

+ 54
- 0
src/components/cResume/experience.vue View File

@@ -0,0 +1,54 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item required label="是否至今" name="是否至今">
<a-radio-group v-model:value="createForm.end_today" button-style="solid">
<a-radio-button value="1">非至今</a-radio-button>
<a-radio-button value="2">至今</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="公司名称" name="company_name">
<a-input v-model:value="createForm.company_name" placeholder="请输入公司名称" />
</a-form-item>
<a-form-item required label="职位" name="position">
<a-input v-model:value="createForm.position" placeholder="请输入职位" />
</a-form-item>
<a-form-item label="离职原因" name="reason_for_leaving">
<a-input v-model:value="createForm.reason_for_leaving" placeholder="请输入离职原因" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px">重置</a-button>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
start_year: 0,
start_month: 0,
end_year: 0,
end_month: 0,
end_today: 0,
company_name: '',
position: '',
reason_for_leaving: ''
})
const resetForm = () => {
createForm.value = {
start_year: 0,
start_month: 0,
end_year: 0,
end_month: 0,
end_today: 0,
company_name: '',
position: '',
reason_for_leaving: ''
}
}
</script>

<style>
</style>

+ 145
- 0
src/components/cResume/intention.vue View File

@@ -0,0 +1,145 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item label="意向地区">
<a-c-cascader :dict="2009" @saveCascader="areaSave"></a-c-cascader>
</a-form-item>
<a-form-item label="意向职位">
<a-c-cascader :dict="2004" @saveCascader="positionSave"></a-c-cascader>
</a-form-item>
<a-form-item label="求职类型">
<a-c-select :dict="2019" placeholder="请选择求职类型" @saveSelect="saveJobType"></a-c-select>
</a-form-item>
<a-form-item label="人才类型">
<a-c-select :dict="2020" placeholder="请选择求职类型" @saveSelect="saveTalentType"></a-c-select>
</a-form-item>
<a-form-item required label="工作经验(年)" name="work_experience">
<a-input v-model:value="createForm.base.work_experience" placeholder="请输入工作经验" />
</a-form-item>
<a-form-item required label="其他职位" name="other_positions">
<a-input v-model:value="createForm.base.other_positions" placeholder="请输入其他职位" />
</a-form-item>
<a-form-item label="月薪要求范围">
<a-c-select :dict="2005" placeholder="请选择月薪要求范围" @saveSelect="saveSalaryRange"></a-c-select>
</a-form-item>
<a-form-item label="可到职日期">
<a-c-select :dict="2013" placeholder="请选择可到职日期" @saveSelect="saveAvailableDate"></a-c-select>
</a-form-item>
<a-form-item label="职称要求">
<a-c-select :dict="2014" placeholder="请选择职称要求" @saveSelect="saveTitleRequirement"></a-c-select>
</a-form-item>
<a-form-item label="技能认证">
<a-c-select :dict="2015" placeholder="请选择技能认证" @saveSelect="saveSkillCertification"></a-c-select>
</a-form-item>
<a-form-item label="食宿要求">
<a-c-select :dict="2016" placeholder="请选择食宿要求" @saveSelect="saveAccommodationRequirement"></a-c-select>
</a-form-item>
<a-form-item label="节假日休息情况">
<a-c-select :dict="2017" placeholder="请选择节假日休息情况" @saveSelect="saveHolidayRest"></a-c-select>
</a-form-item>

</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
area: {
level1: 0,
level2: 0,
level3: 0,
level4: 0,
},
position: {
industry: 0,
},
base: {
job_type: 0,
talent_type: 0,
work_experience: 0,
other_positions: '',
salary_range: 0,
available_date: 0,
title_requirement: 0,
skill_certification: 0,
accommodation_requirement: 0,
holiday_rest: 0,
}
})

const resetForm = () => {
createForm.value = {
area: {
level1: 0,
level2: 0,
level3: 0,
level4: 0,
},
position: {
industry: 0,
},
base: {
job_type: 0,
talent_type: 0,
work_experience: 0,
other_positions: '',
salary_range: 0,
available_date: 0,
title_requirement: 0,
skill_certification: 0,
accommodation_requirement: 0,
holiday_rest: 0,
}
}
}
// 意向地区
const areaSave = (data) => {
for (let i = 0; i < 4; i++) {
createForm.value[`now_level${i + 1}`] = data.arr1[i] || 0;
}
}
// 意向求职
const positionSave = (data) => {
for (let i = 0; i < 4; i++) {
createForm.value[`now_level${i + 1}`] = data.arr1[i] || 0;
}
}
// 求职类型
const saveJobType = (data) => {
createForm.value.job_type = data.val;
}
// 人才类型
const saveTalentType = (data) => {
createForm.value.base.talent_type = data.val;
}

// 月薪要求范围
const saveSalaryRange = (data) => {
createForm.value.base.salary_range = data.val;
}
// 可到职日期
const saveAvailableDate = (data) => {
createForm.value.base.available_date = data.val;
}
// 职称要求
const saveTitleRequirement = (data) => {
createForm.value.base.title_requirement = data.val;
}

// 技能认证
const saveSkillCertification = (data) => {
createForm.value.base.skill_certification = data.val;
}

// 食宿要求
const saveAccommodationRequirement = (data) => {
createForm.value.base.accommodation_requirement = data.val;
}

// 节假日休息情况
const saveHolidayRest = (data) => {
createForm.value.base.holiday_rest = data.val;
}
</script>

<style>
</style>

+ 34
- 0
src/components/cResume/introduction.vue View File

@@ -0,0 +1,34 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item label="个人简介" name="description">
<QuillEditor theme="snow" :options="options" toolbar="full"/>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css';
const options = ref({
debug: 'info',
modules: {
},
placeholder: '请输入个人简介',
theme: 'snow'
})


let createForm = ref({
description: '',
})

const resetForm = () => {
createForm.value = {
description: '',
}
}
</script>

<style>
</style>

+ 68
- 0
src/components/cResume/skill.vue View File

@@ -0,0 +1,68 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item label="英语" name="english">
<a-c-select :dict="2008" placeholder="请选择掌握程度" @saveSelect="saveEnglish"></a-c-select>
</a-form-item>
<a-form-item label="国语" name="mandarin">
<a-c-select :dict="2008" placeholder="请选择掌握程度" @saveSelect="saveMandarin"></a-c-select>
</a-form-item>
<a-form-item label="粤语" name="cantonese">
<a-c-select :dict="2008" placeholder="请选择掌握程度" @saveSelect="saveCantonese"></a-c-select>
</a-form-item>
<a-form-item label="第二外语" name="other_language">
<a-c-select :dict="2007" placeholder="请选择掌握程度" @saveSelect="saveOtherLanguage"></a-c-select>
</a-form-item>
<a-form-item label="计算机能力" name="computer_skills">
<a-input v-model:value="createForm.computer_skills" placeholder="请输入计算机能力" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px">重置</a-button>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
english: 0,
mandarin: 0,
cantonese: 0,
other_language: 0,
computer_skills: ""
})

const resetForm = () => {
createForm.value = {
english: 0,
mandarin: 0,
cantonese: 0,
other_language: 0,
computer_skills: ""
}
}
// 英语
const saveEnglish = (data) => {
createForm.value.english = data.val;
}
// 国语
const saveMandarin = (data) => {
createForm.value.mandarin = data.val;
}
// 粤语
const saveCantonese = (data) => {
createForm.value.cantonese = data.val;
}
// 第二外语
const saveOtherLanguage = (data) => {
createForm.value.english = data.val;
}
</script>

<style>
</style>

+ 64
- 0
src/components/cResume/train.vue View File

@@ -0,0 +1,64 @@
<template>
<a-c-form :createForm="createForm">
<a-form-item required label="是否至今" name="是否至今">
<a-radio-group v-model:value="createForm.end_today" button-style="solid">
<a-radio-button value="1">非至今</a-radio-button>
<a-radio-button value="2">至今</a-radio-button>
</a-radio-group>
</a-form-item>
<a-form-item label="学校/培训机构" name="school_or_institution">
<a-input v-model:value="createForm.school_or_institution" placeholder="请输入学校/培训机构" />
</a-form-item>
<a-form-item required label="专业" name="major">
<a-input v-model:value="createForm.major" placeholder="请输入专业" />
</a-form-item>
<a-form-item label="获得证书" name="certificate">
<a-input v-model:value="createForm.certificate" placeholder="请输入获得证书" />
</a-form-item>
<a-form-item label="曾获学校奖项或技能比赛奖项" name="certificate">
<a-input v-model:value="createForm.awards" placeholder="请输入曾获学校奖项或技能比赛奖项" />
</a-form-item>
<a-form-item label="曾任职务" name="awards">
<a-input v-model:value="createForm.awards" placeholder="请输入曾任职务" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px">重置</a-button>
</a-form-item>
</a-c-form>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
let createForm = ref({
start_year: 0,
start_month: 0,
end_year: 0,
end_month: 0,
end_today: 0,
school_or_institution: '',
major: '',
certificate: '',
awards: '',
positions_held: '',
})
const resetForm = () => {
createForm.value = {
start_year: 0,
start_month: 0,
end_year: 0,
end_month: 0,
end_today: 0,
school_or_institution: '',
major: '',
certificate: '',
awards: '',
positions_held: '',
}
}
</script>

<style>
</style>

+ 17
- 0
src/components/cSearch/search.vue View File

@@ -0,0 +1,17 @@
<template>
<a-row :gutter="[16,16]">
<slot></slot>
<a-col>
<a-button size="mini">搜索</a-button>
</a-col>
<a-col><a-button size="mini">重置</a-button></a-col>
</a-row>
</template>

<script setup lang="ts">
import { useSearch } from '@/hooks/useSearch';
</script>

<style lang="less" scoped>
</style>

+ 37
- 0
src/components/cSelect/common.vue View File

@@ -0,0 +1,37 @@
<template>
<a-select v-model:value="value" @change="handleChange" :placeholder="placeholder" show-search :filter-option="false"
label-in-value @search="handleSearch" :options="listOptions">
<a-select-option v-for="item in listOptions" :key="item.id" :value="item.id" :label="item.full_name" label-in-value>{{item.full_name}}</a-select-option>
</a-select>

</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits, computed } from 'vue';
const props = defineProps(['list', 'placeholder']);
let placeholder = ref<String>(props.placeholder);
let listOptions = ref<Object[]>(props.list)
watch(() => props.list, (newVal:string, oldVal:string) => {
newVal.map(item => {
listOptions.push({id: item})
})
listOptions.value = newVal;
})
// 搜索
let lastKeyWord = ref<String>('');
const emit = defineEmits();
const handleSearch = (val : string) => {
lastKeyWord.value = val;
emit('searchKey', { keyword: val});
}
const handleChange = (val : string) => {
console.log(val)
emit('saveSearch', { val: val });
}
</script>

<style>
</style>

+ 40
- 0
src/components/cSelect/select.vue View File

@@ -0,0 +1,40 @@
<template>
<a-select v-model:value="selectValue" @change="handleChange" :placeholder="placeholder">
<a-select-option v-for="item in listOptions" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
</a-select>

</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits } from 'vue';
import { GetDictTree } from '@/apis/models';
let listOptions = ref([]);
let selectValue = ref('');
let placeholder = ref('请选择');
const props = defineProps(['dict', 'placeholder', 'select_content']);
placeholder.value = props.placeholder
watch(() => [props.dict, props.select_content],
(newVal:string, oldVal:string) => {
GetDictTree({
code: newVal[0]
}).then((res:object) => {
listOptions.value = res.data.dicts
})
selectValue.value = newVal[1]
})

onMounted(() => {
GetDictTree({
code: props.dict
}).then((res:object) => {
listOptions.value = res.data.dicts
})
})
const emit = defineEmits();
const handleChange = (val) => {
emit('saveSelect', { val: val });
}
</script>

<style>
</style>

+ 38
- 0
src/components/cSelect/xuanze.vue View File

@@ -0,0 +1,38 @@
<template>
<a-select v-model:value="selectValue" @change="handleChange" :placeholder="placeholder" label-in-value>
<a-select-option v-for="item in listOptions" :key="item.id" :value="item.id" :label="item.name">{{item.name}}</a-select-option>
</a-select>
</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits } from 'vue';
import { GetDictTree } from '@/apis/models';
const props = defineProps(['dict', 'placeholder', 'select_content']);
let listOptions = ref([]);
let selectValue = ref<Number>(0);
let placeholder = ref<String>(props.placeholder);
watch(() => [props.dict, props.select_content],
(newVal) => {
GetDictTree({
code: newVal[0]
}).then((res:object) => {
listOptions.value = res.data.dicts
})
selectValue.value = newVal[1] == 0 ? props.placeholder : newVal[1];
}, { immediate: true })

onMounted(() => {
GetDictTree({
code: props.dict
}).then((res:object) => {
listOptions.value = res.data.dicts
})
})
const emit = defineEmits();
const handleChange = (val) => {
emit('saveSelect', { val: val });
}
</script>

<style>
</style>

+ 90
- 0
src/components/cTable/cTable.vue View File

@@ -0,0 +1,90 @@
<template>
<a-table :data-source="data" :columns="columns" scrollToFirstRowOnChange :pagination="pagination"
@change="pageChange" bordered class="ant-table-striped" childrenColumnName="childs" rowKey="id" :indentSize="30"
:expanded-row-keys="state.expandRowKeys"
:rowClassName="(record, index) => (index % 2 === 1 ? 'table-striped' : null)" :loading="loading"
:scroll="{ y: 600 }">
<template #photo_image="{ record }">
<slot name="photo_image" :record='record'></slot>
</template>
<template #license_image="{ record }">
<slot name="license_image" :record='record'></slot>
</template>
<template #operation="{ record }">
<slot :record='record'></slot>
</template>
<template #p_type="{ record }">
<slot name="p_type" :record='record'></slot>
</template>
<template #parent_id="{ record }">
<slot name="parent_id" :record='record'></slot>
</template>
<template #permission_name="{ record }">
<slot name="permission_name" :record='record'></slot>
</template>
<template #expandIcon="{ record }">
<template v-if="record.childs && record.childs.length === 0"><span
style="margin-right: 24px"></span></template>
<template v-else>
<button :class="[
'ant-table-row-expand-icon',
!state.isExpand[record.id]
? 'ant-table-row-expand-icon-collapsed' //使用组件库原展开按钮的样式
: 'ant-table-row-expand-icon-expanded'
]" @click="expandRow(record.id)">
</button>
</template>
</template>

</a-table>
</template>

<script lang="ts" setup>
import { ref, onMounted, defineEmits, defineProps, watch } from 'vue';
let props = defineProps(['data', 'columns', 'pagination', 'loading']);
const emit = defineEmits();
let data = ref<Object[]>([])
let columns = ref<Object[]>([])
let loading = ref<Boolean>(props.loading);
let pagination = ref<CommonType.PageType>({
current: 1,
pageSize: 10,
total: 10,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
})
watch(() => [props.data, props.columns, props.pagination, props.loading],
(newVal, oldVal) => {
data.value = newVal[0];
columns.value = newVal[1];
pagination.value = newVal[2];
loading.value = newVal[3]
})

const pageChange = (val) => {
emit("page", val)
}

const state = ref({
expandRowKeys: [],
isExpand: {}
})

const expandRow = (id) => {
state.value.isExpand[id] = !state.value.isExpand[id];
if (!state.value.expandRowKeys.includes(id)) {
state.value.expandRowKeys.push(id);
} else {
const closedIndex = state.value.expandRowKeys.indexOf(id);
state.value.expandRowKeys.splice(closedIndex, 1);
}
};
</script>

<style scoped>
.ant-table-striped :deep(.table-striped) td {
background-color: #fafafa;
}
</style>

+ 61
- 0
src/components/form/search-select.vue View File

@@ -0,0 +1,61 @@
<template>
<a-select v-model:value="selectValue" show-search label-in-value :placeholder="placeholder" style="width: 100%"
:filter-option="false" :not-found-content="fetching ? undefined : null" :options="listOptions"
@search="searchList" @change="searchChange" :disabled="selectDisabled" :mode="mode">
<template v-if="fetching" #notFoundContent>
<a-spin size="small" />
</template>
</a-select>
</template>
<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits } from 'vue';
import { getCompanyList } from '@/apis/models';
import { debounce } from 'lodash-es';
const emit = defineEmits();
const props = defineProps(
{
list: Array,
placeholder: String,
select_value: Number,
select_disabled: {
type: Boolean,
default: false
},
mode: {
type: String,
default: ''
}
});
let listOptions = ref([]);
let fetching = ref(false);
let placeholder = ref<String>(props.placeholder);
let selectValue = ref<String>('');
let lastFetchId = 0;
let selectDisabled = ref<Boolean>(false)
let mode = ref<String>(props.mode)
watch(() => [props.list, props.select_value, props.select_disabled],
(newVal, oldVal) => {
listOptions.value = newVal[0]
selectValue.value = newVal[1] == '' ? placeholder.value : newVal[1];
selectDisabled.value = newVal[2];
mode.value = newVal[3]
debugger
}, { immediate: true })

const searchList = debounce(value => {
lastFetchId += 1;
const fetchId = lastFetchId;
listOptions.value = [];
fetching.value = true;
emit('searchData', {keyword: value});
if (fetchId !== lastFetchId) {
return;
}
fetching.value = false;
}, 300);
const searchChange = (data) => {
emit('getSelectValue', data);
}
</script>

+ 43
- 0
src/components/form/shujilian.vue View File

@@ -0,0 +1,43 @@
<template>
<a-tree-select v-model:value="treecCascaderParentId" style="width: 100%"
:tree-data="treeData" tree-checkable allow-clear :show-checked-strategy="SHOW_PARENT"
:placeholder="placeholder" tree-node-filter-prop="label"
:fieldNames="listFieldNames" :maxTagCount="3" @change="parentChange" />
</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, defineEmits } from 'vue';
import { GetDictTree } from '@/apis/models';
import { TreeSelect } from 'ant-design-vue';
const props = defineProps(['dict', 'placeholder', 'tree_content']);
let treeData = ref([]);
let treecCascaderParentId = ref<number[]>([]);
const listFieldNames = ref({ label: 'name', value: 'id', children: 'children' });
let placeholder = ref('请选择');
placeholder.value = props.placeholder
const SHOW_PARENT = TreeSelect.SHOW_ALL;
watch(() => [props.dict, props.tree_content],
(newVal, oldVal) => {
GetDictTree({
code: newVal[0]
}).then(res => {
treeData.value = res.data.dicts
})
treecCascaderParentId.value = newVal[1]
}, {immediate: true})

// onMounted(() => {
// GetDictTree({
// code: props.dict
// }).then(res => {
// treeData.value = res.data.dicts
// })
// })
const emit = defineEmits();
const parentChange = (val) => {
emit('saveTreeNode', {arr1: val});
}
</script>

<style>
</style>

+ 0
- 0
src/components/layout/header/aHeader.less View File


+ 103
- 0
src/components/layout/header/aHeader.vue View File

@@ -0,0 +1,103 @@
<template>
<a-row>
<a-col :span="4" style="display: flex;align-items: center;">
<menu-unfold-outlined v-if="collapsed" class="trigger" @click="onCollapsed" />
<menu-fold-outlined v-else class="trigger" @click="onCollapsed" />
<a-input-search v-model:value="routerValue" placeholder="请输入想进入的管理页面" @keyup.enter="onSearch"
@search="onSearch" style="margin-left: 10px;" />
</a-col>
<a-col :span="20">
<a-row type="flex" justify="end" :gutter="20">
<a-col flex="200px">
<div>{{time}}</div>
</a-col>
<a-col flex="50px">
<a-avatar src="@/static/images/logo_1.jpg"></a-avatar>
</a-col>
<a-col flex="50px">
<div>admin</div>
</a-col>
<a-col flex="16px">
<LogoutOutlined @click="loginOut" />
</a-col>
</a-row>

</a-col>
</a-row>

</template>
<script lang="ts" setup>
import { ref, onMounted, computed } from 'vue';
import { store } from '@/store';
import { router } from '@/router';
import { MenuUnfoldOutlined, MenuFoldOutlined, LogoutOutlined } from '@ant-design/icons-vue';
import { getTime } from '@/utils/timeHelper';
import { useComputed } from '@/hooks/useComputed';
import { useMenu } from '@/hooks/useMenu';
let { menuList, onMenu, message } = useMenu();
let routerValue : string = ref('');
const time : string = ref('');
const currentTime = () => {
setInterval(() => {
time.value = getTime().nowTime + " " + getTime().nowDate + " " + getTime().nowWeek;
}, 500);
};
const collapsed = computed(() => {
return store.state.collapsed
})
const onCollapsed = () => {
store.commit('getCollapsed');
}
onMounted(() => {
currentTime();
});
const loginOut = () => {
sessionStorage.clear();
window.location.reload();
router.replace('/login');
}
const onSearch = (val) => {
const result = menuList.value.some(item => deepCompareAndMarkChecked(item, val));
if(result.result == 1) {
onMenu(result.path)
} else {
message.warning('无此页面')
}
}



const deepCompareAndMarkChecked = (item : Object, str : String) => {
let data = {
result: 0,
path: ''
};
if (item.meta.title === str) {
return data = {
result: 1,
path: item.path
};
}

if (item.children && Array.isArray(item.children)) {
for (const child of item.children) {
const result = deepCompareAndMarkChecked(child, str);
if (result === 1) {
return data = {
result: 1,
path: obj.path
};
}
}
}

return data = {
result: 0,
path: ''
};
}
</script>

<style>
</style>

+ 60
- 0
src/components/layout/index.vue View File

@@ -0,0 +1,60 @@
<template>
<a-layout class="layout-box" style="background: #fff; height: 100%;">
<a-layout-sider v-model:collapsed="collapsed" :trigger="null" collapsible
style="background: #19be6b; overflow-y: auto;, height: '100vh', left: 0">
<div class="logo" v-if="collapsed">
<img src="@/static/images/logo_1.jpg" alt="" style="width: 100%;height: 100%;">
</div>
<div class="logo" v-else>
<img src="@/static/images/logo.png" alt="" style="width: 100%;height: 100%;" >
</div>
<a-sider></a-sider>
</a-layout-sider>
<a-layout>
<a-layout-header style="background: #fff; padding: 0 16px">
<a-header></a-header>
</a-layout-header>
<a-layout-content :style="{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }">
<router-view></router-view>
</a-layout-content>
<a-layout-footer style="text-align: center;padding: 0 0 8px 0;">
技术支持:中山安域
</a-layout-footer>
</a-layout>
</a-layout>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { store } from '@/store';
import ASider from './sider/aSider.vue';
import AHeader from './header/aHeader.vue';
import { MenuUnfoldOutlined, MenuFoldOutlined, } from '@ant-design/icons-vue';
const collapsed = computed(() => {
return store.state.collapsed
})
</script>
<style lang="less">
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color 0.3s;
}

#components-layout-demo-custom-trigger .trigger:hover {
color: #1890ff;
}

.logo {
height: 32px;
margin: 16px;
}

.site-layout .site-layout-background {
background: #fff;
}
</style>

+ 0
- 0
src/components/layout/sider/aSider.less View File


+ 74
- 0
src/components/layout/sider/aSider.vue View File

@@ -0,0 +1,74 @@
<template>
<a-menu mode="inline" v-model:openKeys="openSubMenu" @openChange="onOpenChange" inlineCollapsed
v-model:selectedKeys="selectedMenu" style="background: #19be6b; height: '90vh';color: #fff;">
<template v-for="(item,index) in menuList">
<template v-if="!item.children">
<a-menu-item :key="item.path" @click="onMenu(item.path)">
<template #icon>
<component :is="item.meta.icon"></component>
</template>
<span>{{item.meta.title}}</span>
</a-menu-item>
</template>
<template v-else>
<a-sub-menu :key="item.path">
<template #icon>
<component :is="item.meta.icon"></component>
</template>
<template #title>{{item.meta.title}}</template>
<template v-for="(twoItem, twoIndex) in item.children">
<a-sub-menu v-if="twoItem.children" :key="twoItem.path">
<template #title>
{{twoItem.meta.title}}
</template>
<a-menu-item v-for="(threeItem, threeIndex) in twoItem.children" :key="threeItem.path"
@click="onMenu(threeItem.path)">{{ threeItem.meta.title }}</a-menu-item>
</a-sub-menu>
<a-menu-item v-else @click="onMenu(twoItem.path)" :key="twoItem.path">
{{ twoItem.meta.title }}
</a-menu-item>
</template>
</a-sub-menu>
</template>
</template>
</a-menu>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue';
import { useMenu } from '@/hooks/useMenu';
let { menuList, onMenu, routerCur, routerArrayCur } = useMenu();

const selectedMenu = computed(() => {
let newSelectedMenu = [routerCur()];
return newSelectedMenu;
})

const openSubMenu = computed(() => {
let newOpenSubMenu = [routerArrayCur()];
return newOpenSubMenu;
})

const onOpenChange = (openKeys) => {
const latestOpenKey : string = openKeys.length > 0 ? openKeys[openKeys.length - 1] : undefined;
if (latestOpenKey) {
openSubMenu.value = latestOpenKey ? [latestOpenKey] : [];
} else {
openSubMenu.value = [];
}
}
</script>
<style lang="less" scoped>
::-webkit-scrollbar {
/* 设置滚动条宽度 */
width: 0px;
}

.ant-menu {
background-color: #f0f2f5;
/* 修改菜单的背景颜色 */
}

.ant-menu .ant-sub-menu {
color: #000000;
}
</style>

+ 58
- 0
src/components/map/map-iframe.vue View File

@@ -0,0 +1,58 @@
<template>
<div class="map">
<iframe id="mapPage" width="100%" height="800" frameborder=0 :src="getSrc">
</iframe>
</div>
</template>

<script>
export default {
data() {
return {}
},
computed: {
getSrc() {
var baseUrl = 'https://apis.map.qq.com/tools/locpicker?search=1&type=1&key=' + 'MPBBZ-HUICZ-EGRXB-7AHZI-R4GQZ-QWBSO' + '&referer=' + 'myapp'
if (this.lat && this.lng) {
baseUrl += `&coord=${this.lat},${this.lng}`
}
return baseUrl
}
},
props: {
mapKey: {
type: String,
default: ''
},

keyName: {
type: String,
default: ''
},
lat: {
type: [String, Number]
},
lng: {
type: [String, Number]
}
},

mounted() {
var self = this;
window.addEventListener('message', function(event) {
// 对于无法识别的地址,直接返回无法选择
var loc = event.data;
if (loc && loc.module === 'locationPicker') { // 防止其他应用也会向该页面post信息,需判断module是否为'locationPicker'
self.$emit('getLoc', loc)
}
}, false)
}
}
</script>

<style lang="scss" scoped>
.map {
width: 100%;
height: 100%;
}
</style>

+ 72
- 0
src/components/statistics/resume/major/index.vue View File

@@ -0,0 +1,72 @@
<template>
<a-card title="求职者专业统计">
<major-search @searchData="searchData" @clearData="clearData" :search_params="commomParams.search"></major-search>
<a-c-table :data="commomParams.table.data" :columns="commomParams.table.columns" :pagination="commomParams.page"
@page="getPage" :loading="loading">
</a-c-table>
</a-card>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import MajorSearch from '@/components/statistics/resume/major/search/index.vue';
import { GetStatsMajor } from '@/apis/models';
import { useCommon } from '@/hooks/useCommon';
let { commomParams } = useCommon();
let loading = ref<Boolean>(true);


onMounted(() => {
getData(commomParams.value.search);
})
const searchData = (data : object) => {
commomParams.value.search = data
getData();
}
const clearData = (data : object) => {
if (data) {
commomParams.value.search = data
} else {
commomParams.value.search = {
page: 1,
pagesize: 10,
sort: 'major',
sortby: 'asc',
keyword: ''
}
}
getData();
}
const getPage = (data : object) => {
commomParams.value.search.page = data.current;
commomParams.value.search.pagesize = data.pageSize;
getData();
}
const getData = async () => {
try {
loading.value = true;
let res = await GetStatsMajor(commomParams.value.search);
loading.value = false;
commomParams.value.table.data = res.data.list;
commomParams.value.table.columns = cols;
commomParams.value.page = {
current: commomParams.value.search.page,
pageSize: commomParams.value.search.pagesize,
total: res.data.total,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
};
} catch {
loading.value = false;
}
}
</script>

<style>
</style>

+ 57
- 0
src/components/statistics/resume/major/search/index.vue View File

@@ -0,0 +1,57 @@
<template>
<a-range-picker @Change="getRange" />
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed } from 'vue';
import { useCommon } from '@/hooks/useCommon';
let { commomParams, dayjs } = useCommon();
const dayjsRef = ref(dayjs);
let props = defineProps(['search_params']);
const emit = defineEmits();
interface listType {
start_date: String,
end_date: String
}
commomParams.value.search = commomParams.value.search as listType;
commomParams.value.search.start_date = '2020-01-01';
commomParams.value.search.end_date = dayjs().format('YYYY-MM-DD');
commomParams.value.search.sort = 'major';
watch(() => props.search_params, (newVal) => {
emit('searchData', commomParams.value.search)
}, {
immediate: true
})
const getRange = (val) => {
commomParams.value.search.start_date = dayjsRef.value(val[0]).format('YYYY-MM-DD');
commomParams.value.search.end_date = dayjsRef.value(val[1]).format('YYYY-MM-DD');
emit('searchData', commomParams.value.search);
}
const getData = () => {
emit('searchData', commomParams.value.search);
}
// 清空搜索
const clearSearch = () => {
commomParams.value.search = {
page: 1,
pagesize: 10,
sort: 'major',
sortby: 'asc',
keyword: ''
}
emit('clearData', commomParams.value.search);
}
const onClose = () => {
clearSearch()
}
</script>

<style>
</style>

+ 157
- 0
src/components/upload/one.vue View File

@@ -0,0 +1,157 @@
<template>
<div style="display: flex;">
<img v-if="imagesLength == 1 && imageUrl" :src="imageUrl" alt="avatar" width="100px" height="100px"
style="margin-right: 10px;" />
<template v-else>
<template v-for="(item, index) in imagesList" v-key="index">
<div style="margin-right: 10px;">
<a-space direction="vertical">
<a-image :src="item.url" :width="100" :height="100" />
<a-button block danger size="small" @click="delImage(index)">删除此张</a-button>
</a-space>
</div>
</template>
</template>
<template v-if="imagesList.length < imagesLength || imagesList.length == 1">
<a-upload a-upload v-model:file-list="fileList" list-type="picture-card" class="avatar-uploader"
:show-upload-list="false" :before-upload="beforeUpload" :data="uploadData"
:customRequest="uploadCustom">
<plus-outlined />
<div class="ant-upload-text">{{uploadTxt}}</div>
</a-upload>
</template>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed, defineProps, watch, defineEmits } from 'vue';
import axios from 'axios';
import { useCommon } from '@/hooks/useCommon';
let { message, imageprefix } = useCommon();
const props = defineProps({
upload_txt: String,
success_image: String,
images_length: Number,
images_list: {
type: Array,
default: []
},
image_type: {
type: Number,
default: 1
}
});
const emit = defineEmits();
const headers = ref<Object>({
Authorization: sessionStorage.getItem('token'),
'X-Requested-With': null
})
const uploadData = ref<Object>({
image: ''
})
const imageType = ref<Number>(props.image_type)
let imagesList = ref<Object[]>([])
let odImagesList = ref<Object[]>([]) // 暂存
let fileList = ref<Object[]>([])
let imageUrl = ref<String>(props.success_image) // 图片路径
let uploadTxt = ref<String>(props.upload_txt)
let imagesLength = ref<Number>(props.images_length)
watch(() => [props.success_image, props.image_type, props.images_list], (newVal, oldVal) => {
imageUrl.value = newVal[0];
imageType.value = newVal[1];
odImagesList.value = []
imagesList.value = []
if (newVal[2]) {
newVal[2].map(item => {
odImagesList.value.push({ photo: item })
})
}
if (newVal[2]) {
newVal[2].map(item => {
imagesList.value.push({ url: imageprefix + item })
})
}
}, {
immediate: true
})


const beforeUpload = (file) => {
uploadData.value.image = file
}

const uploadCustom = (e) => {
let formdata = new FormData()
formdata.append('image', e.file)
axios({
url: 'https://rcsc-test.jcjob.cn/api/common/image/upload?imgtype=' + imageType.value,
method: 'post',
data: formdata,
headers: headers.value
}).then((res) => {
if (imagesLength.value === 1) {
imagesList.value = [{
uid: '-1', // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
name: e.file.name, // 文件名
status: 'done', // 状态有:uploading done error removed
url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename
}]
} else {
if (imagesList.value.length < imagesLength.value) {
console.log(imagesList.value)
imagesList.value.push({
uid: '-' + (imagesList.value.length + 1), // 文件唯一标识,建议设置为负数,防止和内部产生的 id 冲突
name: e.file.name, // 文件名
status: 'done', // 状态有:uploading done error removed
url: "https://rcsc-test.jcjob.cn/img" + res.data.data.filename
})
} else {
message.danger('最多上传5张');
}
}
console.log(res.data.data.filename)
message.success(`${props.upload_txt}成功`);
emit('uploadSuccess', res.data.data.filename)
})
}

// 删除照片
const delImage = (index) => {
imagesList.value.splice(index, 1)
odImagesList.value.splice(index, 1)
console.log(odImagesList.value)
emit('delImageAfter', odImagesList.value)
}


// const uploadChange = ({ file, fileList }) => {
// console.log(fileList)
// if (file.file.response) {
// message.success(`${props.upload_txt}成功`);
// emit('uploadSuccess', file.file.response)
// }
// }
</script>

<style scoped lang="less">
.avatar-uploader>.ant-upload {
width: 128px;
height: 128px;
}

.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}

.ant-upload-select-picture-card .ant-upload-list-item {
width: 128px;
height: 128px;
margin-right: 8px;
}
</style>

+ 35
- 0
src/hooks/common.d.ts View File

@@ -0,0 +1,35 @@
declare namespace CommonType {
type PageType = {
current ?: Number;
pageSize ?: Number;
total ?: Number;
pageSizeOptions ?: String[];
hideOnSinglePage ?: Boolean;
showSizeChanger ?: Boolean;
}
type ModelType = {
title ?: String;
okText : String | '提交';
resetText : String | '重置';
cancelText : String | '取消';
}
type SearchType = {
page ?: Number,
pagesize ?: Number,
sort ?: String,
sortby ?: String,
keyword ?: String
}
type TableType = {
data : Object[],
columns : Object[],
}
type DeleteType = {
id ?: Number
}
}


+ 0
- 0
src/hooks/index.ts View File


+ 44
- 0
src/hooks/useAsRouter.ts View File

@@ -0,0 +1,44 @@
import { ref } from 'vue';
import { router } from '@/router';

export const useAsRouter = () => {
// 获取当前路由
function routerCur() {
return router.currentRoute.value.path
}
// 获取当前路由父路由
function routerArrayCur() {
return router.currentRoute.value.matched[1].path;
}
// 跳转路由
function routerTo(url : string) {
router.push(url)
}

// 匹配路由页面
function routerDynamic(userRouter : string[], originRouter : Object[]) {
const finalRouter = originRouter.filter(item => userRouter.includes(item.name)).map(item => ({ ...item, children: item.children ? routerDynamic(userRouter, item.children) : null }));
return finalRouter;
}

// 添加路由
function routerAdd(route) {
router.addRoute('', route);
}

// 初始化路由
function routerInit() {
return router.options.routes + router.options.routes.LayoutRoute;
}

return {
routerCur,
routerArrayCur,
routerTo,
routerDynamic,
routerAdd,
routerInit
}
}

+ 149
- 0
src/hooks/useCommon.ts View File

@@ -0,0 +1,149 @@
import { ref } from 'vue';
import { store } from '@/store';
import { useAsRouter } from './useAsRouter'
import dayjs, { Dayjs } from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
import { message } from 'ant-design-vue';



interface CommonInterface {
model ?: CommonType.ModelType,
page ?: CommonType.PageType
search ?: CommonType.SearchType
table ?: CommonType.TableType
delParam ?: CommonType.DeleteType,

}

export const useCommon = () => {
const { routerTo, routerCur, routerArrayCur } = useAsRouter();
let commomParams = ref<CommonInterface>({
model: {
title: '',
okText: '提交',
resetText: '重置',
cancelText: '取消',
},

page: {
current: 1,
pageSize: 1,
total: 10,
pageSizeOptions: ['10', '20', '30', '40'],
hideOnSinglePage: false,
showSizeChanger: true
},

search: {
page: 1,
pagesize: 10,
sort: 'id',
sortby: 'desc',
keyword: ''
},

table: {
data: [],
columns: [],
},

delParam: {
id: 0
},



// // MENU
// openSubMenu: [],
// menuList: [],

})

let openAddModel = ref<Boolean>(store.state.openAddModel);
let openOtherModel_1 = ref<Boolean>(store.state.openOtherModel_1);
let openSearchModel = ref<Boolean>(store.state.openSearchModel); // 搜索

// 点击菜单获取路由
const onMenu = (path) => {
routerTo(path);
};

// Modal
const hideModal = () => {
store.commit('getOpenModel', {
openAddModel: false
})
}

// 打开添加/编辑对话框
const showModal = () => {
store.commit('getOpenModel', {
openAddModel: true
})
};

const showOtherModal1 = () => {
store.commit('getOpenMoreModel', {
openOtherModel_1: true
})
};

const hideOtherModal1 = () => {
store.commit('getOpenMoreModel', {
openOtherModel_1: false
})
}

// 打开搜索
const showSearch = () => {
store.commit('getSearchModel', {
openSearchModel: true
})
};
const hideSearch = () => {
store.commit('getSearchModel', {
openSearchModel: false
})
}

// 富文本全局
let richOption = ref<Object>({
debug: 'info',
modules: {
},
placeholder: '请输入文字'
});
// 禁止使用日期
const disabledDate = (val: Dayjs) => {
return val && val > dayjs().endOf('day');
};
// 照片前缀
const imageprefix : string = 'https://rcsc-test.jcjob.cn/img/'


return {
store,
commomParams,
openAddModel,
onMenu,
hideModal,
showModal,
openOtherModel_1,
showOtherModal1,
hideOtherModal1,
dayjs,
richOption,
message,
disabledDate,
imageprefix,
openSearchModel,
showSearch,
hideSearch
}
}

+ 26
- 0
src/hooks/useMenu.ts View File

@@ -0,0 +1,26 @@
import { ref } from 'vue';
import { useAsRouter } from './useAsRouter'
import { store } from '@/store'
import { message } from 'ant-design-vue';

export const useMenu = () => {
const { routerTo, routerCur, routerArrayCur } = useAsRouter();
const openSubMenu = ref<string[]>([]);
const menuList = ref<object[]>(store.state.permissions.menuList);

// 点击菜单获取路由
const onMenu = (path) => {
routerTo(path);
};


return {
routerCur,
routerArrayCur,
openSubMenu,
menuList,
onMenu,
message
}
}

+ 66
- 0
src/main.ts View File

@@ -0,0 +1,66 @@
import { createApp } from 'vue';
import './style.css';
import App from './App.vue';
import { router } from './router'
import { store } from './store';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';


import { QuillEditor } from '@vueup/vue-quill'
import '@vueup/vue-quill/dist/vue-quill.snow.css';

import ACOperation from '@/components/cOperation/cOperation.vue';
import ACTable from '@/components/cTable/cTable.vue';
import ACCascader from '@/components/cCascader/cascader.vue';

import AShujilian from '@/components/form/shujilian.vue';
import SearchSelect from '@/components/form/search-select.vue';
import AXuanze from '@/components/cSelect/xuanze.vue';
import ACSelect from '@/components/cSelect/select.vue';
import ACSelectCommon from '@/components/cSelect/common.vue';
import UploadOne from '@/components/upload/one.vue';
import { Model } from 'node_modules/echarts/index';
router.beforeEach((to, from, next) => {
document.title = `${to.meta.title} - 菊城人才市场后台管理`;
if (!sessionStorage.getItem('token')) {
if (to.matched.length > 0 && !to.matched.some(record => record.meta.requiresAuth)) {
next()
} else {
next({
path: '/login'
})
}
} else {
if (store.state.permissions.permissionList == null) {
store.dispatch('permissions/FETCH_PERMISSION').then(() => {
next({
path: to.path
})
})
} else {
if (to.path !== '/login') {
next()
} else {
next(from.fullPath)
}
}
}
})

const app = createApp(App);
app.component('a-c-operation', ACOperation);
app.component('a-c-table', ACTable);
app.component('a-c-cascader', ACCascader);
app.component('a-c-select', ACSelect);
app.component('a-xuanze', AXuanze);
app.component('a-shujilian', AShujilian);
app.component('search-select', SearchSelect);

app.component('a-c-select-common', ACSelectCommon);
app.component('QuillEditor', QuillEditor)
app.component('upload-one', UploadOne)
app.use(router);
app.use(store);
app.use(Antd);
app.mount('#app');

+ 326
- 0
src/router/dynamic.ts View File

@@ -0,0 +1,326 @@
import type { AppRouteRecordRaw, AppRouteModule } from '@/router/types';
import { HomeOutlined } from '@ant-design/icons-vue';
import { routerList } from './routerList';

// 权限管理
const PermissionRoute : AppRouteRecordRaw = {
path: '/permission',
name: 'permission',
component: routerList.Permission,
meta: {
title: '权限管理',
icon: HomeOutlined
},
children: [
{
path: '/role',
name: 'role',
component: routerList.ROLE,
meta: {
title: '角色管理',
icon: HomeOutlined
}
},
{
path: '/account',
name: 'account',
component: routerList.Account,
meta: {
title: '账号管理',
icon: HomeOutlined
}
},
{
path: '/permission/list',
name: 'list',
component: routerList.List,
meta: {
title: '权限管理',
icon: HomeOutlined
}
}
]
};


// 企业相关
const CompanyRoute : AppRouteRecordRaw = {
path: '/company',
name: 'company',
component: routerList.Company,
meta: {
title: '企业管理',
icon: HomeOutlined
},
children: [{
path: '/member',
name: 'member',
component: routerList.Member,
meta: {
title: '企业列表',
icon: HomeOutlined
},
},
{
path: '/vip',
name: 'vip',
component: routerList.Vip,
meta: {
title: 'VIP管理',
icon: HomeOutlined
},
},
{
path: '/department',
name: 'department',
component: routerList.Department,
meta: {
title: '部门管理',
icon: HomeOutlined
},
},
{
path: '/job',
name: 'job',
component: routerList.Job,
meta: {
title: '职位管理',
icon: HomeOutlined
},
},
]
};

// 家政
const HomemakeRoute : AppRouteRecordRaw = {
path: '/homemake',
name: 'homemake',
component: routerList.Homemake,
meta: {
title: '家政管理',
icon: HomeOutlined
},
children: [{
path: '/homemake/type',
name: 'homemakeType',
component: routerList.HomemakeType,
meta: {
title: '家政类型',
icon: HomeOutlined
},
},
{
path: '/homemake/position',
name: 'homemakePosition',
component: routerList.HomemakePosition,
meta: {
title: '职位申请',
icon: HomeOutlined
},
},
{
path: '/homemake/demand',
name: 'homemakeDemand',
component: routerList.HomemakeDemand,
meta: {
title: '家政需求',
icon: HomeOutlined
},
},
{
path: '/homemake/appointment',
name: 'homemakeAppointment',
component: routerList.HomemakeAppointment,
meta: {
title: '家政预定',
icon: HomeOutlined
},
},
]
};

// 求职者管理
const JokSeekerRoute : AppRouteRecordRaw = {
path: '/job-seeker',
name: 'jobSeeker',
component: routerList.JobSeeker,
meta: {
title: '求职者管理',
icon: HomeOutlined
},
children: [
{
path: '/resume',
name: 'jobResume',
component: routerList.JobResume,
meta: {
title: '简历列表',
icon: HomeOutlined
},
},
]
};

// 招聘会管理
const JokFairRoute : AppRouteRecordRaw = {
path: '/job-fair',
name: 'jobFair',
component: routerList.JokFair,
meta: {
title: '招聘会管理',
icon: HomeOutlined
},
children: [
{
path: '/job/fair/list',
name: 'jobFairList',
component: routerList.JobFairList,
meta: {
title: '招聘会列表',
icon: HomeOutlined
},
},
// {
// path: '/job/fair/company',
// name: 'jobFairCompany',
// component: routerList.JobFairCompany,
// meta: {
// title: '参与企业',
// icon: HomeOutlined
// },
// },
]
};

// 资讯管理
const InformationRoute : AppRouteRecordRaw = {
path: '/information',
name: 'information',
component: routerList.Information,
meta: {
title: '资讯管理',
icon: HomeOutlined
},
children: [
{
path: '/section',
name: 'section',
component: routerList.InformationSection,
meta: {
title: '栏目/频道',
icon: HomeOutlined
},
},
{
path: '/article',
name: 'article',
component: routerList.InformationArticle,
meta: {
title: '文章列表',
icon: HomeOutlined
},
}
],
};

// 广告管理
const AdvertisementRoute : AppRouteRecordRaw = {
path: '/advertisement',
name: 'advertisement',
component: routerList.Advertisement,
meta: {
title: '广告/活动管理',
icon: HomeOutlined
},
children: [
{
path: '/advertisement/list',
name: 'advertisementList',
component: routerList.AdvertisementList,
meta: {
title: '广告/活动列表',
icon: HomeOutlined
},
},
{
path: '/put/in',
name: 'putIn',
component: routerList.AdvertisementPutin,
meta: {
title: '广告/活动投放',
icon: HomeOutlined
},
}
],
};

// 活动管理
const ActivityRoute : AppRouteRecordRaw = {
path: '/activity',
name: 'activity',
component: routerList.Activity,
meta: {
title: '活动管理',
icon: HomeOutlined
},
children: [
// {
// path: '/activity/list',
// name: 'activityList',
// component: routerList.ActivityList,
// meta: {
// title: '活动列表',
// icon: HomeOutlined
// },
// },
{
path: '/activity/address',
name: 'activityAddress',
component: routerList.ActivityAddress,
meta: {
title: '活动地址',
icon: HomeOutlined
},
}
],
};

// 统计
const StatisticsRoute : AppRouteRecordRaw = {
path: '/statistics',
name: 'statistics',
component: routerList.Statistics,
meta: {
title: '统计管理',
icon: HomeOutlined
},
children: [
{
path: '/statistics/resume',
name: 'statisticsResume',
component: routerList.StatisticsResume,
meta: {
title: '简历统计',
icon: HomeOutlined
},
children: [
{
path: '/statistics/resume/major',
name: 'statisticsResumeMajor',
component: routerList.StatisticsResumeMajor,
meta: {
title: '职称与技能',
icon: HomeOutlined
},
}
],
}
],
};

export const routesModuleList : AppRouteModule[] = [CompanyRoute,HomemakeRoute, JokSeekerRoute, JokFairRoute, InformationRoute, AdvertisementRoute, ActivityRoute, StatisticsRoute,PermissionRoute];

+ 8
- 0
src/router/index.ts View File

@@ -0,0 +1,8 @@
import { createRouter, createWebHistory } from 'vue-router';

import { basicRoutes } from './routes';

export const router = createRouter({
history: createWebHistory(),
routes: basicRoutes
})

+ 80
- 0
src/router/routerList.ts View File

@@ -0,0 +1,80 @@
import Permission from '@/views/permission/index.vue';
import ROLE from '@/views/permission/role/index.vue';
import Account from '@/views/permission/account/index.vue';
import List from '@/views/permission/list/index.vue';
// 企业管理
import Company from '@/views/company/index.vue';
import Department from '@/views/company/department/index.vue';
import Job from '@/views/company/position/index.vue';
import Member from '@/views/company/list/index.vue';
import Vip from '@/views/company/vip/index.vue';

// 家政
import Homemake from '@/views/homemake/index.vue';
import HomemakeType from '@/views/homemake/type/index.vue';
import HomemakePosition from '@/views/homemake/position/index.vue';
import HomemakeDemand from '@/views/homemake/demand/index.vue';
import HomemakeAppointment from '@/views/homemake/appointment/index.vue';

// 求职者管理
import JobSeeker from '@/views/jobSeeker/index.vue';
import JobResume from '@/views/jobSeeker/resume/index.vue';

// 招聘会管理
import JobFair from '@/views/jobFair/index.vue';
import JobFairList from '@/views/jobFair/list/index.vue';
import JobFairCompany from '@/views/jobFair/company/index.vue';

// 资讯管理
import Information from '@/views/information/index.vue';
import InformationSection from '@/views/information/section/index.vue';
import InformationArticle from '@/views/information/article/index.vue';

// 广告管理
import Advertisement from '@/views/advertisement/index.vue';
import AdvertisementList from '@/views/advertisement/list/index.vue';
import AdvertisementPutin from '@/views/advertisement/putin/index.vue';

// 活动管理
import Activity from '@/views/activity/index.vue';
import ActivityList from '@/views/activity/list/index.vue';
import ActivityAddress from '@/views/activity/address/index.vue';

// 统计
import Statistics from '@/views/statistics/index.vue';
import StatisticsResume from '@/views/statistics/resume/index.vue';
import StatisticsResumeMajor from '@/views/statistics/resume/major/index.vue';

export const routerList = {
Permission,
ROLE,
Account,
List,
Company,
Department,
Job,
Member,
Vip,
Homemake,
HomemakeType,
HomemakePosition,
HomemakeDemand,
HomemakeAppointment,
JobSeeker,
JobResume,
JobFair,
JobFairList,
JobFairCompany,
Information,
InformationSection,
InformationArticle,
Advertisement,
AdvertisementList,
AdvertisementPutin,
Activity,
ActivityList,
ActivityAddress,
Statistics,
StatisticsResume,
StatisticsResumeMajor
}

+ 37
- 0
src/router/routes.ts View File

@@ -0,0 +1,37 @@
import type { AppRouteRecordRaw } from '@/router/types';
import { HomeOutlined } from '@ant-design/icons-vue';

import LOGIN from '@/views/login/login.vue';
import HOME from '@/views/home/home.vue';
import Layout from '@/components/layout/index.vue';

// 登录路由
export const LoginRoute: AppRouteRecordRaw = {
path: '/login',
name: 'login',
component: LOGIN,
meta: {
title: '登录'
}
}

// layout路由
export const LayoutRoute: AppRouteRecordRaw = {
path: '',
name: 'layout',
component: Layout,
redirect: '/home',
children: [{
path: '/home',
name: 'home',
component: HOME,
meta: {
title: '首页',
icon: HomeOutlined
}
}]
}

export const basicRoutes = [
LoginRoute
]

+ 12
- 0
src/router/types.ts View File

@@ -0,0 +1,12 @@
import type { RouteRecordRaw, RouteMeta } from 'vue-router';

// @ts-ignore
export interface UseRouteRecordRaw extends omit<RouteRecordRaw, 'meta'> {
path ?: string,
name ?: string,
component ?: string,
meta: RouteMeta,
children ?: UseRouteRecordRaw[]
}

export type UseRouteModule = UseRouteRecordRaw;

BIN
src/static/images/logo.jpg View File


BIN
src/static/images/logo.png View File


BIN
src/static/images/logo_1.jpg View File


+ 13
- 0
src/store/index.ts View File

@@ -0,0 +1,13 @@
import { createStore } from 'vuex';
import { state } from './state';
import { mutations } from './mutations';
import { permissionsModule } from './usePermissionStore';

export const store = createStore({
state,
mutations,
modules: {
permissions: permissionsModule,
}
})


+ 49
- 0
src/store/mutations.ts View File

@@ -0,0 +1,49 @@
const getCollapsed = (state : object) => {
state.collapsed = !state.collapsed;
}

const getOpenModel = (state : object, payload : object) => {
state.openAddModel = payload.openAddModel;
}

const getOpenMoreModel = (state : object, payload : object) => {
state.openOtherModel_1 = payload.openOtherModel_1;
}

// 搜索
const getSearchModel = (state : object, payload : object) => {
state.openSearchModel = payload.openSearchModel;
}

// 查看部门
const getShowDepartmentModel = (state : object, payload : object) => {
state.showDepartmentModel = payload.showDepartmentModel;
}

// 查看职位
const getShowPositionModel = (state : object, payload : object) => {
state.showPositionModel = payload.showPositionModel;
}

// 查看公司
const getShowCompanyModel = (state : object, payload : object) => {
state.showCompanyModel = payload.showCompanyModel;
}

// 加入
const getShowAddCompanyModel = (state : object, payload : object) => {
state.showAddCompanyModel = payload.showAddCompanyModel;
}



export const mutations = {
getCollapsed,
getOpenModel,
getOpenMoreModel,
getSearchModel,
getShowDepartmentModel,
getShowPositionModel,
getShowCompanyModel,
getShowAddCompanyModel,
}

+ 12
- 0
src/store/state.ts View File

@@ -0,0 +1,12 @@
import { StateType } from './types'

export const state = <StateType>{
collapsed: false,
openAddModel: false,
openOtherModel_1: false,
showDepartmentModel: false,
showPositionModel: false,
showCompanyModel: false,
showAddCompanyModel: false,
openSearchModel: false // 搜索
}

+ 10
- 0
src/store/types.ts View File

@@ -0,0 +1,10 @@
export interface StateType {
collapsed: boolean,
openAddModel: boolean,
openOtherModel_1: boolean,
showDepartmentModel: boolean,
showPositionModel: boolean,
showCompanyModel: boolean,
showAddCompanyModel: boolean,
openSearchModel: boolean
}

+ 78
- 0
src/store/usePermissionStore.ts View File

@@ -0,0 +1,78 @@
import { Module } from 'vuex';
import { useAsRouter } from '@/hooks/useAsRouter';
import { routesModuleList } from '@/router/dynamic';
import { LayoutRoute } from '@/router/routes';
import { GetUserMenulist } from '@/apis/models';

const { routerDynamic, routerAdd, routerInit } = useAsRouter();


export interface PermissionState {
arrresult : string[];
menuList : string[];
permissionList : string[] | null;
breadcrumbList : string[];
}

const state : PermissionState = {
arrresult: [],
menuList: [],
permissionList: null,
breadcrumbList: []
};

const mutations = {
SET_PERMISSION(state, routes) {
state.permissionList = routes
},
SET_MENU(state, menu) {
state.menuList = menu
}
};

const actions = {
async FETCH_PERMISSION({
state,
commit
}) {
try {
// state.arrresult = [];
// let res = await GetUserMenulist();
// res.data.menulist.map(item => {
// pushItem(item)
// })
// let arr = state.arrresult;
// let arr = getArr
let arr = ['permission', 'role', 'account', 'company', 'vip', 'member', 'homemake', 'homemakeType', 'homemakePosition', 'homemakeDemand', 'homemakeAppointment', 'job', 'department', 'jobSeeker', 'jobResume', 'jobFair', 'jobFairList', 'jobFairCompany', 'information', 'section', 'article', 'list', 'putIn', 'advertisementList', 'advertisement', 'activity', 'activityList', 'activityAddress', 'statistics', 'statisticsResume', 'statisticsResumeMajor'];
let routes = routerDynamic(arr, routesModuleList);
LayoutRoute.children.push(...routes);
commit('SET_MENU', LayoutRoute.children);
routerAdd(LayoutRoute);
let initialRoutes = routerInit();
commit('SET_PERMISSION', [...initialRoutes]);
} catch {

}
}
};

const pushItem = (item : Object) => {
state.arrresult.push(item.action)
if (item.childs) {
for (const child of item.childs) {
pushItem(child)
}
}

return state.arrresult;
}




export const permissionsModule : Module<PermissionState> = {
namespaced: true,
state,
mutations,
actions
};

+ 79
- 0
src/style.css View File

@@ -0,0 +1,79 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

.card {
padding: 2em;
}

#app {
width: 100%;
height: 100%;
overflow: hidden;
overflow: auto;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

+ 7
- 0
src/types/column.d.ts View File

@@ -0,0 +1,7 @@
declare namespace ColType {
type type = {
title: String,
dataIndex: String,
slots: Object
}
}

+ 52
- 0
src/utils/dataHelper.ts View File

@@ -0,0 +1,52 @@
export const findidx : Function = (arr: any, val: any) => {
return arr.findIndex(item => {
return item.id === val
})
}

export const intersectionAlike : Function = (objA: any, objB: any) => {
const result = {};
for (const keyA in objA) {
if (objB.hasOwnProperty(keyA)) {
result[keyA] = objB[keyA];
}
}
return result;
}



export const hasValue : Function = (obj: any) => {
let result = '';
result = Object.keys(obj).filter(key => obj[key] !== 0).map(key => `${obj[key]}`).join('')
return result;
}


export const divObj : Function = (obj: any) => {
const result = []
obj.reduce((acc, curr, index) => {
curr.idx = index;
result.push(curr)
// const key = `node${index}Info`;
// acc[key] = curr;
// return acc;
}, {});
return result;
}



export const alreadyValue: Function = (obj: any) => {
const result = []
obj.reduce((acc, curr, index) => {
curr.idx = index;
result.push(curr)
// const key = `node${index}Info`;
// acc[key] = curr;
// return acc;
}, {});

return result;
}

+ 6
- 0
src/utils/imageHelper.ts View File

@@ -0,0 +1,6 @@
const ImagePath = '~/static/images/';

export const ImageUrl: object = {
// 未登录头像
logo: ImagePath + 'logo.jpg',
}

+ 30
- 0
src/utils/reqHelper.ts View File

@@ -0,0 +1,30 @@
import { httpGet, httpPost } from '@/apis'

export const getModel : Function = (url : string) => {
return function (params : object) {
return new Promise((resolve, reject) => {
httpGet(url, params, function (response) {
if (response.data.code == 0) {
resolve(response.data)
} else {
reject(response)
}
})
})
}
}

export const postModel : Function = (url : string) => {
return function (params : object) {
return new Promise((resolve, reject) => {
httpPost(url, params, function (response) {
if (response.data.code == 0) {
resolve(response.data)
} else {
reject(response)
}
})
})
}
}


+ 51
- 0
src/utils/timeHelper.ts View File

@@ -0,0 +1,51 @@
interface TimeType {
nowTime ?: string;
nowDate ?: string;
nowWeek ?: string;
}

const timeParams : TimeType = {
nowTime: '',
nowDate: '',
nowWeek: ''
}

export const getTime = () => {
const yy = new Date().getFullYear();
const mm = new Date().getMonth() + 1;
const dd = new Date().getDate();
const week = new Date().getDay();
const hh = new Date().getHours();
const mf =
new Date().getMinutes() < 10 ?
"0" + new Date().getMinutes() :
new Date().getMinutes();
let ss = new Date().getSeconds().toString();
ss = ss.length < 2 ? ('0' + ss) : ss;
switch (week) {
case 1:
timeParams.nowWeek = "星期一";
break;
case 2:
timeParams.nowWeek = "星期二";
break;
case 3:
timeParams.nowWeek = "星期三";
break;
case 4:
timeParams.nowWeek = "星期四";
break;
case 5:
timeParams.nowWeek = "星期五";
break;
case 6:
timeParams.nowWeek = "星期六";
break;
case 7:
timeParams.nowWeek = "星期日";
}
timeParams.nowTime = hh + ":" + mf + ":" + ss;
timeParams.nowDate = yy + "/" + mm + "/" + dd;
return timeParams;
}

+ 15
- 0
src/utils/toastHelper.ts View File

@@ -0,0 +1,15 @@
import { httpGet, httpPost } from '@/apis'
import { message } from 'ant-design-vue';

export const warnToast : Function = (msg : string) => {
message.warning(msg);
}

export const errorToast : Function = (msg : string) => {
message.error(msg);
}

export const successToast : Function = (msg : string) => {
message.success(msg);
}


+ 9
- 0
src/utils/typeHelper.ts View File

@@ -0,0 +1,9 @@
function isType<T>(type:T) {
return function(obj) {
return Object.prototype.toString.call(obj) === "[object " + type + "]";
}
}

export let isFunction = (obj) => {
return isType("Function")(obj);
}

+ 43
- 0
src/views/activity/address/add/add.d.ts View File

@@ -0,0 +1,43 @@
declare namespace companyListType {
type addrFormType = {
full_name ?: String,
registration_number ?: String,
establishment_date ?: String,
contact ?: String,
phone ?: String,
mobile ?: String,
email ?: String,
fax ?: String,
website ?: String,
province ?: Number,
city ?: Number,
district ?: Number,
street ?: Number,
address ?: String,
industry ?: Number,
nature ?: Number,
scale ?: Number,
introduction ?: String,
photo ?: String,
photo_status ?: Number,
license_path ?: String,
license_status : '',
login_name ?: String,
login_pwd ?: String,
company_photos ?: Object[]
}
type addOtherFormType = {
chengli_date?: String,
content?: String,
photo_img?: String,
license_img?: String,
company_photo_img?: String,
company_photos ?: String[],
company_address_cascader?: String,
company_industry_cascader?: String,
company_nature_cascader?: String,
company_scale_cascader?: String,
}
}


+ 0
- 0
src/views/activity/address/add/add.vue View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save