فهرست منبع

Merge branch 'dev' of https://git.citupro.com/zhengnaiwen_citu/menduner-admin into dev

lifanagju_citu 1 ماه پیش
والد
کامیت
1f75ade0ed
54فایلهای تغییر یافته به همراه1992 افزوده شده و 448 حذف شده
  1. 1 0
      src/api/infra/apiAccessLog/index.ts
  2. 1 0
      src/api/mall/product/spu.ts
  3. 29 0
      src/api/menduner/schoolRegisterExamine/index.ts
  4. 10 0
      src/api/menduner/system/jobFair/manage/index.ts
  5. 5 0
      src/api/menduner/system/person/index.ts
  6. 1 0
      src/api/system/social/client/index.ts
  7. 2 1
      src/config/axios/service.ts
  8. 10 0
      src/router/modules/remaining.ts
  9. 2 3
      src/views/infra/apiAccessLog/ApiAccessLogDetail.vue
  10. 23 60
      src/views/infra/apiAccessLog/index.vue
  11. 5 0
      src/views/mall/product/spu/form/InfoForm.vue
  12. 2 0
      src/views/mall/product/spu/form/index.vue
  13. 112 0
      src/views/menduner/schoolRegisterExamine/RefuseForm.vue
  14. 160 0
      src/views/menduner/schoolRegisterExamine/index.vue
  15. 16 4
      src/views/menduner/system/analysis/statisticAnalysis/index.vue
  16. 1 0
      src/views/menduner/system/areaManage/index.vue
  17. 5 2
      src/views/menduner/system/content/index.vue
  18. 0 4
      src/views/menduner/system/enterprise/message/details/index.vue
  19. 1 1
      src/views/menduner/system/enterprise/message/index.vue
  20. 1 1
      src/views/menduner/system/enterprise/userbind/details/index.vue
  21. 4 4
      src/views/menduner/system/enterprise/userbind/index.vue
  22. 2 2
      src/views/menduner/system/enterpriseMenu/index.vue
  23. 1 0
      src/views/menduner/system/industry/index.vue
  24. 1 1
      src/views/menduner/system/invoice/index.vue
  25. 6 6
      src/views/menduner/system/job/index.vue
  26. 278 0
      src/views/menduner/system/jobFair/manage/details/components/Category copy.vue
  27. 318 0
      src/views/menduner/system/jobFair/manage/details/components/Category.vue
  28. 162 0
      src/views/menduner/system/jobFair/manage/details/components/InfoSettings.vue
  29. 87 0
      src/views/menduner/system/jobFair/manage/details/components/TicketSettings.vue
  30. 128 0
      src/views/menduner/system/jobFair/manage/details/components/WhiteList.vue
  31. 242 0
      src/views/menduner/system/jobFair/manage/details/index copy.vue
  32. 35 210
      src/views/menduner/system/jobFair/manage/details/index.vue
  33. 65 16
      src/views/menduner/system/jobFair/manage/details/jobFairForm.vue
  34. 8 39
      src/views/menduner/system/jobFair/manage/index.vue
  35. 40 2
      src/views/menduner/system/jobFair/manage/statistics/index.vue
  36. 8 2
      src/views/menduner/system/major/MajorForm.vue
  37. 8 6
      src/views/menduner/system/major/index.vue
  38. 50 0
      src/views/menduner/system/order/TradeDetail.vue
  39. 55 34
      src/views/menduner/system/order/index.vue
  40. 5 6
      src/views/menduner/system/person/details/components/account.vue
  41. 33 0
      src/views/menduner/system/person/details/components/student.vue
  42. 21 14
      src/views/menduner/system/person/details/index.vue
  43. 13 8
      src/views/menduner/system/person/index.vue
  44. 1 0
      src/views/menduner/system/position/index.vue
  45. 5 5
      src/views/menduner/system/positiontag/index.vue
  46. 3 2
      src/views/menduner/system/redeem/index.vue
  47. 1 0
      src/views/menduner/system/skill/index.vue
  48. 1 0
      src/views/menduner/system/tag/index.vue
  49. 2 2
      src/views/menduner/system/talentMap/details/index.vue
  50. 2 1
      src/views/menduner/system/talentMap/index.vue
  51. 1 0
      src/views/menduner/system/web/WebContentForm.vue
  52. 12 12
      src/views/menduner/system/web/index.vue
  53. 6 0
      src/views/system/social/client/SocialClientForm.vue
  54. 1 0
      src/views/system/social/client/index.vue

+ 1 - 0
src/api/infra/apiAccessLog/index.ts

@@ -14,6 +14,7 @@ export interface ApiAccessLogVO {
   userAgent: string
   operateModule: string
   operateName: string
+  userNickName: string
   operateType: number
   beginTime: Date
   endTime: Date

+ 1 - 0
src/api/mall/product/spu.ts

@@ -42,6 +42,7 @@ export interface Spu {
   picUrl?: string // 商品封面图
   sliderPicUrls?: string[] // 商品轮播图
   introduction?: string // 商品简介
+  activeIntroduction?: string // 优惠活动说明
   deliveryTypes?: number[] // 配送方式
   deliveryTemplateId?: number | undefined // 运费模版
   brandId?: number // 商品品牌编号

+ 29 - 0
src/api/menduner/schoolRegisterExamine/index.ts

@@ -0,0 +1,29 @@
+import request from '@/config/axios'
+
+export const FlameSchoolApi = {
+	// 学校列表
+	flameSchoolPage: async (params: any) => {
+		return await request.get({ url: '/menduner/system/teacher/page', params })
+	},
+
+	// 学校详情
+	flameSchoolDetail: async (data: any) => {
+		return await request.post({ url: '/flames/school/detail', data })
+	},
+
+
+	// 账号申请通过
+	flameSchoolExaminePass: async (data: any) => {
+		return await request.post({ url: `/menduner/system/teacher/approved`, data })
+	},
+
+	// 账号申请拒绝
+	flameSchoolExamineRefuse: async (data: any) => {
+		return await request.post({ url: `/menduner/system/teacher/refuse`, data })
+	},
+
+	// 根据学校id获取账号注册被拒绝的原因
+	flameSchoolExamineReasonById: async (data: any) => {
+		return await request.post({ url: `/flames/user/auth/record/get`, data })
+	}
+}

+ 10 - 0
src/api/menduner/system/jobFair/manage/index.ts

@@ -83,6 +83,11 @@ export const JobFairManageApi = {
     return await request.get({ url: `/menduner/system/job-fair/analysis/user/job/cv-rel`, params })
   },
 
+  // 用户投递列表导出
+  exportDelivery: async (params) => {
+    return await request.download({ url: `/menduner/system/job-fair/analysis/user/job/cv-rel/download`, params })
+  },
+
   // 招聘会门票设置
   updateTicketSettings: async (data: any) => {
     return await request.post({ url: `/menduner/system/job-fair/update/admission`, data })
@@ -101,5 +106,10 @@ export const JobFairManageApi = {
   // 关闭招聘会门票权益
   disableTicketRights: async (id) => {
     return await request.post({ url: `/menduner/system/job-fair/admission/disable?id=${id}` })
+  },
+
+  // 更新招聘会类别
+  updateJobFairCategory: async (data: any) => {
+    return await request.put({ url: `/menduner/system/job-fair/update-category`, data })
   }
 }

+ 5 - 0
src/api/menduner/system/person/index.ts

@@ -151,5 +151,10 @@ export const PersonInfoApi = {
   // 面试邀约分页
   getInterviewInvitePage: async (params: any) => {
     return await request.get({ url: `/menduner/system/interview-invite/page`, params })
+  },
+
+  // 获取学生基本信息
+  getStudentInfo: async (userId: string) => {
+    return await request.post({ url: `/menduner/system/student/get?userId=${userId}` })
   }
 }

+ 1 - 0
src/api/system/social/client/index.ts

@@ -8,6 +8,7 @@ export interface SocialClientVO {
   clientId: string
   clientSecret: string
   agentId: string
+  application: string
   status: number
 }
 

+ 2 - 1
src/config/axios/service.ts

@@ -52,8 +52,9 @@ service.interceptors.request.use(
       }
     })
     if (getAccessToken() && !isToken) {
-      ;(config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
+      (config as Recordable).headers.Authorization = 'Bearer ' + getAccessToken() // 让每个请求携带自定义token
     }
+    (config as Recordable).headers['Login-User-type'] = 2
     // 设置租户
     if (tenantEnable && tenantEnable === 'true') {
       const tenantId = getTenantId()

+ 10 - 0
src/router/modules/remaining.ts

@@ -527,6 +527,16 @@ const remainingRouter: AppRouteRecordRaw[] = [
     name: 'jobFairManage',
     meta: { hidden: true },
     children: [
+      {
+        path: 'jobFair/add',
+        name: 'JobFairAdd',
+        meta: {
+          title: '新增招聘会',
+          noCache: true,
+          hidden: true
+        },
+        component: () => import('@/views/menduner/system/jobFair/manage/details/index.vue')
+      },
       {
         path: 'jobFair/detail/:id',
         name: 'JobFairDetail',

+ 2 - 3
src/views/infra/apiAccessLog/ApiAccessLogDetail.vue

@@ -10,9 +10,8 @@
       <el-descriptions-item label="应用名">
         {{ detailData.applicationName }}
       </el-descriptions-item>
-      <el-descriptions-item label="用户信息">
-        {{ detailData.userId }}
-        <dict-tag :type="DICT_TYPE.USER_TYPE" :value="detailData.userType" />
+      <el-descriptions-item label="操作用户">
+        {{ detailData.userNickName || '游客' }}
       </el-descriptions-item>
       <el-descriptions-item label="用户 IP">
         {{ detailData.userIp }}

+ 23 - 60
src/views/infra/apiAccessLog/index.vue

@@ -9,39 +9,6 @@
       :inline="true"
       label-width="68px"
     >
-      <el-form-item label="用户编号" prop="userId">
-        <el-input
-          v-model="queryParams.userId"
-          placeholder="请输入用户编号"
-          clearable
-          @keyup.enter="handleQuery"
-          class="!w-240px"
-        />
-      </el-form-item>
-      <el-form-item label="用户类型" prop="userType">
-        <el-select
-          v-model="queryParams.userType"
-          placeholder="请选择用户类型"
-          clearable
-          class="!w-240px"
-        >
-          <el-option
-            v-for="dict in getIntDictOptions(DICT_TYPE.USER_TYPE)"
-            :key="dict.value"
-            :label="dict.label"
-            :value="dict.value"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="应用名" prop="applicationName">
-        <el-input
-          v-model="queryParams.applicationName"
-          placeholder="请输入应用名"
-          clearable
-          @keyup.enter="handleQuery"
-          class="!w-240px"
-        />
-      </el-form-item>
       <el-form-item label="请求时间" prop="beginTime">
         <el-date-picker
           v-model="queryParams.beginTime"
@@ -53,15 +20,6 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="执行时长" prop="duration">
-        <el-input
-          v-model="queryParams.duration"
-          placeholder="请输入执行时长"
-          clearable
-          @keyup.enter="handleQuery"
-          class="!w-240px"
-        />
-      </el-form-item>
       <el-form-item label="结果码" prop="resultCode">
         <el-input
           v-model="queryParams.resultCode"
@@ -90,36 +48,41 @@
   <!-- 列表 -->
   <ContentWrap>
     <el-table v-loading="loading" :data="list">
-      <el-table-column label="日志编号" align="center" prop="id" width="100" fix="right" />
-      <el-table-column label="用户编号" align="center" prop="userId" />
-      <el-table-column label="用户类型" align="center" prop="userType">
+      <!-- <el-table-column label="日志编号" align="center" prop="id" width="100" fix="right" /> -->
+      <el-table-column label="操作用户" align="center" prop="userNickName">
+        <template #default="scope">{{ scope.row.userNickName || '游客' }}</template>
+      </el-table-column>
+      <el-table-column label="操作名" align="center" prop="operateName" width="180" />
+      <el-table-column label="操作模块" align="center" prop="operateModule" width="180" />
+      <!-- <el-table-column label="用户类型" align="center" prop="userType">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.USER_TYPE" :value="scope.row.userType" />
         </template>
-      </el-table-column>
-      <el-table-column label="应用名" align="center" prop="applicationName" width="150" />
-      <el-table-column label="请求方法" align="center" prop="requestMethod" width="80" />
-      <el-table-column label="请求地址" align="center" prop="requestUrl" width="500" />
-      <el-table-column label="请求时间" align="center" prop="beginTime" width="180">
+      </el-table-column> -->
+      <!-- <el-table-column label="应用名" align="center" prop="applicationName" width="150" /> -->
+      <!-- <el-table-column label="请求方法" align="center" prop="requestMethod" width="80" /> -->
+      <el-table-column label="操作类型" align="center" prop="operateType">
         <template #default="scope">
-          <span>{{ formatDate(scope.row.beginTime) }}</span>
+          <dict-tag :type="DICT_TYPE.INFRA_OPERATE_TYPE" :value="scope.row.operateType" />
         </template>
       </el-table-column>
-      <el-table-column label="执行时长" align="center" prop="duration" width="180">
-        <template #default="scope"> {{ scope.row.duration }} ms </template>
-      </el-table-column>
       <el-table-column label="操作结果" align="center" prop="status">
         <template #default="scope">
-          {{ scope.row.resultCode === 0 ? '成功' : '失败(' + scope.row.resultMsg + ')' }}
+          <span :style="{'color': scope.row.resultCode === 0 ? '#67c23a' : '#f56c6c'}">
+            {{ scope.row.resultCode === 0 ? '成功' : '失败(' + scope.row.resultMsg + ')' }}
+          </span>
         </template>
       </el-table-column>
-      <el-table-column label="操作模块" align="center" prop="operateModule" width="180" />
-      <el-table-column label="操作名" align="center" prop="operateName" width="180" />
-      <el-table-column label="操作类型" align="center" prop="operateType">
+      <el-table-column label="结果码" align="center" prop="resultCode" />
+      <el-table-column label="请求时间" align="center" prop="beginTime" width="180">
         <template #default="scope">
-          <dict-tag :type="DICT_TYPE.INFRA_OPERATE_TYPE" :value="scope.row.operateType" />
+          <span>{{ formatDate(scope.row.beginTime) }}</span>
         </template>
       </el-table-column>
+      <!-- <el-table-column label="请求地址" align="center" prop="requestUrl" width="500" /> -->
+      <!-- <el-table-column label="执行时长" align="center" prop="duration" width="180">
+        <template #default="scope"> {{ scope.row.duration }} ms </template>
+      </el-table-column> -->
       <el-table-column label="操作" align="center" fixed="right" width="60">
         <template #default="scope">
           <el-button
@@ -128,7 +91,7 @@
             @click="openDetail(scope.row)"
             v-hasPermi="['infra:api-access-log:query']"
           >
-            详
+            详
           </el-button>
         </template>
       </el-table-column>

+ 5 - 0
src/views/mall/product/spu/form/InfoForm.vue

@@ -60,6 +60,9 @@
     <el-form-item label="商品轮播图" prop="sliderPicUrls">
       <UploadImgs v-model="formData.sliderPicUrls" :disabled="isDetail" />
     </el-form-item>
+    <el-form-item label="优惠活动说明" prop="activeIntroduction">
+      <Editor v-model:modelValue="formData.activeIntroduction" height="150px" />
+    </el-form-item>
   </el-form>
 </template>
 
@@ -74,6 +77,7 @@ import { CategoryVO } from '@/api/mall/product/category'
 import * as ProductBrandApi from '@/api/mall/product/brand'
 import { BrandVO } from '@/api/mall/product/brand'
 import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
+import { Editor } from '@/components/Editor'
 
 defineOptions({ name: 'ProductSpuInfoForm' })
 
@@ -95,6 +99,7 @@ const formData = reactive<Spu>({
   picUrl: '', // 商品封面图
   sliderPicUrls: [], // 商品轮播图
   introduction: '', // 商品简介
+  activeIntroduction: undefined, // 优惠活动简介
   type: '0', // 商品类型
   brandId: undefined // 商品品牌
 })

+ 2 - 0
src/views/mall/product/spu/form/index.vue

@@ -89,6 +89,7 @@ const formData = ref<ProductSpuApi.Spu>({
   picUrl: '', // 商品封面图
   sliderPicUrls: [], // 商品轮播图
   introduction: '', // 商品简介
+  activeIntroduction: undefined, // 优惠活动简介
   deliveryTypes: [], // 配送方式数组
   deliveryTemplateId: undefined, // 运费模版
   brandId: undefined, // 商品品牌
@@ -148,6 +149,7 @@ const getDetail = async () => {
           item.secondBrokeragePrice = formatToFraction(item.secondBrokeragePrice)
         }
       })
+      formLoading.value = false
       formData.value = res
     } finally {
       formLoading.value = false

+ 112 - 0
src/views/menduner/schoolRegisterExamine/RefuseForm.vue

@@ -0,0 +1,112 @@
+<template>
+  <Dialog :title="formType === 'details' ? '详情' : t('common.audit')" v-model="dialogVisible">
+		<el-descriptions title="" border :column="1">
+      <el-descriptions-item label="学校名称">{{ formatName(info?.school?.name) }}</el-descriptions-item>
+      <el-descriptions-item label="老师昵称">{{ info?.name || '-' }}</el-descriptions-item>
+      <el-descriptions-item label="联系电话">{{ info?.phone || '-' }}</el-descriptions-item>
+			<el-descriptions-item label="负责院系">
+        {{ info?.authDept && info?.authDept.length > 0 ? info?.authDept.map(item => item.name).join('、') : '-' }}
+      </el-descriptions-item>
+      <el-descriptions-item label="在岗证明图片">
+        <el-image class="!w-80px h-80px" :src="info?.employmentCertificate || ''" hide-on-click-modal :preview-src-list="[info?.employmentCertificate]"/>
+      </el-descriptions-item>
+      <el-descriptions-item label="创建时间">{{ info?.createTime ? formatDate(info?.createTime) : '-' }}</el-descriptions-item>
+      <el-descriptions-item v-if="info?.authStatus === '2'" label="审核拒绝原因">{{ info?.authMessage || '-' }}</el-descriptions-item>
+    </el-descriptions>
+
+    <el-form
+			v-if="formType === 'refuse'"
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="80px"
+			class="mt-50px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="拒绝原因" prop="authMessage">
+        <el-input v-model="formData.authMessage" type="textarea" placeholder="请输入拒绝原因" />
+      </el-form-item>
+    </el-form>
+
+    <template #footer>
+      <el-button v-if="formType === 'agree'" @click="handleAgree" type="success" :disabled="formLoading">通 过</el-button>
+      <el-button v-if="formType === 'refuse'" @click="handleRefuse" type="danger" :disabled="formLoading">拒绝</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+/** 门墩儿-学校注册申请拒绝 表单 */
+defineOptions({ name: 'SchoolRegisterRejectForm' })
+import { formatName } from '@/utils'
+import { formatDate } from '@/utils/formatTime'
+import { FlameSchoolApi } from '@/api/menduner/schoolRegisterExamine'
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const dialogVisible = ref(false) // 弹窗的是否展示
+const formRef = ref() // 表单 Ref
+const formType = ref('')
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formRules = reactive({
+  authMessage: [{ required: true, message: '拒绝原因不能为空', trigger: 'blur' }]
+})
+const formData = ref({
+	authMessage: ''
+})
+
+const handleAgree = async () => {
+	try {
+		await message.confirm('确定要通过该学校注册申请吗?')
+
+		await FlameSchoolApi.flameSchoolExaminePass({ id: info.value.id, authMessage: '' })
+		dialogVisible.value = false
+		message.success('操作成功')
+    // 发送操作成功的事件
+    emit('success')
+	} catch {}
+}
+
+const handleRefuse = async () => {
+	// 校验表单
+  await formRef.value.validate()
+
+  formLoading.value = true
+  try {
+    await message.confirm('确定要拒绝该学校注册申请吗?')
+
+   	await FlameSchoolApi.flameSchoolExamineRefuse({ id: info.value.id, authMessage: formData.value.authMessage })
+    formLoading.value = false
+		dialogVisible.value = false
+		message.success('操作成功')
+    // 发送操作成功的事件
+    emit('success')
+  } catch (err) {
+    message.error('拒绝失败')
+  } finally {
+    formLoading.value = false
+		dialogVisible.value = false
+  }
+}
+
+/** 打开弹窗 */
+const info = ref({})
+const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
+const open = async (item: object, type: string) => {
+	formType.value = type
+  dialogVisible.value = true
+  if (type === 'refuse') resetForm()
+
+  info.value = item
+}
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+
+/** 重置表单 */
+const resetForm = () => {
+  formData.value = {
+    authMessage: ''
+  }
+  formRef.value?.resetFields()
+}
+</script>

+ 160 - 0
src/views/menduner/schoolRegisterExamine/index.vue

@@ -0,0 +1,160 @@
+<template>
+  <!-- 搜索工作栏 -->
+  <ContentWrap>
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
+      <el-form-item label="账号昵称" prop="name">
+        <el-input
+          v-model="queryParams.name"
+          placeholder="请输入账号昵称"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-240px"
+        />
+      </el-form-item>
+      <el-form-item label="联系电话" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入联系电话"
+          clearable
+          @keyup.enter="handleQuery"
+          class="!w-240px"
+        />
+      </el-form-item>
+      <el-form-item label="审核状态" prop="authStatus">
+        <el-select
+          v-model="queryParams.authStatus"
+          placeholder="请选择审核状态"
+          clearable
+          class="!w-240px"
+        >
+          <el-option
+            v-for="dict in statusList"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-table v-loading="loading" :data="list" :stripe="true">
+      <el-table-column label="学校名称" align="center" prop="school.name" fixed="left">
+        <template #default="scope">{{ formatName(scope.row.school?.name) }}</template>
+      </el-table-column>
+      <el-table-column label="账号昵称" align="center" prop="name" />
+      <el-table-column label="联系电话" align="center" prop="phone" />
+      <el-table-column label="审核状态" align="center" prop="authStatus">
+        <template #default="scope">
+          <el-tag :type="statusList.find(e => e.value === scope.row.authStatus)?.color">
+            {{ statusList.find(e => e.value === scope.row.authStatus)?.label }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column
+        label="创建时间"
+        align="center"
+        prop="createTime"
+        :formatter="dateFormatter"
+        width="180px"
+      />
+      <el-table-column label="操作">
+        <template #default="scope">
+          <el-button link type="primary" @click="handleAction(scope.row, 'details')">详情</el-button>
+          <template v-if="scope.row.authStatus === '0'">
+            <el-button link type="danger" @click="handleAction(scope.row, 'refuse')">拒绝</el-button>
+            <el-button link type="success" @click="handleAction(scope.row, 'agree')">通过</el-button>
+          </template>
+        </template>
+      </el-table-column>
+    </el-table>
+    <!-- 分页 -->
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 拒绝-原因 -->
+  <RefuseForm ref="refuseRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+/** 门墩儿-学校注册申请 列表 */
+defineOptions({ name: 'SchoolAccountRegisterExamine' })
+
+import { dateFormatter } from '@/utils/formatTime'
+import { FlameSchoolApi } from '@/api/menduner/schoolRegisterExamine'
+import { formatName } from '@/utils'
+import RefuseForm from './RefuseForm.vue'
+
+const loading = ref(true) // 列表的加载中
+const list = ref([]) // 列表的数据
+const total = ref(0) // 列表的总页数
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 10,
+  phone: undefined,
+  authStatus: undefined,
+  name: undefined
+})
+const queryFormRef = ref() // 搜索的表单
+
+const statusList = [
+  { value: '0', label: '待审核', color: 'warning' },
+  { value: '1', label: '审核通过', color: 'success' },
+  { value: '2', label: '审核不通过', color: 'danger' }
+]
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+
+  try {
+    const data = await FlameSchoolApi.flameSchoolPage(queryParams)
+    list.value = data.list
+    total.value = data.total
+  } finally {
+    loading.value = false
+  }
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+/* 拒绝 */
+const refuseRef = ref()
+const handleAction = (item: object, type: string) => {
+  refuseRef.value.open(item, type)
+}
+
+/** 初始化 **/
+onMounted(() => {
+  queryParams.pageNo = 1
+  getList()
+})
+
+</script>

+ 16 - 4
src/views/menduner/system/analysis/statisticAnalysis/index.vue

@@ -392,6 +392,8 @@ const tableHeaders = {
     { name: '工作地区', prop: 'areaName' },
     { name: '工作经验', prop: 'expName' },
     { name: '学历要求', prop: 'eduName' },
+    { name: '发布时间', prop: 'createTime' },
+    { name: '更新时间', prop: 'updateTime' },
   ],
   // 所有职位数量
   pushTotalNum: [
@@ -402,7 +404,9 @@ const tableHeaders = {
     { name: '工作地区', prop: 'areaName' },
     { name: '工作经验', prop: 'expName' },
     { name: '学历要求', prop: 'eduName' },
-    { name: '众聘', prop: 'hire' },
+    { name: '发布时间', prop: 'createTime' },
+    { name: '更新时间', prop: 'updateTime' },
+    // { name: '众聘', prop: 'hire' },
   ],
   // 发布中职位数量
   pushNum: [
@@ -413,7 +417,9 @@ const tableHeaders = {
     { name: '工作地区', prop: 'areaName' },
     { name: '工作经验', prop: 'expName' },
     { name: '学历要求', prop: 'eduName' },
-    { name: '众聘', prop: 'hire' },
+    // { name: '众聘', prop: 'hire' },
+    { name: '发布时间', prop: 'createTime' },
+    { name: '更新时间', prop: 'updateTime' },
   ],
   // 刷新职位
   refreshJobNum: [
@@ -490,6 +496,8 @@ const dealTableData = async () => {
       item.areaName = !item.areaId ? '全国' : getText(item.areaId, areaList)
       item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType)
       item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType)
+      item.updateTime = timesTampChange(item.updateTime)
+      item.createTime = timesTampChange(item.createTime)
       return item
     })
   }
@@ -506,7 +514,9 @@ const dealTableData = async () => {
       item.jobStatus = getDictLabel(DICT_TYPE.MENDUNER_JOB_SEEK_STATUS, item.jobStatus)
       item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType)
       item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType)
-      item.hire = item.hire ? '是' : '否'
+      // item.hire = item.hire ? '是' : '否'
+      item.updateTime = timesTampChange(item.updateTime)
+      item.createTime = timesTampChange(item.createTime)
       return item
     })
   }
