Procházet zdrojové kódy

绑定用户管理

Xiao_123 před 10 měsíci
rodič
revize
a14c0e7bf6

+ 0 - 22
src/api/enterprise.js

@@ -100,14 +100,6 @@ export const personEntryByEnterprise = async (ids) => {
   })
 }
 
-// 招聘端-系统管理-用户管理-列表
-export const getEnterpriseUserList = async (params) => {
-  return await request.get({
-    url: '/app-admin-api/menduner/system/user/page',
-    params
-  })
-}
-
 // 招聘端-企业信息-获取基本信息
 export const getEnterpriseBaseInfo = async () => {
   return await request.get({
@@ -168,18 +160,4 @@ export const updateEnterpriseWelfare = async (data) => {
     url: '/app-admin-api/menduner/system/enterprise/welfare/update',
     data
   })
-}
-
-// 招聘端-系统管理-启用账户
-export const systemUserEnable = async (ids) => {
-  return await request.post({
-    url: `/app-admin-api/menduner/system/user/enable?ids=${ids}`
-  })
-}
-
-// 招聘端-系统管理-禁用账户
-export const systemUserDisable = async (ids) => {
-  return await request.post({
-    url: `/app-admin-api/menduner/system/user/disable?ids=${ids}`
-  })
 }

+ 30 - 0
src/api/recruit/enterprise/system/user/index.js

@@ -0,0 +1,30 @@
+import request from '@/config/axios'
+
+// 列表
+export const getEnterpriseUserList = async (params) => {
+  return await request.get({
+    url: '/app-admin-api/menduner/system/user/page',
+    params
+  })
+}
+
+// 启用账户
+export const systemUserEnable = async (ids) => {
+  return await request.post({
+    url: `/app-admin-api/menduner/system/user/enable?ids=${ids}`
+  })
+}
+
+// 禁用账户
+export const systemUserDisable = async (ids) => {
+  return await request.post({
+    url: `/app-admin-api/menduner/system/user/disable?ids=${ids}`
+  })
+}
+
+// 绑定用户的岗位
+export const systemUserBindingPost = async (id, postId) => {
+  return await request.post({
+    url: `/app-admin-api/menduner/system/user/bind/post?id=${id}&postId=${postId}`
+  })
+}

+ 2 - 2
src/api/recruit/public/delivery/index.js

@@ -16,9 +16,9 @@ export const getHireJobCvRelRecommendList = async () => {
 }
 
 // 结算
-export const hireJobCvRelSettlement = async (ids) => {
+export const hireJobCvRelSettlement = async (id) => {
   return await request.post({
-    url: `/app-admin-api/menduner/system/hire-job-cv-rel/settlement?ids=${ids}`
+    url: `/app-admin-api/menduner/system/hire-job-cv-rel/settlement?id=${id}`
   })
 }
 

+ 5 - 1
src/locales/en.js

@@ -184,7 +184,11 @@ export default {
       affiliatedEnterprise: 'Affiliated enterprise',
       accountType: 'Account type',
       administrators: 'Administrators',
-      regularUser: 'Regular users'
+      regularUser: 'Regular users',
+      post: 'Post',
+      jobBinding: 'Job binding',
+      postNodataToAdd: 'There is currently no job data available, please add job data first',
+      selectBinding: 'Please select the position to be bound'
     }
   },
   resume: {

+ 5 - 1
src/locales/zh-CN.js

@@ -184,7 +184,11 @@ export default {
       affiliatedEnterprise: '所属企业',
       accountType: '账号类型',
       administrators: '管理员',
-      regularUser: '普通用户'
+      regularUser: '普通用户',
+      post: '岗位',
+      jobBinding: '岗位绑定',
+      postNodataToAdd: '暂无岗位数据,请先添加岗位数据',
+      selectBinding: '请选择要绑定的岗位'
     }
   },
   resume: {

+ 1 - 1
src/styles/index.css

@@ -1,5 +1,5 @@
 :root {
-  --zIndex-dialog: 9999;
+  --zIndex-dialog: 999;
   --default-bgc: #f2f4f7;
   --v-primary-base: #00897B;
   --v-error-base: #fe574a;

+ 1 - 1
src/styles/index.min.css

@@ -1 +1 @@
-:root{--zIndex-dialog:9999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%}
+:root{--zIndex-dialog:999;--default-bgc:#f2f4f7;--v-primary-base:#00897B;--v-error-base:#fe574a;--v-primary-lighten1:#26A69A;--v-primary-lighten2:#4DB6AC;--v-primary-lighten3:#80CBC4;--v-primary-lighten4:#B2DFDB;--color-222:#222;--color-333:#333;--color-666:#666;--color-777:#777;--color-999:#999;--color-ccc:#ccc;--color-f3:#f3f3f3;--color-f2f4f742:#f2f4f742;--color-f8:#f8f8f8;--color-f2f4f7:#f2f4f7;--color-d5e6e8:#d5e6e8;--zIndex-breadcrumbs:999}.color-222{color:#222}.color-333{color:#333}.color-666{color:#666}.color-777{color:#777}.color-999{color:#999}.color-ccc{color:#ccc}.color-f3f3f3{color:#f3f3f3}.color-f2f4f742{color:#f2f4f742}.color-f8f8f8{color:#f8f8f8}.color-f2f4f7{color:#f2f4f7}.color-d5e6e8{color:#d5e6e8}.font-size-12{font-size:12px}.font-size-13{font-size:13px}.font-size-14{font-size:14px}.font-size-15{font-size:15px}.font-size-16{font-size:16px}.font-size-17{font-size:17px}.font-size-18{font-size:18px}.font-size-19{font-size:19px}.font-size-20{font-size:20px}.buttons{height:36px;width:224px}.half-button{height:36px;width:88px}.default-width{width:1184px;min-width:1184px;max-width:1184px;margin:0 auto}.defaultLink{color:#008978;cursor:pointer}.default-active{color:var(--v-primary-base) !important}.border-bottom-dashed{border-bottom:1px dashed var(--color-ccc)}.white-bgc{background-color:#fff}.ellipsis{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.septal-line{display:inline-block;width:1px;height:10px;vertical-align:middle;background-color:#e0e0e0;margin:0 10px}.resume-box{border-radius:5px;padding:20px 30px;background-color:#fff}.resume-header{display:flex;justify-content:space-between;align-items:center;height:36px}.resume-title{font-weight:700;font-size:18px;border-left:5px solid #00897B;padding-left:12px;line-height:17px}.resumeNoDataText{color:var(--color-666);font-size:14px}.card-box{width:100%;height:100%}

+ 1 - 1
src/styles/index.scss

@@ -1,5 +1,5 @@
 :root {
-  --zIndex-dialog: 9999;
+  --zIndex-dialog: 999;
   --default-bgc: #f2f4f7;
   --v-primary-base: #00897B;
   --v-error-base: #fe574a;

+ 1 - 1
src/views/recruit/enterprise/publicRecruitmentManagement/deliver/components/table.vue

@@ -51,7 +51,7 @@ import { ref, computed } from 'vue'
 // const { t } = useI18n()
 // const emit = defineEmits(['refresh'])
 defineProps({
-  tab: Number,
+  tab: String,
   items: Array
 })
 const badgeColor = computed(() => (item) => {

+ 16 - 8
src/views/recruit/enterprise/publicRecruitmentManagement/deliver/index.vue

@@ -1,13 +1,13 @@
 <template>
   <v-card class="pa-5 card-box">
     <div class="d-flex justify-space-between">
-      <v-tabs v-model="tab" align-tabs="start" color="primary" bg-color="#f7f8fa">
+      <v-tabs v-model="query.status" align-tabs="start" color="primary" bg-color="#f7f8fa" @update:model-value="handleSearch">
         <v-tab v-for="k in tabList" :value="k.value" :key="k.value">{{ k.label }}</v-tab>
       </v-tabs>
       <TextInput v-model="textItems.value" :item="textItems" @appendInnerClick="handleSearch" @enter="handleSearch"></TextInput>
     </div>
 
-    <v-window v-model="tab" class="mt-1">
+    <v-window v-model="query.status" class="mt-1">
       <v-window-item v-for="k in tabList" :value="k.value" :key="k.value">
         <TablePage :items="items" :tab="k.value" @refresh="getList"></TablePage>
         <CtPagination
@@ -25,20 +25,18 @@
 <script setup>
 defineOptions({ name: 'public-recruitment-deliver'})
 import { ref } from 'vue'
+import { getDict } from '@/hooks/web/useDictionaries'
 import { getHireJobCvPage } from '@/api/recruit/public/delivery'
 import TablePage from './components/table.vue'
 
 const total = ref(0)
-const tab = ref(0)
 const query = ref({
   pageNo: 1,
-  pageSize: 10
+  pageSize: 10,
+  status: '0'
 })
 const items = ref([])
-const tabList = ref([
-  { label: '已推荐', value: 0 },
-  { label: '已结算', value: 1 }
-])
+const tabList = ref([])
 const textItems = ref({
   type: 'text',
   value: '',
@@ -47,6 +45,15 @@ const textItems = ref({
   appendInnerIcon: 'mdi-magnify'
 })
 
+// 获取tab列表项
+const getTabData = () => {
+  getDict('menduner_hire_job_cv_status').then(({ data }) => {
+    data = data?.length && data || []
+    tabList.value = data
+  })
+}
+getTabData()
+
 const getList = async () => {
   const res = await getHireJobCvPage(query.value)
   items.value = res.list
@@ -55,6 +62,7 @@ const getList = async () => {
 getList()
 
 const handleSearch = () => {
+  query.value.pageNo = 1
   getList()
 }
 

+ 63 - 4
src/views/recruit/enterprise/systemManagement/userManagement/index.vue

@@ -1,9 +1,9 @@
 <template>
   <v-card class="pa-5 card-box">
-    <div class="mb-3">
+    <!-- <div class="mb-3">
       <v-btn color="primary" variant="tonal" :disabled="!selected.length" @click="handleAction('all', 0, {})">{{ $t('enterprise.userManagement.enable') }}</v-btn>
       <v-btn class="ml-3" color="primary" variant="tonal" :disabled="!selected.length" @click="handleAction('all', 1, {})">{{ $t('enterprise.userManagement.disable') }}</v-btn>
-    </div>
+    </div> -->
     <v-data-table
       v-model="selected"
       :headers="headers"
@@ -14,7 +14,11 @@
       item-value="id"
     >
       <template #bottom></template>
+      <template v-slot:item.postId="{ item }">
+        {{ postList.length ? postList.find(e => e.id === item.postId)?.nameCn : '' }}
+      </template>
       <template v-slot:item.actions="{ item }">
+        <v-btn color="primary" variant="text" @click="handleBinding(item)">{{ $t('enterprise.userManagement.jobBinding') }}</v-btn>
         <v-btn v-if="item.status === '1' && item.userType !== '1'" color="primary" variant="text" @click="handleAction('', 0, item)">{{ $t('enterprise.userManagement.enable') }}</v-btn>
         <v-btn v-if="item.status === '0' && item.userType !== '1'" color="primary" variant="text" @click="handleAction('', 1, item)">{{ $t('enterprise.userManagement.disable') }}</v-btn>
       </template>
@@ -26,6 +30,10 @@
       @handleChange="handleChangePage"
     ></CtPagination>
   </v-card>
+
+  <CtDialog :visible="show" :widthType="2" titleClass="text-h6" :title="$t('enterprise.userManagement.selectBinding')" @close="handleClose" @submit="handleSubmit">
+    <CtForm ref="formPageRef" :items="formItems"></CtForm>
+  </CtDialog>
 </template>
 
 <script setup>
@@ -33,34 +41,57 @@ defineOptions({ name: 'system-management-user'})
 import { ref } from 'vue'
 import { timesTampChange } from '@/utils/date'
 import { useI18n } from '@/hooks/web/useI18n'
-import { getEnterpriseUserList, systemUserEnable, systemUserDisable } from '@/api/enterprise'
+import { getEnterprisePostPage } from '@/api/recruit/enterprise/system/post'
+import { getEnterpriseUserList, systemUserEnable, systemUserDisable, systemUserBindingPost } from '@/api/recruit/enterprise/system/user'
 import Confirm from '@/plugins/confirm'
 import Snackbar from '@/plugins/snackbar'
 
 const { t } = useI18n()
+const show = ref(false)
 const total = ref(10)
 const items = ref([])
 const selected = ref([])
+const formPageRef = ref()
+const bindQuery = ref({})
 const query = ref({
   pageNo: 1,
   pageSize: 10
 })
-
+const postList = ref([])
 const headers = [
   { title: t('login.username'), key: 'name' },
   { title: t('enterprise.userManagement.affiliatedEnterprise'), key: 'enterpriseName' },
+  { title: t('enterprise.userManagement.post'), key: 'postId' },
   { title: t('enterprise.userManagement.phone'), key: 'phone' },
   { title: t('enterprise.userManagement.email'), key: 'email' },
   { title: t('enterprise.userManagement.accountType'), key: 'userType', value: item => item.userType === '1' ? t('enterprise.userManagement.administrators') : t('enterprise.userManagement.regularUser')},
   { title: t('enterprise.userManagement.lastLoginTime'), key: 'loginDate', value: item => timesTampChange(item.loginDate) },
   { title: t('common.actions'), key: 'actions' }
 ]
+const formItems = ref({
+  options: [
+    {
+      type: 'autocomplete',
+      key: 'postId',
+      value: null,
+      label: '岗位 *',
+      noAttach: false,
+      itemText: 'nameCn',
+      itemValue: 'id',
+      rules: [v => !!v || '请选择要绑定的岗位'],
+      items: []
+    }
+  ]
+})
 
 // 获取企业用户列表
 const getData = async () => {
   const { list, total: number } = await getEnterpriseUserList(query.value)
   items.value = list
   total.value = number
+  // 岗位列表
+  const res = await getEnterprisePostPage({ pageNo: 1, pageSize: 100 })
+  postList.value = res.list
 }
 getData()
 
@@ -85,6 +116,34 @@ const handleAction = (type, index, item) => {
     getData()
   })
 }
+
+// 绑定岗位
+const handleBinding = async (item) => {
+  if (!postList.value.length) {
+    Snackbar.warning(t('enterprise.userManagement.postNodataToAdd'))
+    return
+  }
+  bindQuery.value.id = item.id
+  const obj = formItems.value.options.find(e => e.key === 'postId')
+  obj.items = postList.value
+  obj.value = item.postId
+  show.value = true
+}
+
+const handleClose = () => {
+  show.value = false
+  query.value = {}
+}
+
+const handleSubmit = async () => {
+  const { valid } = await formPageRef.value.formRef.validate()
+  if (!valid) return
+  const postId = formItems.value.options.find(e => e.key === 'postId').value
+  await systemUserBindingPost(bindQuery.value.id, postId)
+  Snackbar.success(t('common.operationSuccessful'))
+  handleClose()
+  getData()
+}
 </script>
 
 <style scoped lang="scss">