提交 aa04eea3 authored 作者: kxjia's avatar kxjia

问题管理

上级 df2abfb6
......@@ -141,7 +141,9 @@ export const batchDelete = (params, handleSuccess) => {
return defHttp.delete(
{
url: "/flowable/definition/batchDelete",
data: params}
params: params
},
{joinParamsToUrl: true}
).then(() => {
handleSuccess();
});
......@@ -188,3 +190,11 @@ export function definitionStartByDeployId(deployId, data) {
})
}
//根据部署ID查询流程定义信息
export function getNodesByTableName(tableName) {
return defHttp.get({
url: '/flowable/form/getNodesByTableName',
params: {tableName:tableName}
})
}
<template>
<div style="margin:10px;height: 100%;">
<div style="height: 80vh;overflow: hidden;padding: 10px;">
<vxe-grid ref="tableRef" v-bind="gridOptions">
<template #toolbarButtons>
<vxe-button status="primary" icon="vxe-icon-add" @click="handleAdd" :loading="loading.add">新增</vxe-button>
......@@ -107,7 +107,6 @@ const srhParams = ref<SrhParam>({
const gridOptions = reactive<VxeGridProps<RowVO>>({
border: true,
height: "100%",
rowConfig: {
keyField: 'id'
},
......@@ -119,7 +118,18 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
},
pagerConfig: {
enabled: true,
pageSize: 10
pageSize: 10,
currentPage: 1,
pageSizes: [
{ label: '10 条', value: 10 },
{ label: '20 条', value: 20 },
{ label: '50 条', value: 50 },
{ label: '100 条', value: 100 }
],
layouts: ['Total', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'Sizes', 'FullJump'],
perfect: false,
autoHidden: false,
align: 'right'
},
toolbarConfig: {
refresh: false,
......@@ -137,7 +147,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
{ title: '流程编号', field: 'deploymentId', align: 'left', minWidth: '18%' },
{ title: '业务表单', field: 'formName', align: 'center', width: '10%', visible: false },
{ title: '流程版本', field: 'version', align: 'center', width: '10%' },
{ title: '最新版本', field: 'isLastVersion', align: 'center', width: '10%' },
{ title: '最新版本', field: 'isLastVersion', align: 'center', width: '10%', visible: false },
{
title: '状态', field: 'suspensionState', align: 'center', width: '10%',
formatter: ({ cellValue }) => {
......@@ -149,7 +159,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
}
},
{
title: '部署时间', field: 'deploymentTime', align: 'center', width: '10%',
title: '部署时间', field: 'deploymentTime', align: 'center', width: '14%',
formatter: ({ cellValue }) => {
if (!cellValue) return '-'
return new Date(cellValue).toLocaleString()
......@@ -158,7 +168,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
{
title: '操作',
align: 'center',
width: '16%',
width: '20%',
fixed: 'right',
slots: { default: 'operate' }
}
......@@ -167,7 +177,7 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
seq: true,
props: {
result: 'result',
total: 'page.total'
total: 'total'
},
ajax: {
query: ({ page }) => {
......@@ -202,9 +212,7 @@ const findPageList = async (currentPage: number, pageSize: number) => {
srhParams.value.pageSize = pageSize;
const retData = await setData();
return {
page: {
total: retData.total
},
total: retData.total,
result: retData.records
};
};
......@@ -341,20 +349,13 @@ async function handleBatchDelete(ids?: string[]) {
if (isOperationInProgress('batchDelete')) return;
const selectedIds = ids || await getSelectIds();
if (selectedIds.length === 0) {
// 可以添加提示
// message.warning('请选择要删除的流程');
return;
}
setOperationState('batchDelete', null, true);
try {
await batchDelete({ ids: selectedIds.join(",") }, handleSuccess)
// 可以在这里添加成功提示
// message.success(`成功删除 ${selectedIds.length} 个流程`);
} catch (error) {
console.error('批量删除失败:', error);
// 可以在这里添加错误提示
// message.error('批量删除失败');
} finally {
setOperationState('batchDelete', null, false);
}
......
......@@ -249,7 +249,7 @@ const submitForm = async () => {
const submitFn = formState.formId ? updateForm : addForm
await submitFn(formState)
message.success(formState.formId ? '修改成功' : '新增成功')
//message.success(formState.formId ? '修改成功' : '新增成功')
formOpen.value = false
resetForm()
......
......@@ -110,12 +110,12 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
},
columns: [
{ type: 'checkbox', visible: true, width: '40', showOverflow: false },
{ title: '表单主键', field: 'formId', align: 'center', width: '200' },
{ title: '表单编号', field: 'formId', align: 'center', width: '100' },
{
title: '表单类别',
field: 'formTp',
align: 'center',
width: '200',
width: '100',
filters: tpOptions,
filterMultiple: false,
formatter ({ cellValue }) {
......@@ -123,13 +123,14 @@ const gridOptions = reactive<VxeGridProps<RowVO>>({
return item ? item.label : ''
}
},
{ title: '表单名称', field: 'formName', align: 'left', minWidth: '200' },
{ title: '表单地址', field: 'formUrl', align: 'left', minWidth: '200' },
{ title: '备注', field: 'remark', align: 'left', minWidth: '200'},
{ title: '表单名称', field: 'formName', align: 'left', width: '300' },
{ title: '表单地址', field: 'formUrl', align: 'left', minWidth: '220' },
{ title: '列表地址', field: 'formListurl', align: 'left', minWidth: '220' },
{ title: '备注', field: 'remark', align: 'left', minWidth: '100'},
{
title: '操作',
align: 'center',
width: '200',
width: '130',
fixed: 'right',
slots: { default: 'operate' }
}
......
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import { useRoute } from 'vue-router';
const route = useRoute();
//注册model
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
//注册table数据
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '问题归档',
api: list,
columns,
canResize: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch(params) {
params['id'] = route.query.id
},
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handleArchive(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function getTableAction(record) {
return [
{
label: '问题归档',
onClick: handleArchive.bind(null, record),
},
];
}
</script>
<style scoped></style>
<template>
<div>
<!--Tab页导航-->
<a-tabs v-model:activeKey="activeTab" @change="handleTabChange" style="margin-left: 16px">
<a-tab-pane key="1" tab="待计划" />
<a-tab-pane key="2" tab="待执行" />
<a-tab-pane key="3" tab="待审核" />
<a-tab-pane key="4" tab="已完成" />
</a-tabs>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
......@@ -35,49 +27,23 @@
</template>
</BasicTable>
<!-- 表单区域 -->
<StProblemCheckModal @register="registerModal" @success="handleSuccess" />
<!-- 整改计划 -->
<StProblemCheckPlanModal @register="registerPlanModal" @success="handleSuccess" />
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
<!-- 整改审核 -->
<StProblemCheckReviewModal @register="registerReviewModal" @success="handleSuccess" />
<!-- <StProblemCheckFlowModal ref="refStProblemCheckFlow" /> -->
<StProblemCheckModal @register="registerModal" @success="handleSuccess" :bmpNodeId="1" />
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import StProblemCheckModal from './components/StProblemCheckModal.vue';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './StProblemCheck.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import StProblemCheckPlanModal from './components/StProblemCheckPlanModal.vue';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import StProblemCheckReviewModal from './components/StProblemCheckReviewModal.vue';
import StProblemCheckFlowModal from './components/StProblemCheckFlowModal.vue';
import { store } from '/@/store';
import { definitionStartByDeployId } from '/@/components/Process/api/definition';
import { useRoute } from 'vue-router';
const route = useRoute();
const checkedKeys = ref<Array<string | number>>([]);
//Tab页状态
const activeTab = ref('1');
//Tab页切换事件
function handleTabChange(key) {
activeTab.value = key;
reload();
}
//注册model
const [registerModal, { openModal }] = useModal();
const [registerPlanModal, { openModal: openPlanModal }] = useModal();
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
const [registerReviewModal, { openModal: openReviewModal }] = useModal();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
......@@ -94,17 +60,10 @@
fieldMapToTime: [],
},
beforeFetch(params) {
//根据Tab页筛选状态
const tabStatusMap = {
'1': '1', //待计划
'2': '2', //待执行
'3': '3', //待审核
'4': '4', //已完成
};
params['bpmStatus'] = tabStatusMap[activeTab.value];
params['id'] ="" //route.query.id
},
actionColumn: {
width: 200,
width: 400,
fixed: 'right',
},
},
......@@ -127,7 +86,7 @@
openModal(true, {
isUpdate: false,
showFooter: true,
bpmStatus: activeTab.value,
bmpNodeId: route.query.bmpNodeId
});
}
/**
......@@ -138,7 +97,6 @@
record,
isUpdate: true,
showFooter: true,
bpmStatus: activeTab.value,
});
}
function handlePlan(record: Recordable) {
......@@ -148,20 +106,7 @@
showFooter: true,
});
}
function handleExecute(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleReview(record: Recordable) {
openReviewModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
......@@ -194,50 +139,27 @@
* 操作栏
*/
function getTableAction(record) {
const actions = [
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '启动流程',
// onClick: handleFlow.bind(null, record),
ifShow: () => {
if (record['bpmStatus'] == null || record['bpmStatus'] == '') return true;
else return false;
},
onClick: handleFlow.bind(null, record),
// ifShow: ()=> {
// if(record['bpmStatus']==null||record['bpmStatus']=='')
// return true
// else return false
// }
},
];
//根据当前Tab页显示不同的操作按钮
switch (activeTab.value) {
case '1': //待计划
actions.push({
label: '去计划',
onClick: handlePlan.bind(null, record),
});
break;
case '2': //待执行
actions.push({
label: '去执行',
onClick: handleExecute.bind(null, record),
});
break;
case '3': //待审核
actions.push({
label: '去审核',
onClick: handleReview.bind(null, record),
});
break;
case '4': //已完成
actions.push({
label: '查看详情',
onClick: handleDetail.bind(null, record),
});
break;
}
// {
// label: '整改计划',
// onClick: handlePlan.bind(null, record),
// },
return actions;
];
}
/**
* 下拉操作栏
......@@ -258,16 +180,18 @@
];
}
const formData = ref<any>({}); // 填写的表单数据
// const refStProblemCheckFlow = ref();
// function handleFlow(record: Recordable) {
// formData.dataId = record.id;
// formData.dataName = 'id';
// definitionStartByDeployId(record.deployId, formData).then((res) => {
// console.log('计划启动----------- res', res);
// handle.valueSuccess();
// });
// }
const formData = ref<any>({}) // 填写的表单数据
const refStProblemCheckFlow = ref();
function handleFlow(record: Recordable) {
formData.dataId=record.id;
formData.dataName='id';
definitionStartByDeployId(record.deployId, formData).then(res => {
handleSuccess();
})
}
</script>
<style scoped></style>
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import { useRoute } from 'vue-router';
const route = useRoute();
//注册model
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
//注册table数据
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '计划执行审批',
api: list,
columns,
canResize: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch(params) {
params['id'] = route.query.id
},
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handleExecuteApproval(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function getTableAction(record) {
return [
{
label: '整改审核',
onClick: handleExecuteApproval.bind(null, record),
},
];
}
</script>
<style scoped></style>
......@@ -4,70 +4,36 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button
>批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
<!-- 表单区域 -->
<StProblemCheckModal @register="registerModal" @success="handleSuccess" />
<!-- 整改计划 -->
<StProblemCheckPlanModal @register="registerPlanModal" @success="handleSuccess" />
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
<!-- 整改审核 -->
<StProblemCheckReviewModal @register="registerReviewModal" @success="handleSuccess" />
<!-- <StProblemCheckFlowModal ref="refStProblemCheckFlow" /> -->
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import StProblemCheckModal from './components/StProblemCheckModal.vue';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './StProblemCheck.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import StProblemCheckPlanModal from './components/StProblemCheckPlanModal.vue';
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import StProblemCheckReviewModal from './components/StProblemCheckReviewModal.vue';
import StProblemCheckFlowModal from './components/StProblemCheckFlowModal.vue';
import { store } from '/@/store';
import { definitionStartByDeployId } from "/@/components/Process/api/definition"
import { useRoute } from 'vue-router';
const route = useRoute();
const checkedKeys = ref<Array<string | number>>([]);
//注册model
const [registerModal, { openModal }] = useModal();
const [registerPlanModal, { openModal: openPlanModal }] = useModal();
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
const [registerReviewModal, { openModal: openReviewModal }] = useModal();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '问题整改',
api: list,
......@@ -85,48 +51,14 @@
params['id'] = route.query.id
},
actionColumn: {
width: 400,
width: 200,
fixed: 'right',
},
},
exportConfig: {
name: '问题整改',
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handlePlan(record: Recordable) {
openPlanModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleExecute(record: Recordable) {
openExecuteModal(true, {
record,
......@@ -134,103 +66,19 @@
showFooter: true,
});
}
function handleReview(record: Recordable) {
openReviewModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '启动流程',
onClick: handleFlow.bind(null, record),
ifShow: ()=> {
if(record['bpmStatus']==null||record['bpmStatus']=='')
return true
else return false
}
},
{
label: '整改计划',
onClick: handlePlan.bind(null, record),
},
{
label: '整改执行',
onClick: handleExecute.bind(null, record),
},
{
label: '整改审核',
onClick: handleReview.bind(null, record),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
];
}
const formData = ref<any>({}) // 填写的表单数据
const refStProblemCheckFlow = ref();
function handleFlow(record: Recordable) {
formData.dataId=record.id;
formData.dataName='id';
definitionStartByDeployId(record.deployId, formData).then(res => {
handleSuccess();
})
}
</script>
......
<template>
<div>
<a-tabs v-model:activeKey="activeTab" @change="handleTabChange" style="margin-left: 16px">
<a-tab-pane v-for="(node, index) in workflowNodes" :key="index + 1" :tab="node.name">
<div v-if="node.formListUrl" class="tab-content">
<component :is="loadComponent(node.formListUrl)" />
</div>
<div v-else class="no-form">
该节点未配置表单
</div>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, nextTick, onMounted, defineAsyncComponent, h } from 'vue';
import { useRoute } from 'vue-router';
import { getNodesByTableName } from '/@/components/Process/api/definition';
const route = useRoute();
const workflowNodes = ref<any[]>([]);
const activeTab = ref(1);
// 组件缓存,避免重复加载
const componentCache = new Map();
function handleTabChange(key) {
activeTab.value = key;
}
// 将formListurl转换为正确的导入路径并动态加载组件
function loadComponent(formListurl: string) {
console.log('开始加载组件,formListurl:', formListurl);
if (componentCache.has(formListurl)) {
console.log('从缓存加载组件:', formListurl);
return componentCache.get(formListurl);
}
// 解析formListurl,提取组件路径
// formListurl格式:/project/problemCheck/StProblemCheckList
// 转换为:./StProblemCheckList.vue
const pathParts = formListurl.split('/');
console.log('路径分割结果:', pathParts);
// 获取最后一个部分作为组件名
const componentName = pathParts[pathParts.length - 1];
console.log('提取的组件名:', componentName);
// 构建导入路径
const importPath = `./${componentName}.vue`;
console.log('生成的导入路径:', importPath);
const AsyncComponent = defineAsyncComponent({
loader: async () => {
try {
const module = await import(importPath);
return module.default || module;
} catch (error) {
console.error(`加载组件失败 (${formListurl}):`, error);
return { render: () => h('div', '组件加载失败') };
}
},
loadingComponent: { render: () => h('div', '加载中...') },
errorComponent: { render: () => h('div', '组件加载失败') },
// 延迟显示加载组件的时间(毫秒)
delay: 200,
// 超时时间(毫秒)
timeout: 3000
});
componentCache.set(formListurl, AsyncComponent);
return AsyncComponent;
}
onMounted(async () => {
await nextTick();
try {
const nodes = await getNodesByTableName("st_problem_check");
const nodeData = nodes?.data?.records || nodes?.records || nodes || [];
workflowNodes.value = nodeData;
} catch (error) {
console.error('获取工作流节点失败:', error);
}
});
</script>
<style scoped>
.tab-content {
padding: 0px;
}
.no-form {
padding: 40px;
text-align: center;
color: #999;
}
</style>
<template>
<div>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import { useRoute } from 'vue-router';
const route = useRoute();
//注册model
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
//注册table数据
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '问题整改',
api: list,
columns,
canResize: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToNumber: [],
fieldMapToTime: [],
},
beforeFetch(params) {
params['id'] = route.query.id
},
actionColumn: {
width: 200,
fixed: 'right',
},
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handlePlanApproval(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
function getTableAction(record) {
return [
{
label: '计划审核',
onClick: handlePlanApproval.bind(null, record),
},
];
}
</script>
<style scoped></style>
......@@ -4,72 +4,35 @@
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined" />
删除
</a-menu-item>
</a-menu>
</template>
<a-button
>批量操作
<Icon icon="mdi:chevron-down" />
</a-button>
</a-dropdown>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
<TableAction :actions="getTableAction(record)"/>
</template>
</BasicTable>
<!-- 表单区域 -->
<StProblemCheckModal @register="registerModal" @success="handleSuccess" />
<!-- 整改计划 -->
<StProblemCheckPlanModal @register="registerPlanModal" @success="handleSuccess" />
<!-- 整改执行 -->
<StProblemCheckExecuteModal @register="registerExecuteModal" @success="handleSuccess" />
<!-- 整改审核 -->
<StProblemCheckReviewModal @register="registerReviewModal" @success="handleSuccess" />
<!-- <StProblemCheckFlowModal ref="refStProblemCheckFlow" /> -->
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, computed, unref } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { ref } from 'vue';
import { BasicTable, TableAction } from '/@/components/Table';
import { useModal } from '/@/components/Modal';
import { useListPage } from '/@/hooks/system/useListPage';
import StProblemCheckModal from './components/StProblemCheckModal.vue';
import { columns, searchFormSchema } from './StProblemCheck.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './StProblemCheck.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import StProblemCheckPlanModal from './components/StProblemCheckPlanModal.vue';
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
import StProblemCheckReviewModal from './components/StProblemCheckReviewModal.vue';
import StProblemCheckFlowModal from './components/StProblemCheckFlowModal.vue';
import { store } from '/@/store';
import { definitionStartByDeployId } from "/@/components/Process/api/definition"
import { useRoute } from 'vue-router';
const route = useRoute();
const checkedKeys = ref<Array<string | number>>([]);
//注册model
const [registerModal, { openModal }] = useModal();
const [registerPlanModal, { openModal: openPlanModal }] = useModal();
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
const [registerReviewModal, { openModal: openReviewModal }] = useModal();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '问题整改',
title: '问题整改计划',
api: list,
columns,
canResize: false,
......@@ -85,152 +48,34 @@
params['id'] = route.query.id
},
actionColumn: {
width: 400,
width: 200,
fixed: 'right',
},
},
exportConfig: {
name: '问题整改',
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handlePlan(record: Recordable) {
openPlanModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleExecute(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
function handleReview(record: Recordable) {
openReviewModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '启动流程',
onClick: handleFlow.bind(null, record),
ifShow: ()=> {
if(record['bpmStatus']==null||record['bpmStatus']=='')
return true
else return false
}
},
{
label: '整改计划',
label: '制定整改计划',
onClick: handlePlan.bind(null, record),
},
{
label: '整改执行',
onClick: handleExecute.bind(null, record),
},
{
label: '整改审核',
onClick: handleReview.bind(null, record),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '删除',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
];
}
const formData = ref<any>({}) // 填写的表单数据
const refStProblemCheckFlow = ref();
function handleFlow(record: Recordable) {
formData.dataId=record.id;
formData.dataName='id';
definitionStartByDeployId(record.deployId, formData).then(res => {
handleSuccess();
})
}
</script>
......
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm">
<BasicModal
v-bind="$attrs"
@register="registerModal"
destroyOnClose
:title="modalTitle"
:width="modalWidth"
:fullscreen="true"
@ok="handleSubmit"
class="problem-check-plan-modal"
>
<div class="plan-modal-content">
<a-row :gutter="16" class="plan-content-wrapper">
<!-- 左侧:问题内容展示区域 -->
<a-col :xs="24" :sm="24" :md="12" :lg="10" :xl="9" class="problem-display-section">
<div class="problem-display-card">
<div class="section-header">
<Icon icon="carbon:warning-alt" class="header-icon" />
<span class="header-title">问题详情</span>
</div>
<div class="problem-content">
<div class="problem-item">
<div class="item-label">问题编号:</div>
<div class="item-value">{{ problemData.problemNo || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">项目分类:</div>
<div class="item-value">{{ problemData.projectCategory || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">问题来源:</div>
<div class="item-value">{{ problemData.problemSource || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">所属领域:</div>
<div class="item-value">{{ problemData.domain || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">风险等级:</div>
<div class="item-value">
<a-tag :color="getRiskLevelColor(problemData.riskLevel)">{{ problemData.riskLevel || '-' }}</a-tag>
</div>
</div>
<div class="problem-item">
<div class="item-label">严重程度:</div>
<div class="item-value">
<a-tag :color="getSeverityColor(problemData.severity)">{{ problemData.severity || '-' }}</a-tag>
</div>
</div>
<div class="problem-item problem-des">
<div class="item-label">问题描述:</div>
<div class="item-value">{{ problemData.problemDes || '-' }}</div>
</div>
</div>
</div>
</a-col>
<!-- 右侧:计划表单区域 -->
<a-col :xs="24" :sm="24" :md="12" :lg="14" :xl="15" class="plan-form-section">
<div class="plan-form-card">
<div class="section-header">
<Icon icon="carbon:task-approved" class="header-icon" />
<span class="header-title">制定计划</span>
</div>
<BasicForm @register="registerForm" class="plan-form">
<template #jSelectUser="{ model, field }">
<JSelectUser v-model:value="model[field]" />
</template>
</BasicForm>
</div>
</a-col>
</a-row>
</div>
<template #footer>
<a-button key="back" @click="handleCancel">取消</a-button>
<a-button key="submit" type="primary" @click="handleSubmit" :loading="confirmLoading">确定</a-button>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { ref, computed, unref, watch } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { executeFormSchema } from '../StProblemCheck.data';
import { Icon } from '/@/components/Icon';
import { JSelectUser } from '/@/components/Form';
import { planFormSchema } from '../StProblemCheck.data';
import { saveOrUpdate } from '../StProblemCheck.api';
import StProblemCheckExecuteForm from './StProblemCheckExecuteForm.vue';
import { message } from 'ant-design-vue';
// Emits声明
const emit = defineEmits(['register', 'success']);
// 状态变量
const isUpdate = ref(true);
const confirmLoading = ref(false);
const problemData = ref<any>({});
const modalWidth = ref('80%');
const bpmStatus = ref('');
// 动态标题
const modalTitle = computed(() => '制定计划');
// 响应式宽度调整
watch(
() => window.innerWidth,
(width) => {
if (width < 768) {
modalWidth.value = '100%';
} else if (width < 1200) {
modalWidth.value = '90%';
} else {
modalWidth.value = '80%';
}
},
{ immediate: true }
);
// 增强版表单配置 - 将整改方案改为富文本编辑器
const enhancedPlanFormSchema = [
...planFormSchema.map(schema => {
// 将整改方案字段改为富文本编辑器
if (schema.field === 'rectifyPlan') {
return {
...schema,
component: 'JEditor',
componentProps: {
height: 350,
placeholder: '请输入详细的整改方案...',
},
};
}
return schema;
}),
];
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: executeFormSchema,
schemas: enhancedPlanFormSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
bpmStatus.value = data?.bpmStatus || '';
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
//表单赋值
problemData.value = { ...data.record };
await setFieldsValue({
...data.record,
});
} else {
// 新增模式
problemData.value = data.record ? { ...data.record } : {};
await setFieldsValue({
bpmStatus: bpmStatus.value,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
// 获取风险等级颜色
function getRiskLevelColor(level: string) {
const colorMap: Record<string, string> = {
'高': 'red',
'中': 'orange',
'低': 'green',
};
return colorMap[level] || 'blue';
}
// 获取严重程度颜色
function getSeverityColor(severity: string) {
const colorMap: Record<string, string> = {
'严重': 'red',
'一般': 'orange',
'轻微': 'green',
};
return colorMap[severity] || 'blue';
}
//取消按钮
function handleCancel() {
closeModal();
}
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({ confirmLoading: true });
// 构建提交数据
const submitData = {
...values,
problemNo: problemData.value.problemNo,
projectCategory: problemData.value.projectCategory,
domain: problemData.value.domain,
};
//提交表单
await saveOrUpdate(values, isUpdate.value);
await saveOrUpdate(submitData, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
message.success('计划保存成功!');
} catch (error: any) {
console.error('提交失败:', error);
} finally {
setModalProps({ confirmLoading: false });
}
......@@ -61,6 +233,177 @@
</script>
<style lang="less" scoped>
.problem-check-plan-modal {
:deep(.ant-modal-body) {
padding: 0;
max-height: calc(100vh - 120px);
overflow-y: auto;
}
}
.plan-modal-content {
padding: 20px;
min-height: calc(100vh - 180px);
}
.plan-content-wrapper {
height: 100%;
}
// 左侧问题展示区域
.problem-display-section {
height: 100%;
margin-bottom: 16px;
@media (min-width: 768px) {
margin-bottom: 0;
}
}
.problem-display-card {
background: #f5f7fa;
border-radius: 8px;
padding: 20px;
height: 100%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 右侧表单区域
.plan-form-section {
height: 100%;
}
.plan-form-card {
background: #fff;
border-radius: 8px;
padding: 20px;
height: 100%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 区域标题
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 12px;
border-bottom: 2px solid #e8e8e8;
.header-icon {
font-size: 20px;
margin-right: 10px;
color: #1890ff;
}
.header-title {
font-size: 16px;
font-weight: 600;
color: #262626;
}
}
// 问题内容样式
.problem-content {
.problem-item {
margin-bottom: 16px;
display: flex;
.item-label {
width: 100px;
flex-shrink: 0;
font-weight: 500;
color: #595959;
font-size: 14px;
line-height: 1.6;
}
.item-value {
flex: 1;
color: #262626;
font-size: 14px;
line-height: 1.6;
word-break: break-word;
}
&.problem-des {
.item-value {
white-space: pre-wrap;
}
}
}
}
// 表单样式
.plan-form {
:deep(.ant-form-item) {
margin-bottom: 20px;
}
:deep(.ant-form-item-label) {
label {
font-weight: 500;
}
}
}
// 响应式调整
@media (max-width: 767px) {
.plan-modal-content {
padding: 12px;
}
.problem-display-card,
.plan-form-card {
padding: 16px;
}
.section-header {
margin-bottom: 16px;
.header-title {
font-size: 15px;
}
}
.problem-content {
.problem-item {
flex-direction: column;
.item-label {
width: auto;
margin-bottom: 4px;
}
}
}
}
@media (min-width: 768px) and (max-width: 1023px) {
.plan-modal-content {
padding: 16px;
}
}
// 滚动条美化
.plan-modal-content {
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 4px;
&:hover {
background: #999;
}
}
&::-webkit-scrollbar-track {
background: #f0f0f0;
}
}
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
......
......@@ -41,6 +41,7 @@
let formData = {};
const queryByIdUrl = '/problem/stProblemCheck/queryById/';
alert(props.formData.dataId)
async function initFormData() {
let params = { id: props.formData.dataId };
const data = await defHttp.get({ url: queryByIdUrl, params });
......
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<!-- <st-problem-check-form /> -->
<BasicForm @register="registerForm"></BasicForm>
<st-problem-check-form />
<!-- <BasicForm @register="registerForm"></BasicForm> -->
</BasicModal>
</template>
......
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm">
<BasicModal
v-bind="$attrs"
@register="registerModal"
destroyOnClose
:title="modalTitle"
:width="modalWidth"
:fullscreen="true"
@ok="handleSubmit"
class="problem-check-plan-modal"
>
<div class="plan-modal-content">
<a-row :gutter="16" class="plan-content-wrapper">
<!-- 左侧:问题内容展示区域 -->
<a-col :xs="24" :sm="24" :md="12" :lg="10" :xl="9" class="problem-display-section">
<div class="problem-display-card">
<div class="section-header">
<Icon icon="carbon:warning-alt" class="header-icon" />
<span class="header-title">问题详情</span>
</div>
<div class="problem-content">
<div class="problem-item">
<div class="item-label">问题编号:</div>
<div class="item-value">{{ problemData.problemNo || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">项目分类:</div>
<div class="item-value">{{ problemData.projectCategory || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">问题来源:</div>
<div class="item-value">{{ problemData.problemSource || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">所属领域:</div>
<div class="item-value">{{ problemData.domain || '-' }}</div>
</div>
<div class="problem-item">
<div class="item-label">风险等级:</div>
<div class="item-value">
<a-tag :color="getRiskLevelColor(problemData.riskLevel)">{{ problemData.riskLevel || '-' }}</a-tag>
</div>
</div>
<div class="problem-item">
<div class="item-label">严重程度:</div>
<div class="item-value">
<a-tag :color="getSeverityColor(problemData.severity)">{{ problemData.severity || '-' }}</a-tag>
</div>
</div>
<div class="problem-item problem-des">
<div class="item-label">问题描述:</div>
<div class="item-value">{{ problemData.problemDes || '-' }}</div>
</div>
</div>
</div>
</a-col>
<!-- 右侧:计划表单区域 -->
<a-col :xs="24" :sm="24" :md="12" :lg="14" :xl="15" class="plan-form-section">
<div class="plan-form-card">
<div class="section-header">
<Icon icon="carbon:task-approved" class="header-icon" />
<span class="header-title">制定计划</span>
</div>
<BasicForm @register="registerForm" class="plan-form">
<template #jSelectUser="{ model, field }">
<JSelectUser v-model:value="model[field]" />
</template>
</BasicForm>
</div>
</a-col>
</a-row>
</div>
<template #footer>
<a-button key="back" @click="handleCancel">取消</a-button>
<a-button key="submit" type="primary" @click="handleSubmit" :loading="confirmLoading">确定</a-button>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { ref, computed, unref, watch } from 'vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form/index';
import { Icon } from '/@/components/Icon';
import { JSelectUser } from '/@/components/Form';
import { planFormSchema } from '../StProblemCheck.data';
import { saveOrUpdate } from '../StProblemCheck.api';
import StProblemCheckPlanForm from './StProblemCheckPlanForm.vue';
import { message } from 'ant-design-vue';
// Emits声明
const emit = defineEmits(['register', 'success']);
// 状态变量
const isUpdate = ref(true);
const confirmLoading = ref(false);
const problemData = ref<any>({});
const modalWidth = ref('80%');
const bpmStatus = ref('');
// 动态标题
const modalTitle = computed(() => '制定计划');
// 响应式宽度调整
watch(
() => window.innerWidth,
(width) => {
if (width < 768) {
modalWidth.value = '100%';
} else if (width < 1200) {
modalWidth.value = '90%';
} else {
modalWidth.value = '80%';
}
},
{ immediate: true }
);
// 增强版表单配置 - 将整改方案改为富文本编辑器
const enhancedPlanFormSchema = [
...planFormSchema.map(schema => {
// 将整改方案字段改为富文本编辑器
if (schema.field === 'rectifyPlan') {
return {
...schema,
component: 'JEditor',
componentProps: {
height: 350,
placeholder: '请输入详细的整改方案...',
},
};
}
return schema;
}),
];
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate }] = useForm({
//labelWidth: 150,
schemas: planFormSchema,
schemas: enhancedPlanFormSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
await resetFields();
bpmStatus.value = data?.bpmStatus || '';
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
if (unref(isUpdate)) {
//表单赋值
problemData.value = { ...data.record };
await setFieldsValue({
...data.record,
});
} else {
// 新增模式
problemData.value = data.record ? { ...data.record } : {};
await setFieldsValue({
bpmStatus: bpmStatus.value,
});
......@@ -47,22 +174,58 @@
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
// 获取风险等级颜色
function getRiskLevelColor(level: string) {
const colorMap: Record<string, string> = {
'高': 'red',
'中': 'orange',
'低': 'green',
};
return colorMap[level] || 'blue';
}
// 获取严重程度颜色
function getSeverityColor(severity: string) {
const colorMap: Record<string, string> = {
'严重': 'red',
'一般': 'orange',
'轻微': 'green',
};
return colorMap[severity] || 'blue';
}
//取消按钮
function handleCancel() {
closeModal();
}
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
if(!isUpdate.value) {
values.bpmStatus = bpmStatus.value;
}
setModalProps({ confirmLoading: true });
// 构建提交数据
const submitData = {
...values,
problemNo: problemData.value.problemNo,
projectCategory: problemData.value.projectCategory,
domain: problemData.value.domain,
};
//提交表单
await saveOrUpdate(values, isUpdate.value);
await saveOrUpdate(submitData, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
message.success('计划保存成功!');
} catch (error: any) {
console.error('提交失败:', error);
} finally {
setModalProps({ confirmLoading: false });
}
......@@ -70,6 +233,177 @@
</script>
<style lang="less" scoped>
.problem-check-plan-modal {
:deep(.ant-modal-body) {
padding: 0;
max-height: calc(100vh - 120px);
overflow-y: auto;
}
}
.plan-modal-content {
padding: 20px;
min-height: calc(100vh - 180px);
}
.plan-content-wrapper {
height: 100%;
}
// 左侧问题展示区域
.problem-display-section {
height: 100%;
margin-bottom: 16px;
@media (min-width: 768px) {
margin-bottom: 0;
}
}
.problem-display-card {
background: #f5f7fa;
border-radius: 8px;
padding: 20px;
height: 100%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 右侧表单区域
.plan-form-section {
height: 100%;
}
.plan-form-card {
background: #fff;
border-radius: 8px;
padding: 20px;
height: 100%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
// 区域标题
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 12px;
border-bottom: 2px solid #e8e8e8;
.header-icon {
font-size: 20px;
margin-right: 10px;
color: #1890ff;
}
.header-title {
font-size: 16px;
font-weight: 600;
color: #262626;
}
}
// 问题内容样式
.problem-content {
.problem-item {
margin-bottom: 16px;
display: flex;
.item-label {
width: 100px;
flex-shrink: 0;
font-weight: 500;
color: #595959;
font-size: 14px;
line-height: 1.6;
}
.item-value {
flex: 1;
color: #262626;
font-size: 14px;
line-height: 1.6;
word-break: break-word;
}
&.problem-des {
.item-value {
white-space: pre-wrap;
}
}
}
}
// 表单样式
.plan-form {
:deep(.ant-form-item) {
margin-bottom: 20px;
}
:deep(.ant-form-item-label) {
label {
font-weight: 500;
}
}
}
// 响应式调整
@media (max-width: 767px) {
.plan-modal-content {
padding: 12px;
}
.problem-display-card,
.plan-form-card {
padding: 16px;
}
.section-header {
margin-bottom: 16px;
.header-title {
font-size: 15px;
}
}
.problem-content {
.problem-item {
flex-direction: column;
.item-label {
width: auto;
margin-bottom: 4px;
}
}
}
}
@media (min-width: 768px) and (max-width: 1023px) {
.plan-modal-content {
padding: 16px;
}
}
// 滚动条美化
.plan-modal-content {
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-thumb {
background: #bfbfbf;
border-radius: 4px;
&:hover {
background: #999;
}
}
&::-webkit-scrollbar-track {
background: #f0f0f0;
}
}
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论