@@ -523,7 +533,9 @@ const dealTableData = async () => {
       item.jobStatus = getDictLabel(DICT_TYPE.MENDUNER_JOB_SEEK_STATUS, item.jobStatus)
       item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType)
       item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType)
-      item.hire = item.hire ? '是' : '否'
+      // item.hire = item.hire ? '是' : '否'
+      item.updateTime = timesTampChange(item.updateTime)
+      item.createTime = timesTampChange(item.createTime)
       return item
     })
   }

+ 1 - 0
src/views/menduner/system/areaManage/index.vue

@@ -102,6 +102,7 @@
             v-if="scope.row.type < 4"
             link
             type="primary"
+            v-hasPermi="['menduner:system:area:update']"
             @click="openForm('create', scope.row.id, scope.row.type)"
           >
             添加下级

+ 5 - 2
src/views/menduner/system/content/index.vue

@@ -38,12 +38,13 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:morning-news:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:morning-news:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <el-button
           type="primary"
           plain
           @click="openForm('create')"
+          v-hasPermi="['menduner:system:morning-news:create']"
         >
           <Icon icon="ep:plus" class="mr-5px" /> 新增
         </el-button>
@@ -69,11 +70,13 @@
             link
             type="primary"
             @click="openForm('update', scope.row.id)"
+            v-hasPermi="['menduner:system:morning-news:update']"
           >
             编辑
           </el-button> -->
           <el-button
             link
+            v-hasPermi="['menduner:system:morning-news:delete']"
             type="danger"
             @click="handleDelete(scope.row.id)"
           >

+ 0 - 4
src/views/menduner/system/enterprise/message/details/index.vue

@@ -26,9 +26,6 @@
             <el-tab-pane label="下级企业">
               <SubordinateEnterprises :id="id" />
             </el-tab-pane>
-            <!-- <el-tab-pane v-hasPermi="['menduner:system:enterprise-post:query']" label="岗位管理">
-              <EnterprisePost :id="id" />
-            </el-tab-pane> -->
             <el-tab-pane label="企业用户">
               <EnterpriseUser :id="id" />
             </el-tab-pane>
@@ -49,7 +46,6 @@ import { ElMessage } from 'element-plus'
 import Info from './components/info.vue'
 import Business from './components/businessInfo.vue'
 import SubordinateEnterprises from './components/subordinateEnterprises.vue'
-// import EnterprisePost from './components/post.vue'
 import EnterpriseUser from './components/user.vue'
 import EnterpriseJob from './components/job.vue'
 

+ 1 - 1
src/views/menduner/system/enterprise/message/index.vue

@@ -137,7 +137,7 @@
       <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
       <el-table-column label="操作" align="center" fixed="right" min-width="180">
         <template #default="scope">
-          <el-button link type="success" @click="handleSetVip(scope.row.id, scope.row.vipExpireDate)">权益</el-button>
+          <el-button link type="success" @click="handleSetVip(scope.row.id, scope.row.vipExpireDate)" v-hasPermi="['menduner:system:enterprise:update']">权益</el-button>
           <el-button link type="primary" @click="openDetail(scope.row.id)">详情</el-button>
           <el-button link type="primary" @click="openEdit(scope.row.id)" v-hasPermi="['menduner:system:enterprise:update']">编辑</el-button>
           <!-- <el-button link type="primary" @click="openPositionForm(scope.row.id)" v-hasPermi="['menduner:system:enterprise:update']">更新职位发布类型</el-button> -->

+ 1 - 1
src/views/menduner/system/enterprise/userbind/details/index.vue

@@ -26,7 +26,7 @@
             <el-tab-pane label="交易订单">
               <TradeOrder :user-id="userId" :enterprise-id="enterpriseId" />
             </el-tab-pane>
-            <el-tab-pane label="充值订单">
+            <el-tab-pane label="充值订单" v-hasPermi="['pay:currency-recharge:query']">
               <RechargeOrder :user-id="userId" :enterprise-id="enterpriseId" />
             </el-tab-pane>
           </el-tabs>

+ 4 - 4
src/views/menduner/system/enterprise/userbind/index.vue

@@ -113,10 +113,10 @@
         <template #default="scope">
           <el-button link type="primary" @click="openDetail(scope.row.id, scope.row.enterpriseId, scope.row.userId)">详情</el-button>
           <!-- <el-button link type="primary" @click="openEditEmail(scope.row.id)">修改登录邮箱</el-button> -->
-          <el-button link type="primary" @click="openEdit(scope.row.id)">编辑</el-button>
-          <el-button link type="primary" @click="openEditPassword(scope.row.id)">修改登录密码</el-button>
-          <el-button v-if="scope.row.status === '0'" link type="danger" @click="handleActions(scope.row.id, 'disabled')">禁用</el-button>
-          <el-button v-if="scope.row.status === '1'" link type="success" @click="handleActions(scope.row.id, 'enable')">启用</el-button>
+          <el-button link type="primary" @click="openEdit(scope.row.id)" v-hasPermi="['menduner:system:enterprise-user-bind:update']">编辑</el-button>
+          <el-button link type="primary" @click="openEditPassword(scope.row.id)" v-hasPermi="['menduner:system:enterprise-user-bind:update']">修改登录密码</el-button>
+          <el-button v-if="scope.row.status === '0'" link type="danger" @click="handleActions(scope.row.id, 'disabled')" v-hasPermi="['menduner:system:enterprise-user-bind:update']">禁用</el-button>
+          <el-button v-if="scope.row.status === '1'" link type="success" @click="handleActions(scope.row.id, 'enable')" v-hasPermi="['menduner:system:enterprise-user-bind:update']">启用</el-button>
         </template>
       </el-table-column>
     </el-table>

+ 2 - 2
src/views/menduner/system/enterpriseMenu/index.vue

@@ -34,11 +34,11 @@
         </el-select>
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery">
+        <el-button v-hasPermi="['menduner:system:menu:query']" @click="handleQuery">
           <Icon class="mr-5px" icon="ep:search" />
           搜索
         </el-button>
-        <el-button @click="resetQuery">
+        <el-button @click="resetQuery" v-hasPermi="['menduner:system:menu:query']">
           <Icon class="mr-5px" icon="ep:refresh" />
           重置
         </el-button>

+ 1 - 0
src/views/menduner/system/industry/index.vue

