证书功能

This commit is contained in:
马梓彭 2026-04-15 14:27:27 +08:00
parent d5358f8526
commit 4b63e2d366
2 changed files with 78 additions and 24 deletions

View File

@ -142,5 +142,19 @@ export const certificateSetstatusPatch = (data) => {
* }>>}
*/
export const certificateTemplateListGet = () => {
return http.post('/certificatetemplate/gettemplatelist');
return http.get('/certificatetemplate/gettemplatelist');
};
/**
* 获取证书列表
* @returns {Promise<Array<{
* id: number,
* name: string,
* code: string,
* templateId: number,
* displayName: string
* }>>}
*/
export const certificateListGet = () => {
return http.get('/certificate/getlist');
};

View File

@ -203,14 +203,13 @@
<!-- 发放证书对话框 -->
<el-dialog v-model="certificateDialogVisible" title="发放证书" width="500px">
<el-form :model="certificateForm" label-width="120px">
<el-form-item label="选择证书模板">
<el-select v-model="selectedTemplateId" placeholder="请选择证书模板" style="width: 100%;">
<el-option label="默认模板" :value="undefined" />
<el-form-item label="选择证书">
<el-select v-model="selectedCertificateId" placeholder="请选择证书" style="width: 100%;">
<el-option
v-for="template in certificateTemplateList"
:key="template.id"
:label="template.DisplayName || `模板 ${template.id} (v${template.version})`"
:value="template.id"
v-for="certificate in certificateList"
:key="certificate.id"
:label="certificate.name || certificate.Name || `证书 ${certificate.id}`"
:value="certificate.id"
/>
</el-select>
</el-form-item>
@ -296,7 +295,7 @@ import { eventDetailGet } from '/@/api/match/event';
import { eventarrangementListGet, eventarrangementPut, eventarrangementExportPost, eventarrangementPreviewPost } from '/@/api/match/eventarrangement';
import { eventregistrationPagePost, eventregistrationBatchauditPost, eventregistrationMaterialurlsPost } from '/@/api/match/eventregistration';
import { eventscorePageathletePost, eventscorePagecoachleaderPost,eventscoreImportscorePost, eventscoreDownloadtemplateGet, eventscoreExportcertificatePost, eventscoreIssuecertificatePost, eventscoreGetCertificateDetailGet, eventscoreIssuepointsPost } from '/@/api/match/eventscore';
import { certificateTemplateListGet } from '/@/api/match/certificate';
import { certificateListGet } from '/@/api/match/certificate';
import Step1BasicInfo from './Steps/Step1BasicInfo.vue';
import Step2Units from './Steps/Step2Units.vue';
import Step3ProjectConfig from './Steps/Step3ProjectConfig.vue';
@ -326,10 +325,10 @@ const tableLeader = ref();
// 证书发放相关
const certificateDialogVisible = ref(false);
const selectedTemplateId = ref();
const selectedCertificateId = ref();
const issuingCertificate = ref(false);
const certificateForm = ref({});
const certificateTemplateList = ref([]);
const certificateList = ref([]);
// 表单数据(响应式对象)
const formData = ref({
// 步骤1:基本信息
@ -378,10 +377,13 @@ const formData = ref({
});
// 打开弹窗
const openDialog = async (id) => {
isShowDialog.value = true;
const res = await eventDetailGet(id);
// 先设置 eventId,再显示对话框
initParam.value.eventId = id;
initParam.value.id = id;
selectedProjectGroup.value = null;
isShowDialog.value = true;
const res = await eventDetailGet(id);
const d = res?.data;
if (d) {
previewEventName.value = d.eventName || '赛事编排预览';
@ -413,7 +415,6 @@ const openDialog = async (id) => {
console.log('formData.value', formData.value);
projectGroupTreeData.value = buildProjectGroupTree(d.projects)
selectedProjectGroup.value = null
if (projectGroupTreeRef.value) {
projectGroupTreeRef.value.setCurrentKey(null)
}
@ -800,6 +801,16 @@ watch(user, (newValue) => {
})
})
// 监听对话框关闭,重置状态
watch(isShowDialog, (newValue) => {
if (!newValue) {
// 对话框关闭时重置状态
selectedProjectGroup.value = null
user.value = '运动员'
activeName.value = 'first'
}
})
const columnsScore = ref([
{ prop: 'index', label: '序号', align: 'center', type: 'selection' },
{ prop: 'name', label: '姓名', width: '120px', },
@ -832,14 +843,17 @@ const scoreQueryParam = computed(() => ({
refresh: initParam.value.refresh,
eventId: initParam.value.eventId,
projectId: selectedProjectGroup.value?.type === 'project' ? selectedProjectGroup.value?.id : undefined,
eventProjectGroupId: selectedProjectGroup.value?.type === 'group' ? selectedProjectGroup.value?.eventProjectGroupId : undefined,
groupName: selectedProjectGroup.value?.type === 'group' ? selectedProjectGroup.value?.groupName : undefined
}))
const buildProjectGroupTree = (projects) => {
console.log('buildProjectGroupTree 开始处理 projects:', projects)
const treeData = []
if (!projects || !Array.isArray(projects)) return treeData
projects.forEach(project => {
console.log('处理项目:', project)
const projectNode = {
nodeKey: `project-${project.id}`,
id: project.id,
@ -850,11 +864,14 @@ const buildProjectGroupTree = (projects) => {
}
if (project.groups && Array.isArray(project.groups)) {
project.groups.forEach((group, idx) => {
console.log('项目下的组别:', project.groups)
project.groups.forEach((group) => {
console.log('添加组别节点:', group)
projectNode.children.push({
nodeKey: `group-${project.id}-${idx}`,
nodeKey: `group-${project.id}-${group.id}`,
id: project.id,
projectId: project.id,
eventProjectGroupId: group.id,
type: 'group',
groupName: group.groupName,
label: group.groupName
@ -865,11 +882,17 @@ const buildProjectGroupTree = (projects) => {
treeData.push(projectNode)
})
console.log('生成的树数据:', treeData)
return treeData
}
const handleTreeNodeClick = (data) => {
console.log('树节点被点击:', data)
selectedProjectGroup.value = data
// 同时更新 refresh 标志,强制 ProTable 重新查询
initParam.value.refresh = !initParam.value.refresh
console.log('更新后的 selectedProjectGroup:', selectedProjectGroup.value)
console.log('scoreQueryParam:', scoreQueryParam.value)
nextTick(() => {
refreshScoreTable()
})
@ -880,6 +903,8 @@ const resetSelectedGroup = () => {
if (projectGroupTreeRef.value) {
projectGroupTreeRef.value.setCurrentKey(null)
}
// 同时更新 refresh 标志,强制 ProTable 重新查询
initParam.value.refresh = !initParam.value.refresh
nextTick(() => {
refreshScoreTable()
})
@ -924,14 +949,20 @@ const columnsLeader = ref([
])
const refreshScoreTable = () => {
console.log('refreshScoreTable 被调用,当前用户类型:', user.value)
console.log('当前 selectedProjectGroup:', selectedProjectGroup.value)
console.log('scoreQueryParam:', scoreQueryParam.value)
isScoreTableLoading.value = true
nextTick(() => {
try {
if (user.value === '运动员') {
console.log('调用运动员表格 getTableList')
tableuu.value?.getTableList?.()
} else if (user.value === '教练') {
console.log('调用教练表格 getTableList')
tableCoach.value?.getTableList?.()
} else if (user.value === '领队') {
console.log('调用领队表格 getTableList')
tableLeader.value?.getTableList?.()
}
} finally {
@ -1031,15 +1062,19 @@ const selectedCount = computed(() => {
return selectListIds.value.length;
});
// 加载证书模板列表
const loadCertificateTemplates = async () => {
// 加载证书列表
const loadCertificates = async () => {
try {
const res = await certificateTemplateListGet();
console.log('开始加载证书列表...');
const res = await certificateListGet();
console.log('证书列表 API 返回结果:', res);
if (res?.succeeded && res?.data) {
certificateTemplateList.value = res.data;
console.log('证书列表数据:', res.data);
console.log('第一个证书对象:', res.data[0]);
certificateList.value = res.data;
}
} catch (error) {
console.error('加载证书模板失败:', error);
console.error('加载证书列表失败:', error);
}
};
@ -1049,8 +1084,8 @@ const openIssueCertificateDialog = async () => {
ElMessage.warning('请先选择要发放证书的人员');
return;
}
selectedTemplateId.value = undefined;
await loadCertificateTemplates();
selectedCertificateId.value = undefined;
await loadCertificates();
certificateDialogVisible.value = true;
};
@ -1061,12 +1096,17 @@ const issueCertificate = async () => {
return;
}
if (!selectedCertificateId.value) {
ElMessage.warning('请选择证书');
return;
}
issuingCertificate.value = true;
try {
const res = await eventscoreIssuecertificatePost({
personIds: selectListIds.value,
eventId: initParam.value.eventId,
templateId: selectedTemplateId.value
certificateId: selectedCertificateId.value
});
if (res?.succeeded) {
ElMessage.success(`证书发放成功!成功 ${res.data?.successCount || 0} 条,失败 ${res.data?.failCount || 0} 条`);