diff --git a/public/excel/dictlist.xlsx b/public/excel/dictlist.xlsx new file mode 100644 index 0000000..a942c45 Binary files /dev/null and b/public/excel/dictlist.xlsx differ diff --git a/src/api/basic/basicasynctask.ts b/src/api/basic/basicasynctask.ts new file mode 100644 index 0000000..bad7dc1 --- /dev/null +++ b/src/api/basic/basicasynctask.ts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2025, cyweb All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + */ + +import request from '/@/utils/request'; + +/** + * 获取列表 + * @param query + */ +export const fetchList = (query?: any) => { + return request({ + url: '/basic/basicAsyncTask/page', + method: 'get', + params: query, + }); +}; diff --git a/src/api/professional/professionalfile.ts b/src/api/professional/professionalfile.ts index 3c5d078..cbceb39 100644 --- a/src/api/professional/professionalfile.ts +++ b/src/api/professional/professionalfile.ts @@ -1,9 +1,9 @@ import request from '/@/utils/request'; -export const exportTeacherInfoBySelf = (data?: any) => { +export const makeExportTeacherInfoBySelfTask = (data?: any) => { return request({ - url: '/professional/file/exportTeacherInfoBySelf', + url: '/professional/file/makeExportTeacherInfoBySelfTask', method: 'post', data: data, }); diff --git a/src/api/purchase/acceptanceItemConfig.ts b/src/api/purchase/acceptanceItemConfig.ts new file mode 100644 index 0000000..cc66d73 --- /dev/null +++ b/src/api/purchase/acceptanceItemConfig.ts @@ -0,0 +1,106 @@ +import request from "/@/utils/request" + +// ========== 基础CRUD接口 ========== + +/** + * 分页查询列表数据 + * @param query - 查询参数对象 + * @returns Promise<分页数据> + */ +export function fetchList(query?: Object) { + return request({ + url: '/purchase/acceptanceItemConfig/page', + method: 'get', + params: query + }) +} + +/** + * 新增数据 + * @param obj - 要新增的数据对象 + * @returns Promise - 操作结果 + */ +export function addObj(obj?: Object) { + return request({ + url: '/purchase/acceptanceItemConfig', + method: 'post', + data: obj + }) +} + +/** + * 获取详情数据 + * @param obj - 查询参数对象(包含ID等) + * @returns Promise<数据详情> + */ +export function getObj(obj?: Object) { + return request({ + url: '/purchase/acceptanceItemConfig/details', + method: 'get', + params: obj + }) +} + +/** + * 批量删除数据 + * @param ids - 要删除的ID数组 + * @returns Promise<操作结果> + */ +export function delObjs(ids?: Object) { + return request({ + url: '/purchase/acceptanceItemConfig', + method: 'delete', + data: ids + }) +} + +/** + * 更新数据 + * @param obj - 要更新的数据对象 + * @returns Promise<操作结果> + */ +export function putObj(obj?: Object) { + return request({ + url: '/purchase/acceptanceItemConfig', + method: 'put', + data: obj + }) +} + +// ========== 工具函数 ========== + +/** + * 验证字段值唯一性 + * @param rule - 验证规则对象 + * @param value - 要验证的值 + * @param callback - 验证回调函数 + * @param isEdit - 是否为编辑模式 + * + * @example + * // 在表单验证规则中使用 + * fieldName: [ + * { + * validator: (rule, value, callback) => { + * validateExist(rule, value, callback, form.id !== ''); + * }, + * trigger: 'blur', + * }, + * ] + */ +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + // 编辑模式下跳过验证 + if (isEdit) { + return callback(); + } + + // 查询是否存在相同值 + getObj({ [rule.field]: value }).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} + diff --git a/src/api/purchase/puchasingAcceptContent.ts b/src/api/purchase/puchasingAcceptContent.ts new file mode 100644 index 0000000..29a3f7e --- /dev/null +++ b/src/api/purchase/puchasingAcceptContent.ts @@ -0,0 +1,106 @@ +import request from "/@/utils/request" + +// ========== 基础CRUD接口 ========== + +/** + * 分页查询列表数据 + * @param query - 查询参数对象 + * @returns Promise<分页数据> + */ +export function fetchList(query?: Object) { + return request({ + url: '/purchase/puchasingAcceptContent/page', + method: 'get', + params: query + }) +} + +/** + * 新增数据 + * @param obj - 要新增的数据对象 + * @returns Promise - 操作结果 + */ +export function addObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptContent', + method: 'post', + data: obj + }) +} + +/** + * 获取详情数据 + * @param obj - 查询参数对象(包含ID等) + * @returns Promise<数据详情> + */ +export function getObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptContent/details', + method: 'get', + params: obj + }) +} + +/** + * 批量删除数据 + * @param ids - 要删除的ID数组 + * @returns Promise<操作结果> + */ +export function delObjs(ids?: Object) { + return request({ + url: '/purchase/puchasingAcceptContent', + method: 'delete', + data: ids + }) +} + +/** + * 更新数据 + * @param obj - 要更新的数据对象 + * @returns Promise<操作结果> + */ +export function putObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptContent', + method: 'put', + data: obj + }) +} + +// ========== 工具函数 ========== + +/** + * 验证字段值唯一性 + * @param rule - 验证规则对象 + * @param value - 要验证的值 + * @param callback - 验证回调函数 + * @param isEdit - 是否为编辑模式 + * + * @example + * // 在表单验证规则中使用 + * fieldName: [ + * { + * validator: (rule, value, callback) => { + * validateExist(rule, value, callback, form.id !== ''); + * }, + * trigger: 'blur', + * }, + * ] + */ +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + // 编辑模式下跳过验证 + if (isEdit) { + return callback(); + } + + // 查询是否存在相同值 + getObj({ [rule.field]: value }).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} + diff --git a/src/api/purchase/puchasingAcceptTeam.ts b/src/api/purchase/puchasingAcceptTeam.ts new file mode 100644 index 0000000..ad67e07 --- /dev/null +++ b/src/api/purchase/puchasingAcceptTeam.ts @@ -0,0 +1,106 @@ +import request from "/@/utils/request" + +// ========== 基础CRUD接口 ========== + +/** + * 分页查询列表数据 + * @param query - 查询参数对象 + * @returns Promise<分页数据> + */ +export function fetchList(query?: Object) { + return request({ + url: '/purchase/puchasingAcceptTeam/page', + method: 'get', + params: query + }) +} + +/** + * 新增数据 + * @param obj - 要新增的数据对象 + * @returns Promise - 操作结果 + */ +export function addObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptTeam', + method: 'post', + data: obj + }) +} + +/** + * 获取详情数据 + * @param obj - 查询参数对象(包含ID等) + * @returns Promise<数据详情> + */ +export function getObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptTeam/details', + method: 'get', + params: obj + }) +} + +/** + * 批量删除数据 + * @param ids - 要删除的ID数组 + * @returns Promise<操作结果> + */ +export function delObjs(ids?: Object) { + return request({ + url: '/purchase/puchasingAcceptTeam', + method: 'delete', + data: ids + }) +} + +/** + * 更新数据 + * @param obj - 要更新的数据对象 + * @returns Promise<操作结果> + */ +export function putObj(obj?: Object) { + return request({ + url: '/purchase/puchasingAcceptTeam', + method: 'put', + data: obj + }) +} + +// ========== 工具函数 ========== + +/** + * 验证字段值唯一性 + * @param rule - 验证规则对象 + * @param value - 要验证的值 + * @param callback - 验证回调函数 + * @param isEdit - 是否为编辑模式 + * + * @example + * // 在表单验证规则中使用 + * fieldName: [ + * { + * validator: (rule, value, callback) => { + * validateExist(rule, value, callback, form.id !== ''); + * }, + * trigger: 'blur', + * }, + * ] + */ +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + // 编辑模式下跳过验证 + if (isEdit) { + return callback(); + } + + // 查询是否存在相同值 + getObj({ [rule.field]: value }).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} + diff --git a/src/api/purchase/purchasingAccept.ts b/src/api/purchase/purchasingAccept.ts new file mode 100644 index 0000000..6ca9182 --- /dev/null +++ b/src/api/purchase/purchasingAccept.ts @@ -0,0 +1,173 @@ +import request from "/@/utils/request" + +// ========== 基础CRUD接口 ========== + +/** + * 分页查询列表数据 + * @param query - 查询参数对象 + * @returns Promise<分页数据> + */ +export function fetchList(query?: Object) { + return request({ + url: '/purchase/purchasingAccept/page', + method: 'get', + params: query + }) +} + +/** + * 新增数据 + * @param obj - 要新增的数据对象 + * @returns Promise - 操作结果 + */ +export function addObj(obj?: Object) { + return request({ + url: '/purchase/purchasingAccept', + method: 'post', + data: obj + }) +} + +/** + * 获取详情数据 + * @param obj - 查询参数对象(包含ID等) + * @returns Promise<数据详情> + */ +export function getObj(obj?: Object) { + return request({ + url: '/purchase/purchasingAccept/details', + method: 'get', + params: obj + }) +} + +/** + * 批量删除数据 + * @param ids - 要删除的ID数组 + * @returns Promise<操作结果> + */ +export function delObjs(ids?: Object) { + return request({ + url: '/purchase/purchasingAccept', + method: 'delete', + data: ids + }) +} + +/** + * 更新数据 + * @param obj - 要更新的数据对象 + * @returns Promise<操作结果> + */ +export function putObj(obj?: Object) { + return request({ + url: '/purchase/purchasingAccept', + method: 'put', + data: obj + }) +} + +// ========== 履约验收流程接口 ========== + +/** + * 第一步:保存履约验收公共配置,按分期次数自动生成批次 + */ +export function saveCommonConfig(data: any) { + return request({ + url: '/purchase/purchasingAccept/saveCommonConfig', + method: 'post', + data + }) +} + +/** + * 获取履约验收公共配置及批次列表 + */ +export function getCommonConfigWithBatches(purchaseId: string) { + return request({ + url: '/purchase/purchasingAccept/commonConfigWithBatches', + method: 'get', + params: { purchaseId } + }) +} + +/** + * 第二步:更新单个批次 + */ +export function updateBatch(data: any) { + return request({ + url: '/purchase/purchasingAccept/updateBatch', + method: 'put', + data + }) +} + +/** + * 获取验收详情(含验收内容、验收小组) + */ +export function getDetail(purchaseId: string, batch?: number) { + return request({ + url: '/purchase/purchasingAccept/detail', + method: 'get', + params: { purchaseId, batch } + }) +} + +/** + * 是否允许填报方式(金额<30万) + */ +export function canFillForm(purchaseId: string) { + return request({ + url: '/purchase/purchasingAccept/canFillForm', + method: 'get', + params: { purchaseId } + }) +} + +/** + * 根据品目类型获取验收项配置 + */ +export function getAcceptanceItems(acceptanceType: string) { + return request({ + url: `/purchase/acceptanceItemConfig/listByType/${acceptanceType}`, + method: 'get' + }) +} + +// ========== 工具函数 ========== + +/** + * 验证字段值唯一性 + * @param rule - 验证规则对象 + * @param value - 要验证的值 + * @param callback - 验证回调函数 + * @param isEdit - 是否为编辑模式 + * + * @example + * // 在表单验证规则中使用 + * fieldName: [ + * { + * validator: (rule, value, callback) => { + * validateExist(rule, value, callback, form.id !== ''); + * }, + * trigger: 'blur', + * }, + * ] + */ +export function validateExist(rule: any, value: any, callback: any, isEdit: boolean) { + // 编辑模式下跳过验证 + if (isEdit) { + return callback(); + } + + // 查询是否存在相同值 + getObj({ [rule.field]: value }).then((response) => { + const result = response.data; + if (result !== null && result.length > 0) { + callback(new Error('数据已经存在')); + } else { + callback(); + } + }); +} + diff --git a/src/assets/styles/page-cards.scss b/src/assets/styles/page-cards.scss new file mode 100644 index 0000000..61e0884 --- /dev/null +++ b/src/assets/styles/page-cards.scss @@ -0,0 +1,188 @@ +/** + * 列表页卡片布局公共样式(筛选卡片 + 内容卡片 + 表头) + * 各业务模块通用,不限于专业模块 + * + * 使用:@import '/@/assets/styles/page-cards.scss'; + * 模板类名:.page-cards > .page-wrapper > .search-card / .content-card + */ + +// 页面整体 +.page-cards { + padding: 12px; + min-height: 100%; + background: var(--el-bg-color-page, #f5f6f8); +} + +// 页面包装器 +.page-wrapper { + display: flex; + flex-direction: column; + gap: 12px; +} + +// 筛选卡片 +.search-card { + border-radius: 8px; + border: 1px solid var(--el-border-color-lighter); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); + background: var(--el-bg-color); + + :deep(.el-card__body) { + padding: 18px 20px 5px 20px; + } +} + +// 列表内容卡片 +.content-card { + border-radius: 8px; + border: 1px solid var(--el-border-color-lighter); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); + background: var(--el-bg-color); + + :deep(.el-card__header) { + padding: 20px 20px 15px; + border-bottom: 1px solid var(--el-border-color-lighter); + } + + :deep(.el-card__body) { + padding: 15px 20px 20px; + } +} + +.card-header { + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; +} + +.card-title { + display: inline-flex; + align-items: center; + gap: 8px; + font-size: 15px; + font-weight: 500; + color: var(--el-text-color-primary); + + .title-icon { + font-size: 16px; + color: var(--el-color-primary); + } +} + +.header-actions { + display: flex; + align-items: center; + flex-wrap: wrap; +} + +.action-group { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 10px; +} + +.header-right { + display: flex; + align-items: center; + padding-left: 10px; +} + +// 小屏幕适配(≤768px) +@media screen and (max-width: 768px) { + .page-cards { + padding: 8px; + } + + .page-wrapper { + gap: 8px; + } + + .search-card :deep(.el-card__body) { + padding: 12px 14px 4px 14px; + } + + .content-card :deep(.el-card__header) { + padding: 14px 14px 12px; + } + + .content-card :deep(.el-card__body) { + padding: 12px 14px 14px; + } + + .card-header { + gap: 8px; + } + + .card-title { + font-size: 14px; + .title-icon { + font-size: 15px; + } + } + + .header-actions { + gap: 8px; + } + + .action-group { + gap: 8px; + // 按钮间距 + .el-button { + margin-left: 0; + } + } + + .header-right { + padding-left: 8px; + } +} + +// 超小屏幕适配(≤576px) +@media screen and (max-width: 576px) { + .page-cards { + padding: 6px; + } + + .page-wrapper { + gap: 6px; + } + + .search-card :deep(.el-card__body) { + padding: 10px 12px 14px 12px; + } + + .content-card :deep(.el-card__header) { + padding: 12px 12px 10px; + } + + .content-card :deep(.el-card__body) { + padding: 10px 12px 12px; + } + + .card-header { + flex-direction: column; + align-items: flex-start; + gap: 10px; + } + + .header-actions { + width: 100%; + } + .action-group { + gap: 6px; + // 按钮间距 + .el-button { + margin-left: 0; + } + } + + .header-right { + width: 100%; + padding-left: 0; + padding-top: 8px; + border-left: none; + border-top: 1px solid var(--el-border-color-lighter); + } +} diff --git a/src/components/ClickableTag/index.vue b/src/components/ClickableTag/index.vue index 1961923..a40bce9 100644 --- a/src/components/ClickableTag/index.vue +++ b/src/components/ClickableTag/index.vue @@ -2,25 +2,21 @@ - - + + + - - - + + + @@ -36,26 +32,32 @@ + + diff --git a/src/layout/navBars/breadcrumb/user.vue b/src/layout/navBars/breadcrumb/user.vue index 4bd1c7c..576c6bd 100644 --- a/src/layout/navBars/breadcrumb/user.vue +++ b/src/layout/navBars/breadcrumb/user.vue @@ -1,6 +1,6 @@ @@ -95,8 +101,10 @@ import { fetchUserMessageList } from '/@/api/admin/message'; import {useFlowJob} from "/@/flow/stores/flowJob"; -const ChangeRoleRef=ref() +const ChangeRoleRef = ref() const ChangeRole = defineAsyncComponent(() => import('/@/views/admin/system/role/change-role.vue')) +const asyncTaskDrawerRef = ref() +const AsyncTaskDrawer = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/asyncTaskDrawer.vue')) // 引入组件 const GlobalWebsocket = defineAsyncComponent(() => import('/@/components/Websocket/index.vue')); const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/userNews.vue')); @@ -207,6 +215,10 @@ const onHandleCommandClick = (path: string) => { const onSearchClick = () => { searchRef.value.openSearch(); }; +// 上传/下载任务点击 +const onAsyncTaskClick = () => { + asyncTaskDrawerRef.value?.open(); +}; // 语言切换 const onLanguageChange = (lang: string) => { Local.remove('themeConfig'); @@ -241,15 +253,25 @@ const getIsDot = () => { }); }; +// 登录后若存储中无角色信息则弹出角色切换框 +const openChangeRoleIfMissing = () => { + const hasRole = Local.get('roleCode') && Local.get('roleName') && Local.get('roleId') + if (!hasRole) { + nextTick(() => { + setTimeout(() => ChangeRoleRef.value?.open(), 100) + }) + } +} + // 页面加载时 onMounted(() => { if (Local.get('themeConfig')) { initI18nOrSize('globalComponentSize', 'disabledSize'); initI18nOrSize('globalI18n', 'disabledI18n'); } - useFlowJob().topJobList() - - getIsDot(); + useFlowJob().topJobList() + getIsDot() + openChangeRoleIfMissing() }); diff --git a/src/theme/app.scss b/src/theme/app.scss index cb0cf69..b4f5d26 100644 --- a/src/theme/app.scss +++ b/src/theme/app.scss @@ -50,7 +50,7 @@ body, width: 100%; height: 100%; .layout-pd { - padding: 10px !important; + padding: 12px !important; background: linear-gradient(135deg,#f5f7fa,#e9ecef); } .layout-flex { diff --git a/src/theme/element.scss b/src/theme/element.scss index 29aa617..3a148c4 100644 --- a/src/theme/element.scss +++ b/src/theme/element.scss @@ -439,6 +439,12 @@ background-color: #f5f7ff; } +/* 表格单元格内边距(全局)- 左右用默认,上下 9px */ +.el-table .el-table__body td, +.el-table .el-table__header th { + padding: 9px 0; +} + /* scrollbar ------------------------------- */ .el-scrollbar__bar { diff --git a/src/views/admin/system/role/change-role.vue b/src/views/admin/system/role/change-role.vue index 027511b..25b4087 100644 --- a/src/views/admin/system/role/change-role.vue +++ b/src/views/admin/system/role/change-role.vue @@ -1,60 +1,86 @@ - \ No newline at end of file diff --git a/src/views/finance/purchasingrequisition/accept/AcceptBatchForm.vue b/src/views/finance/purchasingrequisition/accept/AcceptBatchForm.vue new file mode 100644 index 0000000..eeb0b9f --- /dev/null +++ b/src/views/finance/purchasingrequisition/accept/AcceptBatchForm.vue @@ -0,0 +1,199 @@ + + + + + diff --git a/src/views/finance/purchasingrequisition/accept/AcceptCommonForm.vue b/src/views/finance/purchasingrequisition/accept/AcceptCommonForm.vue new file mode 100644 index 0000000..696ac1a --- /dev/null +++ b/src/views/finance/purchasingrequisition/accept/AcceptCommonForm.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/src/views/finance/purchasingrequisition/accept/PurchasingAcceptModal.vue b/src/views/finance/purchasingrequisition/accept/PurchasingAcceptModal.vue new file mode 100644 index 0000000..af263a2 --- /dev/null +++ b/src/views/finance/purchasingrequisition/accept/PurchasingAcceptModal.vue @@ -0,0 +1,405 @@ + + + + + diff --git a/src/views/finance/purchasingrequisition/index.vue b/src/views/finance/purchasingrequisition/index.vue index 142661b..0895c09 100644 --- a/src/views/finance/purchasingrequisition/index.vue +++ b/src/views/finance/purchasingrequisition/index.vue @@ -191,7 +191,7 @@ - - + @@ -258,6 +265,9 @@ ref="formDialogRef" :dict-data="dictData" @refresh="getDataList" /> + + + @@ -269,10 +279,11 @@ import { getPage, delObj } from "/@/api/finance/purchasingrequisition"; import { useMessage, useMessageBox } from "/@/hooks/message"; import { getDicts } from '/@/api/admin/dict'; import { getTree } from '/@/api/finance/purchasingcategory'; -import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning } from '@element-plus/icons-vue' +import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning, DocumentChecked } from '@element-plus/icons-vue' // 引入组件 const FormDialog = defineAsyncComponent(() => import('./form.vue')); +const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue')); // 字典数据和品目树数据 const dictData = ref({ @@ -289,6 +300,7 @@ const dictData = ref({ const router = useRouter() const tableRef = ref() const formDialogRef = ref() +const acceptModalRef = ref() const searchFormRef = ref() const showSearch = ref(true) const showAddIframe = ref(false) @@ -363,6 +375,7 @@ const handleIframeMessage = (event: MessageEvent) => { }; /** +<<<<<<< HEAD * 打开查看对话框 * @param row - 当前行数据 */ @@ -376,6 +389,12 @@ const handleView = (row: any) => { */ const handleEdit = (row: any) => { formDialogRef.value?.openDialog('edit', row); +======= + * 履约验收 + */ +const handleAccept = (row: any) => { + acceptModalRef.value?.open(row); +>>>>>>> 61380fa2bca0fe9fd37af1c494a51ba523501f7d }; /** diff --git a/src/views/professional/common/import-teacher-other-info.vue b/src/views/professional/common/import-teacher-other-info.vue new file mode 100644 index 0000000..4ddce74 --- /dev/null +++ b/src/views/professional/common/import-teacher-other-info.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/views/professional/professionalpartychange/index.vue b/src/views/professional/professionalpartychange/index.vue index 76651b9..c6a633d 100755 --- a/src/views/professional/professionalpartychange/index.vue +++ b/src/views/professional/professionalpartychange/index.vue @@ -37,6 +37,20 @@ + + +
+ 导入信息 +
+
+ + + + @@ -88,6 +105,7 @@ import { BasicTableProps, useTable } from '/@/hooks/table' import { fetchList } from '/@/api/professional/professionaluser/professionalpartychange' const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue')) +const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue')) // 表格引用 const tableRef = ref() @@ -100,6 +118,10 @@ const search = reactive({ realName: '' }) +// 导入加载状态 +const exportLoading = ref(false) +const importTeacherOtherInfoRef = ref() + // 配置 useTable const state: BasicTableProps = reactive({ pageList: async (params: any) => { @@ -130,6 +152,11 @@ const resetQuery = () => { getDataList() } +// 打开导入弹窗 +const handleImportDialog = () => { + importTeacherOtherInfoRef.value?.init('partyChange') +} + // 表格数据由 useTable(createdIsNeed 默认 true)在挂载时自动请求 diff --git a/src/views/professional/professionalqualificationrelation/index.vue b/src/views/professional/professionalqualificationrelation/index.vue index 0cfb540..d3d2ee2 100644 --- a/src/views/professional/professionalqualificationrelation/index.vue +++ b/src/views/professional/professionalqualificationrelation/index.vue @@ -1,87 +1,108 @@ @@ -245,6 +254,7 @@ const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/i const DataForm = defineAsyncComponent(() => import('./form.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue')) +const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue')) // 审核状态选项 const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS @@ -279,6 +289,7 @@ const imgUrl = ref>([]) // 导出加载状态 const exportLoading = ref(false) +const importTeacherOtherInfoRef = ref() // 学位、学历和教育类型列表 const degreeList = ref([]) @@ -442,6 +453,11 @@ const getEducationTypeName = (id: string | number | undefined) => { return item ? item.name : '-' } +// 打开导入弹窗 +const handleImportDialog = () => { + importTeacherOtherInfoRef.value?.init('eduDegree') +} + // 加载字典数据 const loadDictData = async () => { try { diff --git a/src/views/professional/professionalteachercertificaterelation/index.vue b/src/views/professional/professionalteachercertificaterelation/index.vue index 5aff00a..5a4253a 100755 --- a/src/views/professional/professionalteachercertificaterelation/index.vue +++ b/src/views/professional/professionalteachercertificaterelation/index.vue @@ -69,6 +69,14 @@ @click="handleDownLoadWord" :loading="exportLoading">导出信息 + 导入信息 + @@ -188,6 +196,7 @@ + @@ -213,6 +222,7 @@ const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/i const DataForm = defineAsyncComponent(() => import('./form.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue')) +const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue')) // 审核状态选项(独立定义,防止其他页面修改时被波及) import type { StateOption } from '/@/components/AuditState/index.vue' @@ -247,6 +257,7 @@ const imgUrl = ref>([]) // 导出加载状态 const exportLoading = ref(false) +const importTeacherOtherInfoRef = ref() // 证书列表 const certificateList = ref([]) @@ -385,6 +396,11 @@ const getCertificateName = (id: string | number) => { return item ? item.cretificateName : '-' } +// 打开导入弹窗 +const handleImportDialog = () => { + importTeacherOtherInfoRef.value?.init('cerRelation') +} + // 加载字典数据 const loadDictData = async () => { try { diff --git a/src/views/professional/professionalteacherhonor/index.vue b/src/views/professional/professionalteacherhonor/index.vue index 21cfbd5..bb265d6 100755 --- a/src/views/professional/professionalteacherhonor/index.vue +++ b/src/views/professional/professionalteacherhonor/index.vue @@ -68,6 +68,14 @@ @click="handleDownLoadWord" :loading="exportLoading">导出信息 + 导入信息 + @@ -83,9 +91,45 @@ > - + @@ -114,8 +158,6 @@ - - @@ -183,6 +224,7 @@ + @@ -199,13 +241,16 @@ import { examObj, delObj } from '/@/api/professional/professionaluser/professionalteacherhonor' -import { PROFESSIONAL_AUDIT_STATE_OPTIONS } from '/@/config/global' +import { PROFESSIONAL_AUDIT_STATE_OPTIONS, getStatusConfig } from '/@/config/global' import { defineAsyncComponent } from 'vue' const TeacherNameNo = defineAsyncComponent(() => import('/@/components/TeacherNameNo/index.vue')) const AuditState = defineAsyncComponent(() => import('/@/components/AuditState/index.vue')) +const ClickableTag = defineAsyncComponent(() => import('/@/components/ClickableTag/index.vue')) +const DetailPopover = defineAsyncComponent(() => import('/@/components/DetailPopover/index.vue')) const ProfessionalBackResaon = defineAsyncComponent(() => import('/@/views/professional/common/professional-back-resaon.vue')) const DataForm = defineAsyncComponent(() => import('./form.vue')) const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue')) +const ImportTeacherOtherInfo = defineAsyncComponent(() => import('/@/views/professional/common/import-teacher-other-info.vue')) // 消息提示 hooks const message = useMessage() @@ -217,6 +262,13 @@ const { professional_state: professionalState } = useDict('professional_state') // 审核状态选项 const auditStateOptions = PROFESSIONAL_AUDIT_STATE_OPTIONS +// 审核状态转 ClickableTag 配置(用 options 的 icon 字符串,与 AuditState 一致为实心) +const getAuditStateTagConfig = (state: string | number) => { + const opt = getStatusConfig(auditStateOptions, state) + if (!opt) return null + return { type: opt.type, label: opt.label, leftIcon: opt.icon, effect: opt.effect || 'dark' } +} + // 无权限即无节点 const { hasAuth } = useAuth() @@ -239,6 +291,7 @@ const imgUrl = ref>([]) // 导出加载状态 const exportLoading = ref(false) +const importTeacherOtherInfoRef = ref() // 配置 useTable const state: BasicTableProps = reactive({ @@ -365,8 +418,38 @@ const handleDownLoadWord = async () => { } } +// 打开导入弹窗 +const handleImportDialog = () => { + importTeacherOtherInfoRef.value?.init('honor') +} + // 表格数据由 useTable(createdIsNeed 默认 true)在挂载时自动请求 diff --git a/src/views/professional/professionaltitlerelation/index.vue b/src/views/professional/professionaltitlerelation/index.vue index dcbaf10..ba4e06d 100755 --- a/src/views/professional/professionaltitlerelation/index.vue +++ b/src/views/professional/professionaltitlerelation/index.vue @@ -1,41 +1,9 @@