@@ -112,6 +112,7 @@
           <el-button
             link
             type="primary"
+            v-hasPermi="['menduner:system:industry:update']"
             @click="openForm('create', scope.row.id, scope.row.level)"
           >
             添加下级

+ 1 - 1
src/views/menduner/system/invoice/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <ContentWrap>
+  <ContentWrap v-hasPermi="['member:invoice-list:query']">
     <!-- 搜索工作栏 -->
     <el-form
       class="-mb-15px"

+ 6 - 6
src/views/menduner/system/job/index.vue

@@ -95,9 +95,9 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-        <el-button @click="handleSetting" type="primary" plain><Icon icon="ep:setting" class="mr-5px" /> 佣金配置</el-button>
+        <el-button v-hasPermi="['menduner:system:job-advertised:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:job-advertised:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:job-advertised:update']" @click="handleSetting" type="primary" plain><Icon icon="ep:setting" class="mr-5px" /> 佣金配置</el-button>
         <el-button
           type="primary"
           plain
@@ -160,9 +160,9 @@
       <el-table-column label="操作" align="center">
         <template #default="scope">
           <!-- <el-button v-if="scope.row.status === '0'" link type="primary" @click="openForm('update', scope.row.id)">编辑</el-button> -->
-          <el-button link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
-          <el-button v-if="scope.row.status === '0'" link type="warning" @click="handleAction(0, scope.row.id)">关闭</el-button>
-          <el-button v-if="scope.row.status === '1'" link type="success" @click="handleAction(1, scope.row.id)">激活</el-button>
+          <el-button v-hasPermi="['menduner:system:job-advertised:delete']" link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
+          <el-button v-hasPermi="['menduner:system:job-advertised:update']" v-if="scope.row.status === '0'" link type="warning" @click="handleAction(0, scope.row.id)">关闭</el-button>
+          <el-button v-hasPermi="['menduner:system:job-advertised:update']" v-if="scope.row.status === '1'" link type="success" @click="handleAction(1, scope.row.id)">激活</el-button>
         </template>
       </el-table-column>
     </el-table>

+ 278 - 0
src/views/menduner/system/jobFair/manage/details/components/Category copy.vue

@@ -0,0 +1,278 @@
+<template>
+  <div>
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="140px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="类别" prop="category" @change="handleChangeCategory">
+        <el-radio-group v-model="formData.category">
+          <el-radio
+            v-for="dict in categoryList"
+            :key="dict.value"
+            :label="dict.value"
+          >
+            {{ dict.label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="类别详情" prop="tag">
+        <!-- 职位类型 -->
+        <div v-if="formData.category === '1'" class="!w-100%">
+          <el-row v-for="(val, index) in formData.tag" :key="index" class="mb-10px">
+            <el-col :span="8">
+              <el-input v-model="val.title" clearable placeholder="请输入类别名称"/>
+            </el-col>
+            <el-col :span="10" class="mx-10px">
+              <!-- 职位 -->
+              <el-select  v-model="val.value" filterable multiple placeholder="请选择职位类型" collapse-tags collapse-tags-tooltip>
+                <el-option v-for="k in position" :key="k.id" :label="k.nameCn" :value="k.id.toString()"/>
+              </el-select>
+            </el-col>
+            <el-col :span="4">
+              <el-button text circle @click="handleDelete(index)">
+                <Icon icon="ep:close" />
+              </el-button>
+            </el-col>
+          </el-row>
+        </div>
+        <!-- 企业 -->
+        <div v-if="formData.category === '0'" class="!w-100%">
+          <div v-for="(val, index) in formData.tag" :key="index" class="mb-10px pa-20px" style="border: 1px solid #ccc;">
+            <div style="display: flex; justify-content: space-between; align-items: center">
+              <el-input v-model="val.title" clearable placeholder="请输入类别名称" class="!w-240px" />
+              <div class="text-right">
+                <el-button type="primary" class="mr-10px" @click="handleAddEnterprise(val, index)">添加企业</el-button>
+                <el-button type="danger" @click="handleDelete(index)">删除</el-button>
+              </div>
+            </div>
+
+            <el-table :data="val.value" :stripe="true">
+              <el-table-column label="企业logo" align="center" prop="name">
+                <template #default="scope">
+                  <el-image v-if="scope.row?.logoUrl" :src="scope.row?.logoUrl" class="!w-50px !h-50px" />
+                  <span v-else style="line-height: 70px; color: #999;">未上传</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="企业全称" align="center" prop="name">
+                <template #default="scope">{{ formatName(scope.row?.name) }}</template>
+              </el-table-column>
+              <el-table-column label="企业别名" align="center" prop="anotherName">
+                <template #default="scope">{{ formatName(scope.row?.anotherName) }}</template>
+              </el-table-column>
+              <el-table-column label="操作" align="center">
+                <template #default="scope">
+                  <el-button link type="danger" @click="handleDeleteTagItem(index, scope.$index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+
+        <div>
+          <el-button type="primary" @click="handleAdd"><Icon class="mr-5px" icon="ep:plus" />添加类别</el-button>
+          <div class="color-red-400 mt-5px">若填写了类别,请最少填写两项</div>
+        </div>
+      </el-form-item>
+    </el-form>
+    
+		<div class="text-right">
+			<el-button @click="emit('close')">返回</el-button>
+			<el-button @click="submitForm" type="primary" :disabled="formLoading">保存</el-button>
+		</div>
+  </div>
+
+  <Dialog title="添加企业" v-model="dialogVisible">
+    <el-form
+      ref="formRef"
+      :model="addFormData"
+      :rules="addFormRules"
+      label-width="100px"
+    >
+      <el-form-item label="企业别名" prop="select">
+        <el-select v-model="addFormData.select" value-key="id" multiple filterable clearable remote :remote-method="remoteMethod" :loading="loading" placeholder="请输入企业别称进行查找">
+          <el-option v-for="(item, index) in enterpriseList" :key="index" :value="item" :label="formatName(item.anotherName || item.name)">
+            <span>{{ formatName(item.anotherName || item.name) }}</span>
+          </el-option>
+          <p v-if="showLoadMore" class="text-center color-lightblue cursor-pointer" @click="handleLoadMore">加载更多</p>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="handleSubmitEnterprise" type="primary">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+/** 招聘会管理 信息设置 */
+defineOptions({ name: 'JobFairManageInfoSettings' })
+import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
+import { PositionApi } from '@/api/menduner/system/position'
+import { cloneDeep } from 'lodash-es'
+import { formatName } from '@/utils'
+import { EnterpriseApi } from '@/api/menduner/system/enterprise/message'
+
+const props = defineProps({ formType: String, info: Object })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const dialogVisible = ref(false)
+
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  id: undefined,
+  category: '0',
+  tag: []
+})
+const formRules = reactive({
+  category: [{ required: true, message: '展示类别不能为空', trigger: 'blur' }]
+})
+const categoryList = [
+  { label: '企业', value: '0' },
+  { label: '招聘职位', value: '1' }
+]
+const formRef = ref() // 表单 Ref
+
+const showLoadMore = ref(true) // 是否展示加载更多按钮
+const loading = ref(false)
+const enterpriseList = ref([])
+
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 20
+})
+const addFormData = ref({
+  select: [],
+  index: 0
+})
+const addFormRules = reactive({
+  // select: [{ required: true, message: '请选择企业', trigger: 'blur' }]
+})
+const getEnterpriseList = async () => {
+  const result = await EnterpriseApi.getEnterprisePage(queryParams)
+  const list = result.list || []
+  enterpriseList.value = enterpriseList.value.concat(list)
+  if (enterpriseList.value.length === result.total) showLoadMore.value = false
+}
+
+
+const remoteMethod = async (query: string) => {
+  if (query) {
+    loading.value = true
+    enterpriseList.value = []
+    queryParams.pageNo = 1
+    queryParams.anotherName = query
+    await getEnterpriseList()
+    loading.value = false
+  }
+}
+const handleLoadMore = () => {
+  queryParams.pageNo++
+  getEnterpriseList()
+}
+
+// 添加企业
+const handleAddEnterprise = (val, index) => {
+  console.log(val, index, 'add')
+  addFormData.value = {
+    select: val.value,
+    index
+  }
+  getEnterpriseList()
+  dialogVisible.value = true
+}
+// 添加企业-submit
+const handleSubmitEnterprise = () => {
+  const { select, index } = addFormData.value
+  formData.value.tag[index].value = select
+  dialogVisible.value = false
+  addFormData.value = {}
+}
+
+// 职位类型
+const position = ref([])
+const getPositionList = async () => {
+  const data = await PositionApi.getPositionList({})
+  position.value = data || []
+}
+
+
+onMounted(() => {
+  getPositionList()
+  if (props.info && Object.keys(props.info).length > 0) {
+		formLoading.value = true
+    formData.value.id = props.info.id
+		if (!props.info.tag || !props.info.tag.length) {
+			formData.value.tag = []
+		} else {
+      formData.value.tag = cloneDeep(props.info.tag)
+    }
+		formLoading.value = false
+  }
+})
+
+// 切换类别时需将数据清空
+const handleChangeCategory = () => {
+  formData.value.tag.forEach(e => e.value = [])
+}
+
+const handleDelete = (index) => {
+  formData.value.tag.splice(index, 1)
+}
+
+const handleAdd = () => {
+  formData.value.tag.push({ title: '', value: [] })
+}
+
+// 删除企业
+const handleDeleteTagItem = (index, tagItemIndex) => {
+  formData.value.tag[index].value.splice(tagItemIndex, 1)
+}
+
+// 效验内容是否填写完整
+const checkObjectValues = (obj) => {
+  for (let key in obj) {
+    if (obj.hasOwnProperty(key)) {
+      if (obj[key] === undefined || obj[key] === null || obj[key] === '' || obj[key].length === 0) {
+        return false
+      }
+    }
+  }
+  return true
+}
+
+/** 提交表单 */
+const emit = defineEmits(['close'])
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+  
+  if (formData.value?.tag && formData.value?.tag.length > 0) {
+    // 效验类别项是否填写完整
+    const check = formData.value.tag.every(e => checkObjectValues(e))
+    if (!check) return message.warning('请将类别详情中的项填写完整')
+    if (formData.value.tag.length < 2) return message.warning('请至少填写两个类别详情')
+    formData.value.tag.forEach(e => e.key = formData.value.category === '0' ? 'enterpriseId' : 'positionId')
+  }
+
+  // 提交请求
+  formLoading.value = true
+  try {
+		await JobFairManageApi.updateJobFairCategory(formData.value)
+		message.success(t('common.updateSuccess'))
+  } finally {
+    formLoading.value = false
+  }
+}
+
+</script>
+
+<style>
+.el-row {
+  width: 100%;
+}
+</style>

+ 318 - 0
src/views/menduner/system/jobFair/manage/details/components/Category.vue

@@ -0,0 +1,318 @@
+<template>
+  <div>
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="140px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="类别" prop="category" @change="handleChangeCategory">
+        <el-radio-group v-model="formData.category">
+          <el-radio
+            v-for="dict in categoryList"
+            :key="dict.value"
+            :label="dict.value"
+          >
+            {{ dict.label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="类别详情" prop="tag">
+        <!-- 职位类型 -->
+        <div v-if="formData.category === '1'" class="!w-100%">
+          <el-row v-for="(val, index) in formData.tag" :key="index" class="mb-10px">
+            <el-col :span="8">
+              <el-input v-model="val.title" clearable placeholder="请输入类别名称"/>
+            </el-col>
+            <el-col :span="10" class="mx-10px">
+              <!-- 职位 -->
+              <el-select  v-model="val.value" filterable multiple placeholder="请选择职位类型" collapse-tags collapse-tags-tooltip>
+                <el-option v-for="k in position" :key="k.id" :label="k.nameCn" :value="k.id.toString()"/>
+              </el-select>
+            </el-col>
+            <el-col :span="4">
+              <el-button text circle @click="handleDelete(index)">
+                <Icon icon="ep:close" />
+              </el-button>
+            </el-col>
+          </el-row>
+        </div>
+        <!-- 企业 -->
+        <div v-if="formData.category === '0'" class="!w-100%">
+          <div v-for="(val, index) in formData.tag" :key="index" class="mb-10px pa-20px" style="border: 1px solid #ccc;">
+            <div style="display: flex; justify-content: space-between; align-items: center">
+              <el-input v-model="val.title" clearable placeholder="请输入类别名称" class="!w-240px" />
+              <div class="text-right">
+                <el-button type="primary" class="mr-10px" @click="handleAddEnterprise(index)">添加企业</el-button>
+                <el-button type="danger" @click="handleDelete(index)">删除</el-button>
+              </div>
+            </div>
+
+            <el-table :data="val.value" :stripe="true" height="250">
+              <el-table-column label="企业LOGO" align="center" prop="name">
+                <template #default="scope">
+                  <el-image v-if="scope.row?.logoUrl" :src="scope.row?.logoUrl" class="!w-50px !h-50px" />
+                  <span v-else style="line-height: 70px; color: #999;">未上传</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="企业全称" align="center" prop="name">
+                <template #default="scope">{{ formatName(scope.row?.name) }}</template>
+              </el-table-column>
+              <el-table-column label="企业别名" align="center" prop="anotherName">
+                <template #default="scope">{{ formatName(scope.row?.anotherName) }}</template>
+              </el-table-column>
+              <el-table-column label="顺序" align="center" prop="sort">
+                <template #default="scope">
+                  <el-input-number v-model="scope.row.sort" :min="0" :step="1" class="!w-120px" />
+                </template>
+              </el-table-column>
+              <el-table-column label="操作" align="center">
+                <template #default="scope">
+                  <el-button link type="danger" @click="handleDeleteTagItem(index, scope.$index)">删除</el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+
+        <div>
+          <el-button type="primary" @click="handleAdd"><Icon class="mr-5px" icon="ep:plus" />添加类别</el-button>
+          <div class="color-red-400 mt-5px">若填写了类别,请最少填写两项</div>
+        </div>
+      </el-form-item>
+    </el-form>
+    
+		<div class="text-right">
+			<el-button @click="emit('close')">返回</el-button>
+			<el-button @click="submitForm" type="primary" :disabled="formLoading">保存</el-button>
+		</div>
+  </div>
+
+  <Dialog title="添加企业" v-model="dialogVisible">
+    <el-form
+      ref="addFormRef"
+      :model="addFormData"
+      :rules="addFormRules"
+      label-width="100px"
+    >
+      <el-form-item label="企业别名" prop="select">
+        <el-select v-model="addFormData.select" value-key="id" multiple filterable clearable remote :remote-method="remoteMethod" :loading="loading" placeholder="请输入企业别称进行查找">
+          <el-option v-for="(item, index) in enterpriseList" :key="index" :value="item" :label="formatName(item.anotherName || item.name)">
+            <span>{{ formatName(item.anotherName || item.name) }}</span>
+          </el-option>
+          <p v-if="showLoadMore" class="text-center color-lightblue cursor-pointer" @click="handleLoadMore">加载更多</p>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="handleSubmitEnterprise" type="primary">确 定</el-button>
+      <el-button @click="dialogVisible = false">取 消</el-button>
+    </template>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+/** 招聘会管理 信息设置 */
+defineOptions({ name: 'JobFairManageInfoSettings' })
+import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
+import { PositionApi } from '@/api/menduner/system/position'
+import { cloneDeep } from 'lodash-es'
+import { formatName } from '@/utils'
+import { EnterpriseApi } from '@/api/menduner/system/enterprise/message'
+
+const props = defineProps({ formType: String, info: Object })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+const dialogVisible = ref(false)
+
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  id: undefined,
+  category: '0',
+  tag: []
+})
+const formRules = reactive({
+  category: [{ required: true, message: '展示类别不能为空', trigger: 'blur' }]
+})
+const categoryList = [
+  { label: '企业', value: '0', key: 'enterpriseId' },
+  { label: '招聘职位', value: '1', key: 'positionId' }
+]
+const formRef = ref() // 表单 Ref
+const addFormRef = ref() // 添加表单 Ref
+
+const showLoadMore = ref(true) // 是否展示加载更多按钮
+const loading = ref(false)
+const enterpriseList = ref([])
+
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 20
+})
+const addFormData = ref({
+  select: [],
+  index: 0
+})
+const addFormRules = reactive({
+  select: [{ required: true, message: '请选择企业', trigger: 'blur' }]
+})
+
+// 获取企业列表
+const getEnterpriseList = async (isConCat = false) => {
+  const result = await EnterpriseApi.getEnterprisePage(queryParams)
+  const list = result.list || []
+  enterpriseList.value = isConCat ? enterpriseList.value.concat(list) : list
+  if (enterpriseList.value.length === result.total) showLoadMore.value = false
+}
+
+const remoteMethod = async (query: string) => {
+  if (query) {
+    loading.value = true
+    enterpriseList.value = []
+    queryParams.pageNo = 1
+    queryParams.anotherName = query
+    await getEnterpriseList()
+    loading.value = false
+  }
+}
+const handleLoadMore = () => {
+  queryParams.pageNo++
+  getEnterpriseList(true)
+}
+
+// 添加企业
+const handleAddEnterprise = (index) => {
+  addFormData.value = {
+    select: [],
+    index
+  }
+  getEnterpriseList()
+  dialogVisible.value = true
+}
+// 添加企业-submit
+const handleSubmitEnterprise = async () => {
+  // 校验表单
+  await addFormRef.value.validate()
+
+  const { select, index } = cloneDeep(addFormData.value)
+  formData.value.tag[index].value = formData.value.tag[index].value && formData.value.tag[index].value.length ? formData.value.tag[index].value.concat(select) : select
+  formData.value.tag[index].value.forEach((val, index) => {
+    val.sort = index + 1
+  })
+  
+  dialogVisible.value = false
+  addFormData.value = {}
+}
+
+// 职位类型
+const position = ref([])
+const getPositionList = async () => {
+  const data = await PositionApi.getPositionList({})
+  position.value = data || []
+}
+
+onMounted(() => {
+  getPositionList()
+  if (props.info && Object.keys(props.info).length > 0) {
+		formLoading.value = true
+    formData.value.id = props.info.id
+    formData.value.category = props.info.category
+    console.log(props.info, 'props.info')
+		if (!props.info.tag || !props.info.tag.length) {
+			formData.value.tag = []
+		} else {
+      const key = props.info.tag[0].key
+      const tags = cloneDeep(props.info.tag)
+      if (key !== 'enterpriseId') {
+        formData.value.tag = tags.map(e => {
+          e.value = e.content.map(k => k.value)
+          return e
+        })
+        console.log(formData.value.tag, 'formData.value.tag');
+        formLoading.value = false
+        return
+      }
+      formData.value.tag = tags.map(e => {
+        e.value = e.content.map(k => {
+          const enterprise = props.info.enterprise.find(i => i.id.toString() === k.value)
+          return { ...k, ...enterprise }
+        })
+        return e
+      })
+    }
+		formLoading.value = false
+  }
+})
+
+// 切换类别时需将数据清空
+const handleChangeCategory = () => {
+  formData.value.tag = [{ title: '', value: [], key: '' }]
+}
+
+const handleDelete = (index) => {
+  formData.value.tag.splice(index, 1)
+}
+
+const handleAdd = () => {
+  formData.value.tag.push({ title: '', value: [], key: '' })
+}
+
+// 删除企业
+const handleDeleteTagItem = (index, tagItemIndex) => {
+  formData.value.tag[index].value.splice(tagItemIndex, 1)
+}
+
+// 效验内容是否填写完整
+// const checkObjectValues = (obj) => {
+//   for (let key in obj) {
+//     if (obj.hasOwnProperty(key)) {
+//       if (obj[key] === undefined || obj[key] === null || obj[key] === '' || obj[key].length === 0) {
+//         return false
+//       }
+//     }
+//   }
+//   return true
+// }
+
+/** 提交表单 */
+const emit = defineEmits(['close'])
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+
+  let params = cloneDeep(formData.value)
+  if (params?.tag && params?.tag.length > 0) {
+    const key = categoryList.find(e => e.value === params.category)?.key
+    // 效验类别项是否填写完整
+    const check = params.tag.every(e => e.title && e.value.length > 0)
+    if (!check) return message.warning('请将类别详情中的项填写完整')
+    if (params.tag.length < 2) return message.warning('请至少填写两个类别详情')
+
+    params.tag = params.tag.map(e => {
+      return {
+        title: e.title,
+        key,
+        content: e.value.map(k => ({ value: key === 'enterpriseId' ? k.id : k, sort: k.sort }))
+      }
+    })
+  }
+
+  // 提交请求
+  formLoading.value = true
+  try {
+		await JobFairManageApi.updateJobFairCategory(params)
+		message.success(t('common.updateSuccess'))
+  } finally {
+    formLoading.value = false
+  }
+}
+
+</script>
+
+<style>
+.el-row {
+  width: 100%;
+}
+</style>

