提交 5a8e52f3 authored 作者: liuluyu's avatar liuluyu

计划管理流转记录更新

上级 ae0a6c59
...@@ -57,20 +57,20 @@ ...@@ -57,20 +57,20 @@
<div class="content-wrapper"> <div class="content-wrapper">
<!-- 左侧主表单 --> <!-- 左侧主表单 -->
<div class="main-form-section"> <div class="main-form-section">
<a-card title="审批表单" :bordered="false" class="form-card"> <!-- <a-card title="审批表单" :bordered="false" class="form-card">
<template #extra> <template #extra>
<a-button type="link" @click="refreshForm"> <ReloadOutlined /> 刷新 </a-button> <a-button type="link" @click="refreshForm"> <ReloadOutlined /> 刷新 </a-button>
</template> </template> -->
<div class="form-content"> <div class="form-card">
<div v-show="formTp == 1" class="form-wrapper"> <div v-show="formTp == 1" class="form-wrapper">
<FlowInnerForm ref="refCruInnerForm" :key="formKey" style="width: 100%" /> <FlowInnerForm ref="refCruInnerForm" :key="formKey" style="width: 100%; height: 100%" />
</div> </div>
<div v-show="formTp == 2" class="iframe-container" style="height: 470px"> <div v-show="formTp == 2" class="form-wrapper">
<iFrame :key="formKey" :src="formUrl" class="responsive-iframe" style="width: 100%; height: 100%" /> <iFrame :key="formKey" :src="formUrl" class="responsive-iframe" style="width: 100%; height: 100%" />
</div> </div>
</div> </div>
</a-card> <!-- </a-card> -->
</div> </div>
<!-- 右侧审批栏 --> <!-- 右侧审批栏 -->
...@@ -220,7 +220,7 @@ ...@@ -220,7 +220,7 @@
// API // API
import { flowRecord } from '/@/components/Process/api/finished'; import { flowRecord } from '/@/components/Process/api/finished';
import { flowXmlAndNode } from '/@/components/Process/api/definition'; import { flowXmlAndNode } from '/@/components/Process/api/definition';
import { complete, flowTaskForm, getNextFlowNode, getMyTaskFlow,assign,assignRead } from '/@/components/Process/api/todo'; import { complete, flowTaskForm, getNextFlowNode, getMyTaskFlow, assign, assignRead } from '/@/components/Process/api/todo';
import { flowTaskInfo } from '/@/components/Process/api/process'; import { flowTaskInfo } from '/@/components/Process/api/process';
// 组件 // 组件
...@@ -765,7 +765,6 @@ ...@@ -765,7 +765,6 @@
const dataName = formUrl.value.substring(startIndex + 1, lastEqualIndex); const dataName = formUrl.value.substring(startIndex + 1, lastEqualIndex);
submitData.values['dataName'] = dataName; submitData.values['dataName'] = dataName;
// 执行发送 // 执行发送
const result = await assign(submitData); const result = await assign(submitData);
...@@ -815,8 +814,6 @@ ...@@ -815,8 +814,6 @@
submitData.values['approvalType'] = 'role'; submitData.values['approvalType'] = 'role';
} }
// 执行发送 // 执行发送
const result = await assignRead(submitData); const result = await assignRead(submitData);
...@@ -835,8 +832,6 @@ ...@@ -835,8 +832,6 @@
} }
}; };
defineExpose({ defineExpose({
iniData, iniData,
}); });
...@@ -868,7 +863,7 @@ ...@@ -868,7 +863,7 @@
height: 100vh; height: 100vh;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: linear-gradient(135deg, #b0b3c2 0%, #764ba2 100%); // background: linear-gradient(135deg, #b0b3c2 0%, #764ba2 100%);
overflow: hidden; overflow: hidden;
} }
...@@ -945,6 +940,7 @@ ...@@ -945,6 +940,7 @@
} }
.next-node-label { .next-node-label {
width: 120px;
color: #666; color: #666;
font-size: 14px; font-size: 14px;
} }
......
<template> <template>
<div class="plan-management-page"> <div class="plan-management-page">
<!-- 页面头部区域 -->
<!-- <div class="page-header">
<div class="header-content">
<div class="header-left">
<h1 class="page-title">计划编制管理</h1>
<p class="page-desc">统一管理和追踪所有业务计划的编制与审批流程</p>
</div>
<div class="header-stats">
<div class="stat-item">
<span class="stat-value">--</span>
<span class="stat-label">计划总数</span>
</div>
<div class="stat-item warning">
<span class="stat-value">--</span>
<span class="stat-label">待处理</span>
</div>
<div class="stat-item success">
<span class="stat-value">--</span>
<span class="stat-label">已完成</span>
</div>
</div>
</div>
</div> -->
<!-- 主内容区 --> <!-- 主内容区 -->
<div class="main-content"> <div class="main-content">
<!-- 搜索区域 --> <!-- 搜索区域 -->
...@@ -43,12 +19,12 @@ ...@@ -43,12 +19,12 @@
<JSearchSelect placeholder="请选择类型" v-model:value="queryParam['projectType']" dict="projecttype" /> <JSearchSelect placeholder="请选择类型" v-model:value="queryParam['projectType']" dict="projecttype" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :xl="5" :lg="8" :md="12" :sm="24"> <a-col :xl="7" :lg="8" :md="12" :sm="24">
<a-form-item label="执行部门"> <a-form-item label="执行部门">
<JSelectDept placeholder="请选择执行部门" v-model:value="queryParam['execDepCode']" /> <JSelectDept placeholder="请选择执行部门" v-model:value="queryParam['execDepCode']" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :xl="4" :lg="8" :md="12" :sm="24"> <a-col :xl="5" :lg="8" :md="12" :sm="24">
<a-form-item label="计划状态"> <a-form-item label="计划状态">
<a-select <a-select
v-model:value="queryParam['status']" v-model:value="queryParam['status']"
...@@ -66,6 +42,8 @@ ...@@ -66,6 +42,8 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row>
<a-row :gutter="16">
<a-col :xl="5" :lg="8" :md="12" :sm="24"> <a-col :xl="5" :lg="8" :md="12" :sm="24">
<a-form-item label="计划日期"> <a-form-item label="计划日期">
<a-range-picker <a-range-picker
...@@ -76,8 +54,6 @@ ...@@ -76,8 +54,6 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row>
<a-row :gutter="16">
<a-col :xl="5" :lg="8" :md="12" :sm="24"> <a-col :xl="5" :lg="8" :md="12" :sm="24">
<a-form-item label="优先级"> <a-form-item label="优先级">
<a-select <a-select
...@@ -106,7 +82,7 @@ ...@@ -106,7 +82,7 @@
/> />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :xl="14" :lg="16" :md="24" :sm="24"> <a-col :xl="7" :lg="16" :md="24" :sm="24">
<a-form-item class="search-btn-group"> <a-form-item class="search-btn-group">
<a-space :size="8"> <a-space :size="8">
<a-button type="primary" @click="searchQuery">查询</a-button> <a-button type="primary" @click="searchQuery">查询</a-button>
...@@ -166,12 +142,12 @@ ...@@ -166,12 +142,12 @@
<!-- 待办抽屉 --> <!-- 待办抽屉 -->
<div v-if="isShowDrawer"> <div v-if="isShowDrawer">
<a-drawer destroyOnClose v-model:open="isShowDrawer" class="flat-drawer" title="待办任务" placement="right" width="90%"> <a-drawer destroyOnClose v-model:open="isShowDrawer" class="flat-drawer" title="待办任务" placement="right" width="90%">
<template #extra> <!-- <template #extra>
<div class="drawer-tags"> <div class="drawer-tags">
<span class="tag">发起人: {{ startUser }}</span> <span class="tag">发起人: {{ startUser }}</span>
<span class="tag">任务节点: {{ taskName }}</span> <span class="tag">任务节点: {{ taskName }}</span>
</div> </div>
</template> </template> -->
<TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" /> <TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" />
</a-drawer> </a-drawer>
</div> </div>
...@@ -545,8 +521,8 @@ ...@@ -545,8 +521,8 @@
{ {
label: '待办', label: '待办',
ifShow: () => { ifShow: () => {
console.log("-------------record['uid'] ",record['uid']); console.log("-------------record['uid'] ", record['uid']);
console.log("-------------userStore.getUserInfo.id ",userStore.getUserInfo.id); console.log('-------------userStore.getUserInfo.id ', userStore.getUserInfo.id);
if (record['bpmStatus'] == '2' && record['uid'] == userStore.getUserInfo.id) return true; if (record['bpmStatus'] == '2' && record['uid'] == userStore.getUserInfo.id) return true;
else return false; else return false;
}, },
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted, watch, nextTick } from 'vue'; import { ref, reactive, onMounted, watch, nextTick, toRaw } from 'vue';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { saveOrUpdate } from '../StPlanMan.api'; import { saveOrUpdate } from '../StPlanMan.api';
...@@ -107,6 +107,25 @@ ...@@ -107,6 +107,25 @@
attachments: [] as any[], attachments: [] as any[],
}); });
// accept external formData prop from parent modal
const props = defineProps({
formData: {
type: Object,
default: () => ({}),
},
});
// sync incoming prop into internal reactive formData
watch(
() => props.formData,
(v) => {
if (v && Object.keys(v).length > 0) {
Object.assign(formData, v);
}
},
{ immediate: true, deep: true }
);
// 监听formData变化,用于调试 // 监听formData变化,用于调试
watch( watch(
...@@ -272,7 +291,8 @@ ...@@ -272,7 +291,8 @@
const response = await saveOrUpdate(submitData, true); const response = await saveOrUpdate(submitData, true);
if (response) { if (response) {
message.success('保存成功'); // message.success('保存成功');
console.log('保存成功:');
// 更新缓存 // 更新缓存
planFormStore.updateFormDataCache(formData); planFormStore.updateFormDataCache(formData);
console.log(response); console.log(response);
...@@ -355,6 +375,7 @@ ...@@ -355,6 +375,7 @@
resetForm, resetForm,
initFormData, initFormData,
isInitialized, isInitialized,
getFormData: () => toRaw(formData),
}); });
</script> </script>
...@@ -489,10 +510,8 @@ ...@@ -489,10 +510,8 @@
/* ==================== 表单底部按钮 ==================== */ /* ==================== 表单底部按钮 ==================== */
.form-footer { .form-footer {
padding: 14px 32px; padding: 14px 32px;
background: var(--color-bg-section);
border-top: 1px solid var(--color-border);
display: flex; display: flex;
justify-content: flex-end; justify-content: center;
} }
/* ==================== 上传区域 ==================== */ /* ==================== 上传区域 ==================== */
......
...@@ -13,12 +13,7 @@ ...@@ -13,12 +13,7 @@
<template #planBasis="{ model, field }"> <template #planBasis="{ model, field }">
<div class="basis-container" v-if="model[field]"> <div class="basis-container" v-if="model[field]">
<div v-if="isValidJson(model[field])" class="basis-tags"> <div v-if="isValidJson(model[field])" class="basis-tags">
<a-tag <a-tag v-for="item in safeJsonParse(model[field])" @click="viewBasisDetail(item)" :key="item.id" class="basis-tag">
v-for="item in safeJsonParse(model[field])"
@click="viewBasisDetail(item)"
:key="item.id"
class="basis-tag"
>
{{ item.name }} {{ item.name }}
</a-tag> </a-tag>
</div> </div>
...@@ -46,7 +41,7 @@ ...@@ -46,7 +41,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { BasicForm, useForm } from '/@/components/Form/index'; import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, ref, onMounted, watchEffect, toRaw } from 'vue'; import { computed, ref, onMounted, watchEffect, toRaw, watch } from 'vue';
import { defHttp } from '/@/utils/http/axios'; import { defHttp } from '/@/utils/http/axios';
import { getBpmFormSchema } from '../StPlanMan.data'; import { getBpmFormSchema } from '../StPlanMan.data';
import { saveOrUpdate } from '../StPlanMan.api'; import { saveOrUpdate } from '../StPlanMan.api';
...@@ -79,6 +74,22 @@ ...@@ -79,6 +74,22 @@
baseColProps: { span: 24 }, baseColProps: { span: 24 },
}); });
// watch incoming prop and populate the form when provided
watch(
() => props.formData,
(v) => {
if (v && Object.keys(v).length > 0) {
formData.value = { ...v };
try {
setFieldsValue(v);
} catch (e) {
console.warn('setFieldsValue failed:', e);
}
}
},
{ immediate: true, deep: true }
);
const formDisabled = computed(() => { const formDisabled = computed(() => {
return props.formData?.disabled !== false; return props.formData?.disabled !== false;
}); });
...@@ -186,11 +197,19 @@ ...@@ -186,11 +197,19 @@
onMounted(() => { onMounted(() => {
initFormData(); initFormData();
}); });
// expose getFormData so parent modal can read current values
defineExpose({
submitForm,
// resetForm,
initFormData,
getFormData: () => toRaw(formData.value),
});
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
/* ==================== 柔和中性风格 - CSS 变量 ==================== */ /* ==================== 柔和中性风格 - CSS 变量 ==================== */
.plan-form-container { .plan-form-container {
--color-primary: #3b5bdb; --color-primary: #3b5bdb;
--color-primary-hover: #364fc7; --color-primary-hover: #364fc7;
--color-primary-light: #e8ecfd; --color-primary-light: #e8ecfd;
...@@ -210,49 +229,49 @@ ...@@ -210,49 +229,49 @@
background: var(--color-bg-white); background: var(--color-bg-white);
min-height: 100vh; min-height: 100vh;
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
} }
/* ==================== 表单头部 ==================== */ /* ==================== 表单头部 ==================== */
.form-header { .form-header {
background: var(--color-bg-white); background: var(--color-bg-white);
border-bottom: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
padding: 20px 32px; padding: 20px 32px;
border-left: 3px solid var(--color-primary); border-left: 3px solid var(--color-primary);
padding-left: 28px; padding-left: 28px;
} }
.form-title { .form-title {
font-size: 18px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: var(--color-text-primary); color: var(--color-text-primary);
margin: 0 0 3px 0; margin: 0 0 3px 0;
letter-spacing: -0.2px; letter-spacing: -0.2px;
} }
.form-subtitle { .form-subtitle {
font-size: 13px; font-size: 13px;
color: var(--color-text-muted); color: var(--color-text-muted);
margin: 0; margin: 0;
} }
/* ==================== 表单主体 ==================== */ /* ==================== 表单主体 ==================== */
.form-body { .form-body {
padding: 24px 32px; padding: 24px 32px;
background: var(--color-bg-white); background: var(--color-bg-white);
} }
/* 依据标签样式 */ /* 依据标签样式 */
.basis-container { .basis-container {
padding: 8px 0; padding: 8px 0;
} }
.basis-tags { .basis-tags {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 8px; gap: 8px;
} }
.basis-tag { .basis-tag {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
padding: 4px 10px; padding: 4px 10px;
...@@ -267,43 +286,43 @@ ...@@ -267,43 +286,43 @@
&:hover { &:hover {
background: #d0d9f8; background: #d0d9f8;
} }
} }
.basis-alert { .basis-alert {
border-radius: var(--radius); border-radius: var(--radius);
} }
.basis-empty { .basis-empty {
padding: 16px; padding: 16px;
background: var(--color-bg-section); background: var(--color-bg-section);
border-radius: var(--radius); border-radius: var(--radius);
border: 1px dashed var(--color-border-strong); border: 1px dashed var(--color-border-strong);
} }
/* ==================== 表单底部按钮 ==================== */ /* ==================== 表单底部按钮 ==================== */
.form-footer { .form-footer {
padding: 14px 32px; padding: 14px 32px;
background: var(--color-bg-section); background: var(--color-bg-section);
border-top: 1px solid var(--color-border); border-top: 1px solid var(--color-border);
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
} }
/* ==================== 表单控件样式覆盖 ==================== */ /* ==================== 表单控件样式覆盖 ==================== */
:deep(.ant-form-item) { :deep(.ant-form-item) {
margin-bottom: 18px; margin-bottom: 18px;
} }
:deep(.ant-form-item-label > label) { :deep(.ant-form-item-label > label) {
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 500;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
:deep(.ant-input), :deep(.ant-input),
:deep(.ant-select-selector), :deep(.ant-select-selector),
:deep(.ant-picker), :deep(.ant-picker),
:deep(.ant-input-textarea textarea) { :deep(.ant-input-textarea textarea) {
border-radius: var(--radius) !important; border-radius: var(--radius) !important;
border-color: var(--color-border) !important; border-color: var(--color-border) !important;
font-size: 13px; font-size: 13px;
...@@ -318,15 +337,15 @@ ...@@ -318,15 +337,15 @@
border-color: var(--color-primary) !important; border-color: var(--color-primary) !important;
box-shadow: 0 0 0 2px var(--color-primary-light) !important; box-shadow: 0 0 0 2px var(--color-primary-light) !important;
} }
} }
:deep(.ant-select-focused .ant-select-selector) { :deep(.ant-select-focused .ant-select-selector) {
border-color: var(--color-primary) !important; border-color: var(--color-primary) !important;
box-shadow: 0 0 0 2px var(--color-primary-light) !important; box-shadow: 0 0 0 2px var(--color-primary-light) !important;
} }
/* ==================== 按钮样式 ==================== */ /* ==================== 按钮样式 ==================== */
:deep(.ant-btn) { :deep(.ant-btn) {
border-radius: var(--radius); border-radius: var(--radius);
font-weight: 500; font-weight: 500;
font-size: 13px; font-size: 13px;
...@@ -355,15 +374,15 @@ ...@@ -355,15 +374,15 @@
background: var(--color-primary-light); background: var(--color-primary-light);
} }
} }
} }
/* ==================== 加载状态 ==================== */ /* ==================== 加载状态 ==================== */
:deep(.ant-spin-container) { :deep(.ant-spin-container) {
min-height: 400px; min-height: 400px;
} }
/* ==================== 响应式设计 ==================== */ /* ==================== 响应式设计 ==================== */
@media (max-width: 768px) { @media (max-width: 768px) {
.form-header { .form-header {
padding: 16px 20px; padding: 16px 20px;
} }
...@@ -375,5 +394,5 @@ ...@@ -375,5 +394,5 @@
.form-footer { .form-footer {
padding: 12px 20px; padding: 12px 20px;
} }
} }
</style> </style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论