Merge branch 'developer' of ssh://code.cyweb.top:30033/scj/zhxy/v3/cloud-ui into developer
This commit is contained in:
131
src/api/finance/purchasingdoc.ts
Normal file
131
src/api/finance/purchasingdoc.ts
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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 applyId 采购申请ID
|
||||||
|
*/
|
||||||
|
export function getDocList(applyId: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/list/' + applyId,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传采购文件(招标代理)
|
||||||
|
* @param data 文件信息
|
||||||
|
*/
|
||||||
|
export function uploadDoc(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/upload',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重新上传采购文件
|
||||||
|
* @param data 文件信息
|
||||||
|
*/
|
||||||
|
export function reuploadDoc(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/reupload',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取采购文件下载地址
|
||||||
|
* @param id 采购文件ID
|
||||||
|
*/
|
||||||
|
export function getDocDownloadUrl(id: number | string) {
|
||||||
|
return `/purchase/purchasingdoc/download/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认无误
|
||||||
|
* @param data 审核信息
|
||||||
|
*/
|
||||||
|
export function confirmDoc(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/confirm',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退回修改
|
||||||
|
* @param data 审核信息
|
||||||
|
*/
|
||||||
|
export function returnDoc(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/return',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认流程结束
|
||||||
|
* @param applyId 采购申请ID
|
||||||
|
*/
|
||||||
|
export function completeDoc(applyId: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/complete',
|
||||||
|
method: 'post',
|
||||||
|
params: { applyId }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取审核记录
|
||||||
|
* @param applyId 采购申请ID
|
||||||
|
*/
|
||||||
|
export function getAuditRecords(applyId: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/audit-records/' + applyId,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取待审核列表
|
||||||
|
* @param params 分页参数
|
||||||
|
*/
|
||||||
|
export function getMyPending(params?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/my-pending',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取可执行操作
|
||||||
|
* @param applyId 采购申请ID
|
||||||
|
*/
|
||||||
|
export function getAvailableActions(applyId: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingdoc/actions/' + applyId,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
48
src/api/finance/purchasingtemplate.ts
Normal file
48
src/api/finance/purchasingtemplate.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 采购模板管理 API
|
||||||
|
*/
|
||||||
|
|
||||||
|
import request from '/@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板列表
|
||||||
|
*/
|
||||||
|
export function listTemplates(params?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingtemplate/list',
|
||||||
|
method: 'get',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传 / 覆盖模板
|
||||||
|
* @param formData 含 file、type 的 FormData
|
||||||
|
*/
|
||||||
|
export function uploadTemplate(formData: FormData) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingtemplate/upload',
|
||||||
|
method: 'post',
|
||||||
|
data: formData,
|
||||||
|
headers: { 'Content-Type': 'multipart/form-data' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板下载地址
|
||||||
|
*/
|
||||||
|
export function getTemplateDownloadUrl(type: string) {
|
||||||
|
return `/purchase/purchasingtemplate/download?type=${encodeURIComponent(type)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板类型名称
|
||||||
|
*/
|
||||||
|
export function updateTemplateTitle(data: { id: number | string; templateTitle: string }) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingtemplate/updateTitle',
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
61
src/api/purchase/purchasingBusinessLeader.ts
Normal file
61
src/api/purchase/purchasingBusinessLeader.ts
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import request from '/@/utils/request';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询
|
||||||
|
* @param params 查询参数
|
||||||
|
*/
|
||||||
|
export function fetchList(params?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingBusinessLeader/page',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过id查询
|
||||||
|
* @param id ID
|
||||||
|
*/
|
||||||
|
export function getObj(id: string | number) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingBusinessLeader/details',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增业务分管校领导
|
||||||
|
* @param obj 对象数据
|
||||||
|
*/
|
||||||
|
export function addObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingBusinessLeader',
|
||||||
|
method: 'post',
|
||||||
|
data: obj
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改业务分管校领导
|
||||||
|
* @param obj 对象数据
|
||||||
|
*/
|
||||||
|
export function putObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingBusinessLeader',
|
||||||
|
method: 'put',
|
||||||
|
data: obj
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除业务分管校领导
|
||||||
|
* @param ids ID数组
|
||||||
|
*/
|
||||||
|
export function delObjs(ids: string[] | number[]) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingBusinessLeader',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
});
|
||||||
|
}
|
||||||
41
src/api/purchase/purchasingPurchaseManager.ts
Normal file
41
src/api/purchase/purchasingPurchaseManager.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import request from '/@/utils/request'
|
||||||
|
|
||||||
|
export function fetchList(query?: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingPurchaseManager/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getObj(id: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingPurchaseManager/details',
|
||||||
|
method: 'get',
|
||||||
|
params: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingPurchaseManager',
|
||||||
|
method: 'post',
|
||||||
|
data: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function delObjs(ids: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingPurchaseManager',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function putObj(obj: any) {
|
||||||
|
return request({
|
||||||
|
url: '/purchase/purchasingPurchaseManager',
|
||||||
|
method: 'put',
|
||||||
|
data: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -76,8 +76,9 @@ export const getMNObj = (id: string | number) => {
|
|||||||
*/
|
*/
|
||||||
export const delObj = (id: string | number) => {
|
export const delObj = (id: string | number) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/recruit/recruitImitateAdjustBatch/${id}`,
|
url: `/recruit/recruitImitateAdjustBatch/delete`,
|
||||||
method: 'delete',
|
method: 'post',
|
||||||
|
data: { id:id }
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,8 +88,9 @@ export const delObj = (id: string | number) => {
|
|||||||
*/
|
*/
|
||||||
export const delMNObj = (id: string | number) => {
|
export const delMNObj = (id: string | number) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/recruit/recruitImitateAdjustBatch/delMNObj/${id}`,
|
url: `/recruit/recruitImitateAdjustBatch/delMNObj`,
|
||||||
method: 'delete',
|
method: 'post',
|
||||||
|
data: { id:id }
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
106
src/api/recruit/recruitPolicyFile.ts
Normal file
106
src/api/recruit/recruitPolicyFile.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import request from "/@/utils/request"
|
||||||
|
|
||||||
|
// ========== 基础CRUD接口 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询列表数据
|
||||||
|
* @param query - 查询参数对象
|
||||||
|
* @returns Promise<分页数据>
|
||||||
|
*/
|
||||||
|
export function fetchList(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPolicyFile/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增数据
|
||||||
|
* @param obj - 要新增的数据对象
|
||||||
|
* @returns Promise<boolean> - 操作结果
|
||||||
|
*/
|
||||||
|
export function addObj(obj?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPolicyFile',
|
||||||
|
method: 'post',
|
||||||
|
data: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取详情数据
|
||||||
|
* @param obj - 查询参数对象(包含ID等)
|
||||||
|
* @returns Promise<数据详情>
|
||||||
|
*/
|
||||||
|
export function getObj(obj?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPolicyFile/details',
|
||||||
|
method: 'get',
|
||||||
|
params: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除数据
|
||||||
|
* @param ids - 要删除的ID数组
|
||||||
|
* @returns Promise<操作结果>
|
||||||
|
*/
|
||||||
|
export function delObjs(ids?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPolicyFile',
|
||||||
|
method: 'delete',
|
||||||
|
data: ids
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新数据
|
||||||
|
* @param obj - 要更新的数据对象
|
||||||
|
* @returns Promise<操作结果>
|
||||||
|
*/
|
||||||
|
export function putObj(obj?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPolicyFile',
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
56
src/api/recruit/recruitPreexamPeople.ts
Normal file
56
src/api/recruit/recruitPreexamPeople.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import request from "/@/utils/request"
|
||||||
|
|
||||||
|
// ========== 基础CRUD接口 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询列表数据
|
||||||
|
* @param query - 查询参数对象
|
||||||
|
* @returns Promise<分页数据>
|
||||||
|
*/
|
||||||
|
export function fetchList(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPreexamPeople/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增数据
|
||||||
|
* @param obj - 要新增的数据对象
|
||||||
|
* @returns Promise<boolean> - 操作结果
|
||||||
|
*/
|
||||||
|
export function addObj(obj?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPreexamPeople',
|
||||||
|
method: 'post',
|
||||||
|
data: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取详情数据
|
||||||
|
* @param obj - 查询参数对象(包含ID等)
|
||||||
|
* @returns Promise<数据详情>
|
||||||
|
*/
|
||||||
|
export function getObj(obj?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitPreexamPeople/details',
|
||||||
|
method: 'get',
|
||||||
|
params: obj
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export const delObj = (id: string | number) => {
|
||||||
|
return request({
|
||||||
|
url: `/recruit/recruitPreexamPeople/delete`,
|
||||||
|
method: 'post',
|
||||||
|
data: { id: id }
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
17
src/api/recruit/recruitSchoolHistory.ts
Normal file
17
src/api/recruit/recruitSchoolHistory.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import request from "/@/utils/request"
|
||||||
|
|
||||||
|
// ========== 基础CRUD接口 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询列表数据
|
||||||
|
* @param query - 查询参数对象
|
||||||
|
* @returns Promise<分页数据>
|
||||||
|
*/
|
||||||
|
export function fetchList(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/recruitSchoolHistory/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
19
src/api/recruit/recruitfile.ts
Normal file
19
src/api/recruit/recruitfile.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import request from '/@/utils/request';
|
||||||
|
|
||||||
|
|
||||||
|
export const exportPreStuSuccess = (data?: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/file/exportPreStuSuccess',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const exportAdjustExcel = (data?: any) => {
|
||||||
|
return request({
|
||||||
|
url: '/recruit/file/exportAdjustExcel',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
});
|
||||||
|
};
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -376,7 +376,19 @@ const handleRemove = (file: { name?: string; id?: string; url?: string }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePreview = (file: any) => {
|
const handlePreview = (file: any) => {
|
||||||
other.downBlobFile(file.url, {}, file.name);
|
// 优先使用文件ID下载(采购附件使用 downloadById 接口)
|
||||||
|
if (file.id) {
|
||||||
|
// 判断是否是采购附件(通过 fileType 判断)
|
||||||
|
const downloadUrl = `/purchase/purchasingfiles/downloadById?fileId=${encodeURIComponent(file.id)}`;
|
||||||
|
other.downBlobFile(downloadUrl, {}, file.name || file.fileTitle || '文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 兼容旧的URL下载方式
|
||||||
|
if (file.url) {
|
||||||
|
other.downBlobFile(file.url, {}, file.name || file.fileTitle || '文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
useMessage().warning('无法获取文件下载信息');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加 handleExceed 函数
|
// 添加 handleExceed 函数
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
type="textarea" :placeholder="t('jfcomment.inputRemarkTip')">
|
type="textarea" :placeholder="t('jfcomment.inputRemarkTip')">
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item :label="t('jfcomment.signName')">
|
<el-form-item :label="t('jfcomment.signName')" style="display: none">
|
||||||
<sign-name ref="signNameRef" :currJob="data.currJob"></sign-name>
|
<sign-name ref="signNameRef" :currJob="data.currJob"></sign-name>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
|
|||||||
@@ -46,7 +46,8 @@
|
|||||||
const methods = {
|
const methods = {
|
||||||
open(flowData) {
|
open(flowData) {
|
||||||
flowData = stringifyRemoveNullKey(flowData);
|
flowData = stringifyRemoveNullKey(flowData);
|
||||||
data.flowData = !window.isWebTest ? {contact: "演示环境不能操作,如需了解联系我们"}: JSON.parse(flowData);
|
// data.flowData = !window.isWebTest ? {contact: "演示环境不能操作,如需了解联系我们"}: JSON.parse(flowData);
|
||||||
|
data.flowData = JSON.parse(flowData);
|
||||||
data.viewJsonVisible = true;
|
data.viewJsonVisible = true;
|
||||||
},
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export function useTable(options?: BasicTableProps) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 覆盖默认值
|
// 覆盖默认值
|
||||||
const state = mergeDefaultOptions(defaultOptions, options);
|
const state = mergeDefaultOptions(defaultOptions, options || {});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发起分页查询,并设置表格数据和分页信息
|
* 发起分页查询,并设置表格数据和分页信息
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { Session } from '/@/utils/storage';
|
import {Local, Session} from '/@/utils/storage';
|
||||||
import { getUserInfo, login, loginByMobile, loginBySocial, refreshTokenApi } from '/@/api/login/index';
|
import { getUserInfo, login, loginByMobile, loginBySocial, refreshTokenApi } from '/@/api/login/index';
|
||||||
import { useMessage } from '/@/hooks/message';
|
import { useMessage } from '/@/hooks/message';
|
||||||
import { initUserTableConfigs } from '/@/api/admin/usertable';
|
import { initUserTableConfigs } from '/@/api/admin/usertable';
|
||||||
@@ -34,9 +34,13 @@ export const useUserInfo = defineStore('userInfo', {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
login(data)
|
login(data)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
debugger
|
||||||
// 存储token 信息
|
// 存储token 信息
|
||||||
Session.set('token', res.access_token);
|
Session.set('token', res.access_token);
|
||||||
Session.set('refresh_token', res.refresh_token);
|
Session.set('refresh_token', res.refresh_token);
|
||||||
|
Local.remove('roleCode');
|
||||||
|
Local.remove('roleName');
|
||||||
|
Local.remove('roleId');
|
||||||
resolve(res);
|
resolve(res);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|||||||
@@ -128,3 +128,8 @@ const resetQuery = () => {
|
|||||||
queryRef.value.resetFields();
|
queryRef.value.resetFields();
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
:deep(.el-table__body tr td) {
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -13,16 +13,21 @@
|
|||||||
<el-form-item class="role-form-item">
|
<el-form-item class="role-form-item">
|
||||||
<el-radio-group v-model="radio" class="role-radio-group" @change="handleChangeRole">
|
<el-radio-group v-model="radio" class="role-radio-group" @change="handleChangeRole">
|
||||||
<template v-for="(roles, groupName) in allRoleGroups" :key="groupName">
|
<template v-for="(roles, groupName) in allRoleGroups" :key="groupName">
|
||||||
<div class="role-group">
|
<el-card class="role-group-card" shadow="hover">
|
||||||
<el-divider>{{ groupName }}</el-divider>
|
<template #header>
|
||||||
<el-radio-button
|
<span class="group-name">{{ groupName }}</span>
|
||||||
v-for="item in roles"
|
</template>
|
||||||
:key="item.roleCode"
|
<div class="role-group">
|
||||||
:label="item.roleCode"
|
<el-radio-button
|
||||||
>
|
v-for="item in roles"
|
||||||
{{ item.roleName }}
|
:key="item.roleCode"
|
||||||
</el-radio-button>
|
:label="item.roleCode"
|
||||||
</div>
|
size="small"
|
||||||
|
>
|
||||||
|
{{ item.roleName }}
|
||||||
|
</el-radio-button>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -121,31 +126,12 @@ defineExpose({
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.role-group {
|
|
||||||
width: 100%;
|
|
||||||
flex: 0 0 100%;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px 12px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.group-name {
|
|
||||||
font-size: 13px;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
.role-radio-group {
|
.role-radio-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-direction: column;
|
||||||
gap: 8px;
|
gap: 6px;
|
||||||
align-items: flex-start;
|
width: 100%;
|
||||||
|
|
||||||
/* 每个分组内按钮可换行,分组之间不重叠 */
|
|
||||||
:deep(.el-radio-button) {
|
:deep(.el-radio-button) {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
@@ -153,9 +139,35 @@ defineExpose({
|
|||||||
border-radius: 6px !important;
|
border-radius: 6px !important;
|
||||||
border: 1px solid var(--el-border-color) !important;
|
border: 1px solid var(--el-border-color) !important;
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
|
line-height: 1.3;
|
||||||
}
|
}
|
||||||
:deep(.el-radio-button.is-active .el-radio-button__inner) {
|
:deep(.el-radio-button.is-active .el-radio-button__inner) {
|
||||||
border-color: var(--el-color-primary) !important;
|
border-color: var(--el-color-primary) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.role-group-card {
|
||||||
|
width: 100%;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
:deep(.el-card__header) {
|
||||||
|
padding: 6px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 6px 12px 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.role-group {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px 8px;
|
||||||
|
}
|
||||||
|
.group-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--el-text-color-primary);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -46,7 +46,8 @@
|
|||||||
<el-button
|
<el-button
|
||||||
icon="FolderAdd"
|
icon="FolderAdd"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="formDialogRef.openDialog('add')">
|
@click="formDialogRef.openDialog('add')"
|
||||||
|
v-auth="'purchase_purchasingagent_add'">
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||||
@@ -91,14 +92,16 @@
|
|||||||
<el-button
|
<el-button
|
||||||
icon="Edit"
|
icon="Edit"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
v-auth="'purchase_purchasingagent_edit'"
|
||||||
@click="formDialogRef.openDialog('edit', scope.row)">
|
@click="formDialogRef.openDialog('edit', scope.row)">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
icon="Delete"
|
icon="Delete"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
|
v-auth="'purchase_purchasingagent_del'"
|
||||||
@click="handleDelete(scope.row)">
|
@click="handleDelete(scope.row)">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-button
|
<el-button
|
||||||
icon="FolderAdd"
|
icon="FolderAdd"
|
||||||
type="primary"
|
type="primary"
|
||||||
|
v-auth="'purchase_purchasingcategory_add'"
|
||||||
@click="formDialogRef.openDialog('add')">
|
@click="formDialogRef.openDialog('add')">
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -65,14 +66,16 @@
|
|||||||
<el-button
|
<el-button
|
||||||
icon="Edit"
|
icon="Edit"
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
|
v-auth="'purchase_purchasingcategory_edit'"
|
||||||
@click="formDialogRef.openDialog('edit', scope.row)">
|
@click="formDialogRef.openDialog('edit', scope.row)">
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
icon="Delete"
|
icon="Delete"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
|
v-auth="'purchase_purchasingcategory_del'"
|
||||||
@click="handleDelete(scope.row)">
|
@click="handleDelete(scope.row)">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<el-table :data="records" stripe v-loading="loading" max-height="400">
|
||||||
|
<el-table-column prop="operateTypeDesc" label="操作类型" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="getOperateTypeStyle(scope.row.operateType)">
|
||||||
|
{{ scope.row.operateTypeDesc }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="operateRoleDesc" label="操作角色" width="100" />
|
||||||
|
<el-table-column prop="operateByName" label="操作人" width="100" />
|
||||||
|
<el-table-column prop="currentVersion" label="文件版本" width="80" align="center" />
|
||||||
|
<el-table-column prop="remark" label="批注意见" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.remark || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="operateTime" label="操作时间" width="160" />
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { getAuditRecords } from '/@/api/finance/purchasingdoc'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
applyId: number | string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const records = ref<any[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const loadRecords = async () => {
|
||||||
|
if (!props.applyId) return
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getAuditRecords(props.applyId)
|
||||||
|
records.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
records.value = []
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const refresh = () => {
|
||||||
|
loadRecords()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getOperateTypeStyle = (type: string) => {
|
||||||
|
const styleMap: Record<string, string> = {
|
||||||
|
'UPLOAD': 'primary',
|
||||||
|
'CONFIRM': 'success',
|
||||||
|
'RETURN': 'warning',
|
||||||
|
'COMPLETE': 'success'
|
||||||
|
}
|
||||||
|
return styleMap[type] || 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.applyId, () => {
|
||||||
|
loadRecords()
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
defineExpose({ refresh })
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
v-model="visible"
|
||||||
|
title="采购文件审核"
|
||||||
|
width="900px"
|
||||||
|
destroy-on-close
|
||||||
|
@close="handleClose">
|
||||||
|
<el-tabs v-model="activeTab">
|
||||||
|
<!-- 项目信息 -->
|
||||||
|
<el-tab-pane label="项目信息" name="info">
|
||||||
|
<el-descriptions :column="2" border>
|
||||||
|
<el-descriptions-item label="采购编号">{{ applyInfo.purchaseNo }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="项目名称">{{ applyInfo.projectName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="需求部门">{{ applyInfo.deptName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="预算金额">{{ applyInfo.budget ? Number(applyInfo.budget).toLocaleString() + '元' : '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="招标代理">{{ applyInfo.agentName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="审核状态">
|
||||||
|
<el-tag :type="getStatusType(applyInfo.docAuditStatus)">
|
||||||
|
{{ getStatusLabel(applyInfo.docAuditStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<!-- 采购需求文件 -->
|
||||||
|
<el-tab-pane label="采购需求文件" name="requirement">
|
||||||
|
<el-table :data="requirementFiles" stripe v-loading="requirementLoading">
|
||||||
|
<el-table-column prop="fileTitle" label="文件名称" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="fileType" label="文件类型" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ getFileTypeLabel(scope.row.fileType) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link icon="Download" @click="handleDownloadRequirement(scope.row)">
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<!-- 采购文件 -->
|
||||||
|
<el-tab-pane label="采购文件" name="doc">
|
||||||
|
<div class="doc-header">
|
||||||
|
<el-button v-if="canUpload" type="primary" icon="Upload" @click="handleUpload">
|
||||||
|
{{ applyInfo.docAuditStatus === 'RETURNED' ? '重新上传' : '上传文件' }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="docList" stripe v-loading="docLoading">
|
||||||
|
<el-table-column prop="fileName" label="文件名称" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="version" label="版本" width="80" align="center" />
|
||||||
|
<el-table-column prop="uploadByName" label="上传人" width="100" />
|
||||||
|
<el-table-column prop="uploadTime" label="上传时间" width="160" />
|
||||||
|
<el-table-column label="操作" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link icon="Download" @click="handleDownloadDoc(scope.row)">
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
<!-- 审核记录 -->
|
||||||
|
<el-tab-pane label="审核记录" name="audit">
|
||||||
|
<AuditRecordList :apply-id="applyInfo.id" ref="auditRecordListRef" />
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
<!-- 操作区域 -->
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button v-if="canConfirm" type="success" @click="handleConfirm">确认无误</el-button>
|
||||||
|
<el-button v-if="canReturn" type="warning" @click="handleReturn">退回修改</el-button>
|
||||||
|
<el-button v-if="canComplete" type="primary" @click="handleComplete">确认流程结束</el-button>
|
||||||
|
<el-button @click="handleClose">关闭</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 退回原因弹窗 -->
|
||||||
|
<el-dialog v-model="returnDialogVisible" title="退回原因" width="400px" append-to-body>
|
||||||
|
<el-form>
|
||||||
|
<el-form-item label="退回原因">
|
||||||
|
<el-input v-model="returnRemark" type="textarea" :rows="3" placeholder="请输入退回原因" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="returnDialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="submitReturn">确定</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, defineAsyncComponent } from 'vue'
|
||||||
|
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||||
|
import { getObj, getApplyFiles } from '/@/api/finance/purchasingrequisition'
|
||||||
|
import { getDocList, uploadDoc, reuploadDoc, confirmDoc, returnDoc, completeDoc, getAvailableActions, getDocDownloadUrl } from '/@/api/finance/purchasingdoc'
|
||||||
|
import other from '/@/utils/other'
|
||||||
|
|
||||||
|
const AuditRecordList = defineAsyncComponent(() => import('./AuditRecordList.vue'));
|
||||||
|
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
const activeTab = ref('info')
|
||||||
|
const applyInfo = ref<any>({})
|
||||||
|
const requirementFiles = ref<any[]>([])
|
||||||
|
const requirementLoading = ref(false)
|
||||||
|
const docList = ref<any[]>([])
|
||||||
|
const docLoading = ref(false)
|
||||||
|
const auditRecordListRef = ref()
|
||||||
|
const availableActions = ref<string[]>([])
|
||||||
|
|
||||||
|
const returnDialogVisible = ref(false)
|
||||||
|
const returnRemark = ref('')
|
||||||
|
|
||||||
|
const canUpload = computed(() => availableActions.value.includes('upload'))
|
||||||
|
const canConfirm = computed(() => availableActions.value.includes('confirm'))
|
||||||
|
const canReturn = computed(() => availableActions.value.includes('return'))
|
||||||
|
const canComplete = computed(() => availableActions.value.includes('complete'))
|
||||||
|
|
||||||
|
const open = async (row: any) => {
|
||||||
|
visible.value = true
|
||||||
|
activeTab.value = 'info'
|
||||||
|
applyInfo.value = {}
|
||||||
|
requirementFiles.value = []
|
||||||
|
docList.value = []
|
||||||
|
returnRemark.value = ''
|
||||||
|
|
||||||
|
// 加载详情
|
||||||
|
try {
|
||||||
|
const res = await getObj(row.id)
|
||||||
|
applyInfo.value = res.data || res
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '加载项目信息失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载可执行操作
|
||||||
|
try {
|
||||||
|
const actionsRes = await getAvailableActions(row.id)
|
||||||
|
availableActions.value = actionsRes.data || []
|
||||||
|
} catch (e) {
|
||||||
|
availableActions.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载采购需求文件
|
||||||
|
loadRequirementFiles()
|
||||||
|
// 加载采购文件
|
||||||
|
loadDocList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadRequirementFiles = async () => {
|
||||||
|
if (!applyInfo.value.id) return
|
||||||
|
requirementLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getApplyFiles(applyInfo.value.id)
|
||||||
|
const files = res.data || res || []
|
||||||
|
// 过滤采购需求文件(fileType=120)
|
||||||
|
requirementFiles.value = files.filter((f: any) => f.fileType === '120')
|
||||||
|
} catch (e) {
|
||||||
|
requirementFiles.value = []
|
||||||
|
} finally {
|
||||||
|
requirementLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadDocList = async () => {
|
||||||
|
if (!applyInfo.value.id) return
|
||||||
|
docLoading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getDocList(applyInfo.value.id)
|
||||||
|
docList.value = res.data || []
|
||||||
|
} catch (e) {
|
||||||
|
docList.value = []
|
||||||
|
} finally {
|
||||||
|
docLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpload = () => {
|
||||||
|
// 触发文件上传
|
||||||
|
const input = document.createElement('input')
|
||||||
|
input.type = 'file'
|
||||||
|
input.accept = '*/*'
|
||||||
|
input.onchange = async (e: any) => {
|
||||||
|
const file = e.target.files[0]
|
||||||
|
if (!file) return
|
||||||
|
// TODO: 实现文件上传到OSS,然后调用上传接口
|
||||||
|
useMessage().info('文件上传功能需要配合OSS实现')
|
||||||
|
}
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDownloadRequirement = (row: any) => {
|
||||||
|
if (row.remark) {
|
||||||
|
const url = `/purchase/purchasingfiles/download?fileName=${encodeURIComponent(row.remark)}&fileTitle=${encodeURIComponent(row.fileTitle)}`
|
||||||
|
other.downBlobFile(url, {}, row.fileTitle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDownloadDoc = (row: any) => {
|
||||||
|
const url = getDocDownloadUrl(row.id)
|
||||||
|
other.downBlobFile(url, {}, row.fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleConfirm = async () => {
|
||||||
|
try {
|
||||||
|
await useMessageBox().confirm('确定要确认该采购文件无误吗?')
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await confirmDoc({ applyId: applyInfo.value.id })
|
||||||
|
useMessage().success('确认成功')
|
||||||
|
emit('refresh')
|
||||||
|
loadDocList()
|
||||||
|
auditRecordListRef.value?.refresh()
|
||||||
|
// 重新加载可执行操作
|
||||||
|
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||||
|
availableActions.value = actionsRes.data || []
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '确认失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleReturn = () => {
|
||||||
|
returnRemark.value = ''
|
||||||
|
returnDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitReturn = async () => {
|
||||||
|
try {
|
||||||
|
await returnDoc({ applyId: applyInfo.value.id, remark: returnRemark.value })
|
||||||
|
useMessage().success('退回成功')
|
||||||
|
returnDialogVisible.value = false
|
||||||
|
emit('refresh')
|
||||||
|
loadDocList()
|
||||||
|
auditRecordListRef.value?.refresh()
|
||||||
|
// 重新加载可执行操作
|
||||||
|
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||||
|
availableActions.value = actionsRes.data || []
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '退回失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleComplete = async () => {
|
||||||
|
try {
|
||||||
|
await useMessageBox().confirm('确定要确认流程结束吗?')
|
||||||
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await completeDoc(applyInfo.value.id)
|
||||||
|
useMessage().success('流程已结束')
|
||||||
|
emit('refresh')
|
||||||
|
loadDocList()
|
||||||
|
auditRecordListRef.value?.refresh()
|
||||||
|
// 重新加载可执行操作
|
||||||
|
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||||
|
availableActions.value = actionsRes.data || []
|
||||||
|
} catch (e: any) {
|
||||||
|
useMessage().error(e?.msg || '操作失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
visible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusType = (status: string) => {
|
||||||
|
const typeMap: Record<string, string> = {
|
||||||
|
'PENDING_UPLOAD': 'info',
|
||||||
|
'ASSET_REVIEWING': 'warning',
|
||||||
|
'DEPT_REVIEWING': 'warning',
|
||||||
|
'AUDIT_REVIEWING': 'warning',
|
||||||
|
'ASSET_CONFIRMING': 'primary',
|
||||||
|
'COMPLETED': 'success',
|
||||||
|
'RETURNED': 'danger'
|
||||||
|
}
|
||||||
|
return typeMap[status] || 'info'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStatusLabel = (status: string) => {
|
||||||
|
const labelMap: Record<string, string> = {
|
||||||
|
'PENDING_UPLOAD': '待上传',
|
||||||
|
'ASSET_REVIEWING': '资产管理处审核中',
|
||||||
|
'DEPT_REVIEWING': '需求部门审核中',
|
||||||
|
'AUDIT_REVIEWING': '内审部门审核中',
|
||||||
|
'ASSET_CONFIRMING': '资产管理处确认中',
|
||||||
|
'COMPLETED': '已完成',
|
||||||
|
'RETURNED': '已退回'
|
||||||
|
}
|
||||||
|
return labelMap[status] || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFileTypeLabel = (type: string) => {
|
||||||
|
const labelMap: Record<string, string> = {
|
||||||
|
'120': '采购需求表',
|
||||||
|
'130': '采购文件'
|
||||||
|
}
|
||||||
|
return labelMap[type] || type
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.doc-header {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
193
src/views/finance/purchasingrequisition/docAudit/index.vue
Normal file
193
src/views/finance/purchasingrequisition/docAudit/index.vue
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modern-page-container">
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- 搜索表单卡片 -->
|
||||||
|
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><Search /></el-icon>
|
||||||
|
筛选条件
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList" class="search-form">
|
||||||
|
<el-form-item label="采购编号" prop="purchaseNo">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.purchaseNo"
|
||||||
|
placeholder="请输入采购编号"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="项目名称" prop="projectName">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.projectName"
|
||||||
|
placeholder="请输入项目名称"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="审核状态" prop="docAuditStatus">
|
||||||
|
<el-select
|
||||||
|
v-model="state.queryForm.docAuditStatus"
|
||||||
|
placeholder="请选择审核状态"
|
||||||
|
clearable
|
||||||
|
style="width: 200px">
|
||||||
|
<el-option label="待上传" value="PENDING_UPLOAD" />
|
||||||
|
<el-option label="资产管理处审核中" value="ASSET_REVIEWING" />
|
||||||
|
<el-option label="需求部门审核中" value="DEPT_REVIEWING" />
|
||||||
|
<el-option label="内审部门审核中" value="AUDIT_REVIEWING" />
|
||||||
|
<el-option label="资产管理处确认中" value="ASSET_CONFIRMING" />
|
||||||
|
<el-option label="已完成" value="COMPLETED" />
|
||||||
|
<el-option label="已退回" value="RETURNED" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="handleReset">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 内容卡片 -->
|
||||||
|
<el-card class="content-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><DocumentChecked /></el-icon>
|
||||||
|
采购文件审核
|
||||||
|
</span>
|
||||||
|
<div class="header-actions">
|
||||||
|
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<el-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
stripe
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
|
class="modern-table">
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center">
|
||||||
|
<template #header>
|
||||||
|
<el-icon><List /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="purchaseNo" label="采购编号" min-width="140" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="projectName" label="项目名称" min-width="200" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="deptName" label="需求部门" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="budget" label="预算金额(元)" width="120" align="right">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="docAuditStatus" label="审核状态" width="140" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag :type="getStatusType(scope.row.docAuditStatus)">
|
||||||
|
{{ getStatusLabel(scope.row.docAuditStatus) }}
|
||||||
|
</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="currentDocVersion" label="当前版本" width="100" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
{{ scope.row.currentDocVersion || '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" fixed="right" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button type="primary" link icon="View" @click="handleAudit(scope.row)">
|
||||||
|
审核
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<pagination
|
||||||
|
v-if="state.pagination && state.pagination.total && state.pagination.total > 0"
|
||||||
|
:total="state.pagination.total"
|
||||||
|
:current="state.pagination.current"
|
||||||
|
:size="state.pagination.size"
|
||||||
|
@sizeChange="sizeChangeHandle"
|
||||||
|
@currentChange="currentChangeHandle"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 审核弹窗 -->
|
||||||
|
<DocAuditDialog ref="docAuditDialogRef" @refresh="getDataList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingDocAudit">
|
||||||
|
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
|
||||||
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
|
import { useMessage } from "/@/hooks/message";
|
||||||
|
import { getPage } from "/@/api/finance/purchasingrequisition";
|
||||||
|
import { Search, DocumentChecked, List } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 引入组件
|
||||||
|
const DocAuditDialog = defineAsyncComponent(() => import('./DocAuditDialog.vue'));
|
||||||
|
|
||||||
|
const docAuditDialogRef = ref()
|
||||||
|
const searchFormRef = ref()
|
||||||
|
const showSearch = ref(true)
|
||||||
|
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
pageList: getPage,
|
||||||
|
queryForm: {
|
||||||
|
purchaseNo: '',
|
||||||
|
projectName: '',
|
||||||
|
docAuditStatus: '',
|
||||||
|
},
|
||||||
|
createdIsNeed: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const { getDataList, tableStyle, sizeChangeHandle, currentChangeHandle } = useTable(state);
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
searchFormRef.value?.resetFields();
|
||||||
|
getDataList();
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusType = (status: string) => {
|
||||||
|
const typeMap: Record<string, string> = {
|
||||||
|
'PENDING_UPLOAD': 'info',
|
||||||
|
'ASSET_REVIEWING': 'warning',
|
||||||
|
'DEPT_REVIEWING': 'warning',
|
||||||
|
'AUDIT_REVIEWING': 'warning',
|
||||||
|
'ASSET_CONFIRMING': 'primary',
|
||||||
|
'COMPLETED': 'success',
|
||||||
|
'RETURNED': 'danger'
|
||||||
|
};
|
||||||
|
return typeMap[status] || 'info';
|
||||||
|
};
|
||||||
|
|
||||||
|
const getStatusLabel = (status: string) => {
|
||||||
|
const labelMap: Record<string, string> = {
|
||||||
|
'PENDING_UPLOAD': '待上传',
|
||||||
|
'ASSET_REVIEWING': '资产管理处审核中',
|
||||||
|
'DEPT_REVIEWING': '需求部门审核中',
|
||||||
|
'AUDIT_REVIEWING': '内审部门审核中',
|
||||||
|
'ASSET_CONFIRMING': '资产管理处确认中',
|
||||||
|
'COMPLETED': '已完成',
|
||||||
|
'RETURNED': '已退回'
|
||||||
|
};
|
||||||
|
return labelMap[status] || '-';
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAudit = (row: any) => {
|
||||||
|
docAuditDialogRef.value?.open(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 页面加载时的初始化逻辑
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '/@/assets/styles/modern-page.scss';
|
||||||
|
</style>
|
||||||
@@ -235,52 +235,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="fileFlowStatus" label="文件审批状态" width="110" align="center">
|
|
||||||
<template #header>
|
|
||||||
<el-icon><DocumentChecked /></el-icon>
|
|
||||||
<span style="margin-left: 4px">文件审批状态</span>
|
|
||||||
</template>
|
|
||||||
<template #default="scope">
|
|
||||||
<template v-if="scope.row.fileFlowInstId">
|
|
||||||
<el-tooltip content="点击查看审批过程" placement="top">
|
|
||||||
<el-tag
|
|
||||||
v-if="scope.row.fileFlowStatus === '-2'"
|
|
||||||
type="info"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">撤回</el-tag>
|
|
||||||
<el-tag
|
|
||||||
v-else-if="scope.row.fileFlowStatus === '-1'"
|
|
||||||
type="warning"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">暂存</el-tag>
|
|
||||||
<el-tag
|
|
||||||
v-else-if="scope.row.fileFlowStatus === '0'"
|
|
||||||
type="primary"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">运行中</el-tag>
|
|
||||||
<el-tag
|
|
||||||
v-else-if="scope.row.fileFlowStatus === '1'"
|
|
||||||
type="success"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">完成</el-tag>
|
|
||||||
<el-tag
|
|
||||||
v-else-if="scope.row.fileFlowStatus === '2'"
|
|
||||||
type="danger"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">作废</el-tag>
|
|
||||||
<el-tag
|
|
||||||
v-else-if="scope.row.fileFlowStatus === '3'"
|
|
||||||
type="info"
|
|
||||||
class="status-tag-clickable"
|
|
||||||
@click="handleShowFileFlowComment(scope.row)">终止</el-tag>
|
|
||||||
<span v-else class="status-tag-clickable" @click="handleShowFileFlowComment(scope.row)">-</span>
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<span style="color: #909399;">—</span>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" align="center" fixed="right" width="150">
|
<el-table-column label="操作" align="center" fixed="right" width="150">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="op-cell">
|
<div class="op-cell">
|
||||||
@@ -391,6 +346,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 采购文件审核弹窗 -->
|
||||||
|
<DocAuditDialog ref="docAuditDialogRef" @refresh="getDataList" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -412,6 +370,7 @@ const ImplementForm = defineAsyncComponent(() => import('./implementForm.vue'));
|
|||||||
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'));
|
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'));
|
||||||
const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue'));
|
const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue'));
|
||||||
const FlowCommentTimeline = defineAsyncComponent(() => import('/@/views/jsonflow/comment/timeline.vue'));
|
const FlowCommentTimeline = defineAsyncComponent(() => import('/@/views/jsonflow/comment/timeline.vue'));
|
||||||
|
const DocAuditDialog = defineAsyncComponent(() => import('./docAudit/DocAuditDialog.vue'));
|
||||||
|
|
||||||
// 字典数据和品目树数据
|
// 字典数据和品目树数据
|
||||||
const dictData = ref({
|
const dictData = ref({
|
||||||
@@ -431,6 +390,7 @@ const formDialogRef = ref()
|
|||||||
const acceptModalRef = ref()
|
const acceptModalRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const showSearch = ref(true)
|
const showSearch = ref(true)
|
||||||
|
const docAuditDialogRef = ref()
|
||||||
/** 审批过程弹窗:是否显示、当前行对应的流程 job(供 Comment 组件用)、类型(申请单/文件) */
|
/** 审批过程弹窗:是否显示、当前行对应的流程 job(供 Comment 组件用)、类型(申请单/文件) */
|
||||||
const showFlowComment = ref(false)
|
const showFlowComment = ref(false)
|
||||||
const currFlowJob = ref<{ id?: number; flowInstId?: number } | null>(null)
|
const currFlowJob = ref<{ id?: number; flowInstId?: number } | null>(null)
|
||||||
@@ -599,6 +559,11 @@ const handleImplement = (row: any) => {
|
|||||||
implementFormRef.value?.openDialog(row);
|
implementFormRef.value?.openDialog(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 打开采购文件审核 */
|
||||||
|
const handleDocAudit = (row: any) => {
|
||||||
|
docAuditDialogRef.value?.open(row);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除当前行
|
* 删除当前行
|
||||||
* @param row - 当前行数据
|
* @param row - 当前行数据
|
||||||
@@ -611,7 +576,7 @@ const handleDelete = async (row: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await delObj(row.id);
|
await delObj({id:row.id});
|
||||||
useMessage().success('删除成功');
|
useMessage().success('删除成功');
|
||||||
getDataList();
|
getDataList();
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
@@ -692,6 +657,12 @@ const getActionMenuItems = (row: any) => {
|
|||||||
icon: Collection,
|
icon: Collection,
|
||||||
visible: () => row?.purchaseMode === '2' || (row?.purchaseMode === '0' && row?.purchaseType === '4'),
|
visible: () => row?.purchaseMode === '2' || (row?.purchaseMode === '0' && row?.purchaseType === '4'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
command: 'docAudit',
|
||||||
|
label: '采购文件审核',
|
||||||
|
icon: DocumentChecked,
|
||||||
|
visible: () => row?.implementType === '2' && row?.agentId,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -725,6 +696,9 @@ const handleMoreCommand = (command: string, row: any) => {
|
|||||||
case 'assignAgent':
|
case 'assignAgent':
|
||||||
openAssignAgentDialog(row);
|
openAssignAgentDialog(row);
|
||||||
break;
|
break;
|
||||||
|
case 'docAudit':
|
||||||
|
handleDocAudit(row);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
271
src/views/finance/purchasingtemplate/index.vue
Normal file
271
src/views/finance/purchasingtemplate/index.vue
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modern-page-container">
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<el-card class="content-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
|
||||||
|
<div class="header-actions">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="FolderAdd"
|
||||||
|
@click="openUploadDialog()"
|
||||||
|
v-auth="'purchase_template_add'">
|
||||||
|
新增模板
|
||||||
|
</el-button>
|
||||||
|
<el-alert type="info" :closable="false" class="mb3 mt-3" show-icon>
|
||||||
|
此处模版中的模版编码对应用户端下载模版匹配,请勿随意修改或删除。正常情况下如有发生模版变化,重新上传即可。如有新增模版,请联系管理员进行处理。
|
||||||
|
</el-alert>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-table :data="tableData" v-loading="loading" stripe class="modern-table">
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center">
|
||||||
|
<template #header>
|
||||||
|
<el-icon><List /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="templateTitle" label="模板类型名称" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="templateType" label="模板类型编码" min-width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="templateName" label="模板名称" min-width="220" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="updateTime" label="更新时间" width="180" show-overflow-tooltip />
|
||||||
|
<el-table-column label="操作" width="260" align="center" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
icon="Download"
|
||||||
|
@click="handleDownload(row)"
|
||||||
|
v-auth="'purchase_template_view'">
|
||||||
|
下载
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
icon="UploadFilled"
|
||||||
|
@click="openUploadDialog(row)"
|
||||||
|
v-auth="'purchase_template_add'">
|
||||||
|
重新上传
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
icon="Edit"
|
||||||
|
@click="openEditDialog(row)"
|
||||||
|
v-auth="'purchase_template_add'">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<el-dialog v-model="uploadDialogVisible" title="上传模板" width="450px" destroy-on-close>
|
||||||
|
<el-form :model="uploadForm" label-width="100px">
|
||||||
|
<el-form-item label="模板类型编码" required>
|
||||||
|
<el-input
|
||||||
|
v-model="uploadForm.templateType"
|
||||||
|
placeholder="例如: business_negotiation, inquiry"
|
||||||
|
:disabled="!!uploadForm.lockType"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板类型名称">
|
||||||
|
<el-input
|
||||||
|
v-model="uploadForm.templateTitle"
|
||||||
|
placeholder="例如: 部门采购询价模版"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板文件" required>
|
||||||
|
<el-upload
|
||||||
|
class="upload-block"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="1"
|
||||||
|
:file-list="fileList"
|
||||||
|
:on-change="handleFileChange"
|
||||||
|
:on-remove="handleFileRemove"
|
||||||
|
>
|
||||||
|
<el-button type="primary" icon="UploadFilled">选择文件</el-button>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip">支持 doc、docx 等 Word 模板文件,上传后前端下载将使用该文件。</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="uploadDialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="uploading" @click="handleUploadConfirm">上 传</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog v-model="editDialogVisible" title="编辑模板" width="420px" destroy-on-close>
|
||||||
|
<el-form :model="editForm" label-width="100px">
|
||||||
|
<el-form-item label="模板类型编码">
|
||||||
|
<el-input v-model="editForm.templateType" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板类型名称" required>
|
||||||
|
<el-input v-model="editForm.templateTitle" placeholder="请输入模板类型名称" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="editDialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" :loading="editing" @click="handleEditConfirm">保 存</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingTemplateManage">
|
||||||
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
import { Document, List, UploadFilled, Download, Edit } from '@element-plus/icons-vue';
|
||||||
|
import { listTemplates, uploadTemplate, getTemplateDownloadUrl, updateTemplateTitle } from '/@/api/finance/purchasingtemplate';
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
const tableData = ref<any[]>([]);
|
||||||
|
|
||||||
|
const uploadDialogVisible = ref(false);
|
||||||
|
const uploading = ref(false);
|
||||||
|
const uploadForm = reactive<{
|
||||||
|
templateType: string;
|
||||||
|
templateTitle: string;
|
||||||
|
lockType?: boolean;
|
||||||
|
}>({
|
||||||
|
templateType: '',
|
||||||
|
templateTitle: '',
|
||||||
|
lockType: false,
|
||||||
|
});
|
||||||
|
const editDialogVisible = ref(false);
|
||||||
|
const editing = ref(false);
|
||||||
|
const editForm = reactive<{
|
||||||
|
id: number | null;
|
||||||
|
templateType: string;
|
||||||
|
templateTitle: string;
|
||||||
|
}>({
|
||||||
|
id: null,
|
||||||
|
templateType: '',
|
||||||
|
templateTitle: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const fileList = ref<any[]>([]);
|
||||||
|
const currentFile = ref<File | null>(null);
|
||||||
|
|
||||||
|
const fetchData = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
try {
|
||||||
|
const res = await listTemplates();
|
||||||
|
tableData.value = (res && res.data) || [];
|
||||||
|
} catch (e) {
|
||||||
|
tableData.value = [];
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(fetchData);
|
||||||
|
|
||||||
|
const openUploadDialog = (row?: any) => {
|
||||||
|
uploadDialogVisible.value = true;
|
||||||
|
uploadForm.templateType = row?.templateType || '';
|
||||||
|
uploadForm.templateTitle = row?.templateTitle || '';
|
||||||
|
uploadForm.lockType = !!row?.templateType;
|
||||||
|
fileList.value = [];
|
||||||
|
currentFile.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileChange = (file: any, files: any[]) => {
|
||||||
|
fileList.value = files.slice(-1);
|
||||||
|
currentFile.value = file.raw || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFileRemove = () => {
|
||||||
|
fileList.value = [];
|
||||||
|
currentFile.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUploadConfirm = async () => {
|
||||||
|
if (!uploadForm.templateType || !uploadForm.templateType.trim()) {
|
||||||
|
useMessage().error('请填写模板类型编码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!currentFile.value) {
|
||||||
|
useMessage().error('请选择要上传的模板文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uploading.value = true;
|
||||||
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('type', uploadForm.templateType.trim());
|
||||||
|
if (uploadForm.templateTitle && uploadForm.templateTitle.trim()) {
|
||||||
|
formData.append('title', uploadForm.templateTitle.trim());
|
||||||
|
}
|
||||||
|
formData.append('file', currentFile.value);
|
||||||
|
await uploadTemplate(formData);
|
||||||
|
useMessage().success('模板上传成功');
|
||||||
|
uploadDialogVisible.value = false;
|
||||||
|
await fetchData();
|
||||||
|
} catch (e) {
|
||||||
|
useMessage().error('模板上传失败');
|
||||||
|
} finally {
|
||||||
|
uploading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleDownload = async (row: any) => {
|
||||||
|
if (!row?.templateType) {
|
||||||
|
useMessage().error('缺少模板类型编码');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const url = getTemplateDownloadUrl(row.templateType);
|
||||||
|
const fileName = row.templateName || row.templateTitle || row.templateType;
|
||||||
|
try {
|
||||||
|
await (window as any).other?.downBlobFile?.(url, {}, fileName) ||
|
||||||
|
// 兼容直接使用工具函数
|
||||||
|
(await import('/@/utils/other')).default.downBlobFile(url, {}, fileName);
|
||||||
|
} catch (e) {
|
||||||
|
// 如果工具函数不可用,则退回 window.open
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const openEditDialog = (row: any) => {
|
||||||
|
editDialogVisible.value = true;
|
||||||
|
editForm.id = row?.id ?? null;
|
||||||
|
editForm.templateType = row?.templateType || '';
|
||||||
|
editForm.templateTitle = row?.templateTitle || '';
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleEditConfirm = async () => {
|
||||||
|
if (!editForm.id) {
|
||||||
|
useMessage().error('缺少模板ID');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!editForm.templateTitle || !editForm.templateTitle.trim()) {
|
||||||
|
useMessage().error('请输入模板类型名称');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editing.value = true;
|
||||||
|
try {
|
||||||
|
await updateTemplateTitle({
|
||||||
|
id: editForm.id,
|
||||||
|
templateTitle: editForm.templateTitle.trim(),
|
||||||
|
});
|
||||||
|
useMessage().success('保存成功');
|
||||||
|
editDialogVisible.value = false;
|
||||||
|
await fetchData();
|
||||||
|
} catch (e) {
|
||||||
|
useMessage().error('保存失败');
|
||||||
|
} finally {
|
||||||
|
editing.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.upload-block {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="card-title">
|
<span class="card-title">
|
||||||
<el-icon class="title-icon"><Document /></el-icon>
|
<el-icon class="title-icon"><Document /></el-icon>
|
||||||
业务分管部门及人员
|
业务分管处室及人员
|
||||||
</span>
|
</span>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-button
|
<el-button
|
||||||
|
|||||||
182
src/views/purchase/purchasingBusinessLeader/form.vue
Normal file
182
src/views/purchase/purchasingBusinessLeader/form.vue
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:title="form.id ? '编辑' : '新增'"
|
||||||
|
v-model="visible"
|
||||||
|
width="600px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
draggable>
|
||||||
|
<el-form
|
||||||
|
ref="dataFormRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="dataRules"
|
||||||
|
label-width="120px"
|
||||||
|
v-loading="loading">
|
||||||
|
<el-form-item label="选取用户" prop="userId">
|
||||||
|
<org-selector
|
||||||
|
v-model:orgList="userList"
|
||||||
|
type="user"
|
||||||
|
:multiple="false"
|
||||||
|
@update:orgList="handleUserChange" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="form.name"
|
||||||
|
placeholder="选择用户后自动填充"
|
||||||
|
readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户工号" prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="form.username"
|
||||||
|
placeholder="选择用户后自动填充"
|
||||||
|
readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input
|
||||||
|
v-model="form.remark"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onSubmit" :disabled="loading">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingBusinessLeaderForm">
|
||||||
|
import { reactive, ref, nextTick } from 'vue'
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/purchase/purchasingBusinessLeader';
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import orgSelector from '/@/components/OrgSelector/index.vue';
|
||||||
|
|
||||||
|
// 定义子组件向父组件传值/事件
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
|
// 定义变量内容
|
||||||
|
const dataFormRef = ref();
|
||||||
|
const userList = ref<any[]>([]);
|
||||||
|
const form = reactive({
|
||||||
|
id: '',
|
||||||
|
userId: '',
|
||||||
|
username: '',
|
||||||
|
name: '',
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
const visible = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const dataRules = ref({
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: '请选取用户', trigger: 'change' }
|
||||||
|
],
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请先选取用户', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '请先选取用户', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理用户选择变化
|
||||||
|
const handleUserChange = (list: any[]) => {
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
const user = list[0];
|
||||||
|
form.userId = user.userId || user.id || '';
|
||||||
|
form.username = user.username || user.userName || '';
|
||||||
|
form.name = user.name || user.realName || '';
|
||||||
|
} else {
|
||||||
|
form.userId = '';
|
||||||
|
form.username = '';
|
||||||
|
form.name = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const openDialog = async (id?: string) => {
|
||||||
|
visible.value = true;
|
||||||
|
form.id = '';
|
||||||
|
form.userId = '';
|
||||||
|
form.username = '';
|
||||||
|
form.name = '';
|
||||||
|
form.remark = '';
|
||||||
|
userList.value = [];
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
dataFormRef.value?.resetFields();
|
||||||
|
if (id) {
|
||||||
|
// 编辑时,先获取详情数据
|
||||||
|
loading.value = true;
|
||||||
|
getObj(id).then((res: any) => {
|
||||||
|
if (res.data && res.data.length > 0) {
|
||||||
|
const data = res.data[0];
|
||||||
|
Object.assign(form, {
|
||||||
|
id: data.id || '',
|
||||||
|
userId: data.userId || '',
|
||||||
|
username: data.username || '',
|
||||||
|
name: data.name || '',
|
||||||
|
remark: data.remark || '',
|
||||||
|
});
|
||||||
|
// 设置用户列表用于回显
|
||||||
|
if (data.userId) {
|
||||||
|
userList.value = [{
|
||||||
|
userId: data.userId,
|
||||||
|
username: data.username,
|
||||||
|
name: data.name,
|
||||||
|
id: data.userId,
|
||||||
|
userName: data.username,
|
||||||
|
realName: data.name,
|
||||||
|
type: 'user',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
}).catch((err: any) => {
|
||||||
|
useMessage().error(err.msg || '获取详情失败');
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const onSubmit = async () => {
|
||||||
|
// 立即设置 loading,防止重复点击
|
||||||
|
if (loading.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
|
if (!valid) {
|
||||||
|
loading.value = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.id) {
|
||||||
|
await putObj(form);
|
||||||
|
useMessage().success('编辑成功');
|
||||||
|
} else {
|
||||||
|
await addObj(form);
|
||||||
|
useMessage().success('新增成功');
|
||||||
|
}
|
||||||
|
visible.value = false;
|
||||||
|
emit('refresh');
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || (form.id ? '编辑失败' : '新增失败'));
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露变量
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
240
src/views/purchase/purchasingBusinessLeader/index.vue
Normal file
240
src/views/purchase/purchasingBusinessLeader/index.vue
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modern-page-container">
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- 搜索表单卡片 -->
|
||||||
|
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><Search /></el-icon>
|
||||||
|
筛选条件
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList" class="search-form">
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.name"
|
||||||
|
placeholder="请输入姓名"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户工号" prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.username"
|
||||||
|
placeholder="请输入用户工号"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 内容卡片 -->
|
||||||
|
<el-card class="content-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><User /></el-icon>
|
||||||
|
业务分管校领导
|
||||||
|
</span>
|
||||||
|
<div class="header-actions">
|
||||||
|
<el-button
|
||||||
|
icon="FolderAdd"
|
||||||
|
type="primary"
|
||||||
|
@click="formDialogRef.openDialog()"
|
||||||
|
v-auth="'purchasing_bus_leader_add'">
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'purchasing_bus_leader_del'"
|
||||||
|
@click="handleDelete(selectObjs)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
<right-toolbar
|
||||||
|
v-model:showSearch="showSearch"
|
||||||
|
:export="'purchasing_bus_leader_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
@queryTable="getDataList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<el-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
stripe
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
|
@selection-change="selectionChangHandle"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
class="modern-table">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center">
|
||||||
|
<template #header>
|
||||||
|
<el-icon><List /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="name" label="姓名" min-width="120" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
<span style="margin-left: 4px">姓名</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="username" label="用户工号" min-width="150" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><UserFilled /></el-icon>
|
||||||
|
<span style="margin-left: 4px">用户工号</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="remark" label="备注" min-width="300" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><EditPen /></el-icon>
|
||||||
|
<span style="margin-left: 4px">备注</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="创建时间" width="180" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><Clock /></el-icon>
|
||||||
|
<span style="margin-left: 4px">创建时间</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" fixed="right" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
icon="Delete"
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
v-auth="'purchasing_bus_leader_del'"
|
||||||
|
@click="handleDelete([scope.row.id])">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<pagination
|
||||||
|
v-if="state.pagination"
|
||||||
|
v-show="state.pagination.total && state.pagination.total > 0"
|
||||||
|
:total="state.pagination.total"
|
||||||
|
:current="state.pagination.current"
|
||||||
|
:size="state.pagination.size"
|
||||||
|
@size-change="sizeChangeHandle"
|
||||||
|
@current-change="currentChangeHandle"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 编辑、新增表单对话框 -->
|
||||||
|
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingBusinessLeader">
|
||||||
|
import { ref, reactive, defineAsyncComponent } from 'vue'
|
||||||
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
|
import { fetchList, delObjs } from "/@/api/purchase/purchasingBusinessLeader";
|
||||||
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
|
import { List, User, UserFilled, EditPen, Clock, Search } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 引入组件
|
||||||
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
|
|
||||||
|
// 定义变量内容
|
||||||
|
const tableRef = ref()
|
||||||
|
const formDialogRef = ref()
|
||||||
|
const queryRef = ref()
|
||||||
|
const showSearch = ref(true)
|
||||||
|
const selectObjs = ref([]) as any
|
||||||
|
const multiple = ref(true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义响应式表格数据
|
||||||
|
*/
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
pageList: fetchList,
|
||||||
|
queryForm: {
|
||||||
|
name: '',
|
||||||
|
username: '',
|
||||||
|
},
|
||||||
|
createdIsNeed: true
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 useTable 定义表格相关操作
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
getDataList,
|
||||||
|
currentChangeHandle,
|
||||||
|
sizeChangeHandle,
|
||||||
|
sortChangeHandle,
|
||||||
|
downBlobFile,
|
||||||
|
tableStyle
|
||||||
|
} = useTable(state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置搜索表单
|
||||||
|
*/
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryRef.value?.resetFields();
|
||||||
|
selectObjs.value = [];
|
||||||
|
multiple.value = true;
|
||||||
|
getDataList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出Excel文件
|
||||||
|
*/
|
||||||
|
const exportExcel = () => {
|
||||||
|
downBlobFile(
|
||||||
|
'/purchase/purchasingBusinessLeader/export',
|
||||||
|
Object.assign(state.queryForm, { ids: selectObjs.value }),
|
||||||
|
'purchasingBusinessLeader.xlsx'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格多选事件处理
|
||||||
|
* @param objs 选中的数据行
|
||||||
|
*/
|
||||||
|
const selectionChangHandle = (objs: { id: string }[]) => {
|
||||||
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
|
multiple.value = !objs.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除当前行
|
||||||
|
* @param ids - 要删除的ID数组
|
||||||
|
*/
|
||||||
|
const handleDelete = async (ids: string[]) => {
|
||||||
|
try {
|
||||||
|
await useMessageBox().confirm('确定要删除该记录吗?');
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await delObjs(ids);
|
||||||
|
useMessage().success('删除成功');
|
||||||
|
getDataList();
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || '删除失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '/@/assets/styles/modern-page.scss';
|
||||||
|
</style>
|
||||||
228
src/views/purchase/purchasingPurchaseManager/form.vue
Normal file
228
src/views/purchase/purchasingPurchaseManager/form.vue
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
:title="form.id ? '编辑' : '新增'"
|
||||||
|
v-model="visible"
|
||||||
|
width="700px"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
draggable>
|
||||||
|
<el-form
|
||||||
|
ref="dataFormRef"
|
||||||
|
:model="form"
|
||||||
|
:rules="dataRules"
|
||||||
|
label-width="120px"
|
||||||
|
v-loading="loading">
|
||||||
|
<!-- 新增时先选取用户,选后自动带出姓名、工号 -->
|
||||||
|
<el-form-item label="选取用户" prop="userId">
|
||||||
|
<org-selector
|
||||||
|
v-model:orgList="userList"
|
||||||
|
type="user"
|
||||||
|
:multiple="false"
|
||||||
|
@update:orgList="handleUserChange" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="form.name"
|
||||||
|
placeholder="选择用户后自动填充"
|
||||||
|
readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户工号" prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="form.username"
|
||||||
|
placeholder="选择用户后自动填充"
|
||||||
|
readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门" prop="deptId">
|
||||||
|
<org-selector
|
||||||
|
v-model:orgList="deptList"
|
||||||
|
type="dept"
|
||||||
|
:multiple="false"
|
||||||
|
@update:orgList="handleDeptChange" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门名称" prop="deptName">
|
||||||
|
<el-input
|
||||||
|
v-model="form.deptName"
|
||||||
|
placeholder="选择部门后自动填充"
|
||||||
|
readonly />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input
|
||||||
|
v-model="form.remark"
|
||||||
|
type="textarea"
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入备注"
|
||||||
|
clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onSubmit" :disabled="loading">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingPurchaseManagerForm">
|
||||||
|
import { reactive, ref, nextTick } from 'vue'
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/purchase/purchasingPurchaseManager';
|
||||||
|
import { useMessage } from '/@/hooks/message';
|
||||||
|
import orgSelector from '/@/components/OrgSelector/index.vue';
|
||||||
|
|
||||||
|
// 定义子组件向父组件传值/事件
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
|
// 定义变量内容
|
||||||
|
const dataFormRef = ref();
|
||||||
|
const deptList = ref<any[]>([]);
|
||||||
|
const userList = ref<any[]>([]);
|
||||||
|
const form = reactive({
|
||||||
|
id: '',
|
||||||
|
deptId: '',
|
||||||
|
deptName: '',
|
||||||
|
userId: '',
|
||||||
|
username: '',
|
||||||
|
name: '',
|
||||||
|
remark: '',
|
||||||
|
});
|
||||||
|
const visible = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
const dataRules = ref({
|
||||||
|
userId: [
|
||||||
|
{ required: true, message: '请选取用户(分管负责人)', trigger: 'change' }
|
||||||
|
],
|
||||||
|
deptId: [
|
||||||
|
{ required: true, message: '请选择部门', trigger: 'change' }
|
||||||
|
],
|
||||||
|
name: [
|
||||||
|
{ required: true, message: '请先选取用户', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '请先选取用户', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理部门选择变化
|
||||||
|
const handleDeptChange = (list: any[]) => {
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
const dept = list[0];
|
||||||
|
form.deptId = dept.deptId || dept.id || '';
|
||||||
|
form.deptName = dept.name || dept.deptName || '';
|
||||||
|
} else {
|
||||||
|
form.deptId = '';
|
||||||
|
form.deptName = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理用户选择变化(选取用户后自动带出姓名、工号)
|
||||||
|
const handleUserChange = (list: any[]) => {
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
const user = list[0];
|
||||||
|
form.userId = user.userId || user.id || '';
|
||||||
|
form.username = user.username || user.userName || '';
|
||||||
|
form.name = user.name || user.realName || '';
|
||||||
|
} else {
|
||||||
|
form.userId = '';
|
||||||
|
form.username = '';
|
||||||
|
form.name = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开弹窗
|
||||||
|
const openDialog = async (id?: string) => {
|
||||||
|
visible.value = true;
|
||||||
|
form.id = '';
|
||||||
|
form.deptId = '';
|
||||||
|
form.deptName = '';
|
||||||
|
form.userId = '';
|
||||||
|
form.username = '';
|
||||||
|
form.name = '';
|
||||||
|
form.remark = '';
|
||||||
|
deptList.value = [];
|
||||||
|
userList.value = [];
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
dataFormRef.value?.resetFields();
|
||||||
|
if (id) {
|
||||||
|
// 编辑时,先获取详情数据
|
||||||
|
loading.value = true;
|
||||||
|
getObj(id).then((res: any) => {
|
||||||
|
if (res.data && res.data.length > 0) {
|
||||||
|
const data = res.data[0];
|
||||||
|
Object.assign(form, {
|
||||||
|
id: data.id || '',
|
||||||
|
deptId: data.deptId || '',
|
||||||
|
deptName: data.deptName || '',
|
||||||
|
userId: data.userId || '',
|
||||||
|
username: data.username || '',
|
||||||
|
name: data.name || '',
|
||||||
|
remark: data.remark || '',
|
||||||
|
});
|
||||||
|
// 设置部门列表用于回显
|
||||||
|
if (data.deptId) {
|
||||||
|
deptList.value = [{
|
||||||
|
deptId: data.deptId,
|
||||||
|
name: data.deptName,
|
||||||
|
id: data.deptId,
|
||||||
|
type: 'dept',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
// 设置用户列表用于回显
|
||||||
|
if (data.userId) {
|
||||||
|
userList.value = [{
|
||||||
|
userId: data.userId,
|
||||||
|
username: data.username,
|
||||||
|
name: data.name,
|
||||||
|
id: data.userId,
|
||||||
|
userName: data.username,
|
||||||
|
realName: data.name,
|
||||||
|
type: 'user',
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
}).catch((err: any) => {
|
||||||
|
useMessage().error(err.msg || '获取详情失败');
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交
|
||||||
|
const onSubmit = async () => {
|
||||||
|
// 立即设置 loading,防止重复点击
|
||||||
|
if (loading.value) return;
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
|
if (!valid) {
|
||||||
|
loading.value = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (form.id) {
|
||||||
|
await putObj(form);
|
||||||
|
useMessage().success('编辑成功');
|
||||||
|
} else {
|
||||||
|
await addObj(form);
|
||||||
|
useMessage().success('新增成功');
|
||||||
|
}
|
||||||
|
visible.value = false;
|
||||||
|
emit('refresh');
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || (form.id ? '编辑失败' : '新增失败'));
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴露变量
|
||||||
|
defineExpose({
|
||||||
|
openDialog,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
254
src/views/purchase/purchasingPurchaseManager/index.vue
Normal file
254
src/views/purchase/purchasingPurchaseManager/index.vue
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
<template>
|
||||||
|
<div class="modern-page-container">
|
||||||
|
<div class="page-wrapper">
|
||||||
|
<!-- 搜索表单卡片 -->
|
||||||
|
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><Search /></el-icon>
|
||||||
|
筛选条件
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-form :model="state.queryForm" ref="queryRef" :inline="true" @keyup.enter="getDataList" class="search-form">
|
||||||
|
<el-form-item label="部门名称" prop="deptName">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.deptName"
|
||||||
|
placeholder="请输入部门名称"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户工号" prop="username">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.username"
|
||||||
|
placeholder="请输入用户工号"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="姓名" prop="name">
|
||||||
|
<el-input
|
||||||
|
v-model="state.queryForm.name"
|
||||||
|
placeholder="请输入姓名"
|
||||||
|
clearable
|
||||||
|
style="width: 200px" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<!-- 内容卡片 -->
|
||||||
|
<el-card class="content-card" shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">
|
||||||
|
<el-icon class="title-icon"><Document /></el-icon>
|
||||||
|
采购分管领导
|
||||||
|
</span>
|
||||||
|
<div class="header-actions">
|
||||||
|
<el-button
|
||||||
|
icon="FolderAdd"
|
||||||
|
type="primary"
|
||||||
|
@click="formDialogRef.openDialog()"
|
||||||
|
v-auth="'purchase_manager_add'">
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
v-auth="'purchase_manager_del'"
|
||||||
|
@click="handleDelete(selectObjs)">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
<right-toolbar
|
||||||
|
v-model:showSearch="showSearch"
|
||||||
|
:export="'purchase_manager_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10"
|
||||||
|
@queryTable="getDataList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<el-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
stripe
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
|
@selection-change="selectionChangHandle"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
class="modern-table">
|
||||||
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center">
|
||||||
|
<template #header>
|
||||||
|
<el-icon><List /></el-icon>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="deptName" label="部门名称" min-width="200" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><OfficeBuilding /></el-icon>
|
||||||
|
<span style="margin-left: 4px">部门名称</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="name" label="姓名" min-width="120" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><User /></el-icon>
|
||||||
|
<span style="margin-left: 4px">姓名</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="username" label="用户工号" min-width="150" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><UserFilled /></el-icon>
|
||||||
|
<span style="margin-left: 4px">用户工号</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="remark" label="备注" min-width="300" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><EditPen /></el-icon>
|
||||||
|
<span style="margin-left: 4px">备注</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" label="创建时间" width="180" show-overflow-tooltip>
|
||||||
|
<template #header>
|
||||||
|
<el-icon><Clock /></el-icon>
|
||||||
|
<span style="margin-left: 4px">创建时间</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" fixed="right" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
icon="Delete"
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
v-auth="'purchase_manager_del'"
|
||||||
|
@click="handleDelete([scope.row.id])">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<pagination
|
||||||
|
v-if="state.pagination"
|
||||||
|
v-show="state.pagination.total && state.pagination.total > 0"
|
||||||
|
:total="state.pagination.total"
|
||||||
|
:current="state.pagination.current"
|
||||||
|
:size="state.pagination.size"
|
||||||
|
@size-change="sizeChangeHandle"
|
||||||
|
@current-change="currentChangeHandle"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 编辑、新增表单对话框 -->
|
||||||
|
<form-dialog ref="formDialogRef" @refresh="getDataList" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="PurchasingPurchaseManager">
|
||||||
|
import { ref, reactive, defineAsyncComponent } from 'vue'
|
||||||
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
|
import { fetchList, delObjs } from "/@/api/purchase/purchasingPurchaseManager";
|
||||||
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
|
import { List, Document, User, UserFilled, EditPen, Clock, Search, OfficeBuilding } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 引入组件
|
||||||
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
|
|
||||||
|
// 定义变量内容
|
||||||
|
const tableRef = ref()
|
||||||
|
const formDialogRef = ref()
|
||||||
|
const queryRef = ref()
|
||||||
|
const showSearch = ref(true)
|
||||||
|
const selectObjs = ref([]) as any
|
||||||
|
const multiple = ref(true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义响应式表格数据
|
||||||
|
*/
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
pageList: fetchList,
|
||||||
|
queryForm: {
|
||||||
|
deptName: '',
|
||||||
|
username: '',
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
createdIsNeed: true
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 useTable 定义表格相关操作
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
getDataList,
|
||||||
|
currentChangeHandle,
|
||||||
|
sizeChangeHandle,
|
||||||
|
sortChangeHandle,
|
||||||
|
downBlobFile,
|
||||||
|
tableStyle
|
||||||
|
} = useTable(state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置搜索表单
|
||||||
|
*/
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryRef.value?.resetFields();
|
||||||
|
selectObjs.value = [];
|
||||||
|
multiple.value = true;
|
||||||
|
getDataList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出Excel文件
|
||||||
|
*/
|
||||||
|
const exportExcel = () => {
|
||||||
|
downBlobFile(
|
||||||
|
'/purchasingPurchaseManager/export',
|
||||||
|
Object.assign(state.queryForm, { ids: selectObjs.value }),
|
||||||
|
'purchasingPurchaseManager.xlsx'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格多选事件处理
|
||||||
|
* @param objs 选中的数据行
|
||||||
|
*/
|
||||||
|
const selectionChangHandle = (objs: { id: string }[]) => {
|
||||||
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
|
multiple.value = !objs.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除当前行
|
||||||
|
* @param ids - 要删除的ID数组
|
||||||
|
*/
|
||||||
|
const handleDelete = async (ids: string[]) => {
|
||||||
|
try {
|
||||||
|
await useMessageBox().confirm('确定要删除该记录吗?');
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await delObjs(ids);
|
||||||
|
useMessage().success('删除成功');
|
||||||
|
getDataList();
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg || '删除失败');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import '/@/assets/styles/modern-page.scss';
|
||||||
|
</style>
|
||||||
@@ -39,13 +39,15 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="card-title">
|
<span class="card-title">
|
||||||
<el-icon class="title-icon"><User /></el-icon>
|
<el-icon class="title-icon"><User /></el-icon>
|
||||||
校领导(党委)管理
|
校党委人员
|
||||||
</span>
|
</span>
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<el-button
|
<el-button
|
||||||
icon="FolderAdd"
|
icon="FolderAdd"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="formDialogRef.openDialog('add')">
|
@click="formDialogRef.openDialog('add')"
|
||||||
|
v-auth="'purchase_purchasingSchoolLeader_add'"
|
||||||
|
>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||||
@@ -103,7 +105,8 @@
|
|||||||
<el-button
|
<el-button
|
||||||
icon="Delete"
|
icon="Delete"
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
|
v-auth="'purchase_purchasingSchoolLeader_del'"
|
||||||
@click="handleDelete(scope.row)">
|
@click="handleDelete(scope.row)">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ const uploadRef = ref<{ clearFiles?: () => void }>()
|
|||||||
const titleMap: Record<string, string> = {
|
const titleMap: Record<string, string> = {
|
||||||
R10001: '计划专业导入',
|
R10001: '计划专业导入',
|
||||||
R10002: '地区分数导入',
|
R10002: '地区分数导入',
|
||||||
R10003: '中招平台数据导入'
|
R10003: '中招平台数据导入',
|
||||||
|
R10004: '学校维护导入',
|
||||||
}
|
}
|
||||||
// 方法
|
// 方法
|
||||||
const init = (type: any) => {
|
const init = (type: any) => {
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ const remoteTeacherByQuery = (query: string) => {
|
|||||||
serialNumberList.value = []
|
serialNumberList.value = []
|
||||||
if (query !== '') {
|
if (query !== '') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getList({ groupId: dataForm.groupId, name: query }).then((response: any) => {
|
getList({ groupId: dataForm.groupId, serialNumber: query }).then((response: any) => {
|
||||||
serialNumberList.value = response.data
|
serialNumberList.value = response.data
|
||||||
})
|
})
|
||||||
}, 200)
|
}, 200)
|
||||||
|
|||||||
@@ -85,7 +85,8 @@
|
|||||||
type="warning"
|
type="warning"
|
||||||
link
|
link
|
||||||
icon="Download"
|
icon="Download"
|
||||||
@click="handleExport(scope.row.batchCode, scope.row.groupId)"
|
:loading="btnLoading"
|
||||||
|
@click="handleExport(scope.row)"
|
||||||
>
|
>
|
||||||
导出模拟结果
|
导出模拟结果
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -132,6 +133,7 @@ import { BasicTableProps, useTable } from '/@/hooks/table'
|
|||||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import { delObj, fetchList } from '/@/api/recruit/recruitImitateAdjustBatch'
|
import { delObj, fetchList } from '/@/api/recruit/recruitImitateAdjustBatch'
|
||||||
|
import {exportAdjustExcel} from "/@/api/recruit/recruitfile"
|
||||||
|
|
||||||
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
||||||
const MnTable = defineAsyncComponent(() => import('./mnTable.vue'))
|
const MnTable = defineAsyncComponent(() => import('./mnTable.vue'))
|
||||||
@@ -204,17 +206,14 @@ const showTable = (batchNo: string, groupId: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const btnLoading=ref(false)
|
||||||
// 导出模拟结果
|
// 导出模拟结果
|
||||||
const handleExport = async (code: string, gid: string) => {
|
const handleExport = async (data:any) => {
|
||||||
try {
|
btnLoading.value=true
|
||||||
await downBlobFile(
|
exportAdjustExcel(data).then((res:any)=>{
|
||||||
'/recruit/recruitImitateAdjustBatch/exportExcel',
|
messageBox.success('导出后台执行中,请稍后查看下载任务')
|
||||||
{ batchNo: code, groupId: gid },
|
btnLoading.value=false
|
||||||
'招生模拟统计.xls'
|
})
|
||||||
)
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.msg || '导出失败')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
title="模拟列表"
|
title="模拟列表"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
width="80%"
|
width="98%"
|
||||||
>
|
>
|
||||||
<el-form :inline="true">
|
<el-form :inline="true">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -109,6 +109,7 @@
|
|||||||
<el-table-column
|
<el-table-column
|
||||||
header-align="center"
|
header-align="center"
|
||||||
align="center"
|
align="center"
|
||||||
|
min-width="200"
|
||||||
label="操作">
|
label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button v-if="hasAuth('recruit_recruitImitateAdjustBatch_edit')" type="text" size="small" :icon="Edit" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
|
<el-button v-if="hasAuth('recruit_recruitImitateAdjustBatch_edit')" type="text" size="small" :icon="Edit" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
|
||||||
|
|||||||
243
src/views/recruit/recruitPolicyFile/form.vue
Normal file
243
src/views/recruit/recruitPolicyFile/form.vue
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :title="form.id ? '编辑' : '新增'" v-model="visible"
|
||||||
|
:close-on-click-modal="false" draggable>
|
||||||
|
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
||||||
|
<el-row :gutter="24">
|
||||||
|
<el-col :span="24" class="mb20">
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="form.title" placeholder="请输入标题"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24" class="mb20">
|
||||||
|
<el-form-item label="文件地址" prop="fileUrl">
|
||||||
|
|
||||||
|
<el-upload
|
||||||
|
:headers="headers"
|
||||||
|
:limit="1"
|
||||||
|
:action="uploadUrl"
|
||||||
|
:file-list="fileList"
|
||||||
|
:on-success="handleUploadSuccess"
|
||||||
|
:accept="'.pdf'"
|
||||||
|
>
|
||||||
|
<el-button size="small" type="primary">点击上传</el-button>
|
||||||
|
<template #tip>
|
||||||
|
<div style="margin-top: 8px;">
|
||||||
|
<el-tag>仅支持pdf后缀的文件上传</el-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<!-- <el-upload-->
|
||||||
|
<!-- :action="uploadUrl"-->
|
||||||
|
<!-- class="avatar-uploader"-->
|
||||||
|
<!-- name="file"-->
|
||||||
|
<!-- :headers="headers"-->
|
||||||
|
<!-- :data="uploadData"-->
|
||||||
|
<!-- :file-list="fileList"-->
|
||||||
|
<!-- :before-upload="beforeUpload"-->
|
||||||
|
<!-- :http-request="httpRequest"-->
|
||||||
|
<!-- :limit="1"-->
|
||||||
|
<!-- :accept="['.jpg,.jpeg,.png,.pdf']"-->
|
||||||
|
<!-- :on-success="handleUploadSuccess">-->
|
||||||
|
<!-- <el-button size="small" type="primary">点击上传</el-button>-->
|
||||||
|
<!-- <template #tip>-->
|
||||||
|
<!-- <div style="margin-top: 8px;">-->
|
||||||
|
<!-- <el-tag>仅支持jpg,jpeg,png,pdf后缀的文件上传</el-tag>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </el-upload>-->
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- <el-col :span="12" class="mb20">-->
|
||||||
|
<!-- <el-form-item label="1 资助政策文件" prop="type">-->
|
||||||
|
<!-- <el-input v-model="form.type" placeholder="请输入1 资助政策文件"/>-->
|
||||||
|
<!-- </el-form-item>-->
|
||||||
|
<!-- </el-col>-->
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onSubmit" :disabled="loading">确 认</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="RecruitPolicyFileDialog">
|
||||||
|
// ========== 1. 导入语句 ==========
|
||||||
|
import { useMessage } from "/@/hooks/message";
|
||||||
|
import { getObj, addObj, putObj } from '/@/api/recruit/recruitPolicyFile';
|
||||||
|
import {Plus} from "@element-plus/icons-vue";
|
||||||
|
import {reactive, ref} from "vue";
|
||||||
|
import axios from "axios";
|
||||||
|
import { Session } from '/@/utils/storage'
|
||||||
|
const fileList = ref<any[]>([])
|
||||||
|
|
||||||
|
// ========== 2. 组件定义 ==========
|
||||||
|
// 定义组件事件
|
||||||
|
const emit = defineEmits(['refresh']);
|
||||||
|
|
||||||
|
// ========== 3. 响应式数据定义 ==========
|
||||||
|
// 基础响应式变量
|
||||||
|
const dataFormRef = ref(); // 表单引用
|
||||||
|
const visible = ref(false); // 弹窗显示状态
|
||||||
|
const loading = ref(false); // 加载状态
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL
|
||||||
|
|
||||||
|
// 表单数据对象
|
||||||
|
const form = reactive({
|
||||||
|
id: '', // 主键
|
||||||
|
fileUrl: '', // 文件地址
|
||||||
|
title: '', // 标题
|
||||||
|
type: '', // 1 资助政策文件
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadUrl = baseUrl + '/recruit/file/uploadPdf'
|
||||||
|
// 请求头
|
||||||
|
const headers = computed(() => {
|
||||||
|
return {
|
||||||
|
"Authorization": 'Bearer ' + Session.getToken()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const uploadData = reactive({})
|
||||||
|
const fileReader = ref<FileReader | null>(null)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 上传前验证
|
||||||
|
const beforeUpload = (file: File) => {
|
||||||
|
const isLt5M = file.size < 10 * 1024 * 1024
|
||||||
|
if (!isLt5M) {
|
||||||
|
useMessage().error('文件大小不能超过10M')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// 通用上传成功回调(单文件 - avatar模式)
|
||||||
|
const handleUploadSuccess = (res:any) => {
|
||||||
|
const fileUrl = res.fileUrl
|
||||||
|
form['fileUrl'] = fileUrl
|
||||||
|
}
|
||||||
|
// ========== 4. 字典数据处理 ==========
|
||||||
|
|
||||||
|
// ========== 5. 表单校验规则 ==========
|
||||||
|
const dataRules = ref({
|
||||||
|
title: [
|
||||||
|
{ required: true, message: '请输入标题', trigger: 'blur' },
|
||||||
|
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
fileUrl: [
|
||||||
|
{ required: true, message: '请上传文件', trigger: 'blur' },
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// ========== 6. 方法定义 ==========
|
||||||
|
// 获取详情数据
|
||||||
|
const getRecruitPolicyFileData = async (id: string) => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const { data } = await getObj({ id: id });
|
||||||
|
// 直接将第一条数据赋值给表单
|
||||||
|
Object.assign(form, data[0]);
|
||||||
|
} catch (error) {
|
||||||
|
useMessage().error('获取数据失败');
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 打开弹窗方法
|
||||||
|
const openDialog = (id: string) => {
|
||||||
|
visible.value = true;
|
||||||
|
form.id = '';
|
||||||
|
|
||||||
|
// 重置表单数据
|
||||||
|
nextTick(() => {
|
||||||
|
dataFormRef.value?.resetFields();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取RecruitPolicyFile信息
|
||||||
|
if (id) {
|
||||||
|
form.id = id;
|
||||||
|
getRecruitPolicyFileData(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交表单方法
|
||||||
|
const onSubmit = async () => {
|
||||||
|
loading.value = true; // 防止重复提交
|
||||||
|
|
||||||
|
// 表单校验
|
||||||
|
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||||
|
if (!valid) {
|
||||||
|
loading.value = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 根据是否有ID判断是新增还是修改
|
||||||
|
form.id ? await putObj(form) : await addObj(form);
|
||||||
|
useMessage().success(form.id ? '修改成功' : '添加成功');
|
||||||
|
visible.value = false;
|
||||||
|
emit('refresh'); // 通知父组件刷新列表
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 初始化 FileReader
|
||||||
|
onMounted(() => {
|
||||||
|
if (!window.FileReader) {
|
||||||
|
useMessage().error('您的浏览器不支持 FileReader API!')
|
||||||
|
} else {
|
||||||
|
fileReader.value = new FileReader()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// ========== 7. 对外暴露 ==========
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
openDialog
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
//.avatar-uploader {
|
||||||
|
// :deep(.el-upload) {
|
||||||
|
// border: 1px dashed var(--el-border-color);
|
||||||
|
// border-radius: 6px;
|
||||||
|
// cursor: pointer;
|
||||||
|
// position: relative;
|
||||||
|
// overflow: hidden;
|
||||||
|
// transition: var(--el-transition-duration-fast);
|
||||||
|
// width: 148px;
|
||||||
|
// height: 148px;
|
||||||
|
// &:hover {
|
||||||
|
// border-color: var(--el-color-primary);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//.avatar-uploader-icon {
|
||||||
|
// font-size: 28px;
|
||||||
|
// color: #8c939d;
|
||||||
|
// width: 148px;
|
||||||
|
// height: 148px;
|
||||||
|
// line-height: 148px;
|
||||||
|
// text-align: center;
|
||||||
|
//}
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
width: 148px;
|
||||||
|
height: 148px;
|
||||||
|
.avatar {
|
||||||
|
width: 148px;
|
||||||
|
height: 148px;
|
||||||
|
display: block;
|
||||||
|
object-fit: cover;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
232
src/views/recruit/recruitPolicyFile/index.vue
Normal file
232
src/views/recruit/recruitPolicyFile/index.vue
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
<template>
|
||||||
|
<div class="layout-padding">
|
||||||
|
<div class="layout-padding-auto layout-padding-view">
|
||||||
|
|
||||||
|
<!-- 操作按钮区域 -->
|
||||||
|
<el-row>
|
||||||
|
<div class="mb8" style="width: 100%">
|
||||||
|
<el-button
|
||||||
|
icon="folder-add"
|
||||||
|
type="primary"
|
||||||
|
class="ml10"
|
||||||
|
@click="formDialogRef.openDialog()"
|
||||||
|
v-auth="'recruit_recruitPolicyFile_add'"
|
||||||
|
>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
plain
|
||||||
|
:disabled="multiple"
|
||||||
|
icon="Delete"
|
||||||
|
type="primary"
|
||||||
|
v-auth="'recruit_recruitPolicyFile_del'"
|
||||||
|
@click="handleDelete(selectObjs)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
<right-toolbar
|
||||||
|
v-model:showSearch="showSearch"
|
||||||
|
:export="'recruit_recruitPolicyFile_export'"
|
||||||
|
@exportExcel="exportExcel"
|
||||||
|
class="ml10 mr20"
|
||||||
|
style="float: right;"
|
||||||
|
@queryTable="getDataList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 数据表格区域 -->
|
||||||
|
<el-table
|
||||||
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
border
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
|
@selection-change="selectionChangHandle"
|
||||||
|
@sort-change="sortChangeHandle"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="40" align="center" />
|
||||||
|
<el-table-column type="index" label="#" width="40" />
|
||||||
|
<el-table-column
|
||||||
|
prop="fileUrl"
|
||||||
|
label="文件"
|
||||||
|
show-overflow-tooltip
|
||||||
|
>
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
icon="Document"
|
||||||
|
@click="handlePreview(scope.row.fileUrl)"
|
||||||
|
>查看
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
prop="title"
|
||||||
|
label="标题"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<!-- <el-table-column -->
|
||||||
|
<!-- prop="type" -->
|
||||||
|
<!-- label="1 资助政策文件" -->
|
||||||
|
<!-- show-overflow-tooltip-->
|
||||||
|
<!-- />-->
|
||||||
|
<el-table-column label="操作" width="150">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
icon="edit-pen"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'recruit_recruitPolicyFile_edit'"
|
||||||
|
@click="formDialogRef.openDialog(scope.row.id)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
icon="delete"
|
||||||
|
text
|
||||||
|
type="primary"
|
||||||
|
v-auth="'recruit_recruitPolicyFile_del'"
|
||||||
|
@click="handleDelete([scope.row.id])"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination
|
||||||
|
@size-change="sizeChangeHandle"
|
||||||
|
@current-change="currentChangeHandle"
|
||||||
|
v-bind="state.pagination"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 编辑、新增弹窗 -->
|
||||||
|
<form-dialog ref="formDialogRef" @refresh="getDataList(false)" />
|
||||||
|
|
||||||
|
<!-- 导入excel弹窗 (需要在 upms-biz/resources/file 下维护模板) -->
|
||||||
|
<upload-excel
|
||||||
|
ref="excelUploadRef"
|
||||||
|
title="导入"
|
||||||
|
url="/recruit/recruitPolicyFile/import"
|
||||||
|
temp-url="/admin/sys-file/local/file/recruitPolicyFile.xlsx"
|
||||||
|
@refreshDataList="getDataList"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<preview-file v-for="src in imgUrl" :key="src.title" :authSrc="src.url" dialog-title="职称材料" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="systemRecruitPolicyFile">
|
||||||
|
// ========== 导入声明 ==========
|
||||||
|
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||||
|
import { fetchList, delObjs } from "/@/api/recruit/recruitPolicyFile";
|
||||||
|
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||||
|
import { useDict } from '/@/hooks/dict';
|
||||||
|
import {defineAsyncComponent, ref} from "vue";
|
||||||
|
const previewFile = defineAsyncComponent(() => import('/@/components/tools/preview-file.vue'));
|
||||||
|
|
||||||
|
// ========== 组件声明 ==========
|
||||||
|
// 异步加载表单弹窗组件
|
||||||
|
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||||
|
const baseUrl = import.meta.env.VITE_API_URL
|
||||||
|
|
||||||
|
// ========== 字典数据 ==========
|
||||||
|
|
||||||
|
// ========== 组件引用 ==========
|
||||||
|
const formDialogRef = ref(); // 表单弹窗引用
|
||||||
|
const excelUploadRef = ref(); // Excel上传弹窗引用
|
||||||
|
const queryRef = ref(); // 查询表单引用
|
||||||
|
|
||||||
|
// ========== 响应式数据 ==========
|
||||||
|
const showSearch = ref(true); // 是否显示搜索区域
|
||||||
|
const selectObjs = ref([]) as any; // 表格多选数据
|
||||||
|
const multiple = ref(true); // 是否多选
|
||||||
|
|
||||||
|
// ========== 表格状态 ==========
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
queryForm: {}, // 查询参数
|
||||||
|
pageList: fetchList // 分页查询方法
|
||||||
|
});
|
||||||
|
const imgUrl = ref<Array<{ title: string; url: string }>>([]);
|
||||||
|
|
||||||
|
// ========== Hook引用 ==========
|
||||||
|
// 表格相关Hook
|
||||||
|
const {
|
||||||
|
getDataList,
|
||||||
|
currentChangeHandle,
|
||||||
|
sizeChangeHandle,
|
||||||
|
sortChangeHandle,
|
||||||
|
downBlobFile,
|
||||||
|
tableStyle
|
||||||
|
} = useTable(state);
|
||||||
|
|
||||||
|
// ========== 方法定义 ==========
|
||||||
|
/**
|
||||||
|
* 重置查询条件
|
||||||
|
*/
|
||||||
|
const resetQuery = () => {
|
||||||
|
// 清空搜索条件
|
||||||
|
queryRef.value?.resetFields();
|
||||||
|
// 清空多选
|
||||||
|
selectObjs.value = [];
|
||||||
|
// 重新查询
|
||||||
|
getDataList();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出Excel文件
|
||||||
|
*/
|
||||||
|
const exportExcel = () => {
|
||||||
|
downBlobFile(
|
||||||
|
'/recruit/recruitPolicyFile/export',
|
||||||
|
Object.assign(state.queryForm, { ids: selectObjs }),
|
||||||
|
'recruitPolicyFile.xlsx'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格多选事件处理
|
||||||
|
* @param objs 选中的数据行
|
||||||
|
*/
|
||||||
|
const selectionChangHandle = (objs: { id: string }[]) => {
|
||||||
|
selectObjs.value = objs.map(({ id }) => id);
|
||||||
|
multiple.value = !objs.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 预览材料
|
||||||
|
const handlePreview = (url: string) => {
|
||||||
|
imgUrl.value = [];
|
||||||
|
nextTick(() => {
|
||||||
|
imgUrl.value.push({
|
||||||
|
title: '',
|
||||||
|
url: baseUrl+url,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除数据处理
|
||||||
|
* @param ids 要删除的数据ID数组
|
||||||
|
*/
|
||||||
|
const handleDelete = async (ids: string[]) => {
|
||||||
|
try {
|
||||||
|
await useMessageBox().confirm('此操作将永久删除');
|
||||||
|
} catch {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await delObjs(ids);
|
||||||
|
getDataList();
|
||||||
|
useMessage().success('删除成功');
|
||||||
|
} catch (err: any) {
|
||||||
|
useMessage().error(err.msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
129
src/views/recruit/recruitPreexamPeople/add-form.vue
Normal file
129
src/views/recruit/recruitPreexamPeople/add-form.vue
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<!--
|
||||||
|
- 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.
|
||||||
|
-
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-dialog v-model="dialogVisible" title="保存审核人员" width="600px" append-to-body @close="handleClose">
|
||||||
|
<el-form :model="{ belongTeacherNos }" label-width="100px">
|
||||||
|
<el-form-item label="选择教师:">
|
||||||
|
<el-select
|
||||||
|
v-model="belongTeacherNos"
|
||||||
|
filterable
|
||||||
|
remote
|
||||||
|
clearable
|
||||||
|
reserve-keyword
|
||||||
|
placeholder="请选择或输入教师姓名"
|
||||||
|
:remote-method="remoteTeacherByQuery"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in teacherList"
|
||||||
|
:key="item.teacherNo"
|
||||||
|
:label="item.realName"
|
||||||
|
:value="item.teacherNo"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="AddExamPeopleForm">
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import {getTeacherInfoCommon} from '/@/api/professional/professionaluser/teacherbase'
|
||||||
|
|
||||||
|
// Props
|
||||||
|
const props = defineProps<{
|
||||||
|
visible: boolean
|
||||||
|
timeRange: string[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// Emits
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(e: 'update:visible', value: boolean): void
|
||||||
|
(e: 'save', data: { teacherNo: string; startTime: string; endTime: string }): void
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 弹窗显示状态
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const belongTeacherNos = ref('')
|
||||||
|
const teacherList = ref<any[]>([])
|
||||||
|
|
||||||
|
// 监听 visible 变化
|
||||||
|
watch(() => props.visible, (newVal) => {
|
||||||
|
dialogVisible.value = newVal
|
||||||
|
if (newVal) {
|
||||||
|
belongTeacherNos.value = ''
|
||||||
|
teacherList.value = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听 dialogVisible 变化,同步到父组件
|
||||||
|
watch(dialogVisible, (newVal) => {
|
||||||
|
emit('update:visible', newVal)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检索教师
|
||||||
|
const remoteTeacherByQuery = (query: string) => {
|
||||||
|
teacherList.value = []
|
||||||
|
if (query !== '') {
|
||||||
|
setTimeout(() => {
|
||||||
|
getTeacherInfoCommon({searchKeywords:query,tied:"0"}).then(response => {
|
||||||
|
teacherList.value = response.data
|
||||||
|
})
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭窗口
|
||||||
|
const handleClose = () => {
|
||||||
|
belongTeacherNos.value = ''
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存
|
||||||
|
const handleSave = () => {
|
||||||
|
if (props.timeRange.length === 0) {
|
||||||
|
emit('save', {
|
||||||
|
teacherNo: belongTeacherNos.value,
|
||||||
|
startTime: '',
|
||||||
|
endTime: ''
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
emit('save', {
|
||||||
|
teacherNo: belongTeacherNos.value,
|
||||||
|
startTime: props.timeRange[0],
|
||||||
|
endTime: props.timeRange[1]
|
||||||
|
})
|
||||||
|
handleClose()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.dialog-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
225
src/views/recruit/recruitPreexamPeople/index.vue
Normal file
225
src/views/recruit/recruitPreexamPeople/index.vue
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
<!--
|
||||||
|
- 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.
|
||||||
|
-
|
||||||
|
-->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-dialog
|
||||||
|
title="招生审核人员管理"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
v-model="visible"
|
||||||
|
width="800"
|
||||||
|
:append-to-body="true"
|
||||||
|
destroy-on-close
|
||||||
|
>
|
||||||
|
<div class="dialog-content">
|
||||||
|
<!-- 时间选择器和操作按钮 -->
|
||||||
|
<el-form :inline="true" :model="queryForm">
|
||||||
|
<el-form-item label="审核时间范围:">
|
||||||
|
<el-time-picker
|
||||||
|
is-range
|
||||||
|
v-model="form.time1"
|
||||||
|
format="HH:mm:ss"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
range-separator="至"
|
||||||
|
start-placeholder="开始时间"
|
||||||
|
end-placeholder="结束时间"
|
||||||
|
placeholder="选择时间范围"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="mb15" v-if="hasAuth('recruit_recruitexampeople_add')">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="FolderAdd"
|
||||||
|
@click="handleAdd"
|
||||||
|
>
|
||||||
|
新 增
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 表格 -->
|
||||||
|
<div class="table-wrapper">
|
||||||
|
<el-table
|
||||||
|
ref="tableRef"
|
||||||
|
:data="state.dataList || []"
|
||||||
|
v-loading="state.loading"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle"
|
||||||
|
empty-text="暂无数据"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||||
|
<el-table-column label="工号" align="center" prop="teacherNo" show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="姓名" align="center" prop="teacherName" show-overflow-tooltip>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" width="150px" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
v-if="hasAuth('recruit_recruitexampeople_del')"
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
icon="Delete"
|
||||||
|
@click="handleDel(scope.row)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<pagination
|
||||||
|
v-bind="state.pagination"
|
||||||
|
@current-change="currentChangeHandle"
|
||||||
|
@size-change="sizeChangeHandle"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 保存审核人员弹窗 -->
|
||||||
|
<add-form
|
||||||
|
v-model:visible="setTeachNoFormVisible"
|
||||||
|
:time-range="form.time1"
|
||||||
|
@save="handleSave"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts" name="recruitexampeople">
|
||||||
|
import { ref, reactive, nextTick, defineAsyncComponent } from 'vue'
|
||||||
|
import { useAuth } from '/@/hooks/auth'
|
||||||
|
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||||
|
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||||
|
import { addObj, delObj, fetchList } from '/@/api/recruit/recruitPreexamPeople'
|
||||||
|
|
||||||
|
const AddForm = defineAsyncComponent(() => import('./add-form.vue'))
|
||||||
|
const { hasAuth } = useAuth()
|
||||||
|
// 消息提示 hooks
|
||||||
|
const message = useMessage()
|
||||||
|
const messageBox = useMessageBox()
|
||||||
|
|
||||||
|
// 表格引用
|
||||||
|
const tableRef = ref()
|
||||||
|
|
||||||
|
// 弹窗状态
|
||||||
|
const visible = ref(false)
|
||||||
|
const setTeachNoFormVisible = ref(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const form = reactive({
|
||||||
|
time1: [] as string[]
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询表单
|
||||||
|
const queryForm = reactive<Record<string, any>>({})
|
||||||
|
|
||||||
|
// 表格状态
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
queryForm: queryForm,
|
||||||
|
pageList: async (params: any) => {
|
||||||
|
const response = await fetchList(params)
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
records: response.data.records || [],
|
||||||
|
total: response.data.total || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createdIsNeed: false, // 弹窗组件,不在挂载时自动加载数据
|
||||||
|
dataList: [], // 确保 dataList 初始化为空数组
|
||||||
|
loading: false, // 确保 loading 初始化为 false
|
||||||
|
onLoaded: async (state: any) => {
|
||||||
|
// 如果有数据,设置时间范围
|
||||||
|
if (state.dataList && state.dataList.length > 0) {
|
||||||
|
form.time1 = [state.dataList[0].startTime, state.dataList[0].endTime]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 使用 table hook
|
||||||
|
// 注意:useTable 会直接修改传入的 state 对象,所以不需要从返回值中获取 state
|
||||||
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
const init = () => {
|
||||||
|
visible.value = true
|
||||||
|
form.time1 = []
|
||||||
|
// 等待弹窗显示后再加载数据
|
||||||
|
nextTick(() => {
|
||||||
|
getDataList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
const handleAdd = () => {
|
||||||
|
setTeachNoFormVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存审核人员
|
||||||
|
const handleSave = async (data: { teacherNo: string; startTime: string; endTime: string }) => {
|
||||||
|
if (form.time1.length === 0) {
|
||||||
|
message.error('审核时间不能为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await addObj({
|
||||||
|
teacherNo: data.teacherNo,
|
||||||
|
startTime: data.startTime,
|
||||||
|
endTime: data.endTime
|
||||||
|
})
|
||||||
|
message.success('添加成功')
|
||||||
|
getDataList()
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error(error.msg || '添加失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const handleDel = async (row: any) => {
|
||||||
|
try {
|
||||||
|
await messageBox.confirm(`是否确认删除工号为${row.teacherNo}的记录?`)
|
||||||
|
await delObj(row.id)
|
||||||
|
message.success('删除成功')
|
||||||
|
getDataList()
|
||||||
|
} catch {
|
||||||
|
// 用户取消
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置查询
|
||||||
|
const resetQuery = () => {
|
||||||
|
Object.keys(queryForm).forEach(key => {
|
||||||
|
queryForm[key] = ''
|
||||||
|
})
|
||||||
|
getDataList()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法
|
||||||
|
defineExpose({
|
||||||
|
init
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
@@ -79,6 +79,15 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="majorCode" label="专业序号" align="center" show-overflow-tooltip />
|
<el-table-column prop="majorCode" label="专业序号" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="majorName" label="专业名称" align="center" show-overflow-tooltip />
|
<el-table-column prop="majorName" label="专业名称" align="center" show-overflow-tooltip />
|
||||||
|
<el-table-column prop="majorName" label="规范专业名称" align="center" show-overflow-tooltip >
|
||||||
|
<template #default="scope">
|
||||||
|
<span v-if="scope.row.standardMajorName">
|
||||||
|
{{ scope.row.standardMajorName+"-"+scope.row.standardMajorTwoName }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip>
|
<el-table-column prop="deptCode" label="学院" align="center" show-overflow-tooltip>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ getDeptName(scope.row.deptCode) }}
|
{{ getDeptName(scope.row.deptCode) }}
|
||||||
|
|||||||
@@ -92,7 +92,8 @@
|
|||||||
>
|
>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
|
v-auth="'pre_stu_success_export'"
|
||||||
type="warning"
|
type="warning"
|
||||||
plain
|
plain
|
||||||
icon="Download"
|
icon="Download"
|
||||||
@@ -102,6 +103,10 @@
|
|||||||
>
|
>
|
||||||
导出
|
导出
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|
||||||
|
<el-button v-if="hasAuth('recruit_preexamPeople_add')" type="primary" plain icon="UserFilled" class="ml10" @click="editExam">
|
||||||
|
审核人员管理
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
@@ -191,6 +196,8 @@
|
|||||||
:planMajorList="planMajorList"
|
:planMajorList="planMajorList"
|
||||||
:schoolList="schoolList"
|
:schoolList="schoolList"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<pre-exam-people-index ref="PreExamPeopleIndexRef"></pre-exam-people-index>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -207,7 +214,11 @@ import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
|||||||
import { listcz } from '/@/api/recruit/recruitstudentplan'
|
import { listcz } from '/@/api/recruit/recruitstudentplan'
|
||||||
import { queryByGroupId as schoolListApi} from '/@/api/recruit/recruitstudentschool'
|
import { queryByGroupId as schoolListApi} from '/@/api/recruit/recruitstudentschool'
|
||||||
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept'
|
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept'
|
||||||
|
import {exportPreStuSuccess} from '/@/api/recruit/recruitfile'
|
||||||
|
|
||||||
|
const PreExamPeopleIndex = defineAsyncComponent(() => import('@/views/recruit/recruitPreexamPeople/index.vue'));
|
||||||
|
|
||||||
|
const PreExamPeopleIndexRef=ref()
|
||||||
const TableForm = defineAsyncComponent(() => import('./enrolplantemplate-form.vue'))
|
const TableForm = defineAsyncComponent(() => import('./enrolplantemplate-form.vue'))
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth()
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
@@ -366,20 +377,30 @@ const resetQuery = () => {
|
|||||||
|
|
||||||
// 导出
|
// 导出
|
||||||
const dataExportHandle = async () => {
|
const dataExportHandle = async () => {
|
||||||
try {
|
exportLoading.value = true
|
||||||
exportLoading.value = true
|
exportPreStuSuccess(queryForm).then((res:any)=>{
|
||||||
await downBlobFile(
|
message.success('导出后台执行中,请稍后查看下载任务')
|
||||||
'/recruit/recruitprestudent/export',
|
|
||||||
queryForm,
|
|
||||||
'预登记导出.xls'
|
|
||||||
)
|
|
||||||
} catch (error: any) {
|
|
||||||
message.error(error.msg || '导出失败')
|
|
||||||
} finally {
|
|
||||||
exportLoading.value = false
|
exportLoading.value = false
|
||||||
}
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 编辑审核人员
|
||||||
|
const editExam = () => {
|
||||||
|
// 如果组件已经加载,立即初始化
|
||||||
|
if (PreExamPeopleIndexRef.value && typeof PreExamPeopleIndexRef.value.init === 'function') {
|
||||||
|
nextTick(() => {
|
||||||
|
try {
|
||||||
|
PreExamPeopleIndexRef.value.init();
|
||||||
|
} catch (error: any) {
|
||||||
|
message.error('初始化预登记人员弹窗失败:' + (error.message || '未知错误'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 否则等待 watch 监听器处理
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init()
|
init()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -42,13 +42,29 @@
|
|||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<div class="mb15">
|
<div class="mb15">
|
||||||
<el-button
|
<el-button
|
||||||
v-if="hasAuth('recruit_recruitstudentplangroup_add')"
|
v-if="hasAuth('recruit_recruitstudentschool_add')"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="FolderAdd"
|
icon="FolderAdd"
|
||||||
@click="addOrUpdateHandle"
|
@click="addOrUpdateHandle"
|
||||||
>
|
>
|
||||||
新 增
|
新 增
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-auth="'recruit_studentschool_import'"
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="UploadFilled"
|
||||||
|
@click="handleImportDialog"
|
||||||
|
>导入信息
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-if="hasAuth('recruit_schoolhistory_view')"
|
||||||
|
type="plain"
|
||||||
|
icon="View"
|
||||||
|
@click="handleShowHistory"
|
||||||
|
>
|
||||||
|
变更历史
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
@@ -109,6 +125,11 @@
|
|||||||
<!-- 弹窗, 新增 / 修改 -->
|
<!-- 弹窗, 新增 / 修改 -->
|
||||||
<table-form ref="addOrUpdateRef" @refreshDataList="getDataList" />
|
<table-form ref="addOrUpdateRef" @refreshDataList="getDataList" />
|
||||||
<major-group-by-dept-form v-if="majorGroupByDeptVisible" ref="majorGroupByDeptRef" />
|
<major-group-by-dept-form v-if="majorGroupByDeptVisible" ref="majorGroupByDeptRef" />
|
||||||
|
|
||||||
|
<school-history ref="SchoolHistoryRef"></school-history>
|
||||||
|
|
||||||
|
<import-recruit-info ref="ImportRecruitInfoRef" @refreshDataList="getDataList"></import-recruit-info>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -124,11 +145,16 @@ import { getDeptList } from '/@/api/basic/basicclass'
|
|||||||
|
|
||||||
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
const TableForm = defineAsyncComponent(() => import('./detaiform.vue'))
|
||||||
const MajorGroupByDeptForm = defineAsyncComponent(() => import('/@/views/recruit/recruitplanmajor/majorGroupByDept.vue'))
|
const MajorGroupByDeptForm = defineAsyncComponent(() => import('/@/views/recruit/recruitplanmajor/majorGroupByDept.vue'))
|
||||||
|
const ImportRecruitInfo = defineAsyncComponent(() => import('/@/views/recruit/common/import-recruit-info.vue'));
|
||||||
|
const SchoolHistory = defineAsyncComponent(() => import('/@/views/recruit/recruitstudentschool/school-history.vue'))
|
||||||
|
|
||||||
const { hasAuth } = useAuth()
|
const { hasAuth } = useAuth()
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const messageBox = useMessageBox()
|
const messageBox = useMessageBox()
|
||||||
|
const ImportRecruitInfoRef=ref<any>();
|
||||||
|
|
||||||
|
const SchoolHistoryRef=ref()
|
||||||
// 表格引用
|
// 表格引用
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
@@ -236,6 +262,14 @@ const resetQuery = () => {
|
|||||||
getDataList()
|
getDataList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleShowHistory=()=>{
|
||||||
|
SchoolHistoryRef.value?.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleImportDialog = () => {
|
||||||
|
ImportRecruitInfoRef.value?.init("R10004");
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init()
|
init()
|
||||||
})
|
})
|
||||||
|
|||||||
63
src/views/recruit/recruitstudentschool/school-history.vue
Normal file
63
src/views/recruit/recruitstudentschool/school-history.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="visible" width="80%" title="学校变更历史">
|
||||||
|
<el-table ref="tableRef"
|
||||||
|
:data="state.dataList"
|
||||||
|
v-loading="state.loading"
|
||||||
|
border
|
||||||
|
stripe
|
||||||
|
row-key="id"
|
||||||
|
:cell-style="tableStyle.cellStyle"
|
||||||
|
:header-cell-style="tableStyle.headerCellStyle">
|
||||||
|
<el-table-column label="学校代码" prop="schoolCode"></el-table-column>
|
||||||
|
<el-table-column label="旧名称" prop="oldName"></el-table-column>
|
||||||
|
<el-table-column label="新名称" prop="newName"></el-table-column>
|
||||||
|
<el-table-column label="变动时间" prop="createTime"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-bind="state.pagination"
|
||||||
|
@current-change="currentChangeHandle"
|
||||||
|
@size-change="sizeChangeHandle"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {useTable,BasicTableProps} from "/@/hooks/table";
|
||||||
|
import {fetchList} from "/@/api/recruit/recruitSchoolHistory";
|
||||||
|
|
||||||
|
// 表格状态
|
||||||
|
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||||
|
queryForm: {},
|
||||||
|
createdIsNeed: false,
|
||||||
|
pageList: async (params: any) => {
|
||||||
|
const response = await fetchList(params)
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
records: response.data.records,
|
||||||
|
total: response.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createdIsNeed: false
|
||||||
|
})
|
||||||
|
const visible = ref(false)
|
||||||
|
|
||||||
|
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||||
|
|
||||||
|
|
||||||
|
const init=()=>{
|
||||||
|
visible.value = true
|
||||||
|
getDataList()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
init
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mod-config">
|
<div >
|
||||||
<basic-container>
|
|
||||||
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
||||||
<el-form-item label="招生计划" prop="groupId">
|
<el-form-item label="招生计划" prop="groupId">
|
||||||
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划" size="small">
|
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划" >
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in planList"
|
v-for="item in planList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -14,10 +13,10 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="Search" type="primary" size="small"
|
<el-button icon="Search" type="primary"
|
||||||
@click="handleFilter">查询
|
@click="handleFilter">查询
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Delete" type="default" plain size="small"
|
<el-button icon="Delete" type="default" plain
|
||||||
@click="resetForm">清空
|
@click="resetForm">清空
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -27,27 +26,24 @@
|
|||||||
<el-button icon="Download" type="warning" size="small" @click="dataExportHandle">导出</el-button>
|
<el-button icon="Download" type="warning" size="small" @click="dataExportHandle">导出</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="avue-crud">
|
|
||||||
<el-table :data="dataList" border stripe v-loading="dataListLoading"
|
<el-table :data="dataList" border stripe v-loading="dataListLoading"
|
||||||
:summary-method="getSummaries" show-summary
|
:summary-method="getSummaries" show-summary height="700"
|
||||||
>
|
>
|
||||||
<el-table-column align="center" header-align="center" prop="provinceName" label="省市" />
|
<el-table-column align="center" header-align="center" prop="provinceName" label="省市" />
|
||||||
<el-table-column align="center" header-align="center" prop="peopleNum" label="人数" />
|
<el-table-column align="center" header-align="center" prop="peopleNum" label="人数" />
|
||||||
<el-table-column align="center" header-align="center" prop="peopleRate" label="占比" />
|
<el-table-column align="center" header-align="center" prop="peopleRate" label="占比" />
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<chart ref="typeEchartBarRef" style="width:100%;margin-top:80px" :options="chartOption" theme="macarons"></chart>
|
<!-- <chart ref="typeEchartBarRef" style="width:100%;margin-top:80px" :options="chartOption" theme="macarons"></chart>-->
|
||||||
|
|
||||||
</div>
|
|
||||||
</basic-container>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { getAreaStatic } from "@/api/recruit/recruitstudentsignup"
|
import { getAreaStatic } from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getList } from "@/api/recruit/recruitstudentplangroup"
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
|
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const dataForm = reactive({
|
const dataForm = reactive({
|
||||||
@@ -65,11 +61,13 @@ const typeEchartBarRef = ref()
|
|||||||
// 初始化
|
// 初始化
|
||||||
const init = () => {
|
const init = () => {
|
||||||
getList().then((data: any) => {
|
getList().then((data: any) => {
|
||||||
planList.value = data.data
|
planList.value = Array.isArray(data?.data) ? data.data : []
|
||||||
if (planList.value.length > 0) {
|
if (planList.value.length > 0) {
|
||||||
dataForm.groupId = planList.value[0].id
|
dataForm.groupId = planList.value[0].id
|
||||||
}
|
}
|
||||||
getDataList()
|
getDataList()
|
||||||
|
}).catch(() => {
|
||||||
|
planList.value = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +77,26 @@ const getDataList = () => {
|
|||||||
dataForm.degreeOfEducation = '1'
|
dataForm.degreeOfEducation = '1'
|
||||||
dataListLoading.value = true
|
dataListLoading.value = true
|
||||||
getAreaStatic(dataForm).then((response: any) => {
|
getAreaStatic(dataForm).then((response: any) => {
|
||||||
dataList.value = response.data
|
const res = response?.data
|
||||||
chartOption.value = response.data.option
|
// 兼容:接口可能返回 { data: [], option: {} } 或直接返回数组
|
||||||
|
dataList.value = Array.isArray(res) ? res : (res?.data || res?.records || res?.list || [])
|
||||||
|
const rawOption = Array.isArray(res) ? null : (res?.option ?? null)
|
||||||
|
// 确保 chart 的 option 合法,series[].data 必须为数组,避免 .includes 报错
|
||||||
|
if (rawOption && typeof rawOption === 'object') {
|
||||||
|
const option = { ...rawOption }
|
||||||
|
if (Array.isArray(option.series)) {
|
||||||
|
option.series = option.series.map((s: any) => ({
|
||||||
|
...s,
|
||||||
|
data: Array.isArray(s?.data) ? s.data : []
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
if (option.data !== undefined && !Array.isArray(option.data)) {
|
||||||
|
option.data = []
|
||||||
|
}
|
||||||
|
chartOption.value = option
|
||||||
|
} else {
|
||||||
|
chartOption.value = {}
|
||||||
|
}
|
||||||
dataListLoading.value = false
|
dataListLoading.value = false
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
dataListLoading.value = false
|
dataListLoading.value = false
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mod-config">
|
<div>
|
||||||
<basic-container>
|
|
||||||
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
||||||
<el-form-item label="招生计划" prop="groupId">
|
<el-form-item label="招生计划" prop="groupId">
|
||||||
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划" size="small">
|
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划" >
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in planList"
|
v-for="item in planList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -14,30 +13,26 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="Search" type="primary" size="small"
|
<el-button icon="Search" type="primary"
|
||||||
@click="handleFilter">查询
|
@click="handleFilter">查询
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Delete" type="default" plain size="small"
|
<el-button icon="Delete" type="default" plain
|
||||||
@click="resetForm">清空
|
@click="resetForm">清空
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="Download" type="warning" size="small" @click="dataExportHandle">导出</el-button>
|
<el-button icon="Download" type="warning" @click="dataExportHandle">导出</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="avue-crud">
|
<el-table :data="dataList" border stripe v-loading="dataListLoading" height="700"
|
||||||
<el-table :data="dataList" border stripe v-loading="dataListLoading"
|
:summary-method="getSummaries" show-summary>
|
||||||
:summary-method="getSummaries" show-summary
|
|
||||||
>
|
|
||||||
<el-table-column align="center" header-align="center" prop="deptName" label="部门" />
|
<el-table-column align="center" header-align="center" prop="deptName" label="部门" />
|
||||||
<el-table-column align="center" header-align="center" prop="allNum" label="合计" />
|
<el-table-column align="center" header-align="center" prop="allNum" label="合计" />
|
||||||
<el-table-column align="center" header-align="center" prop="schoolNum" label="学校推荐" />
|
<el-table-column align="center" header-align="center" prop="schoolNum" label="学校推荐" />
|
||||||
<el-table-column align="center" header-align="center" prop="contantNum" label="联系人" />
|
<el-table-column align="center" header-align="center" prop="contantNum" label="联系人" />
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
|
||||||
</basic-container>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mod-config">
|
<div class="mod-config">
|
||||||
<basic-container>
|
|
||||||
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
<el-form :inline="true" :model="dataForm" @keyup.enter="handleFilter" ref="searchFormRef">
|
||||||
<el-form-item label="招生计划" prop="groupId">
|
<el-form-item label="招生计划" prop="groupId">
|
||||||
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划" size="small">
|
<el-select v-model="dataForm.groupId" filterable placeholder="请选择招生计划">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in planList"
|
v-for="item in planList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -14,17 +13,17 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="Search" type="primary" size="small"
|
<el-button icon="Search" type="primary"
|
||||||
@click="handleFilter">查询
|
@click="handleFilter">查询
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button icon="Delete" type="default" plain size="small"
|
<el-button icon="Delete" type="default" plain
|
||||||
@click="resetForm">清空
|
@click="resetForm">清空
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<el-form>
|
<el-form>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button icon="Download" type="warning" size="small" @click="dataExportHandle">导出</el-button>
|
<el-button icon="Download" type="warning" @click="dataExportHandle">导出</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="avue-crud">
|
<div class="avue-crud">
|
||||||
@@ -40,7 +39,6 @@
|
|||||||
<el-table-column align="center" header-align="center" prop="allNum" label="高中+技职校" />
|
<el-table-column align="center" header-align="center" prop="allNum" label="高中+技职校" />
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</basic-container>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -671,8 +671,9 @@
|
|||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="dataFormSubmit('0')" v-if="hasAuth('recruit_recruitstudentsignup_add') && canSubmit&&!dataForm.id">保存并送审</el-button>
|
<el-button type="primary" @click="dataFormSubmit('0')" v-if="hasAuth('recruit_recruitstudentsignup_add') && canSubmit&&!dataForm.id">保存并送审</el-button>
|
||||||
<el-button type="primary" @click="dataFormSubmit('0')" v-if="hasAuth('recruit_recruitstudentsignup_edit') && canSubmit&&dataForm.id">保存</el-button>
|
<el-button type="primary" @click="dataFormSubmit('0')" v-if="hasAuth('recruit_recruitstudentsignup_edit') && canSubmit&&dataForm.id">保存</el-button>
|
||||||
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('20')" v-if="hasAuth('signup_info_exam') && canSubmit&&dataForm.id">确认录取</el-button>
|
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('20',false)" v-if="hasAuth('signup_info_exam') && canSubmit&&dataForm.id">确认录取</el-button>
|
||||||
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('-20')" v-if="hasAuth('signup_info_exam') && canSubmit&&dataForm.id">驳回录取</el-button>
|
<el-button type="warning" icon="CircleCheck" @click="dataFormSubmit('20',true)" v-if="hasAuth('signup_pass_force') && canSubmit&&dataForm.id">强制录取</el-button>
|
||||||
|
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('-20',false)" v-if="hasAuth('signup_info_exam') && canSubmit&&dataForm.id">驳回</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -1493,7 +1494,7 @@ const updateTuitionByMajorAndEducation = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const dataFormSubmit = (state: string) => {
|
const dataFormSubmit = (state: string,force:any) => {
|
||||||
dataForm.auditStatus = state
|
dataForm.auditStatus = state
|
||||||
let submitTitle = "确认通过该学生的报名申请么?"
|
let submitTitle = "确认通过该学生的报名申请么?"
|
||||||
// 新增模式
|
// 新增模式
|
||||||
@@ -1545,6 +1546,7 @@ const dataFormSubmit = (state: string) => {
|
|||||||
canSubmit.value = false
|
canSubmit.value = false
|
||||||
if (dataForm.id) {
|
if (dataForm.id) {
|
||||||
// 编辑模式
|
// 编辑模式
|
||||||
|
dataForm.force=force
|
||||||
putObj(dataForm).then(() => {
|
putObj(dataForm).then(() => {
|
||||||
message.success('操作成功')
|
message.success('操作成功')
|
||||||
visible.value = false
|
visible.value = false
|
||||||
|
|||||||
@@ -289,6 +289,15 @@
|
|||||||
@click="handleImportDialog"
|
@click="handleImportDialog"
|
||||||
>导入中招平台数据
|
>导入中招平台数据
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-auth="'recruit_sign_sync'"
|
||||||
|
type="warning"
|
||||||
|
plain
|
||||||
|
icon="Refresh"
|
||||||
|
:loading="exportLoading"
|
||||||
|
@click="handleSyncData"
|
||||||
|
>一键同步省人社
|
||||||
|
</el-button>
|
||||||
<!-- <el-button-->
|
<!-- <el-button-->
|
||||||
<!-- v-if="hasAuth('zipExport')"-->
|
<!-- v-if="hasAuth('zipExport')"-->
|
||||||
<!-- type="warning"-->
|
<!-- type="warning"-->
|
||||||
@@ -1158,6 +1167,16 @@ const handleImportDialog = () => {
|
|||||||
ImportRecruitInfoRef.value?.init("R10003");
|
ImportRecruitInfoRef.value?.init("R10003");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportLoading=ref(false);
|
||||||
|
const handleSyncData=()=>{
|
||||||
|
exportLoading.value=true;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
exportLoading.value=false;
|
||||||
|
message.success('同步成功');
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init()
|
init()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
<el-table-column prop="minScore" header-align="center" align="center" label="最低分" />
|
<el-table-column prop="minScore" header-align="center" align="center" label="最低分" />
|
||||||
<el-table-column prop="avgScore" header-align="center" align="center" label="平均分" />
|
<el-table-column prop="avgScore" header-align="center" align="center" label="平均分" />
|
||||||
<el-table-column prop="majorPeopleNum" header-align="center" align="center" label="专业人数" />
|
<el-table-column prop="majorPeopleNum" header-align="center" align="center" label="专业人数" />
|
||||||
<el-table-column prop="avgScoreDB" header-align="center" align="center" label="均分对比" />
|
<!-- <el-table-column prop="avgScoreDB" header-align="center" align="center" label="均分对比" />-->
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -76,12 +76,13 @@ import { useDict } from '/@/hooks/dict'
|
|||||||
import { juniorlneStatic } from '/@/api/recruit/recruitstudentsignup'
|
import { juniorlneStatic } from '/@/api/recruit/recruitstudentsignup'
|
||||||
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
import { getList } from '/@/api/recruit/recruitstudentplangroup'
|
||||||
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept'
|
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept'
|
||||||
|
import {getDictsByTypes} from "/@/api/admin/dict";
|
||||||
|
|
||||||
// 消息提示 hooks
|
// 消息提示 hooks
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
|
||||||
// 字典
|
// 字典
|
||||||
const { getTypeValue } = useDict()
|
// const { useDict } = useDict()
|
||||||
|
|
||||||
// 引用
|
// 引用
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
@@ -104,19 +105,24 @@ const queryForm = reactive({
|
|||||||
// 使用 table hook 获取样式
|
// 使用 table hook 获取样式
|
||||||
const { tableStyle, downBlobFile } = useTable()
|
const { tableStyle, downBlobFile } = useTable()
|
||||||
|
|
||||||
|
const queryDictData=()=>{
|
||||||
|
getDictsByTypes(['basic_major_years']).then((res:any)=>{
|
||||||
|
majorYears.value = res.data.basic_major_years || []
|
||||||
|
})
|
||||||
|
}
|
||||||
// 初始化
|
// 初始化
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
try {
|
try {
|
||||||
const [deptResponse, majorYearsRes, planData] = await Promise.all([
|
queryDictData()
|
||||||
|
|
||||||
|
const [deptResponse, planData] = await Promise.all([
|
||||||
getDeptListByLevelTwo(),
|
getDeptListByLevelTwo(),
|
||||||
getTypeValue('basic_major_years'),
|
|
||||||
getList()
|
getList()
|
||||||
])
|
])
|
||||||
|
|
||||||
deptCodes.value = deptResponse.data || []
|
deptCodes.value = deptResponse.data || []
|
||||||
majorYears.value = majorYearsRes.data || []
|
|
||||||
planList.value = planData.data || []
|
planList.value = planData.data || []
|
||||||
|
|
||||||
if (planList.value.length > 0) {
|
if (planList.value.length > 0) {
|
||||||
queryForm.groupId = planList.value[0].id
|
queryForm.groupId = planList.value[0].id
|
||||||
getDataList()
|
getDataList()
|
||||||
|
|||||||
@@ -102,7 +102,8 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="dataFormSubmit" v-if="canSubmit">确认修改</el-button>
|
<el-button type="primary" @click="dataFormSubmit(false)" v-if="canSubmit">确认修改</el-button>
|
||||||
|
<el-button type="warning" @click="dataFormSubmit(true)" v-if="canSubmit" v-auth="'recruit_signup_change_force'">强制修改</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -272,12 +273,13 @@ const changeCM = (id: string) => {
|
|||||||
|
|
||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const dataFormSubmit = async () => {
|
const dataFormSubmit = async (force:any) => {
|
||||||
const titleText = "确认调整录取专业么?"
|
const titleText = "确认调整录取专业么?"
|
||||||
if (dataForm.confirmedMajor == dataForm.newConfirmedMajor) {
|
if (dataForm.confirmedMajor == dataForm.newConfirmedMajor) {
|
||||||
message.error('新专业不能和原专业相同')
|
message.error('新专业不能和原专业相同')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
dataForm.force=force
|
||||||
try {
|
try {
|
||||||
await messageBox.confirm(titleText)
|
await messageBox.confirm(titleText)
|
||||||
dataFormRef.value?.validate((valid: boolean) => {
|
dataFormRef.value?.validate((valid: boolean) => {
|
||||||
|
|||||||
@@ -183,9 +183,10 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="visible = false">取消</el-button>
|
<el-button @click="visible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="dataFormSubmit('1')" v-if="hasAuth('recruit_recruitstudentsignup_edit') && canSubmit">保存</el-button>
|
<el-button type="primary" @click="dataFormSubmit('1',false)" v-if="hasAuth('recruit_recruitstudentsignup_edit') && canSubmit">保存</el-button>
|
||||||
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('2')" v-if="hasAuth('signup_material_exam') && canSubmit">通过</el-button>
|
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('2',false)" v-if="hasAuth('signup_material_exam') && canSubmit">通过</el-button>
|
||||||
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('3')" v-if="hasAuth('signup_material_exam') && canSubmit">驳回</el-button>
|
<el-button type="success" icon="CircleCheck" @click="dataFormSubmit('2',true)" v-if="hasAuth('signup_material_pass_force') && canSubmit">强制通过</el-button>
|
||||||
|
<el-button type="danger" icon="CircleClose" @click="dataFormSubmit('3',false)" v-if="hasAuth('signup_material_exam') && canSubmit">驳回</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -412,13 +413,14 @@ const initData = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 表单提交
|
// 表单提交
|
||||||
const dataFormSubmit = (submitType: string) => {
|
const dataFormSubmit = (submitType: string,force:any) => {
|
||||||
if ((dataForm.zlshRemark == '' || !dataForm.zlshRemark) && submitType == '3') {
|
if ((dataForm.zlshRemark == '' || !dataForm.zlshRemark) && submitType == '3') {
|
||||||
message.error('请填写驳回理由')
|
message.error('请填写驳回理由')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dataForm.zlsh = submitType
|
dataForm.zlsh = submitType
|
||||||
canSubmit.value = false
|
canSubmit.value = false
|
||||||
|
dataForm.force=force
|
||||||
materialExam(dataForm).then(() => {
|
materialExam(dataForm).then(() => {
|
||||||
message.success('操作成功')
|
message.success('操作成功')
|
||||||
visible.value = false
|
visible.value = false
|
||||||
|
|||||||
@@ -201,7 +201,8 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="cancelPlace">取消</el-button>
|
<el-button @click="cancelPlace">取消</el-button>
|
||||||
<el-button type="primary" @click="update">保存</el-button>
|
<el-button type="primary" @click="update(false)">保存</el-button>
|
||||||
|
<el-button type="warning" @click="update(true)" v-auth="'recruit_signup_change_force'">强制保存</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -273,7 +274,8 @@ const exarmForm = reactive({
|
|||||||
isMajorChange: '',
|
isMajorChange: '',
|
||||||
examRemark: '',
|
examRemark: '',
|
||||||
groupId: '',
|
groupId: '',
|
||||||
remarks: ''
|
remarks: '',
|
||||||
|
force:false
|
||||||
})
|
})
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
@@ -340,11 +342,11 @@ const cancelPlace = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 保存审核
|
// 保存审核
|
||||||
const update = async () => {
|
const update = async (force:any) => {
|
||||||
try {
|
try {
|
||||||
const valid = await exarmFormRef.value?.validate().catch(() => {})
|
const valid = await exarmFormRef.value?.validate().catch(() => {})
|
||||||
if (!valid) return
|
if (!valid) return
|
||||||
|
exarmForm.force=force
|
||||||
await putObj(exarmForm)
|
await putObj(exarmForm)
|
||||||
message.success('审核成功')
|
message.success('审核成功')
|
||||||
majorChangeVisible.value = false
|
majorChangeVisible.value = false
|
||||||
|
|||||||
Reference in New Issue
Block a user