+ 162 - 0
src/views/menduner/system/jobFair/manage/details/components/InfoSettings.vue

@@ -0,0 +1,162 @@
+<template>
+  <div>
+    <el-form
+      ref="formRef"
+      :model="formData"
+      :rules="formRules"
+      label-width="140px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="招聘会标题" prop="title">
+        <el-input v-model="formData.title" :rows="3" type="textarea" placeholder="请输入标题" />
+      </el-form-item>
+      <el-form-item label="招聘会背景色" prop="backgroundColour">
+        <div>
+          <el-color-picker v-model="formData.backgroundColour" size="large" />
+          <div>为了页面的美观性,请勿选择白色(#FFF / #FFFFFF)作为页面背景颜色</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="PC封面海报" prop="pcPreviewImg">
+        <div>
+          <UploadImg v-model="formData.pcPreviewImg" height="150px" width="300px" :fileSize="10" :validSpecifications="true" :maxWidth="800" :maxHeight="300" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽800px*高300px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="小程序封面海报" prop="previewImg">
+        <div>
+          <UploadImg v-model="formData.previewImg" height="150px" width="300px" :fileSize="10" :validSpecifications="true" :maxWidth="750" :maxHeight="350" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽750px*高350px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="PC顶部banner" prop="pcHeadImg">
+        <div>
+          <UploadImgs v-model="formData.pcHeadImg" :limit="20" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽1920px*高553px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="小程序顶部banner" prop="headImg">
+        <div>
+          <UploadImgs v-model="formData.headImg" :limit="20" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽750px*高350px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="招聘会分享海报" prop="shareImg">
+        <div>
+          <UploadImg v-model="formData.shareImg" height="300px" width="250px" :fileSize="10" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽1080px*高1920px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="企业分享海报" prop="contentImg">
+        <div>
+          <UploadImg v-model="formData.contentImg" height="300px" width="250px" :fileSize="10" :validSpecifications="true" :maxWidth="540" :maxHeight="788" />
+          <div class="flex" style="color: orange; align-items: center;"><Icon :size="20" icon="ep:warning" class="mr-3px" />提示:请上传宽540px*高788px规格的图片</div>
+        </div>
+      </el-form-item>
+      <el-form-item label="开始时间" prop="startTime">
+        <el-date-picker v-model="formData.startTime" type="date" value-format="x" placeholder="选择开始时间" />
+      </el-form-item>
+      <el-form-item label="结束时间" prop="endTime">
+        <el-date-picker v-model="formData.endTime" type="date" value-format="x" placeholder="选择结束时间" />
+      </el-form-item>
+      <el-form-item label="状态" prop="status">
+        <el-radio-group v-model="formData.status">
+          <el-radio
+            v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_STATUS)"
+            :key="dict.value"
+            :label="dict.value.toString()"
+          >
+            {{ dict.label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+    </el-form>
+    
+		<div class="text-right">
+			<el-button @click="emit('close')">返回</el-button>
+			<el-button @click="submitForm" type="primary" :disabled="formLoading">保存</el-button>
+		</div>
+  </div>
+</template>
+
+<script setup lang="ts">
+/** 招聘会管理 信息设置 */
+defineOptions({ name: 'JobFairManageInfoSettings' })
+import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
+import { JobFairManageApi, JobFairManageVO } from '@/api/menduner/system/jobFair/manage'
+import { useTagsViewStore } from '@/store/modules/tagsView'
+import { cloneDeep } from 'lodash-es'
+
+const { push, currentRoute } = useRouter() // 路由
+const { delView } = useTagsViewStore() // 视图操作
+
+const props = defineProps({ formType: String, info: Object })
+
+const { t } = useI18n() // 国际化
+const message = useMessage() // 消息弹窗
+
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  id: undefined,
+  type: 1,
+  title: undefined,
+  headImg: [],
+  pcHeadImg: [],
+  backgroundColour: undefined,
+  pcPreviewImg: undefined,
+  previewImg: undefined,
+  startTime: undefined,
+  endTime: undefined,
+  shareImg: undefined,
+  contentImg: undefined,
+  status: '0',
+  category: undefined,
+  tag: []
+})
+const formRules = reactive({
+  backgroundColour: [{ required: true, message: '招聘会背景颜色不能为空', trigger: 'change' }],
+  previewImg: [{ required: true, message: 'PC封面海报不能为空', trigger: 'change' }],
+  pcPreviewImg: [{ required: true, message: '小程序封面海报不能为空', trigger: 'change' }],
+  headImg: [{ required: true, message: '小程序顶部banner图片不能为空', trigger: 'change' }],
+  pcHeadImg: [{ required: true, message: 'PC顶部banner图片不能为空', trigger: 'change' }],
+  shareImg: [{ required: true, message: '招聘会分享海报不能为空', trigger: 'change' }],
+  contentImg: [{ required: true, message: '企业分享海报不能为空', trigger: 'change' }],
+  title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
+  startTime: [{ required: true, message: '开始时间不能为空', trigger: 'blur' }],
+  endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }],
+})
+const formRef = ref() // 表单 Ref
+
+onMounted(() => {
+  if (props.info && Object.keys(props.info).length > 0) {
+		formLoading.value = true
+		formData.value = cloneDeep(props.info)
+		formLoading.value = false
+  }
+})
+
+/** 提交表单 */
+const emit = defineEmits(['close'])
+const submitForm = async () => {
+  if (['#ffffff', '#FFFFFF'].indexOf(formData.value.backgroundColour) !== -1) return message.warning('请勿将白色作为页面背景色')
+  // 校验表单
+  await formRef.value.validate()
+  
+  // 提交请求
+  formLoading.value = true
+  try {
+    const data = formData.value as unknown as JobFairManageVO
+		if (props.formType === 'create') {
+			const result = await JobFairManageApi.createJobFair(data)
+			message.success(t('common.createSuccess'))
+			delView(unref(currentRoute))
+			push({ name: 'JobFairDetail', params: { id: result } })
+		} else {
+			await JobFairManageApi.updateJobFair(data)
+			message.success(t('common.updateSuccess'))
+		}
+  } finally {
+    formLoading.value = false
+  }
+}
+
+</script>

+ 87 - 0
src/views/menduner/system/jobFair/manage/details/components/TicketSettings.vue

@@ -0,0 +1,87 @@
+<template>
+  <div class="text-right">
+    <el-button type="success" plain @click="emit('refresh', info.id)">刷新</el-button>
+  </div>
+  <div class="mb-50px !w-400px color-orange text-16px">
+    <Icon :size="20" icon="ep:warning" class="mr-3px" />
+    提示:不需要设置门票限制时则不需要填写以下内容
+  </div>
+  <div style="display: flex; justify-content: center; flex-direction: column; align-items: center;">
+    <el-form
+      ref="formRef"
+      :model="formData"
+      label-width="110px"
+      class="!w-350px"
+      v-loading="formLoading"
+    >
+      <el-form-item label="门票金额" prop="admissionPrice">
+        <el-input-number v-model="formData.admissionPrice" :precision="2" :min="0.01" :step="100" />
+        <span class="mx-10px">元</span>
+        <Icon @click="formData.admissionPrice = null" class="cursor-pointer" :size="25" icon="ep:circle-close-filled" /> 
+      </el-form-item>
+      <el-form-item label="可发布职位数量" prop="allowedJobNum">
+        <el-input-number v-model="formData.allowedJobNum" :min="0" :step="10" />
+        <span class="mx-10px">个</span>
+        <Icon @click="formData.allowedJobNum = null" class="cursor-pointer" :size="25" icon="ep:circle-close-filled" /> 
+      </el-form-item>
+    </el-form>
+    
+    <div class="mt-50px">
+      <el-button @click="emit('close')">返回</el-button>
+      <el-button @click="submitForm" type="primary" :disabled="formLoading">保 存</el-button>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+/** 招聘会 门票设置 */
+defineOptions({ name: 'JobFairManageTicketSettings' })
+import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
+
+const message = useMessage() // 消息弹窗
+const emit = defineEmits(['refresh', 'close'])
+const props = defineProps({ info: Object })
+
+const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
+const formData = ref({
+  id: undefined,
+  admissionPrice: undefined,
+  allowedJobNum: undefined
+})
+const formRef = ref() // 表单 Ref
+
+onMounted(() => {
+  if (props.info && Object.keys(props.info).length > 0) {
+    const { id, admissionPrice: price, allowedJobNum } = props.info
+    formData.value = {
+      id,
+      admissionPrice: price > 0 ? (price / 100) : null,
+      allowedJobNum
+    }
+  }
+})
+
+
+/** 提交表单 */
+const submitForm = async () => {
+  // 校验表单
+  await formRef.value.validate()
+
+	const { id, admissionPrice, allowedJobNum } = formData.value
+	const params = {
+		id,
+		admissionPrice: admissionPrice > 0 ? (admissionPrice * 100) : null,
+		allowedJobNum
+	}
+
+  // 提交请求
+  formLoading.value = true
+  try {
+    await JobFairManageApi.updateTicketSettings(params)
+    message.success('设置成功')
+    // 发送操作成功的事件
+  } finally {
+    formLoading.value = false
+  }
+}
+</script>

+ 128 - 0
src/views/menduner/system/jobFair/manage/details/components/WhiteList.vue

