| | |
| | | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { ResearchApplicationApi } from '#/api/research/application'; |
| | | import type { ResearchGuidelineApi } from '#/api/research/guideline'; |
| | | |
| | | import { z } from '#/adapter/form'; |
| | | |
| | | import { DICT_TYPE } from '@vben/constants'; |
| | | import { getDictOptions } from '@vben/hooks'; |
| | |
| | | /** 表单类型 */ |
| | | export type FormType = 'create' | 'detail' | 'edit'; |
| | | |
| | | /** 课题组成员角色选项 */ |
| | | export const MEMBER_ROLE_OPTIONS = [ |
| | | { label: '主持人', value: '主持人' }, |
| | | { label: '核心成员', value: '核心成员' }, |
| | | { label: '参与人', value: '参与人' }, |
| | | ]; |
| | | |
| | | /** |
| | | * 成员行投影为可提交对象:只保留后端接受的字段, |
| | | * 不带 id / applicationId,避免与「先删后增」的软删行主键冲突。 |
| | | */ |
| | | export function toSubmitMembers( |
| | | members?: ResearchApplicationApi.ApplicationMember[], |
| | | ): ResearchApplicationApi.ApplicationMember[] { |
| | | return (members ?? []).map((member) => ({ |
| | | name: member.name, |
| | | contactPhone: member.contactPhone, |
| | | workUnit: member.workUnit, |
| | | jobTitle: member.jobTitle, |
| | | memberRole: member.memberRole, |
| | | sortNo: member.sortNo, |
| | | })); |
| | | } |
| | | |
| | | /** 课题申报书状态(对应字典 research_application_status) */ |
| | | export const ApplicationStatus = { |
| | | DRAFT: 0, // 草稿 |
| | |
| | | /** 经费拨付状态(对应字典 research_fund_status) */ |
| | | export const FundStatus = { |
| | | PENDING: 0, // 待拨付 |
| | | APPROVING: 15, // 报销审批中 |
| | | PAID: 20, // 已拨付 |
| | | REJECTED: 30, // 已驳回 |
| | | } as const; |
| | | |
| | | /** 课题申报书表单配置 */ |
| | |
| | | label: '联系电话', |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请输入联系电话', |
| | | maxlength: 20, |
| | | placeholder: '请输入 11 位手机号', |
| | | maxlength: 11, |
| | | disabled: readonly, |
| | | }, |
| | | rules: z |
| | | .string({ message: '联系电话不能为空' }) |
| | | .min(1, '联系电话不能为空') |
| | | .regex(/^1[3-9]\d{9}$/, '联系电话格式不正确,请输入正确的 11 位手机号'), |
| | | }, |
| | | { |
| | | fieldName: 'contactEmail', |
| | |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'teamMembers', |
| | | // 子表编辑由 form.vue 的 #members 插槽渲染 |
| | | fieldName: 'members', |
| | | label: '课题组成员', |
| | | component: 'Textarea', |
| | | componentProps: { |
| | | placeholder: '每行一条,格式:姓名|单位|职称\n例如:李四|XX大学|副教授', |
| | | autoSize: { minRows: 3, maxRows: 6 }, |
| | | disabled: readonly, |
| | | }, |
| | | help: '每行一条,用竖线分隔:姓名|单位|职称', |
| | | component: 'Input', |
| | | formItemClass: 'col-span-2', |
| | | }, |
| | | { |
| | |
| | | { |
| | | field: 'status', |
| | | title: '拨付状态', |
| | | minWidth: 100, |
| | | minWidth: 110, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | props: { type: DICT_TYPE.RESEARCH_FUND_STATUS }, |
| | | }, |
| | | }, |
| | | { |
| | | field: 'reimbursementNo', |
| | | title: '财务报销单号', |
| | | minWidth: 160, |
| | | formatter: dashIfEmpty, |
| | | }, |
| | | { |
| | | field: 'rejectReason', |
| | | title: '驳回原因', |
| | | minWidth: 200, |
| | | formatter: dashIfEmpty, |
| | | }, |
| | | { |
| | | field: 'hasAttachment', |
| | | title: '拨付凭证', |
| | | minWidth: 100, |