!112 refactor(bg): 年份字段从字典组件替换为年份选择器

* refactor(bg): 年份字段从字典组件替换为年份选择器
* feat(bpm): 待办/已办/待阅/已阅弹窗标题改为业务标题
* feat(bpmform): 反馈新增时计划完成目标/日期必填可编辑,编辑时禁用并提示
* style(bpmform): 统一表单标签宽度和对齐,清理调试代码
* feat(bg): 再次发起督办弹窗标题显示中文数字督办次数
* style(bpmform): 新增反馈按钮添加悬浮提示"可以多次新增反馈"
This commit is contained in:
wsm
2026-07-24 03:16:38 +00:00
parent fd66dac804
commit 11f6ba3961
12 changed files with 136 additions and 52 deletions
@@ -6,7 +6,7 @@
<a-row :gutter="24" class="search-form-row">
<a-col :lg="6" :md="8" :sm="12">
<a-form-item label="年份" name="year">
<JDictSelectTag v-model:value="queryParam.year" dictCode="super_year" placeholder="请选择年份" allow-clear @change="searchQuery" />
<a-date-picker v-model:value="queryParam.year" picker="year" value-format="YYYY" placeholder="请选择年份" allow-clear style="width: 100%" @change="searchQuery" />
</a-form-item>
</a-col>
<a-col :lg="6" :md="8" :sm="12">
@@ -554,9 +554,19 @@
return dropDownAction;
}
const CN = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
function toChinese(num: number): string {
return String(num).split('').map(c => CN[Number(c)]).join('');
}
function handleProcess(record) {
const nextCount = getNextSuperviseCount(record.superviseCount);
const title = nextCount > 1
? `发起流程(${record?.title || ''}${toChinese(nextCount)}次督办)`
: '发起流程';
flowScheduleModalRef.value?.open({
title: '发起流程',
title,
taskTitle: record?.title,
payload: { record },
deptOptions: getResponsibleDeptOptions(record),
@@ -39,14 +39,18 @@
<!-- </a-form-item>-->
<!-- </a-col>-->
<a-col :span="24">
<a-form-item label="计划完成目标" name="planExect" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.planExect" :rows="3" allow-clear />
</a-form-item>
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
<a-form-item label="计划完成目标" name="planExect" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.planExect" :rows="3" :disabled="isEdit" allow-clear />
</a-form-item>
</a-tooltip>
</a-col>
<a-col :span="12">
<a-form-item label="计划完成日期" name="planTime">
<a-date-picker v-model:value="formData.planTime" value-format="YYYY-MM-DD" style="width: 100%" allow-clear />
</a-form-item>
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
<a-form-item label="计划完成日期" name="planTime">
<a-date-picker v-model:value="formData.planTime" value-format="YYYY-MM-DD" style="width: 100%" :disabled="isEdit" allow-clear />
</a-form-item>
</a-tooltip>
</a-col>
<a-col :span="12">
<a-form-item label="完成状态" name="bpmStatus">
@@ -55,7 +59,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="实际完成日期" name="actualTime">
<a-date-picker v-model:value="formData.actualTime" value-format="YYYY-MM-DD" placeholder="请选择实际完成日期" style="width: 100%" allow-clear />
<a-date-picker v-model:value="formData.actualTime" value-format="YYYY-MM-DD" placeholder="请选择实际完成日期" style="width: 100%" :disabled="isEdit" allow-clear />
</a-form-item>
</a-col>
<a-col :span="24">
@@ -97,6 +101,7 @@
const visible = ref(false);
const saving = ref(false);
const isEdit = ref(false);
const modalTitle = ref('新增反馈');
const formRef = ref();
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
@@ -122,7 +127,10 @@
mainId: '',
});
const formRules = {};
const formRules = {
planExect: [{ required: true, message: '请输入计划完成目标' }],
planTime: [{ required: true, message: '请选择计划完成日期' }],
};
function resetForm(mainId = '', bpmProcessId = '') {
Object.keys(formData).forEach((key) => {
@@ -138,6 +146,7 @@
resetForm(mainId, bpmProcessId);
uploadSecretLevel.value = normalizeSecretLevel(secretLevel);
if (record?.id) {
isEdit.value = true;
modalTitle.value = '编辑反馈';
Object.keys(formData).forEach((key) => {
if (Object.prototype.hasOwnProperty.call(record, key)) {
@@ -147,6 +156,7 @@
formData.mainId = formData.mainId || mainId;
formData.bpmProcessId = formData.bpmProcessId || bpmProcessId;
} else {
isEdit.value = false;
modalTitle.value = '新增反馈';
// 新增反馈默认按“已完成”处理,时间取打开弹窗时刻,编辑已有记录不覆盖。
formData.bpmStatus = DEFAULT_COMPLETED_STATUS;
@@ -29,12 +29,12 @@
</div>
<a-row class="base-info-row" :gutter="[12, 4]">
<a-col :xs="24" :md="12">
<a-form-item label="事项名称" name="title" :labelCol="compactLabelCol" :wrapperCol="compactWrapperCol">
<a-form-item label="事项名称" name="title">
<a-input v-model:value="mainForm.title" :disabled="mainDisabled" allow-clear />
</a-form-item>
</a-col>
<a-col :xs="24" :md="12">
<a-form-item label="会议决议" name="content" :labelCol="compactLabelCol" :wrapperCol="compactWrapperCol">
<a-form-item label="会议决议" name="content">
<a-textarea v-model:value="mainForm.content" :auto-size="{ minRows: 1, maxRows: 7 }" :disabled="mainDisabled" allow-clear />
</a-form-item>
</a-col>
@@ -42,11 +42,13 @@
<a-divider />
<a-col :span="12">
<a-form-item label="年份" name="year">
<j-dict-select-tag
<a-date-picker
v-model:value="mainForm.year"
picker="year"
value-format="YYYY"
:disabled="mainDisabled"
dictCode="super_year"
placeholder="请选择年份"
style="width: 100%"
allow-clear
/>
</a-form-item>
@@ -170,10 +172,12 @@
<div class="feedback-header section-toolbar">
<div class="section-title">办理情况</div>
<a-space class="section-actions">
<a-button v-if="showAddFeedback" class="section-action-button feedback-add-button" type="primary" @click="openFeedbackModal">
<Icon icon="ant-design:plus-outlined" />
新增反馈
</a-button>
<a-tooltip v-if="showAddFeedback" title="可以多次新增反馈">
<a-button class="section-action-button feedback-add-button" type="primary" @click="openFeedbackModal">
<Icon icon="ant-design:plus-outlined" />
新增反馈
</a-button>
</a-tooltip>
<a-button
class="section-action-button"
:type="showFeedbackDetail ? 'default' : 'link'"
@@ -296,7 +300,7 @@
SUOBAN_DEPT_ID,
MEASURE_RES_LEADER_ROLE_ID,
} from '/@/constant/supervision';
const { isDisabledAuth, hasPermission, initBpmFormData } = usePermission();
const { initBpmFormData } = usePermission();
const props = defineProps({
formDisabled: { type: Boolean, default: false },
@@ -306,8 +310,6 @@
});
initBpmFormData(props.formData);
console.log('@props.formData', props.formData);
console.log('@props', props);
const emit = defineEmits(['ok', 'success', 'claimSuccess']);
const { createMessage } = useMessage();
@@ -317,9 +319,6 @@
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
const compactLabelCol = { xs: { span: 24 }, sm: { span: 5 } };
const compactWrapperCol = { xs: { span: 24 }, sm: { span: 19 } };
const wideActionWrapperCol = { xs: { span: 24 }, sm: { span: 21, offset: 3 } };
const feedbackModalRef = ref();
const loading = ref(false);
@@ -6,7 +6,7 @@
<a-row class="form-content-row" :gutter="[12, 4]">
<a-col :xs="24" :md="12">
<a-form-item label="年份" v-bind="validateInfos.year" id="BgPartymatterForm-year" name="year">
<j-dict-select-tag v-model:value="formData.year" dictCode="super_year" placeholder="请选择年份" allow-clear />
<a-date-picker v-model:value="formData.year" picker="year" value-format="YYYY" placeholder="请选择年份" style="width: 100%" allow-clear />
</a-form-item>
</a-col>
<a-col :xs="24" :md="12">
+11 -1
View File
@@ -477,9 +477,19 @@
/**
* 提交流程
*/
const CN = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];
function toChinese(num: number): string {
return String(num).split('').map(c => CN[Number(c)]).join('');
}
function handleProcess(record) {
const nextCount = getNextSuperviseCount(record.superviseCount);
const title = nextCount > 1
? `发起流程(${record?.title || ''}${toChinese(nextCount)}次督办)`
: '发起流程';
flowScheduleModalRef.value?.open({
title: '发起流程',
title,
taskTitle: record?.title,
payload: { record },
deptOptions: getResponsibleDeptOptions(record),
@@ -12,14 +12,18 @@
<a-form ref="formRef" class="bpm-feedback-modal-form" :model="formData" :rules="formRules" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-row :gutter="16">
<a-col :span="24">
<a-form-item label="计划完成目标" name="planExect" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.planExect" :rows="3" allow-clear />
</a-form-item>
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
<a-form-item label="计划完成目标" name="planExect" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.planExect" :rows="3" :disabled="isEdit" allow-clear />
</a-form-item>
</a-tooltip>
</a-col>
<a-col :span="12">
<a-form-item label="计划完成日期" name="planTime">
<a-date-picker v-model:value="formData.planTime" value-format="YYYY-MM-DD" style="width: 100%" allow-clear />
</a-form-item>
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
<a-form-item label="计划完成日期" name="planTime">
<a-date-picker v-model:value="formData.planTime" value-format="YYYY-MM-DD" style="width: 100%" :disabled="isEdit" allow-clear />
</a-form-item>
</a-tooltip>
</a-col>
<a-col :span="12">
<a-form-item label="完成状态" name="bpmStatus">
@@ -28,7 +32,7 @@
</a-col>
<a-col :span="12">
<a-form-item label="实际完成日期" name="actualTime">
<a-date-picker v-model:value="formData.actualTime" value-format="YYYY-MM-DD" placeholder="请选择实际完成日期" style="width: 100%" allow-clear />
<a-date-picker v-model:value="formData.actualTime" value-format="YYYY-MM-DD" placeholder="请选择实际完成日期" style="width: 100%" :disabled="isEdit" allow-clear />
</a-form-item>
</a-col>
<a-col :span="24">
@@ -80,6 +84,7 @@
const visible = ref(false);
const saving = ref(false);
const isEdit = ref(false);
const modalTitle = ref('新增反馈');
const formRef = ref();
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
@@ -107,7 +112,10 @@
mainId: '',
});
const formRules = {};
const formRules = {
planExect: [{ required: true, message: '请输入计划完成目标' }],
planTime: [{ required: true, message: '请选择计划完成日期' }],
};
function resetForm(mainId = '', bpmProcessId = '') {
Object.keys(formData).forEach((key) => {
@@ -123,6 +131,7 @@
resetForm(mainId, bpmProcessId);
uploadSecretLevel.value = normalizeSecretLevel(secretLevel);
if (record?.id) {
isEdit.value = true;
modalTitle.value = '编辑反馈';
Object.keys(formData).forEach((key) => {
if (Object.prototype.hasOwnProperty.call(record, key)) {
@@ -132,6 +141,7 @@
formData.mainId = formData.mainId || mainId;
formData.bpmProcessId = formData.bpmProcessId || bpmProcessId;
} else {
isEdit.value = false;
modalTitle.value = '新增反馈';
// 新增反馈默认带入当前办理人和办理部门,避免经办人手工维护隐藏归属字段。
formData.bpmStatus = DEFAULT_COMPLETED_STATUS;
@@ -17,12 +17,12 @@
</div>
<a-row class="base-info-row" :gutter="[12, 4]">
<a-col :xs="24" :md="12">
<a-form-item label="意见主题" name="title" :labelCol="compactLabelCol" :wrapperCol="compactWrapperCol">
<a-form-item label="意见主题" name="title">
<a-input v-model:value="mainForm.title" :disabled="mainDisabled" allow-clear />
</a-form-item>
</a-col>
<a-col :xs="24" :md="12">
<a-form-item label="具体意见" name="content" :labelCol="compactLabelCol" :wrapperCol="compactWrapperCol">
<a-form-item label="具体意见" name="content">
<a-textarea v-model:value="mainForm.content" :auto-size="{ minRows: 1, maxRows: 7 }" :disabled="mainDisabled" allow-clear />
</a-form-item>
</a-col>
@@ -30,7 +30,7 @@
<a-divider />
<a-col :span="12">
<a-form-item label="年份" name="year">
<j-dict-select-tag v-model:value="mainForm.year" :disabled="mainDisabled" dictCode="super_year" allow-clear />
<a-date-picker v-model:value="mainForm.year" picker="year" value-format="YYYY" :disabled="mainDisabled" placeholder="请选择年份" style="width: 100%" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
@@ -170,10 +170,12 @@
<div class="feedback-header section-toolbar">
<div class="section-title">办理情况</div>
<a-space class="section-actions">
<a-button v-if="showAddFeedback" class="section-action-button feedback-add-button" type="primary" @click="openFeedbackModal">
<Icon icon="ant-design:plus-outlined" />
新增反馈
</a-button>
<a-tooltip v-if="showAddFeedback" title="可以多次新增反馈">
<a-button class="section-action-button feedback-add-button" type="primary" @click="openFeedbackModal">
<Icon icon="ant-design:plus-outlined" />
新增反馈
</a-button>
</a-tooltip>
<a-button
class="section-action-button"
:type="showFeedbackDetail ? 'default' : 'link'"
@@ -316,8 +318,6 @@
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
const compactLabelCol = { xs: { span: 24 }, sm: { span: 5 } };
const compactWrapperCol = { xs: { span: 24 }, sm: { span: 19 } };
const feedbackModalRef = ref();
const loading = ref(false);
@@ -1039,7 +1039,15 @@
:deep(.ant-input[disabled]),
:deep(.ant-input-disabled),
:deep(.ant-input-affix-wrapper-disabled),
:deep(.ant-input-affix-wrapper-disabled.ant-input-outlined),
:deep(.ant-input-affix-wrapper-disabled:hover),
:deep(.ant-input-affix-wrapper-disabled:focus),
:deep(.ant-input-affix-wrapper-disabled-focused),
:deep(.ant-input-outlined[disabled]),
:deep(.ant-input-outlined.ant-input-disabled),
:deep(.ant-input-number-disabled),
:deep(.ant-input-number-disabled:hover),
:deep(.ant-input-number-disabled:focus),
:deep(textarea.ant-input[disabled]),
:deep(.ant-picker-disabled),
:deep(.ant-select-disabled .ant-select-selector) {
@@ -1060,16 +1068,53 @@
padding-right: 0 !important;
}
:deep(.ant-picker-disabled input),
:deep(.ant-select-disabled .ant-select-selection-item),
:deep(.ant-select-disabled .ant-select-selection-placeholder) {
:deep(.ant-input-affix-wrapper-disabled .ant-input) {
background: transparent !important;
color: #1f2937 !important;
cursor: default !important;
}
:deep(.ant-input-number-disabled .ant-input-number-input) {
background: transparent !important;
color: #1f2937 !important;
-webkit-text-fill-color: #1f2937 !important;
cursor: default !important;
}
:deep(.ant-input[disabled]::placeholder),
:deep(.ant-input-disabled::placeholder),
:deep(.ant-input-affix-wrapper-disabled .ant-input::placeholder) {
color: #9ca3af !important;
}
:deep(.ant-picker-disabled input),
:deep(.ant-select-disabled .ant-select-selection-item),
:deep(.ant-select-disabled .ant-select-selection-item span),
:deep(.ant-select-disabled .ant-select-selection-placeholder),
:deep(.ant-select-disabled .ant-select-selection-placeholder span) {
color: #1f2937 !important;
-webkit-text-fill-color: #1f2937 !important;
cursor: default !important;
}
:deep(.ant-picker-disabled),
:deep(.ant-select-disabled .ant-select-selector) {
padding-left: 0 !important;
}
:deep(.ant-select-disabled),
:deep(.ant-select-disabled *),
:deep(.ant-select-disabled.ant-select-outlined),
:deep(.ant-select-disabled.ant-select-outlined .ant-select-selector) {
color: #1f2937 !important;
-webkit-text-fill-color: #1f2937 !important;
opacity: 1 !important;
}
:deep(.ant-select-disabled .ant-select-arrow),
:deep(.ant-picker-disabled .ant-picker-suffix),
:deep(.ant-input-disabled .ant-input-clear-icon),
:deep(.ant-input-affix-wrapper-disabled .ant-input-clear-icon),
:deep(.ant-input-number-disabled .ant-input-number-handler-wrap),
:deep(.ant-select-disabled .ant-select-clear) {
display: none;
@@ -6,7 +6,7 @@
<a-row class="form-content-row" :gutter="[12, 4]">
<a-col :xs="24" :md="12">
<a-form-item label="年份" v-bind="validateInfos.year" id="BgTakepulseForm-year" name="year">
<j-dict-select-tag v-model:value="formData.year" dictCode="super_year" placeholder="请选择年份" allow-clear />
<a-date-picker v-model:value="formData.year" picker="year" value-format="YYYY" placeholder="请选择年份" style="width: 100%" allow-clear />
</a-form-item>
</a-col>
<a-col :xs="24" :md="12">
@@ -96,7 +96,7 @@
openHistoryModal(true, {
formData,
formUrl,
title: '流程历史',
title: record.bpmBizTitle || '流程历史',
showSupplementApprovalOpinion: true,
});
if (props.isRead === 0 && record?.ccId) {
@@ -35,7 +35,7 @@
openHandleModal(true, {
formData,
formUrl,
title: '流程办理',
title: record.bpmBizTitle || '流程办理',
});
}
@@ -33,7 +33,7 @@
openModal(true, {
formData,
formUrl,
title: '流程历史',
title: record.bpmBizTitle || '流程历史',
showSupplementApprovalOpinion: true,
});
}
@@ -70,7 +70,7 @@
openHandleModal(true, {
formData,
formUrl,
title: '流程办理',
title: record.bpmBizTitle || '流程办理',
});
}
@@ -162,7 +162,7 @@
formData,
formUrl,
isSignTask,
title: '流程办理',
title: record.bpmBizTitle || '流程办理',
});
}