@@ -0,0 +1,128 @@
+<template>
+  <el-form
+    class=" m-y-20px"
+    :model="queryParams"
+    ref="queryFormRef"
+    :inline="true"
+    label-width="68px"
+    @submit.prevent
+  >
+    <el-form-item label="企业名称" prop="name">
+      <el-input v-model="queryParams.name" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
+    </el-form-item>
+    <el-form-item>
+      <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+      <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+      <el-button type="primary" plain @click="handleAdd"><Icon icon="ep:plus" class="mr-5px" />新增</el-button>
+  <el-button type="success" plain @click="queryParams.pageNo = 1, getList()"><Icon icon="ep:refresh" class="mr-5px" />刷新</el-button>
+    </el-form-item>
+  </el-form>
+  <el-table v-loading="loading" :data="list" :stripe="true">
+    <el-table-column label="企业全称" align="center" prop="name">
+      <template #default="scope">{{ formatName(scope.row.enterprise.name) }}</template>
+    </el-table-column>
+    <el-table-column label="企业别称" align="center" prop="anotherName">
+      <template #default="scope">{{ formatName(scope.row.enterprise.anotherName) }}</template>
+    </el-table-column>
+		<el-table-column label="剩余发布职位数" align="center" prop="num" />
+		<el-table-column label="来源" align="center" prop="source">
+      <template #default="scope">{{ scope.row.source === '0' ? '系统添加' : scope.row.source === '1' ? '购买门票' : '' }}</template>
+    </el-table-column>
+    <el-table-column label="操作" align="center">
+      <template #default="scope">
+        <el-button
+          link
+          type="primary"
+          @click="handleRemoveWhiteList(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.enterpriseId)"
+        >
+          移出白名单
+        </el-button>
+      </template>
+    </el-table-column>
+  </el-table>
+    
+  <Pagination
+    :total="total"
+    v-model:page="queryParams.pageNo"
+    v-model:limit="queryParams.pageSize"
+    @pagination="getList"
+  />
+
+  <!-- 表单弹窗:添加/修改 -->
+  <JobFairForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+/** 招聘会 白名单 */
+defineOptions({ name: 'WhiteList' })
+import { JobFairWhiteApi } from '@/api/menduner/system/jobFair/white'
+import JobFairForm from '../jobFairForm.vue'
+import { formatName } from '@/utils'
+
+const props = defineProps({ info: Object })
+const message = useMessage() // 消息弹窗
+
+const loading = ref(false) // 列表的加载中
+const list = ref([]) // 列表的数据
+const total = ref(0)
+const queryParams = ref({
+  pageNo: 1,
+  pageSize: 10,
+  name: undefined,
+  jobFairId: undefined
+})
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  try {
+    const data = await JobFairWhiteApi.getJobFairWhiteList(queryParams.value)
+    total.value = data.total
+    list.value = data.list
+  } finally {
+    loading.value = false
+  }
+}
+
+const handleQuery = () => {
+  total.value = 0
+  list.value = []
+  queryParams.value.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const queryFormRef = ref()
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+const formRef = ref()
+const handleAdd = () => {
+  formRef.value.open(queryParams.value.jobFairId)
+}
+
+// 移出白名单
+const handleRemoveWhiteList = async (enterpriseName: string, enterpriseId: string) => {
+  if (!enterpriseId) return message.warning('操作失败,请刷新页面重试')
+  try {
+    await message.confirm(`确定要将【${enterpriseName}】移出白名单吗?`)
+    await JobFairWhiteApi.removeJobFairWhiteList({ enterpriseIds: enterpriseId, jobFairId: queryParams.value.jobFairId })
+    message.success('移出成功')
+    getList()
+  } catch (err) {}
+}
+
+onMounted(() => {
+	if (props.info && Object.keys(props.info).length > 0) {
+		queryParams.value.jobFairId = props.info.id
+    queryParams.value.pageNo = 1
+		getList()
+	}
+})
+
+defineExpose({
+  getList
+})
+</script>

+ 242 - 0
src/views/menduner/system/jobFair/manage/details/index copy.vue

@@ -0,0 +1,242 @@
+<template>
+  <ContentWrap>
+    <!-- 搜索工作栏 -->
+    <CardTitle fontSize="16" :title="jobFairInfo.title?.replace(/<\/?p[^>]*>/gi, '')" />
+    <el-form
+      class="-mb-15px m-t-20px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+      @submit.prevent
+    >
+      <el-form-item label="企业名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
+      </el-form-item>
+      <el-form-item>
+        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button type="primary" :loading="exportLoading" plain @click="handleExport"><Icon icon="ep:download" class="mr-5px" /> 参加招聘会职位列表导出</el-button>
+        <el-button type="primary" :loading="exportDeliveryLoading" plain @click="handleExportDelivery"><Icon icon="ep:download" class="mr-5px" /> 招聘会职位投递情况导出</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+
+  <!-- 列表 -->
+  <ContentWrap>
+    <el-tabs v-model="activeName" @tab-change="handleClick">
+      <el-tab-pane label="白名单" name="whiteList">
+        <div class="text-right">
+          <el-button type="primary" plain @click="handleAdd"><Icon icon="ep:plus" class="mr-5px" /> 新增</el-button>
+        </div>
+        <el-table v-loading="loading" :data="list" :stripe="true">
+          <el-table-column label="企业全称" align="center" prop="name">
+            <template #default="scope">{{ formatName(scope.row.enterprise.name) }}</template>
+          </el-table-column>
+          <el-table-column label="企业别称" align="center" prop="anotherName">
+            <template #default="scope">{{ formatName(scope.row.enterprise.anotherName) }}</template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template #default="scope">
+              <el-button
+                link
+                type="primary"
+                @click="handleRemoveWhiteList(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.enterpriseId)"
+              >
+                移出白名单
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-tab-pane>
+      <el-tab-pane label="购买门票企业" name="ticketEntList">
+        <el-table v-loading="loading" :data="list" :stripe="true">
+          <el-table-column label="企业全称" align="center" prop="name">
+            <template #default="scope">{{ formatName(scope.row.enterprise.name) }}</template>
+          </el-table-column>
+          <el-table-column label="企业别称" align="center" prop="anotherName">
+            <template #default="scope">{{ formatName(scope.row.enterprise.anotherName) }}</template>
+          </el-table-column>
+          <el-table-column label="权益" align="center" prop="status">
+            <template #default="scope">
+              <span :style="{'color': scope.row.status === '1' ? '#f56c6c' : '#67c23a' }">{{ scope.row.status === '1' ? '已禁用' : '已开启' }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template #default="scope">
+              <el-button v-if="scope.row.status === '1'" link type="primary" @click="handleEnableRights(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.id)">
+                开启权益
+              </el-button>
+              <el-button v-if="scope.row.status === '0'" link type="danger" @click="handleDisableRights(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.id)">禁用权益</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+      </el-tab-pane>
+    </el-tabs>
+    
+    <Pagination
+      :total="total"
+      v-model:page="queryParams.pageNo"
+      v-model:limit="queryParams.pageSize"
+      @pagination="getList"
+    />
+  </ContentWrap>
+
+  <!-- 表单弹窗:添加/修改 -->
+  <JobFairForm ref="formRef" @success="getList" />
+</template>
+
+<script setup lang="ts">
+import { JobFairWhiteApi } from '@/api/menduner/system/jobFair/white'
+import JobFairForm from './jobFairForm.vue'
+import download from '@/utils/download'
+import { useTagsViewStore } from '@/store/modules/tagsView'
+import { ElMessage } from 'element-plus'
+import { formatName } from '@/utils'
+import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
+
+/** 招聘会 列表 */
+defineOptions({ name: 'JobFairDetails' })
+
+const message = useMessage() // 消息弹窗
+
+const activeName = ref('whiteList')
+const loading = ref(true) // 列表的加载中
+const list = ref([]) // 列表的数据
+const total = ref(0)
+const queryParams = ref({
+  pageNo: 1,
+  pageSize: 10,
+  name: undefined,
+  jobFairId: ''
+})
+
+/** 查询列表 */
+const getList = async () => {
+  loading.value = true
+  const api = activeName.value === 'whiteList' ? JobFairWhiteApi.getJobFairWhiteList : JobFairManageApi.getBuyTicketEnterprise
+  try {
+    const data = await api(queryParams.value)
+    total.value = data.total
+    list.value = data.list
+  } finally {
+    loading.value = false
+  }
+}
+
+const handleClick = () => {
+  total.value = 0
+  list.value = []
+  queryParams.value.pageNo = 1
+  getList()
+}
+
+/* 查询招聘会详情 */
+const jobFairInfo = ref({})
+const getJobFairDetail = async () => {
+  try {
+    const data = await JobFairManageApi.getJobFair(queryParams.value.jobFairId)
+    jobFairInfo.value = data
+  } catch {}
+}
+
+const handleQuery = () => {
+  total.value = 0
+  list.value = []
+  queryParams.value.pageNo = 1
+  getList()
+}
+
+/** 重置按钮操作 */
+const queryFormRef = ref()
+const resetQuery = () => {
+  queryFormRef.value.resetFields()
+  handleQuery()
+}
+
+const formRef = ref()
+const handleAdd = () => {
+  formRef.value.open(queryParams.value.jobFairId)
+}
+
+// 移出白名单
+const handleRemoveWhiteList = async (enterpriseName: string, enterpriseId: string) => {
+  if (!enterpriseId) return message.warning('操作失败,请刷新页面重试')
+  try {
+    await message.confirm(`确定要将【${enterpriseName}】移出白名单吗?`)
+    await JobFairWhiteApi.removeJobFairWhiteList({ enterpriseIds: enterpriseId, jobFairId: queryParams.value.jobFairId })
+    message.success('移出成功')
+    getList()
+  } catch (err) {}
+}
+
+// 开启权益
+const handleEnableRights = async (enterpriseName: string, id: string) => {
+  if (!id) return message.warning('操作失败,请刷新页面重试')
+  try {
+    await message.confirm(`是否确定开启【${formatName(enterpriseName)}】的招聘会权益?`)
+    await JobFairManageApi.enableTicketRights(id)
+    message.success('开启成功')
+    getList()
+  } catch (err) {}
+}
+
+// 关闭权益
+const handleDisableRights = async (enterpriseName: string, id: string) => {
+  if (!id) return message.warning('操作失败,请刷新页面重试')
+  try {
+    await message.confirm(`是否确定禁用【${formatName(enterpriseName)}】的招聘会权益?`)
+    await JobFairManageApi.disableTicketRights(id)
+    message.success('禁用成功')
+    getList()
+  } catch (err) {}
+}
+
+const exportLoading = ref(false)
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await JobFairWhiteApi.exportJobFairWhiteList(queryParams.value.jobFairId)
+    download.excel(data, '招聘会职位列表.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+// 招聘会投递情况导出
+const exportDeliveryLoading = ref(false)
+const handleExportDelivery = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportDeliveryLoading.value = true
+    const data = await JobFairWhiteApi.exportJobFairApplyData(queryParams.value.jobFairId)
+    download.excel(data, '招聘会职位投递情况.xls')
+  } catch {
+  } finally {
+    exportDeliveryLoading.value = false
+  }
+}
+
+/** 初始化 */
+const { currentRoute } = useRouter() // 路由
+const { delView } = useTagsViewStore() // 视图操作
+const route = useRoute()
+const { id } = route.params
+onMounted(() => {
+  if (!id) {
+    ElMessage.warning('参数错误,招聘会编号不能为空!')
+    delView(unref(currentRoute))
+    return
+  }
+  queryParams.value.jobFairId = id
+  getList()
+  getJobFairDetail()
+})
+</script>

+ 35 - 210
src/views/menduner/system/jobFair/manage/details/index.vue

@@ -1,242 +1,67 @@
 <template>
-  <ContentWrap>
-    <!-- 搜索工作栏 -->
+  <ContentWrap v-if="id">
     <CardTitle fontSize="16" :title="jobFairInfo.title?.replace(/<\/?p[^>]*>/gi, '')" />
-    <el-form
-      class="-mb-15px m-t-20px"
-      :model="queryParams"
-      ref="queryFormRef"
-      :inline="true"
-      label-width="68px"
-      @submit.prevent
-    >
-      <el-form-item label="企业名称" prop="name">
-        <el-input v-model="queryParams.name" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" class="!w-240px" />
-      </el-form-item>
-      <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-        <el-button type="primary" :loading="exportLoading" plain @click="handleExport"><Icon icon="ep:download" class="mr-5px" /> 参加招聘会职位列表导出</el-button>
-        <el-button type="primary" :loading="exportDeliveryLoading" plain @click="handleExportDelivery"><Icon icon="ep:download" class="mr-5px" /> 招聘会职位投递情况导出</el-button>
-      </el-form-item>
-    </el-form>
   </ContentWrap>
 
-  <!-- 列表 -->
-  <ContentWrap>
-    <el-tabs v-model="activeName" @tab-change="handleClick">
-      <el-tab-pane label="白名单" name="whiteList">
-        <div class="text-right">
-          <el-button type="primary" plain @click="handleAdd"><Icon icon="ep:plus" class="mr-5px" /> 新增</el-button>
-        </div>
-        <el-table v-loading="loading" :data="list" :stripe="true">
-          <el-table-column label="企业全称" align="center" prop="name">
-            <template #default="scope">{{ formatName(scope.row.enterprise.name) }}</template>
-          </el-table-column>
-          <el-table-column label="企业别称" align="center" prop="anotherName">
-            <template #default="scope">{{ formatName(scope.row.enterprise.anotherName) }}</template>
-          </el-table-column>
-          <el-table-column label="操作" align="center">
-            <template #default="scope">
-              <el-button
-                link
-                type="primary"
-                @click="handleRemoveWhiteList(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.enterpriseId)"
-              >
-                移出白名单
-              </el-button>
-            </template>
-          </el-table-column>
-        </el-table>
+  <ContentWrap v-if="!id || (jobFairInfo && Object.keys(jobFairInfo).length > 0)">
+    <el-tabs v-model="activeName" @tab-change="handleTabChange">
+      <el-tab-pane label="招聘会信息" name="infoSettings">
+        <InfoSettings :info="jobFairInfo" :formType="id ? 'update' : 'create'" @close="handleClose" />
       </el-tab-pane>
-      <el-tab-pane label="购买门票企业" name="ticketEntList">
-        <el-table v-loading="loading" :data="list" :stripe="true">
-          <el-table-column label="企业全称" align="center" prop="name">
-            <template #default="scope">{{ formatName(scope.row.enterprise.name) }}</template>
-          </el-table-column>
-          <el-table-column label="企业别称" align="center" prop="anotherName">
-            <template #default="scope">{{ formatName(scope.row.enterprise.anotherName) }}</template>
-          </el-table-column>
-          <el-table-column label="权益" align="center" prop="status">
-            <template #default="scope">
-              <span :style="{'color': scope.row.status === '1' ? '#f56c6c' : '#67c23a' }">{{ scope.row.status === '1' ? '已禁用' : '已开启' }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" align="center">
-            <template #default="scope">
-              <el-button v-if="scope.row.status === '1'" link type="primary" @click="handleEnableRights(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.id)">
-                开启权益
-              </el-button>
-              <el-button v-if="scope.row.status === '0'" link type="danger" @click="handleDisableRights(formatName(scope.row.enterprise.anotherName || scope.row.enterprise.name), scope.row.id)">禁用权益</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
+      <el-tab-pane v-if="id" label="类别设置" name="categorySettings">
+        <Category :info="jobFairInfo" @close="handleClose" />
+      </el-tab-pane>
+      <el-tab-pane v-if="id" label="白名单" name="whiteList">
+        <WhiteList ref="whiteListRef" :info="jobFairInfo" />
+      </el-tab-pane>
+      <el-tab-pane v-if="id" label="门票设置" name="ticketSettings">
+        <TicketSettings :info="jobFairInfo" @close="handleClose" @refresh="getJobFairDetail" />
       </el-tab-pane>
     </el-tabs>
-    
-    <Pagination
-      :total="total"
-      v-model:page="queryParams.pageNo"
-      v-model:limit="queryParams.pageSize"
-      @pagination="getList"
-    />
   </ContentWrap>
-
-  <!-- 表单弹窗:添加/修改 -->
-  <JobFairForm ref="formRef" @success="getList" />
 </template>
 
 <script setup lang="ts">
-import { JobFairWhiteApi } from '@/api/menduner/system/jobFair/white'
-import JobFairForm from './jobFairForm.vue'
-import download from '@/utils/download'
-import { useTagsViewStore } from '@/store/modules/tagsView'
-import { ElMessage } from 'element-plus'
-import { formatName } from '@/utils'
-import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
-
-/** 招聘会 列表 */
+/** 招聘会 详情 */
 defineOptions({ name: 'JobFairDetails' })
+import { JobFairManageApi } from '@/api/menduner/system/jobFair/manage'
+import TicketSettings from './components/TicketSettings.vue'
+import WhiteList from './components/WhiteList.vue'
+import InfoSettings from './components/InfoSettings.vue'
+import Category from './components/Category.vue'
+import { useTagsViewStore } from '@/store/modules/tagsView'
 
-const message = useMessage() // 消息弹窗
-
-const activeName = ref('whiteList')
-const loading = ref(true) // 列表的加载中
-const list = ref([]) // 列表的数据
-const total = ref(0)
-const queryParams = ref({
-  pageNo: 1,
-  pageSize: 10,
-  name: undefined,
-  jobFairId: ''
-})
-
-/** 查询列表 */
-const getList = async () => {
-  loading.value = true
-  const api = activeName.value === 'whiteList' ? JobFairWhiteApi.getJobFairWhiteList : JobFairManageApi.getBuyTicketEnterprise
-  try {
-    const data = await api(queryParams.value)
-    total.value = data.total
-    list.value = data.list
-  } finally {
-    loading.value = false
-  }
-}
-
-const handleClick = () => {
-  total.value = 0
-  list.value = []
-  queryParams.value.pageNo = 1
-  getList()
-}
+const activeName = ref('infoSettings') // 当前激活的tab
 
 /* 查询招聘会详情 */
 const jobFairInfo = ref({})
-const getJobFairDetail = async () => {
+const getJobFairDetail = async (id) => {
   try {
-    const data = await JobFairManageApi.getJobFair(queryParams.value.jobFairId)
+    const data = await JobFairManageApi.getJobFair(id)
     jobFairInfo.value = data
   } catch {}
 }
 
-const handleQuery = () => {
-  total.value = 0
-  list.value = []
-  queryParams.value.pageNo = 1
-  getList()
-}
-
-/** 重置按钮操作 */
-const queryFormRef = ref()
-const resetQuery = () => {
-  queryFormRef.value.resetFields()
-  handleQuery()
+const whiteListRef = ref(null)
+const handleTabChange = () => {
+  if (activeName.value === 'whiteList') {
+    whiteListRef.value?.getList()
+  } else getJobFairDetail(route.params.id)
 }
 
-const formRef = ref()
-const handleAdd = () => {
-  formRef.value.open(queryParams.value.jobFairId)
-}
-
-// 移出白名单
-const handleRemoveWhiteList = async (enterpriseName: string, enterpriseId: string) => {
-  if (!enterpriseId) return message.warning('操作失败,请刷新页面重试')
-  try {
-    await message.confirm(`确定要将【${enterpriseName}】移出白名单吗?`)
-    await JobFairWhiteApi.removeJobFairWhiteList({ enterpriseIds: enterpriseId, jobFairId: queryParams.value.jobFairId })
-    message.success('移出成功')
-    getList()
-  } catch (err) {}
-}
-
-// 开启权益
-const handleEnableRights = async (enterpriseName: string, id: string) => {
-  if (!id) return message.warning('操作失败,请刷新页面重试')
-  try {
-    await message.confirm(`是否确定开启【${formatName(enterpriseName)}】的招聘会权益?`)
-    await JobFairManageApi.enableTicketRights(id)
-    message.success('开启成功')
-    getList()
-  } catch (err) {}
-}
-
-// 关闭权益
-const handleDisableRights = async (enterpriseName: string, id: string) => {
-  if (!id) return message.warning('操作失败,请刷新页面重试')
-  try {
-    await message.confirm(`是否确定禁用【${formatName(enterpriseName)}】的招聘会权益?`)
-    await JobFairManageApi.disableTicketRights(id)
-    message.success('禁用成功')
-    getList()
-  } catch (err) {}
-}
-
-const exportLoading = ref(false)
-/** 导出按钮操作 */
-const handleExport = async () => {
-  try {
-    // 导出的二次确认
-    await message.exportConfirm()
-    // 发起导出
-    exportLoading.value = true
-    const data = await JobFairWhiteApi.exportJobFairWhiteList(queryParams.value.jobFairId)
-    download.excel(data, '招聘会职位列表.xls')
-  } catch {
-  } finally {
-    exportLoading.value = false
-  }
-}
+const { push, currentRoute } = useRouter() // 路由
+const { delView } = useTagsViewStore() // 视图操作
 
-// 招聘会投递情况导出
-const exportDeliveryLoading = ref(false)
-const handleExportDelivery = async () => {
-  try {
-    // 导出的二次确认
-    await message.exportConfirm()
-    // 发起导出
-    exportDeliveryLoading.value = true
-    const data = await JobFairWhiteApi.exportJobFairApplyData(queryParams.value.jobFairId)
-    download.excel(data, '招聘会职位投递情况.xls')
-  } catch {
-  } finally {
-    exportDeliveryLoading.value = false
-  }
+/** 关闭按钮 */
+const handleClose = () => {
+  delView(unref(currentRoute))
+  push({ path: '/job-fair/manage' })
 }
 
 /** 初始化 */
-const { currentRoute } = useRouter() // 路由
-const { delView } = useTagsViewStore() // 视图操作
 const route = useRoute()
 const { id } = route.params
 onMounted(() => {
-  if (!id) {
-    ElMessage.warning('参数错误,招聘会编号不能为空!')
-    delView(unref(currentRoute))
-    return
-  }
-  queryParams.value.jobFairId = id
-  getList()
-  getJobFairDetail()
+  if (id) getJobFairDetail(id)
 })
 </script>

+ 65 - 16
src/views/menduner/system/jobFair/manage/details/jobFairForm.vue

@@ -1,5 +1,5 @@
 <template>
-  <Dialog title="添加白名单" v-model="dialogVisible">
+  <Dialog title="添加白名单" v-model="dialogVisible" class="!w-80%">
     <el-form
       ref="formRef"
       :model="formData"
@@ -7,9 +7,28 @@
       label-width="100px"
       v-loading="formLoading"
     >
-      <el-form-item label="企业名称" prop="enterpriseIds">
-        <el-select v-model="formData.enterpriseIds" multiple filterable clearable placeholder="请输入企业全称进行查找">
-          <el-option v-for="(item, index) in enterpriseList" :key="index" :label="item.name" :value="item.id" />
+      <el-form-item label="企业别名" prop="enterpriseIds">
+        <el-select
+          v-model="formData.enterpriseIds"
+          multiple
+          size="large"
+          filterable
+          clearable
+          remote
+          tag-type="primary"
+          :remote-method="remoteMethod"
+          :loading="loading"
+          placeholder="请输入企业别名进行查找"
+        >
+          <el-option
+            v-for="(item, index) in enterpriseList"
+            :key="index"
+            :label="formatName(item.anotherName || item.name)"
+            :value="item.id"
+          >
+            <span>{{ formatName(item.anotherName || item.name) }}</span>
+          </el-option>
+          <p v-if="showLoadMore" class="text-center color-lightblue cursor-pointer" @click="handleLoadMore">加载更多</p>
         </el-select>
       </el-form-item>
     </el-form>
@@ -22,14 +41,14 @@
 
 <script setup lang="ts">
 import { JobFairWhiteApi } from '@/api/menduner/system/jobFair/white'
-import { EnterpriseUserBindApi } from '@/api/menduner/system/enterprise/userBind'
+import { formatName } from '@/utils'
+import { EnterpriseApi } from '@/api/menduner/system/enterprise/message'
 
 /** 招聘会 表单 */
 defineOptions({ name: 'JobFairDetailsForm' })
 
 const message = useMessage() // 消息弹窗
 
-const enterpriseList = ref([])
 const dialogVisible = ref(false) // 弹窗的是否展示
 const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 const formData = ref({
@@ -41,6 +60,38 @@ const formRules = reactive({
 })
 const formRef = ref() // 表单 Ref
 
+const showLoadMore = ref(true) // 是否展示加载更多按钮
+const loading = ref(false)
+const enterpriseList = ref([])
+
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 20
+})
+const getEnterpriseList = async () => {
+  const result = await EnterpriseApi.getEnterprisePage(queryParams)
+  const list = result.list || []
+  enterpriseList.value = enterpriseList.value.concat(list)
+  if (enterpriseList.value.length === result.total) showLoadMore.value = false
+}
+getEnterpriseList()
+
+const remoteMethod = async (query: string) => {
+  if (query) {
+    loading.value = true
+    enterpriseList.value = []
+    queryParams.pageNo = 1
+    queryParams.anotherName = query
+    await getEnterpriseList()
+    loading.value = false
+  }
+}
+
+const handleLoadMore = () => {
+  queryParams.pageNo++
+  getEnterpriseList()
+}
+
 /** 打开弹窗 */
 const open = async (id: string) => {
   resetForm()
@@ -49,15 +100,6 @@ const open = async (id: string) => {
 }
 defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
-// 企业列表
-const getEnterpriseListData = async () => {
-  try {
-    const data = await EnterpriseUserBindApi.getEnterpriseList()
-    enterpriseList.value = data
-  } catch (err) {}
-}
-getEnterpriseListData()
-
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 const submitForm = async () => {
@@ -85,4 +127,11 @@ const resetForm = () => {
   }
   formRef.value?.resetFields()
 }
-</script>
+</script>
+
+<style scoped lang="scss">
+:deep(.el-select__wrapper) {
+  align-items: start;
+  min-height: 100px;
+}
+</style>

+ 8 - 39
src/views/menduner/system/jobFair/manage/index.vue

@@ -45,12 +45,12 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:job-fair:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:job-fair:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <el-button
           type="primary"
           plain
-          @click="openForm('create')"
+          @click="openForm"
           v-hasPermi="['menduner:system:job-fair:create']"
         >
           <Icon icon="ep:plus" class="mr-5px" /> 新增
@@ -86,13 +86,6 @@
           <el-image v-if="scope.row.pcPreviewImg" :src="scope.row.pcPreviewImg" lazy preview-teleported :preview-src-list="[scope.row.pcPreviewImg]" fit="contain" />
         </template>
       </el-table-column>
-      <!-- <el-table-column label="简历投递次数" align="center" prop="cvRelNum" /> -->
-      <!-- <el-table-column label="门票金额" align="center" prop="admissionPrice">
-        <template #default="scope">
-          {{ scope.row.admissionPrice > 0 ? scope.row.admissionPrice / 100 : '' }}
-        </template>
-      </el-table-column>
-      <el-table-column label="企业可发布职位数" align="center" prop="allowedJobNum" /> -->
       <el-table-column label="状态" align="center" prop="status">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MENDUNER_STATUS" :value="scope.row.status" />
@@ -103,10 +96,8 @@
       <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" />
       <el-table-column label="操作" align="center" fixed="right" min-width="100">
         <template #default="scope">
-          <el-button link type="success" @click="openTicketSettings(scope.row)">门票设置</el-button>
-          <el-button link type="primary" @click="openStatistics(scope.row.id)">数据统计</el-button>
-          <el-button link type="primary" @click="openDetail(scope.row.id)">白名单</el-button>
-          <el-button link type="primary" @click="openForm('update', scope.row.id)" v-hasPermi="['menduner:system:job-fair:update']">编辑</el-button>
+          <el-button link type="primary" @click="openDetail(scope.row.id)">详情</el-button>
+          <el-button link type="success" @click="openStatistics(scope.row.id)">数据统计</el-button>
           <!-- <el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['menduner:system:job-fair:delete']">删除</el-button> -->
         </template>
       </el-table-column>
@@ -152,7 +143,6 @@ const queryParams = reactive({
   createTime: []
 })
 const queryFormRef = ref() // 搜索的表单
-// const exportLoading = ref(false) // 导出的加载中
 
 /** 查询列表 */
 const getList = async () => {
@@ -179,15 +169,10 @@ const resetQuery = () => {
 }
 
 /** 添加/修改操作 */
+const { push } = useRouter()
 const formRef = ref()
-const openForm = (type: string, id?: number) => {
-  formRef.value.open(type, id)
-}
-
-/** 门票设置 */
-const ticketRef = ref()
-const openTicketSettings = ({ id, admissionPrice, allowedJobNum}) => {
-  ticketRef.value.open({ id, admissionPrice, allowedJobNum})
+const openForm = () => {
+  push({ name: 'JobFairAdd' })
 }
 
 /** 删除按钮操作 */
@@ -203,23 +188,7 @@ const handleDelete = async (id: number) => {
   } catch {}
 }
 
-/** 导出按钮操作 */
-// const handleExport = async () => {
-//   try {
-//     // 导出的二次确认
-//     await message.exportConfirm()
-//     // 发起导出
-//     exportLoading.value = true
-//     const data = await JobFairManageApi.exportJobFair(queryParams)
-//     download.excel(data, '招聘会管理.xls')
-//   } catch {
-//   } finally {
-//     exportLoading.value = false
-//   }
-// }
-
 /** 打开招聘会详情 */
-const { push } = useRouter()
 const openDetail = (id) => {
   push({ name: 'JobFairDetail', params: { id } })
 }

+ 40 - 2
src/views/menduner/system/jobFair/manage/statistics/index.vue

@@ -69,6 +69,8 @@
         <el-form-item>
           <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
           <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+          <el-button type="primary" :loading="exportJobLoading" plain @click="handleExportJob"><Icon icon="ep:download" class="mr-5px" /> 职位列表导出</el-button>
+          <el-button type="primary" :loading="exportLoading" plain @click="handleExport"><Icon icon="ep:download" class="mr-5px" /> 用户投递情况导出</el-button>
         </el-form-item>
       </el-form>
     </ContentWrap>
@@ -126,6 +128,8 @@ import ComparisonCard from './components/ComparisonCard.vue'
 import { formatName } from '@/utils'
 import { timesTampChange } from '@/utils/transform/date'
 import { DICT_TYPE, getDictLabel } from '@/utils/dict'
+import { JobFairWhiteApi } from '@/api/menduner/system/jobFair/white'
+import download from '@/utils/download'
 
 const route = useRoute() // 路由信息
 const { id } = route.params
@@ -136,6 +140,7 @@ const currentItem = ref({})
 const tableData = ref([])
 const showDialog = ref(false)
 const total = ref(0)
+const message = useMessage() // 消息弹窗
 const page = reactive({ pageNo: 1, pageSize: 10 })
 
 const queryFormRef = ref()
@@ -240,8 +245,8 @@ const dealTableData = () => {
       item.enterpriseName = formatName(item.enterprise.anotherName || item.enterprise.name)
       item.salaryDisplay = item.payFrom && item.payTo ? `${item.payFrom}-${item.payTo}/${getDictLabel(DICT_TYPE.MENDUNER_PAY_UNIT, item.payUnit)}` : '面议'
       item.areaName = !item.areaId ? '全国' : item.area.str
-      item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType)
-      item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType)
+      item.expName = getDictLabel(DICT_TYPE.MENDUNER_EXP_TYPE, item.expType) || '不限'
+      item.eduName = getDictLabel(DICT_TYPE.MENDUNER_EDUCATION_TYPE, item.eduType) || '不限'
       item.createTime = timesTampChange(item.createTime)
       return item
     })
@@ -258,6 +263,39 @@ const dealTableData = () => {
   }
 }
 
+const exportLoading = ref(false)
+/** 导出按钮操作 */
+const handleExport = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await JobFairManageApi.exportDelivery({ ...queryParams, pageNo: 1 })
+    download.excel(data, '用户投递列表.xls')
+  } catch {
+    exportLoading.value = false
+  } finally {
+    exportLoading.value = false
+  }
+}
+
+const exportJobLoading = ref(false)
+/** 导出按钮操作 */
+const handleExportJob = async () => {
+  try {
+    // 导出的二次确认
+    await message.exportConfirm()
+    // 发起导出
+    exportLoading.value = true
+    const data = await JobFairWhiteApi.exportJobFairWhiteList(id)
+    download.excel(data, '招聘会职位列表.xls')
+  } catch {
+  } finally {
+    exportLoading.value = false
+  }
+}
+
 const getList = async (typeName, details = '') => {
   loading.value = true
   try {

+ 8 - 2
src/views/menduner/system/major/MajorForm.vue

@@ -13,12 +13,16 @@
       <el-form-item label="专业英文名称" prop="nameEn">
         <el-input v-model="formData.nameEn" placeholder="请输入专业英文名称" />
       </el-form-item>
+      <el-form-item label="排序" prop="sort">
+        <el-input-number v-model="formData.sort" :step="1" />
+      </el-form-item>
       <el-form-item label="帐号状态" prop="status">
         <el-radio-group v-model="formData.status">
           <el-radio
             v-for="dict in getIntDictOptions(DICT_TYPE.MENDUNER_STATUS)"
             :key="dict.value"
             :label="dict.value"
+            :value="dict.value.toString()"
           >
             {{ dict.label }}
           </el-radio>
@@ -49,7 +53,8 @@ const formData = ref({
   id: undefined,
   nameCn: undefined,
   nameEn: undefined,
-  status: undefined
+  status: undefined,
+  sort: undefined
 })
 const formRules = reactive({
   status: [{ required: true, message: '帐号状态(0正常 1停用)不能为空', trigger: 'blur' }]
@@ -104,7 +109,8 @@ const resetForm = () => {
     id: undefined,
     nameCn: undefined,
     nameEn: undefined,
-    status: undefined
+    status: undefined,
+    sort: undefined,
   }
   formRef.value?.resetFields()
 }

+ 8 - 6
src/views/menduner/system/major/index.vue

@@ -8,7 +8,7 @@
       :inline="true"
       label-width="68px"
     >
-      <el-form-item label="中文名称" prop="nameCn">
+      <el-form-item label="中文名称" prop="nameCn" v-hasPermi="['menduner:system:major:query']">
         <el-input
           v-model="queryParams.nameCn"
           placeholder="请输入专业中文名称"
@@ -17,7 +17,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="英文名称" prop="nameEn">
+      <el-form-item label="英文名称" prop="nameEn" v-hasPermi="['menduner:system:major:query']">
         <el-input
           v-model="queryParams.nameEn"
           placeholder="请输入专业英文名称"
@@ -26,7 +26,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="帐号状态" prop="status">
+      <el-form-item label="帐号状态" prop="status" v-hasPermi="['menduner:system:major:query']">
         <el-select
           v-model="queryParams.status"
           placeholder="请选择帐号状态"
@@ -41,7 +41,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="创建时间" prop="createTime">
+      <el-form-item label="创建时间" prop="createTime" v-hasPermi="['menduner:system:major:query']">
         <el-date-picker
           v-model="queryParams.createTime"
           value-format="YYYY-MM-DD HH:mm:ss"
@@ -53,8 +53,8 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:major:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:major:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <el-button
           type="primary"
           plain
@@ -80,8 +80,10 @@
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :stripe="true">
       <el-table-column label="id" align="left" prop="id" />
+      <el-table-column label="类别" align="center" prop="categorize" />
       <el-table-column label="专业名称" align="center" prop="nameCn" />
       <el-table-column label="专业英文名称" align="center" prop="nameEn" />
+      <el-table-column label="排序" align="center" prop="sort" />
       <el-table-column label="帐号状态" align="center" prop="status">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MENDUNER_STATUS" :value="scope.row.status" />

+ 50 - 0
src/views/menduner/system/order/TradeDetail.vue

@@ -0,0 +1,50 @@
+<template>
+  <Dialog title="订单详情" v-model="dialogVisible" width="70%">
+    <el-descriptions title="" border :column="2">
+      <el-descriptions-item label="购买方">
+				<span style="color: #409EFF; cursor: pointer;" @click="handleDetail">
+          {{ info?.userType === '0' ? info?.person?.name : info?.enterprise ? formatName(info?.enterprise.name) : info?.person?.name }}
+        </span>
+			</el-descriptions-item>
+      <el-descriptions-item label="商品名称">{{ info?.spuName }}</el-descriptions-item>
+      <el-descriptions-item label="价格">{{ (info?.price / 100.0).toFixed(2) }}元</el-descriptions-item>
+      <el-descriptions-item label="是否已支付">{{ info?.payStatus ? '已支付' : '未支付' }}</el-descriptions-item>
+      <el-descriptions-item label="支付订单编号">{{ info?.payOrderId }}</el-descriptions-item>
+      <el-descriptions-item label="支付渠道">
+				<dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="info.payChannelCode" />
+			</el-descriptions-item>
+      <el-descriptions-item label="订单支付时间">{{ info?.payTime ? formatDate(info?.payTime) : '' }}</el-descriptions-item>
+      <el-descriptions-item label="是否退款">{{ info.payRefundId ? '已退款' : '' }}</el-descriptions-item>
+      <el-descriptions-item label="退款金额">{{ (info.refundPrice / 100.0).toFixed(2) }}</el-descriptions-item>
+      <el-descriptions-item label="退款时间">{{ info?.refundTime ? formatDate(info?.refundTime) : '' }}</el-descriptions-item>
+      <el-descriptions-item label="订单是否取消">{{ info.cancelType ? '订单取消': '' }}</el-descriptions-item>
+      <el-descriptions-item label="订单取消时间">{{ info?.cancelTime ? formatDate(info?.cancelTime) : '' }}</el-descriptions-item>
+      <el-descriptions-item label="订单创建时间">{{ info.createTime ? formatDate(info?.createTime) : '' }}</el-descriptions-item>
+    </el-descriptions>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { formatDate } from '@/utils/formatTime'
+import { formatName } from '@/utils'
+
+defineOptions({ name: 'TradeOrderDetail' })
+const dialogVisible = ref(false) // 弹窗的是否展示
+
+/** 打开弹窗 */
+const info = ref({}) // 详情数据
+const open = async (item: object) => {
+	info.value = item
+  dialogVisible.value = true
+}
+
+const { push } = useRouter()
+const handleDetail = () => {
+	dialogVisible.value = false
+	if (info.value?.userType === '1' && info.value?.enterprise) push({ name: 'EnterpriseDetail', params: { id: info.value?.enterpriseId } })
+	else push({ name: 'PersonDetail', query: { id: info.value?.person?.id, userId: info.value?.userId } })
+}
+
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
+</script>

+ 55 - 34
src/views/menduner/system/order/index.vue

@@ -8,7 +8,7 @@
       :inline="true"
       label-width="140px"
     >
-      <el-form-item label="用户编号" prop="userId">
+      <el-form-item label="用户编号" prop="userId" v-hasPermi="['menduner:system:trade-order:query']">
         <el-input
           v-model="queryParams.userId"
           placeholder="请输入用户编号"
@@ -18,16 +18,16 @@
         />
       </el-form-item>
       <el-form-item label="订单类型" prop="type">
-        <el-select
-          v-model="queryParams.type"
-          placeholder="请选择订单类型"
-          clearable
-          class="!w-240px"
-        >
-          <el-option label="请选择字典生成" value="" />
+        <el-select v-model="queryParams.type" clearable placeholder="请选择订单类型" class="!w-240px">
+          <el-option
+            v-for="dict in getStrDictOptions(DICT_TYPE.MENDUNER_TRADE_ORDER_TYPE)"
+            :key="dict.value"
+            :label="dict.label"
+            :value="dict.value"
+          />
         </el-select>
       </el-form-item>
-      <el-form-item label="商品编号" prop="spuId">
+      <el-form-item label="商品编号" prop="spuId" v-hasPermi="['menduner:system:trade-order:query']">
         <el-input
           v-model="queryParams.spuId"
           placeholder="请输入商品编号"
@@ -36,7 +36,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="商品名字" prop="spuName">
+      <el-form-item label="商品名字" prop="spuName" v-hasPermi="['menduner:system:trade-order:query']">
         <el-input
           v-model="queryParams.spuName"
           placeholder="请输入商品名字"
@@ -60,7 +60,7 @@
           />
         </el-select>
       </el-form-item>
-      <el-form-item label="支付订单编号" prop="payOrderId">
+      <el-form-item label="支付订单编号" prop="payOrderId" v-hasPermi="['menduner:system:trade-order:query']">
         <el-input
           v-model="queryParams.payOrderId"
           placeholder="请输入支付订单编号"
@@ -81,9 +81,9 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
-          <el-button v-hasPermi="['menduner:system:trade-order:create']" type="primary" plain @click="openForm('create')"><Icon icon="ep:plus" />发起订单</el-button>
+        <el-button v-hasPermi="['menduner:system:trade-order:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:trade-order:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <!-- <el-button v-hasPermi="['menduner:system:trade-order:create']" type="primary" plain @click="openForm('create')"><Icon icon="ep:plus" />发起订单</el-button> -->
       </el-form-item>
     </el-form>
   </ContentWrap>
@@ -91,52 +91,54 @@
   <!-- 列表 -->
   <ContentWrap>
     <el-table v-loading="loading" :data="list" :stripe="true">
-      <!-- <el-table-column label="编号" align="center" prop="id" :show-overflow-tooltip="true" /> -->
-      <!-- <el-table-column label="用户编号" align="center" prop="userId" :show-overflow-tooltip="true" /> -->
-      <el-table-column label="商品名字" align="center" prop="spuName">
+      <el-table-column label="购买方" align="center" prop="userType" fixed="left">
+        <template #default="scope">
+          <span style="color: #409EFF; cursor: pointer;" @click="handleToDetail(scope.row)">
+            {{ scope.row?.userType === '0' ? scope.row?.person?.name : scope.row?.enterprise ? formatName(scope.row?.enterprise.name) : scope.row?.person?.name }}
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="商品名字" align="center" prop="spuName" fixed="left" width="180">
         <template #default="scope">{{ formatName(scope.row.spuName) }}</template>
       </el-table-column>
-      <el-table-column label="价格" align="center" prop="price">
+      <el-table-column label="价格" align="center" prop="price" fixed="left">
         <template #default="scope">
           {{ (scope.row.price / 100.0).toFixed(2) }}
         </template>
       </el-table-column>
       <el-table-column label="是否已支付" align="center" prop="payStatus">
         <template #default="scope">
-          {{ scope.row.payStatus ? '已支付' : '未支付' }}
+          <span :style="{'color': scope.row.payStatus ? '#67C23A' : '#F56C6C'}">{{ scope.row.payStatus ? '已支付' : '未支付' }}</span>
         </template>
       </el-table-column>
-      <el-table-column label="支付订单编号" align="center" prop="payOrderId" />
-      <el-table-column label="支付渠道" align="center" prop="payChannelCode">
+      <el-table-column label="支付订单编号" align="center" prop="payOrderId" width="180" />
+      <el-table-column label="支付渠道" align="center" prop="payChannelCode" width="130">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.PAY_CHANNEL_CODE" :value="scope.row.payChannelCode" />
         </template>
       </el-table-column>
       <el-table-column label="订单支付时间" align="center" prop="payTime" :formatter="dateFormatter" width="180px" />
-      <el-table-column label="退款订单编号" align="center" prop="payRefundId" />
-      <el-table-column label="" align="center" prop="" />
-      <el-table-column label="退款金额" align="center" prop="refundPrice">
-        <template #default="scope">
-          {{ (scope.row.refundPrice / 100.0).toFixed(2) }}
-        </template>
+      <el-table-column label="是否退款" align="center" prop="payRefundId">
+        <template #default="scope">{{ scope.row.payRefundId ? '已退款' : '' }}</template>
       </el-table-column>
-      <el-table-column label="退款时间" align="center" prop="refundTime" :formatter="dateFormatter" width="180px" />
-      <el-table-column label="订单取消类型" align="center" prop="cancelType">
+      <el-table-column label="订单是否取消" align="center" prop="cancelType">
         <template #default="scope">
-          <dict-tag :type="DICT_TYPE.MENDUNER_TRADE_ORDER_CANCEL_TYPE" :value="scope.row.cancelType" />
+          {{ scope.row.cancelType ? '订单取消': '' }}
+          <!-- <dict-tag :type="DICT_TYPE.MENDUNER_TRADE_ORDER_CANCEL_TYPE" :value="scope.row.cancelType" /> -->
         </template>
       </el-table-column>
-      <el-table-column label="订单取消时间" align="center" prop="cancelTime" :formatter="dateFormatter" width="180px" />
       <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180px" />
-      <el-table-column label="操作" align="center" fixed="right" min-width="90">
+      <el-table-column label="操作" align="center" fixed="right" min-width="140">
         <template #default="scope">
-          <el-button link type="primary" @click="handlePay(scope.row)" v-if="!scope.row.payStatus && scope.row.cancelType !== '10'">
+          <el-button link type="primary" @click="handleDetail(scope.row)">详情</el-button>
+          <el-button link type="primary" @click="handlePay(scope.row)" v-if="!scope.row.payStatus && scope.row.cancelType !== '10'" v-hasPermi="['menduner:system:trade-order:update']">
             前往支付
           </el-button>
           <el-button
             link
             type="danger"
             @click="handleRefund(scope.row)"
+            v-hasPermi="['menduner:system:trade-order:update']"
             v-if="scope.row.payStatus && !scope.row.payRefundId"
           >
             发起退款
@@ -155,14 +157,18 @@
 
   <!-- 表单弹窗:添加/修改 -->
   <TradeOrderForm ref="formRef" @success="getList" />
+
+  <!-- 详情 -->
+  <TradeDetail ref="detailRef" />
 </template>
 
 <script setup lang="ts">
 import { dateFormatter } from '@/utils/formatTime'
-import { DICT_TYPE } from '@/utils/dict'
 import { TradeOrderApi, TradeOrderVO } from '@/api/menduner/system/order'
 import TradeOrderForm from './TradeOrderForm.vue'
+import TradeDetail from './TradeDetail.vue'
 import { formatName } from '@/utils'
+import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
 
 /** 交易订单	 列表 */
 defineOptions({ name: 'TradeOrder' })
@@ -229,6 +235,20 @@ const openForm = (type: string, id?: number) => {
   formRef.value.open(type, id)
 }
 
+// 订单详情
+const detailRef = ref()
+const handleDetail = (row: object) => {
+  console.log(row, 'detail');
+  detailRef.value.open(row)
+}
+
+// 跳转购买方详情
+const { push } = useRouter()
+const handleToDetail = (row: object) => {
+	if (row?.userType === '1' && row.enterprise) push({ name: 'EnterpriseDetail', params: { id: row?.enterpriseId } })
+	else push({ name: 'PersonDetail', query: { id: row?.person?.id, userId: row?.userId } })
+}
+
 /** 支付按钮操作 */
 const handlePay = (row: any) => {
   router.push({
@@ -256,6 +276,7 @@ const handleRefund = async (row: any) => {
 
 /** 初始化 **/
 onMounted(() => {
+  queryParams.payStatus = true
   getList()
 })
 </script>

+ 5 - 6
src/views/menduner/system/person/details/components/account.vue

@@ -1,13 +1,12 @@
 <template>
   <div>
     <el-descriptions class="margin-top" :column="1" border>
-      <el-descriptions-item label="用户类型">{{ info.userType === '1' ? '管理员' : '普通用户' }}</el-descriptions-item>
+      <el-descriptions-item label="用户类型">{{ info.userType ? info.userType === '1' ? '管理员' : '普通用户' : '' }}</el-descriptions-item>
       <el-descriptions-item label="账户积分">{{ info.point }}</el-descriptions-item>
-      <el-descriptions-item label="账户余额">{{ (info.balance / 100.0).toFixed(2) }}</el-descriptions-item>
-      <el-descriptions-item label="累计支出">{{ (info.totalExpense / 100.0).toFixed(2) }}</el-descriptions-item>
-      <el-descriptions-item label="累计充值">{{ (info.totalRecharge / 100.0).toFixed(2) }}</el-descriptions-item>
-      <el-descriptions-item label="冻结金额">{{ (info.freezePrice / 100.0).toFixed(2) }}</el-descriptions-item>
-      <!-- <el-descriptions-item label="创建时间">{{ formatDate(info.createTime) }}</el-descriptions-item> -->
+      <el-descriptions-item label="账户余额">{{ info.balance ? (info.balance / 100.0).toFixed(2) : '' }}</el-descriptions-item>
+      <el-descriptions-item label="累计支出">{{ info.totalExpense ? (info.totalExpense / 100.0).toFixed(2) : '' }}</el-descriptions-item>
+      <el-descriptions-item label="累计充值">{{ info.totalRecharge ? (info.totalRecharge / 100.0).toFixed(2) :'' }}</el-descriptions-item>
+      <el-descriptions-item label="冻结金额">{{ info.freezePrice ? (info.freezePrice / 100.0).toFixed(2) : '' }}</el-descriptions-item>
     </el-descriptions>
   </div>
 </template>

+ 33 - 0
src/views/menduner/system/person/details/components/student.vue

@@ -0,0 +1,33 @@
+<template>
+  <el-card shadow="never">
+    <template #header>
+      <CardTitle title="学生信息" />
+    </template>
+    <el-descriptions class="margin-top" :column="3" border>
+      <el-descriptions-item label="就读学校">{{ info.schoolInfo?.name }}</el-descriptions-item>
+      <el-descriptions-item label="所在院系">{{ info.schoolDept?.name }}</el-descriptions-item>
+      <el-descriptions-item label="所属专业">{{ info.major?.nameCn }}</el-descriptions-item>
+      <el-descriptions-item label="所在班级">{{ info.schoolClass?.name }}</el-descriptions-item>
+      <el-descriptions-item label="学号">{{ info?.studentNo }}</el-descriptions-item>
+      <el-descriptions-item label="紧急联系人">{{ info?.emergencyContactName }}</el-descriptions-item>
+      <el-descriptions-item label="紧急联系人电话">{{ info?.emergencyContactPhone }}</el-descriptions-item>
+    </el-descriptions>
+  </el-card>
+</template>
+
+<script setup>
+defineOptions({ name: 'EnterpriseDetailsInfo'})
+import { PersonInfoApi } from '@/api/menduner/system/person'
+
+const props = defineProps({
+  userId: String
+})
+
+// 获取学生信息
+const info = ref({})
+const getInfo = async () => {
+  const data = await PersonInfoApi.getStudentInfo(props.userId)
+  info.value = data
+}
+if (props.userId) getInfo()
+</script>

+ 21 - 14
src/views/menduner/system/person/details/index.vue

@@ -9,38 +9,44 @@
           <Info :id="id" :user-id="userId" />
         </el-card>
       </el-col>
-      <el-col :span="6">
-        <el-card shadow="never">
-          <template #header>
-            <CardTitle title="账户信息" />
-          </template>
-          <Account :user-id="userId" />
-        </el-card>
-      </el-col>
-      <el-col :span="6">
+      <el-col :span="6" v-hasPermi="['menduner:system:person-job-favorite:query']">
         <el-card shadow="never">
           <template #header>
             <CardTitle title="职位收藏、企业收藏数" />
           </template>
           <Collect :user-id="userId" />
         </el-card>
-        <el-card shadow="never" class="m-t-10px">
+        <el-card shadow="never" class="m-t-10px" v-hasPermi="['menduner:system:cv-attachment:query']">
           <template #header>
             <CardTitle title="附件简历" />
           </template>
           <Attachment :user-id="userId" />
         </el-card>
       </el-col>
+      <el-col :span="6" v-hasPermi="['menduner:system:user-account:query']">
+        <el-card shadow="never">
+          <template #header>
+            <CardTitle title="账户信息" />
+          </template>
+          <Account :user-id="userId" />
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-t-20px" v-if="type && type === '1'">
+      <el-col :span="24">
+        <Student :user-id="userId" />
+      </el-col>
     </el-row>
 
     <el-row class="m-t-20px">
       <el-col :span="24">
         <el-card shadow="never">
           <el-tabs>
-            <el-tab-pane label="职位投递记录">
+            <el-tab-pane label="职位投递记录" v-hasPermi="['menduner:system:job-cv-rel:query']">
               <DeliveryJob :user-id="userId" />
             </el-tab-pane>
-            <el-tab-pane label="面试邀约记录">
+            <el-tab-pane label="面试邀约记录" v-hasPermi="['menduner:system:interview-invite:query']">
               <InterviewInvite :user-id="userId" />
             </el-tab-pane>
             <el-tab-pane v-hasPermi="['menduner:system:edu-exp:query']" label="教育经历">
@@ -55,7 +61,7 @@
             <el-tab-pane v-hasPermi="['menduner:system:user-account:query']" label="钱包充值记录">
               <RechargeOrder :user-id="userId" />
             </el-tab-pane>
-            <el-tab-pane label="余额明细">
+            <el-tab-pane label="余额明细" v-hasPermi="['pay:wallet:query']">
               <BalanceDetails :user-id="userId" />
             </el-tab-pane>
             <el-tab-pane v-hasPermi="['menduner:system:user-account-record:query']" label="积分变动记录">
@@ -84,12 +90,13 @@ import Attachment from './components/attachment.vue'
 import DeliveryJob from './components/deliveryJob.vue'
 import BalanceDetails from './components/balanceDetails.vue'
 import InterviewInvite from './components/interviewInvite.vue'
+import Student from './components/student.vue'
 
 /** 初始化 */
 const { currentRoute } = useRouter() // 路由
 const { delView } = useTagsViewStore() // 视图操作
 const route = useRoute()
-const { id, userId } = route.query
+const { id, userId, type } = route.query
 onMounted(() => {
   if (!userId) {
     ElMessage.warning('参数错误,用户编号不能为空!')

+ 13 - 8
src/views/menduner/system/person/index.vue

@@ -103,8 +103,8 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button @click="handleQuery" v-hasPermi="['menduner:system:person-info:query']"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button @click="resetQuery" v-hasPermi="['menduner:system:person-info:query']"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <el-button
           type="success"
           plain
@@ -135,6 +135,11 @@
       <el-table-column label="职位" align="center" prop="work.positionName">
         <template #default="{ row }">{{ formatName(row.work?.positionName) }}</template>
       </el-table-column>
+      <el-table-column label="人才类型" align="center" prop="person.type">
+        <template #default="scope">
+          {{ scope.row.person?.type === '1' ? '在校学生' : '职场人士'}}
+        </template>
+      </el-table-column>
       <el-table-column label="求职状态" align="center" prop="person.jobStatus" width="130px">
         <template #default="scope">
           <dict-tag :type="DICT_TYPE.MENDUNER_JOB_SEEK_STATUS" :value="scope.row.person?.jobStatus" />
@@ -155,10 +160,10 @@
       <el-table-column label="邀请人" align="center" prop="inviteUserStr" />
       <el-table-column label="操作" align="center" fixed="right" min-width="220">
         <template #default="scope">
-          <el-button link type="primary" @click="openDetail(scope.row.person?.id, scope.row.user.id)">详情</el-button>
-          <el-button v-if="scope.row.user.status === '1'" link type="success" @click="handleAction(scope.row.user.id, 'enable')">启用</el-button>
-          <el-button v-if="scope.row.user.status === '0'" link type="danger" @click="handleAction(scope.row.user.id, 'disabled')">禁用</el-button>
-          <el-button link type="primary" @click="handleResetPassword(scope.row.user.id)">修改登录密码</el-button>
+          <el-button link type="primary" @click="openDetail(scope.row.person?.id, scope.row.user.id, scope.row.person?.type)">详情</el-button>
+          <el-button v-if="scope.row.user.status === '1'" link type="success" @click="handleAction(scope.row.user.id, 'enable')" v-hasPermi="['menduner:system:person-info:update']">启用</el-button>
+          <el-button v-if="scope.row.user.status === '0'" link type="danger" @click="handleAction(scope.row.user.id, 'disabled')" v-hasPermi="['menduner:system:person-info:update']">禁用</el-button>
+          <el-button link type="primary" @click="handleResetPassword(scope.row.user.id)" v-hasPermi="['menduner:system:mde-user:update-password']">修改登录密码</el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -238,8 +243,8 @@ const handleQuery = () => {
 
 /** 打开用户详情 */
 const { push } = useRouter()
-const openDetail = (id: string, userId: string) => {
-  push({ name: 'PersonDetail', query: { id, userId } })
+const openDetail = (id: string, userId: string, type: string) => {
+  push({ name: 'PersonDetail', query: { id, userId, type } })
 }
 
 /** 重置按钮操作 */

+ 1 - 0
src/views/menduner/system/position/index.vue

@@ -114,6 +114,7 @@
           <el-button
             link
             type="primary"
+            v-hasPermi="['menduner:system:position:update']"
             @click="openForm('create', scope.row.id, scope.row.level)"
           >
             添加下级

+ 5 - 5
src/views/menduner/system/positiontag/index.vue

@@ -8,7 +8,7 @@
       :inline="true"
       label-width="68px"
     >
-      <el-form-item label="职位id" prop="positionId">
+      <el-form-item label="职位id" prop="positionId" v-hasPermi="['menduner:system:position-tag:query']">
         <el-input
           v-model="queryParams.positionId"
           placeholder="请输入职位id"
@@ -17,7 +17,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="标签" prop="label">
+      <el-form-item label="标签" prop="label" v-hasPermi="['menduner:system:position-tag:query']">
         <el-input
           v-model="queryParams.label"
           placeholder="请输入标签"
@@ -26,7 +26,7 @@
           class="!w-240px"
         />
       </el-form-item>
-      <el-form-item label="创建时间" prop="createTime">
+      <el-form-item label="创建时间" prop="createTime" v-hasPermi="['menduner:system:position-tag:query']">
         <el-date-picker
           v-model="queryParams.createTime"
           value-format="YYYY-MM-DD HH:mm:ss"
@@ -38,8 +38,8 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:position-tag:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:position-tag:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <el-button
           type="primary"
           plain

+ 3 - 2
src/views/menduner/system/redeem/index.vue

@@ -74,8 +74,8 @@
         />
       </el-form-item>
       <el-form-item>
-        <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
-        <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
+        <el-button v-hasPermi="['menduner:system:redeem:query']" @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
+        <el-button v-hasPermi="['menduner:system:redeem:query']" @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
         <!--
         <el-button
           type="success"
@@ -116,6 +116,7 @@
           <el-button
             link
             type="primary"
+            v-hasPermi="['menduner:system:redeem:update']"
             @click="uploadOrderNo(scope.row.id)"
           >
             {{ scope.row.orderNo ? '修改订单编号' : '上传订单编号'}}

+ 1 - 0
src/views/menduner/system/skill/index.vue

@@ -112,6 +112,7 @@
             v-if="scope.row.level === 0"
             link
             type="primary"
+            v-hasPermi="['menduner:system:skill:update']"
             @click="openForm('create', scope.row.id, scope.row.level)"
           >
             添加下级

+ 1 - 0
src/views/menduner/system/tag/index.vue

@@ -102,6 +102,7 @@
             v-if="scope.row.level < 1"
             link
             type="primary"
+            v-hasPermi="['menduner:system:tag:update']"
             @click="openForm('create', scope.row.id, scope.row.level)"
           >
             添加下级

+ 2 - 2
src/views/menduner/system/talentMap/details/index.vue

@@ -63,7 +63,7 @@
               <Training v-model="result.trainList" :isEdit="isEdit" />
               <div class="text-center m-t-30px">
                 <el-affix position="bottom" :offset="20">
-                  <el-button @click="push('/menduner/talentMap')" type="warning" plain size="large" class="!w-120px">取 消</el-button>
+                  <el-button @click="push('/headhunting/menduner/system/talentMap/talentMap')" type="warning" plain size="large" class="!w-120px">取 消</el-button>
                   <el-button v-if="id === 'add'" type="primary" @click="handleSave" size="large" class="!w-120px">保 存</el-button>
                 </el-affix>
               </div>
@@ -263,7 +263,7 @@ const handleSave = async () => {
     await TalentMap.createTalentMapInfo(result.value)
     message.success('新增成功!')
     result.value = cloneDeep(DefaultData)
-    push('/menduner/talentMap')
+    push('/headhunting/menduner/system/talentMap/talentMap')
   } catch (error) {
     console.log(error)
   } finally {

+ 2 - 1
src/views/menduner/system/talentMap/index.vue

@@ -72,6 +72,7 @@
         </template>
       </el-table-column>
       <el-table-column label="首次工作时间" align="center" prop="person.firstWorkTime" :formatter="dateFormatter2" />
+      <el-table-column label="创建时间" align="center" prop="person.createTime" :formatter="dateFormatter" />
       <el-table-column label="操作" align="center" fixed="right" min-width="110">
         <template #default="scope">
           <el-button link type="primary" @click="openDetail(scope.row.person.id)">详情</el-button>
@@ -93,7 +94,7 @@
 import { TalentMap } from '@/api/menduner/system/talentMap'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { getDict } from '@/hooks/web/useDictionaries'
-import { dateFormatter2 } from '@/utils/formatTime'
+import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
 
 /** 人才地图 列表 */
 defineOptions({ name: 'TalentMap' })

+ 1 - 0
src/views/menduner/system/web/WebContentForm.vue

@@ -77,6 +77,7 @@ const maxHeight = ref(0)
 const imgSizeList = {
   'pcLeft': [869, 1512],
   'pcAdvertisement': [900, 530],
+  'pcBackendAdvertisement': [900, 530],
   'pcHomeCarousel': [792, 392],
   'pcLoginCarousel': [792, 392],
   'appHomeCarousel': [750, 350],

+ 12 - 12
src/views/menduner/system/web/index.vue

@@ -5,19 +5,19 @@
     </el-tabs>
     <div style="display: flex; justify-content: space-between;">
       <div style="display: flex; color: orange; align-items: center;">
-        <div v-if="tab !== 9">
+        <div v-if="tab !== 10">
           <Icon :size="20" icon="ep:warning" class="mr-3px" />
           图片规格: 
           <span class="m-l-10px">{{ tabList[tab].size }}</span>
         </div>
       </div>
       <div>
-        <el-button @click="getList"><Icon icon="ep:refresh" class="mr-5px" /> 刷 新</el-button>
+        <el-button v-hasPermi="['menduner:system:web-content:query']" @click="getList"><Icon icon="ep:refresh" class="mr-5px" /> 刷 新</el-button>
         <el-button type="primary" @click="handleAdd"><Icon icon="ep:plus" class="mr-5px" v-hasPermi="['menduner:system:web-content:create']" />新 增</el-button>
       </div>
     </div>
 
-    <el-table v-if="tab !== 9" v-loading="loading" :data="info[tabList[tab].key]" :stripe="true">
+    <el-table v-if="tab !== 10" v-loading="loading" :data="info[tabList[tab].key]" :stripe="true">
       <el-table-column label="排序" align="center" prop="sort" />
       <el-table-column label="标题" align="center" prop="title" />
       <el-table-column label="图片" align="center" prop="img" width="200">
@@ -67,7 +67,6 @@
 import { WebContentApi } from '@/api/menduner/system/web'
 import WebContentForm from './WebContentForm.vue'
 import PreferredGroup from './PreferredGroup.vue'
-import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
 import { EnterpriseUserBindApi } from '@/api/menduner/system/enterprise/userBind'
 
 /** 页面内容 列表 */
@@ -82,13 +81,14 @@ const tabList = ref([
   { label: 'PC首页顶部广告图', value: 0, key: 'pcTop', size: '宽1920px*高80px' },
   { label: 'PC首页左侧广告图', value: 1, key: 'pcLeft', size: '宽869px*高1512px' },
   { label: 'PC首页弹窗广告图', value: 2, key: 'pcAdvertisement', size: '宽900px*高530px' },
-  { label: 'PC首页轮播图', value: 3, key: 'pcHomeCarousel', size: '宽792px*高392px' },
-  { label: 'PC首页优选集团', value: 4, key: 'pcHomePreferred', size: '宽378px*高173px' },
-  { label: 'PC登录页轮播图', value: 5, key: 'pcLoginCarousel', size: '宽792px*高392px' },
-  { label: 'PC登录页背景图', value: 6, key: 'pcLoginBackground', size: '宽1920px*高940px' },
-  { label: '小程序首页轮播图', value: 7, key: 'appHomeCarousel', size: '宽750px*高350px' },
-  { label: '小程序首页弹窗广告图', value: 8, key: 'appAdvertisement', size: '宽331px*高442px' },
-  { label: '优选集团内容', value: 9, key: 'appPreferredGroup' }
+  { label: 'PC企业弹窗广告图', value: 3, key: 'pcBackendAdvertisement', size: '宽900px*高530px' },
+  { label: 'PC首页轮播图', value: 4, key: 'pcHomeCarousel', size: '宽792px*高392px' },
+  { label: 'PC首页优选集团', value: 5, key: 'pcHomePreferred', size: '宽378px*高173px' },
+  { label: 'PC登录页轮播图', value: 6, key: 'pcLoginCarousel', size: '宽792px*高392px' },
+  { label: 'PC登录页背景图', value: 7, key: 'pcLoginBackground', size: '宽1920px*高940px' },
+  { label: '小程序首页轮播图', value: 8, key: 'appHomeCarousel', size: '宽750px*高350px' },
+  { label: '小程序首页弹窗广告图', value: 9, key: 'appAdvertisement', size: '宽331px*高442px' },
+  { label: '优选集团内容', value: 10, key: 'appPreferredGroup' }
 ])
 
 /** 查询列表 */
@@ -127,7 +127,7 @@ const tabClick = (val) => {
 }
 
 const handleAdd = () => {
-  if (tab.value === 9) return preferredGroupRef.value.open(tabList.value[tab.value].key) // 优选集团
+  if (tab.value === 10) return preferredGroupRef.value.open(tabList.value[tab.value].key) // 优选集团
   formRef.value.open('add', tabList.value[tab.value].key, tabList.value[tab.value].label)
 }
 

+ 6 - 0
src/views/system/social/client/SocialClientForm.vue

@@ -32,6 +32,9 @@
           </el-radio>
         </el-radio-group>
       </el-form-item>
+      <el-form-item label="应用标识" prop="application">
+        <el-input v-model="formData.application" placeholder="请输入应用标识" />
+      </el-form-item>
       <el-form-item label="客户端编号" prop="clientId">
         <el-input v-model="formData.clientId" placeholder="请输入客户端编号,对应各平台的appKey" />
       </el-form-item>
@@ -81,11 +84,13 @@ const formData = ref({
   clientId: undefined,
   clientSecret: undefined,
   agentId: undefined,
+  application: undefined,
   status: 0
 })
 const formRules = reactive({
   name: [{ required: true, message: '应用名不能为空', trigger: 'blur' }],
   socialType: [{ required: true, message: '社交平台不能为空', trigger: 'blur' }],
+  application: [{ required: true, message: '应用标识不能为空', trigger: 'blur' }],
   userType: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
   clientId: [{ required: true, message: '客户端编号不能为空', trigger: 'blur' }],
   clientSecret: [{ required: true, message: '客户端密钥不能为空', trigger: 'blur' }],
@@ -144,6 +149,7 @@ const resetForm = () => {
     name: undefined,
     socialType: undefined,
     userType: undefined,
+    application: undefined,
     clientId: undefined,
     clientSecret: undefined,
     agentId: undefined,

+ 1 - 0
src/views/system/social/client/index.vue

@@ -104,6 +104,7 @@
           <dict-tag :type="DICT_TYPE.USER_TYPE" :value="scope.row.userType" />
         </template>
       </el-table-column>
+      <el-table-column align="center" label="应用标识" prop="application" />
       <el-table-column align="center" label="客户端编号" prop="clientId" width="180px" />
       <el-table-column align="center" label="状态" prop="status">
         <template #default="scope">