提交 fc9d3541 authored 作者: liuluyu's avatar liuluyu

增加计划执行表单

上级 56fa3c83
......@@ -7,73 +7,88 @@ export const columns: BasicColumn[] = [
title: '计划名称',
align: 'left',
dataIndex: 'projectName',
width: 150,
width: 200,
ellipsis: true,
},
{
title: '类型',
align: 'center',
dataIndex: 'projectTypeName',
width: 150,
},
{
title: '执行部门',
align: 'center',
dataIndex: 'execDepName',
width: 100,
width: 120,
ellipsis: true,
},
// {
// title: '执行部门',
// align: 'center',
// dataIndex: 'execDepName',
// width: 150,
// ellipsis: true,
// },
{
title: '负责人',
align: 'center',
dataIndex: 'headName',
width: 100,
ellipsis: true,
},
{
title: '计划开始日期',
align: 'center',
dataIndex: 'planStartDate',
width: 130,
ellipsis: true,
customRender: ({ text }) => {
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
return !text ? '-' : text.length > 10 ? text.substr(0, 10) : text;
},
width: 130,
},
{
title: '计划结束日期',
align: 'center',
dataIndex: 'planEndDate',
width: 130,
ellipsis: true,
customRender: ({ text }) => {
return !text ? '' : text.length > 10 ? text.substr(0, 10) : text;
return !text ? '-' : text.length > 10 ? text.substr(0, 10) : text;
},
width: 130,
},
{
title: '状态',
align: 'center',
dataIndex: 'statusName',
width: 100,
},
{
title: '执行规则',
align: 'center',
dataIndex: 'exeRule',
width: 100,
ellipsis: true,
customRender: ({ text }) => {
return !text ? '' : text==1? "每发生": text==2?"周期性":"一次性";
const ruleMap = {
1: '每发生',
2: '周期性',
3: '一次性',
};
return ruleMap[text] || '-';
},
},
{
title: '状态',
align: 'center',
dataIndex: 'statusName',
width: 100,
ellipsis: true,
},
{
title: '流程状态',
align: 'center',
dataIndex: 'bpmStatus',
width: 100,
width: 120,
ellipsis: true,
customRender: ({ text }) => {
return render.renderDict(text, 'bpm_status');
return render.renderDict(text, 'bpm_status') || '-';
},
},
// 隐藏列,用于内部使用
{
title: '',
align: 'center',
dataIndex: 'projectType',
width: 0,
ellipsis: false,
},
];
//查询数据
......@@ -87,8 +102,12 @@ export const searchFormSchema: FormSchema[] = [
{
label: '类型',
field: 'projectType',
component: 'Input',
component: 'Select',
colProps: { span: 6 },
componentProps: {
allowClear: true,
placeholder: '请选择类型',
},
},
{
label: '执行部门',
......@@ -97,6 +116,7 @@ export const searchFormSchema: FormSchema[] = [
colProps: { span: 6 },
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
......@@ -115,7 +135,7 @@ export const formSchema: FormSchema[] = [
component: 'JCategorySelect',
componentProps: {
pcode: 'B09',
valueType: 'code'
valueType: 'code',
},
colProps: { lg: 12 },
itemProps: { labelCol: { xs: { span: 24 }, sm: { span: 6 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 18 } } },
......@@ -149,10 +169,10 @@ export const formSchema: FormSchema[] = [
field: 'planBasis',
component: 'Input', // 使用基础组件类型
slot: 'planBasis',
itemProps: {
labelCol: { xs: { span: 24 }, sm: { span: 3 } },
wrapperCol: { xs: { span: 24 }, sm: { span: 21 } }
}
itemProps: {
labelCol: { xs: { span: 24 }, sm: { span: 3 } },
wrapperCol: { xs: { span: 24 }, sm: { span: 21 } },
},
},
{
label: '要求',
......
......@@ -13,11 +13,11 @@
<JSearchSelect placeholder="请输入" v-model:value="queryParam[searchFormSchema[1].field]" dict="projecttype" />
</a-form-item>
</a-col>
<a-col :lg="6">
<!-- <a-col :lg="6">
<a-form-item :label="searchFormSchema[2].label">
<JSelectDept placeholder="请输入" v-model:value="jSelectDeptVal" :multiple="false" @change="updateJSelectDept" />
</a-form-item>
</a-col>
</a-col> -->
<a-col :lg="6">
<a-form-item>
<a-space :size="5">
......@@ -59,10 +59,6 @@
<template #htmlSlot="{ text }">
<div v-html="text"></div>
</template>
<!--省市区字段回显插槽-->
<template #pcaSlot="{ text }">
{{ getAreaTextByCode(text) }}
</template>
<template #fileSlot="{ text }">
<span v-if="!text" style="font-size: 12px; font-style: italic">无文件</span>
<a-button v-else :ghost="true" type="primary" preIcon="ant-design:download-outlined" size="small" @click="downloadFile(text)"
......@@ -144,7 +140,7 @@
const isShowDrawer = ref(false);
const startUser = ref<string>('');
const taskName = ref<string>('');
const showUpBtn = ref(false);
const showUpBtn = ref(true);
const taskCache = new Map<string, any>();
const userStore = useUserStore();
......
<template>
<div class="st-plan-excute-form">
<a-form ref="formRef" :model="formData" label-width="120px">
<!-- 执行状态 -->
<a-form-item label="执行状态" prop="executeStatus">
<a-select v-model:value="formData.executeStatus" placeholder="请选择执行状态">
<a-select-option value="0">未开始</a-select-option>
<a-select-option value="1">进行中</a-select-option>
<a-select-option value="2">已完成</a-select-option>
<a-select-option value="3">已暂停</a-select-option>
</a-select>
</a-form-item>
<!-- 实际开始时间 -->
<a-form-item label="实际开始时间" prop="actualStartTime">
<a-date-picker v-model="formData.actualStartTime" type="datetime" placeholder="选择时间"></a-date-picker>
</a-form-item>
<!-- 实际结束时间 -->
<a-form-item label="实际结束时间" prop="actualEndTime">
<a-date-picker v-model="formData.actualEndTime" type="datetime" placeholder="选择时间"></a-date-picker>
</a-form-item>
<!-- 执行记录 -->
<a-form-item label="执行记录" prop="executeRecord">
<a-textarea v-model="formData.executeRecord" :rows="4" placeholder="请输入执行记录"></a-textarea>
</a-form-item>
<!-- 附件 -->
<a-form-item label="附件" prop="attachments">
<JUpload v-model:value="formModel.fileUploadPath" desText="支持扩展名: .rar .zip .doc .docx .pdf .jpg..." :disabled="isDetail" />
</a-form-item>
<!-- 操作按钮 -->
<a-form-item>
<a-button type="primary" @click="submitForm">保存</a-button>
<a-button @click="resetForm">重置</a-button>
</a-form-item>
</a-form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import JUpload from '/@/components/Form/src/jeecg/components/JUpload/JUpload.vue';
const formRef = ref();
const formData = ref({
executeStatus: '',
actualStartTime: '',
actualEndTime: '',
executeRecord: '',
attachments: [],
});
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
console.log('Form submitted:', formData.value);
// 提交逻辑
}
});
};
const resetForm = () => {
formRef.value.resetFields();
};
</script>
<style scoped>
.st-plan-excute-form {
padding: 20px;
}
</style>
......@@ -5,11 +5,11 @@
<template #planBasis="{ model, field }">
<div v-if="model[field]">
<div v-if="isValidJson(model[field])">
<a-tag
v-for="item in safeJsonParse(model[field])"
@click="viewBasisDetail(item)"
:key="item.id"
style="margin-bottom: 8px; cursor: pointer;"
<a-tag
v-for="item in safeJsonParse(model[field])"
@click="viewBasisDetail(item)"
:key="item.id"
style="margin-bottom: 8px; cursor: pointer"
>
{{ item.name }}
</a-tag>
......@@ -28,74 +28,73 @@
</a-space>
</div>
<AuditInnerDetailDrawer ref="auditInnerDetailDrawerRef" :visible="showDetailDrawer" :basis="selectedBasis" @close="handleDrawerClose" />
<AuditInnerDetailDrawer ref="auditInnerDetailDrawerRef" :visible="showDetailDrawer" :basis="selectedBasis" @close="handleDrawerClose" />
</div>
</template>
<script lang="ts" setup>
import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, ref, onMounted,watchEffect,toRaw } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { getBpmFormSchema } from '../StPlanMan.data';
import { saveOrUpdate } from '../StPlanMan.api';
import { useMessage } from '/@/hooks/web/useMessage';
import AuditInnerDetailDrawer from '/@/views/newlib/components/modal/AuditInnerDetailDrawer.vue';
import { getAuthCache, setAuthCache, removeAuthCache } from '/@/utils/auth';
import { TOKEN_KEY} from '/@/enums/cacheEnum';
import { useUserStore } from '/@/store/modules/user';
import { useRoute } from 'vue-router';
const route = useRoute();
interface Props {
formData: {
disabled?: boolean;
[key: string]: any;
};
}
const showDetailDrawer = ref(false);
const props = defineProps<Props>();
const { createMessage } = useMessage();
const loading = ref(false);
const submitting = ref(false);
const formData = ref<Record<string, any>>({});
const idsystoken = ref('');
const [registerForm, { setFieldsValue, setProps, getFieldsValue, resetFields, validate }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const formDisabled = computed(() => {
return props.formData?.disabled !== false;
});
// 安全解析JSON
const safeJsonParse = (str: string) => {
try {
return JSON.parse(str);
} catch (e) {
console.error('JSON解析错误:', e);
return [];
}
};
// 验证是否为有效JSON
const isValidJson = (str: string) => {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, ref, onMounted, watchEffect, toRaw } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { getBpmFormSchema } from '../StPlanMan.data';
import { saveOrUpdate } from '../StPlanMan.api';
import { useMessage } from '/@/hooks/web/useMessage';
import AuditInnerDetailDrawer from '/@/views/newlib/components/modal/AuditInnerDetailDrawer.vue';
import { getAuthCache, setAuthCache, removeAuthCache } from '/@/utils/auth';
import { TOKEN_KEY } from '/@/enums/cacheEnum';
import { useUserStore } from '/@/store/modules/user';
import { useRoute } from 'vue-router';
const route = useRoute();
interface Props {
formData: {
disabled?: boolean;
[key: string]: any;
};
}
};
const showDetailDrawer = ref(false);
const props = defineProps<Props>();
const { createMessage } = useMessage();
const loading = ref(false);
const submitting = ref(false);
const formData = ref<Record<string, any>>({});
const idsystoken = ref('');
const [registerForm, { setFieldsValue, setProps, getFieldsValue, resetFields, validate }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const formDisabled = computed(() => {
return props.formData?.disabled !== false;
});
// 安全解析JSON
const safeJsonParse = (str: string) => {
try {
return JSON.parse(str);
} catch (e) {
console.error('JSON解析错误:', e);
return [];
}
};
// 依据详情抽屉
const auditInnerDetailDrawerRef = ref();
const selectedBasis = ref<any>(null);
const viewBasisDetail = (item: any) => {
// 验证是否为有效JSON
const isValidJson = (str: string) => {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
};
// 依据详情抽屉
const auditInnerDetailDrawerRef = ref();
const selectedBasis = ref<any>(null);
const viewBasisDetail = (item: any) => {
selectedBasis.value = item;
const data = {
name: item.name,
......@@ -103,35 +102,34 @@ const viewBasisDetail = (item: any) => {
};
showDetailDrawer.value = true;
auditInnerDetailDrawerRef.value.open(data);
};
const handleDrawerClose = () => {
showDetailDrawer.value = false;
selectedBasis.value = null;
};
const handleDrawerClose = () => {
showDetailDrawer.value = false;
selectedBasis.value = null;
};
// 从URL获取参数
const getUrlParams = () => {
const winurl = window.location.href;
const params = new URLSearchParams(winurl.split('?')[1]);
// 从URL获取参数
const getUrlParams = () => {
const winurl = window.location.href;
const params = new URLSearchParams(winurl.split('?')[1]);
console.log('winurl:', winurl);
return {
cctoken: params.get('Token') || '',
WorkID: params.get('WorkID') || '',
console.log('winurl:', winurl);
return {
cctoken: params.get('Token') || '',
WorkID: params.get('WorkID') || '',
};
};
};
// 初始化表单数据
const initFormData = async () => {
try {
loading.value = true;
//const { cctoken, WorkID } = getUrlParams();
//console.log('Token:', cctoken, 'WorkID:', WorkID);
const timestamp = new Date().getTime();
/**
// 初始化表单数据
const initFormData = async () => {
try {
loading.value = true;
//const { cctoken, WorkID } = getUrlParams();
//console.log('Token:', cctoken, 'WorkID:', WorkID);
const timestamp = new Date().getTime();
/**
const gettokeyUrl = '/api/jflow/getCCWorkTokenAndTid';
const {tid,token} = await defHttp.get({
url: gettokeyUrl,
......@@ -143,44 +141,42 @@ const initFormData = async () => {
});
*/
let tid = toRaw(route.query).id;
console.log('tid:', tid);
//setAuthCache(TOKEN_KEY, token);
let tid = toRaw(route.query).id;
console.log('tid:', tid);
//console.log('tid:', tid, 'token:', token);
const queryByIdUrl = '/plan.main/stPlanMan/queryById';
const data = await defHttp.get({
url: queryByIdUrl,
params: { id: tid, "_t": timestamp },
});
//setAuthCache(TOKEN_KEY, token);
formData.value = { ...data };
if (data.planBasis && !isValidJson(data.planBasis)) {
console.warn('planBasis不是有效的JSON格式:', data.planBasis);
formData.value.planBasis = '[]';
}
//console.log('tid:', tid, 'token:', token);
await setFieldsValue(formData.value);
await setProps({ disabled: formDisabled.value });
} catch (error) {
console.error('初始化表单数据失败:', error);
createMessage.error('初始化表单数据失败');
} finally {
loading.value = false;
}
};
onMounted(() => {
initFormData();
});
const queryByIdUrl = '/plan.main/stPlanMan/queryById';
const data = await defHttp.get({
url: queryByIdUrl,
params: { id: tid, _t: timestamp },
});
formData.value = { ...data };
if (data.planBasis && !isValidJson(data.planBasis)) {
console.warn('planBasis不是有效的JSON格式:', data.planBasis);
formData.value.planBasis = '[]';
}
await setFieldsValue(formData.value);
await setProps({ disabled: formDisabled.value });
} catch (error) {
console.error('初始化表单数据失败:', error);
createMessage.error('初始化表单数据失败');
} finally {
loading.value = false;
}
};
onMounted(() => {
initFormData();
});
</script>
<style scoped>
.ant-tag {
margin-right: 8px;
cursor: pointer;
}
</style>
\ No newline at end of file
.ant-tag {
margin-right: 8px;
cursor: pointer;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论