feat(xispeak): 优化流程审批表单权限控制和样式

- 新增 showBaseInfo/baseInfoReadonly 基础信息区域权限控制
- 新增 jiJianFieldsReadonly 纪检字段只读权限
- 隐藏落实方案、完成风险、拖期风险、父级节点、落实情况等字段
- 截止日期精度从时分秒改为日期
- 优化禁用态输入框/单选/数字输入样式
- 优化反馈附件列表样式

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wsm
2026-05-26 10:55:00 +08:00
co-authored by Claude Opus 4.7
parent a3d2c0b86e
commit a538b3113e
2 changed files with 100 additions and 51 deletions
@@ -70,17 +70,17 @@
<!-- </a-col>--> <!-- </a-col>-->
<a-col v-if="showJiJianFields" :span="12"> <a-col v-if="showJiJianFields" :span="12">
<a-form-item label="检查情况(纪检)" name="checkStatus"> <a-form-item label="检查情况(纪检)" name="checkStatus">
<a-input v-model:value="formData.checkStatus" placeholder="填写监督检查情况,成果是否完整,符合,时间是否按时等" allow-clear /> <a-input v-model:value="formData.checkStatus" placeholder="填写监督检查情况,成果是否完整,符合,时间是否按时等" :disabled="jiJianFieldsReadonly" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col v-if="showJiJianFields" :span="24"> <a-col v-if="showJiJianFields" :span="24">
<a-form-item label="监督意见(纪检)" name="inspectionAdvice" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol"> <a-form-item label="监督意见(纪检)" name="inspectionAdvice" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.inspectionAdvice" placeholder="是否通过审核" :rows="3" allow-clear /> <a-textarea v-model:value="formData.inspectionAdvice" placeholder="是否通过审核" :rows="3" :disabled="jiJianFieldsReadonly" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col v-if="showJiJianFields" :span="12"> <a-col v-if="showJiJianFields" :span="12">
<a-form-item label="措施数量(纪检)" name="measureNum"> <a-form-item label="措施数量(纪检)" name="measureNum">
<a-input-number v-model:value="formData.measureNum" placeholder="填写本条举措设计的措施数量" style="width: 100%" allow-clear /> <a-input-number v-model:value="formData.measureNum" placeholder="填写本条举措设计的措施数量" style="width: 100%" :disabled="jiJianFieldsReadonly" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="24"> <a-col :span="24">
@@ -114,6 +114,7 @@
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
const props = defineProps({ const props = defineProps({
showJiJianFields: { type: Boolean, default: false }, showJiJianFields: { type: Boolean, default: false },
jiJianFieldsReadonly: { type: Boolean, default: false },
}); });
const { createMessage } = useMessage(); const { createMessage } = useMessage();
const userStore = useUserStore(); const userStore = useUserStore();
@@ -70,11 +70,11 @@
<j-select-dept v-model:value="mainForm.implDept" :disabled="mainDisabled" :multiple="true" checkStrictly allow-clear /> <j-select-dept v-model:value="mainForm.implDept" :disabled="mainDisabled" :multiple="true" checkStrictly allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <!-- <a-col :span="12">-->
<a-form-item label="落实方案" name="implPlan"> <!-- <a-form-item label="落实方案" name="implPlan">-->
<a-input v-model:value="mainForm.implPlan" :disabled="mainDisabled" allow-clear /> <!-- <a-input v-model:value="mainForm.implPlan" :disabled="mainDisabled" allow-clear />-->
</a-form-item> <!-- </a-form-item>-->
</a-col> <!-- </a-col>-->
<a-col :span="12"> <a-col :span="12">
<a-form-item label="贯彻落实措施" name="implMeasures"> <a-form-item label="贯彻落实措施" name="implMeasures">
<a-input v-model:value="mainForm.implMeasures" :disabled="mainDisabled" allow-clear /> <a-input v-model:value="mainForm.implMeasures" :disabled="mainDisabled" allow-clear />
@@ -102,6 +102,7 @@
dictCode="db_status" dictCode="db_status"
placeholder="请选择完成状态" placeholder="请选择完成状态"
type="radio" type="radio"
:stringToNumber="true"
:disabled="mainDisabled" :disabled="mainDisabled"
/> />
</a-form-item> </a-form-item>
@@ -110,8 +111,7 @@
<a-form-item label="截止日期" name="deadline"> <a-form-item label="截止日期" name="deadline">
<a-date-picker <a-date-picker
v-model:value="mainForm.deadline" v-model:value="mainForm.deadline"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD"
:show-time="true"
:disabled="mainDisabled" :disabled="mainDisabled"
style="width: 100%" style="width: 100%"
allow-clear allow-clear
@@ -123,14 +123,14 @@
<a-input v-model:value="mainForm.reportFeedbackStatus" :disabled="mainDisabled" allow-clear /> <a-input v-model:value="mainForm.reportFeedbackStatus" :disabled="mainDisabled" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <!-- <a-col :span="12">-->
<a-form-item label="是否存在完成风险" name="isCompletionRisk"> <!-- <a-form-item label="是否存在完成风险" name="isCompletionRisk">-->
<a-radio-group v-model:value="mainForm.isCompletionRisk" :disabled="mainDisabled"> <!-- <a-radio-group v-model:value="mainForm.isCompletionRisk" :disabled="mainDisabled">-->
<a-radio :value="0">不存在</a-radio> <!-- <a-radio :value="0">不存在</a-radio>-->
<a-radio :value="1">存在</a-radio> <!-- <a-radio :value="1">存在</a-radio>-->
</a-radio-group> <!-- </a-radio-group>-->
</a-form-item> <!-- </a-form-item>-->
</a-col> <!-- </a-col>-->
<a-col :span="12"> <a-col :span="12">
<a-form-item label="是否需要督办领导" name="needSdwApproval"> <a-form-item label="是否需要督办领导" name="needSdwApproval">
<a-radio-group v-model:value="mainForm.needSdwApproval" :disabled="mainDisabled"> <a-radio-group v-model:value="mainForm.needSdwApproval" :disabled="mainDisabled">
@@ -144,34 +144,34 @@
<j-select-user v-model:value="mainForm.sdwLeaderList" :disabled="mainDisabled" :multiple="true" allow-clear /> <j-select-user v-model:value="mainForm.sdwLeaderList" :disabled="mainDisabled" :multiple="true" allow-clear />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <!-- <a-col :span="12">-->
<a-form-item label="拖期风险应对措施" name="delayRiskMitigation"> <!-- <a-form-item label="拖期风险应对措施" name="delayRiskMitigation">-->
<a-input v-model:value="mainForm.delayRiskMitigation" :disabled="mainDisabled" allow-clear /> <!-- <a-input v-model:value="mainForm.delayRiskMitigation" :disabled="mainDisabled" allow-clear />-->
</a-form-item> <!-- </a-form-item>-->
</a-col> <!-- </a-col>-->
<a-col :span="12"> <a-col :span="12">
<a-form-item label="督办次数" name="supervisionCount"> <a-form-item label="督办次数" name="supervisionCount">
<a-input-number v-model:value="mainForm.supervisionCount" :disabled="mainDisabled" style="width: 100%" /> <a-input-number v-model:value="mainForm.supervisionCount" :disabled="mainDisabled" style="width: 100%" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :span="12"> <!-- <a-col :span="12">-->
<a-form-item label="父级节点" name="pid"> <!-- <a-form-item label="父级节点" name="pid">-->
<j-tree-select <!-- <j-tree-select-->
v-model:value="mainForm.pid" <!-- v-model:value="mainForm.pid"-->
dict="bg_xi_speak,impl_status,id" <!-- dict="bg_xi_speak,impl_status,id"-->
pidField="pid" <!-- pidField="pid"-->
pidValue="0" <!-- pidValue="0"-->
hasChildField="has_child" <!-- hasChildField="has_child"-->
:disabled="mainDisabled" <!-- :disabled="mainDisabled"-->
allow-clear <!-- allow-clear-->
/> <!-- />-->
</a-form-item> <!-- </a-form-item>-->
</a-col> <!-- </a-col>-->
<a-col :span="12"> <!-- <a-col :span="12">-->
<a-form-item label="落实情况" name="implStatus"> <!-- <a-form-item label="落实情况" name="implStatus">-->
<a-textarea v-model:value="mainForm.implStatus" :auto-size="{ minRows: 1, maxRows: 7 }" :disabled="mainDisabled" allow-clear /> <!-- <a-textarea v-model:value="mainForm.implStatus" :auto-size="{ minRows: 1, maxRows: 7 }" :disabled="mainDisabled" allow-clear />-->
</a-form-item> <!-- </a-form-item>-->
</a-col> <!-- </a-col>-->
</template> </template>
</a-row> </a-row>
</a-form> </a-form>
@@ -204,7 +204,7 @@
:columns="feedbackColumns" :columns="feedbackColumns"
:data-source="feedbackList" :data-source="feedbackList"
:pagination="false" :pagination="false"
:scroll="{ x: 2080 }" :scroll="{ x: 1980 }"
> >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'attachments'"> <template v-if="column.key === 'attachments'">
@@ -220,9 +220,15 @@
</template> </template>
</a-table> </a-table>
<BgXiSpeakBPMFeedbackModal ref="feedbackModalRef" :showJiJianFields="showJiJianFields" @success="loadFeedbackList" /> <BgXiSpeakBPMFeedbackModal
ref="feedbackModalRef"
:showJiJianFields="showJiJianFields"
:jiJianFieldsReadonly="jiJianFieldsReadonly"
@success="loadFeedbackList"
/>
<template v-if="showProcessHandle"> <template v-if="showProcessHandle">
<a-divider /> <a-divider />
<div class="process-header section-toolbar"> <div class="process-header section-toolbar">
<div class="section-title">流程办理</div> <div class="section-title">流程办理</div>
@@ -351,7 +357,7 @@
{ title: '是否有报送上级报告', dataIndex: 'isReportedToHigher_dictText', align: 'center', width: 140 }, { title: '是否有报送上级报告', dataIndex: 'isReportedToHigher_dictText', align: 'center', width: 140 },
{ title: '进展情况', dataIndex: 'progress', align: 'left', width: 200 }, { title: '进展情况', dataIndex: 'progress', align: 'left', width: 200 },
{ title: '落实情况', dataIndex: 'implStatus', align: 'left', width: 200 }, { title: '落实情况', dataIndex: 'implStatus', align: 'left', width: 200 },
{ title: '附件', dataIndex: 'id', key: 'attachments', align: 'left', width: 340 }, { title: '附件', dataIndex: 'id', key: 'attachments', align: 'left', width: 280 },
]; ];
if (showJiJianFields.value) { if (showJiJianFields.value) {
cols.push( cols.push(
@@ -387,9 +393,11 @@
if (explicit === '0') return false; if (explicit === '0') return false;
if (explicit === '1') return true; if (explicit === '1') return true;
// 未显式设置时,任一子属性开启则自动显示反馈区域 // 未显式设置时,任一子属性开启则自动显示反馈区域
return String(p?.showAddFeedback ?? p?.addfeedback ?? '') === '1' return (
|| String(p?.showEditFeedback ?? p?.editfeedback ?? '') === '1' String(p?.showAddFeedback ?? p?.addfeedback ?? '') === '1' ||
|| String(p?.showDeptFeedback ?? p?.deptfeedback ?? '') === '1'; String(p?.showEditFeedback ?? p?.editfeedback ?? '') === '1' ||
String(p?.showDeptFeedback ?? p?.deptfeedback ?? '') === '1'
);
}); });
const showEditFeedback = computed( const showEditFeedback = computed(
() => String(props.formData?.extendUrlParams?.showEditFeedback ?? props.formData?.extendUrlParams?.editfeedback ?? '') === '1' () => String(props.formData?.extendUrlParams?.showEditFeedback ?? props.formData?.extendUrlParams?.editfeedback ?? '') === '1'
@@ -398,6 +406,7 @@
() => String(props.formData?.extendUrlParams?.showDeptFeedback ?? props.formData?.extendUrlParams?.deptfeedback ?? '') === '1' () => String(props.formData?.extendUrlParams?.showDeptFeedback ?? props.formData?.extendUrlParams?.deptfeedback ?? '') === '1'
); );
const showJiJianFields = computed(() => String(props.formData?.extendUrlParams?.showJiJianFields ?? '') === '1'); const showJiJianFields = computed(() => String(props.formData?.extendUrlParams?.showJiJianFields ?? '') === '1');
const jiJianFieldsReadonly = computed(() => String(props.formData?.extendUrlParams?.jiJianFieldsReadonly ?? '') === '1');
const showDeptFields = computed(() => String(props.formData?.extendUrlParams?.deptfields ?? '') === '1'); const showDeptFields = computed(() => String(props.formData?.extendUrlParams?.deptfields ?? '') === '1');
const showSubApproveUser = computed( const showSubApproveUser = computed(
() => String(props.formData?.extendUrlParams?.showSubApproveUser ?? props.formData?.extendUrlParams?.selectuser ?? '') === '1' () => String(props.formData?.extendUrlParams?.showSubApproveUser ?? props.formData?.extendUrlParams?.selectuser ?? '') === '1'
@@ -438,7 +447,7 @@
if (!dataId) { if (!dataId) {
return; return;
} }
showBaseInfoDetail.value = false; showBaseInfoDetail.value = true;
loading.value = true; loading.value = true;
try { try {
const data = await defHttp.get({ url: queryByIdUrl, params: { id: dataId } }); const data = await defHttp.get({ url: queryByIdUrl, params: { id: dataId } });
@@ -713,6 +722,7 @@
} }
:deep(.ant-input), :deep(.ant-input),
:deep(.ant-input-number),
:deep(.ant-picker), :deep(.ant-picker),
:deep(.ant-select-selector) { :deep(.ant-select-selector) {
min-height: 30px; min-height: 30px;
@@ -730,6 +740,9 @@
:deep(.ant-input-outlined[disabled]), :deep(.ant-input-outlined[disabled]),
:deep(.ant-input-outlined.ant-input-disabled), :deep(.ant-input-outlined.ant-input-disabled),
:deep(textarea.ant-input[disabled]), :deep(textarea.ant-input[disabled]),
:deep(.ant-input-number-disabled),
:deep(.ant-input-number-disabled:hover),
:deep(.ant-input-number-disabled:focus),
:deep(.ant-picker-disabled), :deep(.ant-picker-disabled),
:deep(.ant-select-disabled .ant-select-selector) { :deep(.ant-select-disabled .ant-select-selector) {
background: transparent !important; background: transparent !important;
@@ -743,6 +756,7 @@
:deep(.ant-input[disabled]), :deep(.ant-input[disabled]),
:deep(.ant-input-disabled), :deep(.ant-input-disabled),
:deep(.ant-input-affix-wrapper-disabled), :deep(.ant-input-affix-wrapper-disabled),
:deep(.ant-input-number-disabled),
:deep(textarea.ant-input[disabled]) { :deep(textarea.ant-input[disabled]) {
padding-left: 0 !important; padding-left: 0 !important;
padding-right: 0 !important; padding-right: 0 !important;
@@ -754,6 +768,13 @@
cursor: default !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-disabled::placeholder), :deep(.ant-input-disabled::placeholder),
:deep(.ant-input-affix-wrapper-disabled .ant-input::placeholder) { :deep(.ant-input-affix-wrapper-disabled .ant-input::placeholder) {
@@ -788,9 +809,23 @@
:deep(.ant-picker-disabled .ant-picker-suffix), :deep(.ant-picker-disabled .ant-picker-suffix),
:deep(.ant-input-disabled .ant-input-clear-icon), :deep(.ant-input-disabled .ant-input-clear-icon),
:deep(.ant-input-affix-wrapper-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) { :deep(.ant-select-disabled .ant-select-clear) {
display: none; display: none;
} }
:deep(.ant-radio-wrapper-disabled) {
color: #1f2937 !important;
cursor: default !important;
}
:deep(.ant-radio-wrapper-disabled:not(.ant-radio-wrapper-checked)) {
display: none;
}
:deep(.ant-radio-disabled .ant-radio-inner) {
display: none;
}
} }
.feedback-header { .feedback-header {
@@ -820,11 +855,12 @@
} }
.feedback-attachment-list { .feedback-attachment-list {
min-width: 300px; min-width: 240px;
:deep(.file-list-wrapper) { :deep(.file-list-wrapper) {
min-height: auto; min-height: 20px;
padding: 8px; max-height: 50px;
padding: 4px 8px;
} }
:deep(.file-list-header) { :deep(.file-list-header) {
@@ -839,6 +875,18 @@
:deep(.ant-empty) { :deep(.ant-empty) {
margin: 0; margin: 0;
padding: 4px 0;
.ant-empty-image {
display: none;
}
.ant-empty-description {
font-size: 12px;
color: #999;
padding: 0;
margin: 0;
}
} }
} }
</style> </style>