提交 769c14f2 authored 作者: kxjia's avatar kxjia

Merge branch 'master' of http://47.97.51.208/root/zrch-risk-39

import {defHttp} from '/@/utils/http/axios';
import { useMessage } from "/@/hooks/web/useMessage";
const { createConfirm } = useMessage();
enum Api {
list = '/plan.approve/stPlanApprove/list',
save='/plan.approve/stPlanApprove/add',
edit='/plan.approve/stPlanApprove/edit',
deleteOne = '/plan.approve/stPlanApprove/delete',
deleteBatch = '/plan.approve/stPlanApprove/deleteBatch',
importExcel = '/plan.approve/stPlanApprove/importExcel',
exportXls = '/plan.approve/stPlanApprove/exportXls',
}
/**
* 导出api
* @param params
*/
export const getExportUrl = Api.exportXls;
/**
* 导入api
*/
export const getImportUrl = Api.importExcel;
/**
* 列表接口
* @param params
*/
export const list = (params) =>
defHttp.get({url: Api.list, params});
/**
* 删除单个
*/
export const deleteOne = (params,handleSuccess) => {
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
handleSuccess();
});
}
/**
* 批量删除
* @param params
*/
export const batchDelete = (params, handleSuccess) => {
createConfirm({
iconType: 'warning',
title: '确认删除',
content: '是否删除选中数据',
okText: '确认',
cancelText: '取消',
onOk: () => {
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
handleSuccess();
});
}
});
}
/**
* 保存或者更新
* @param params
*/
export const saveOrUpdate = (params, isUpdate) => {
let url = isUpdate ? Api.edit : Api.save;
return defHttp.post({url: url, params});
}
import { BasicColumn, FormSchema } from '/@/components/Table';
//列表数据
export const columns: BasicColumn[] = [
{
title: '项目名称',
align:"center",
dataIndex: 'projectName',
width:200,
},{
title: '项目类型',
align:"center",
dataIndex: 'projectTypeName',
width:100,
},{
title: '执行部门',
align:"center",
dataIndex: 'execDepName',
width:100
},
{
title: '负责人',
align:"center",
dataIndex: 'headName',
width:100
},{
title: '计划开始日期',
align:"center",
dataIndex: 'planStartDate',
customRender:({text}) =>{
return !text?"":(text.length>10?text.substr(0,10):text)
},
width:120
},
{
title: '计划结束日期',
align:"center",
dataIndex: 'planEndDate',
customRender:({text}) =>{
return !text?"":(text.length>10?text.substr(0,10):text)
},
width:120
},
{
title: '创建人',
align:"center",
dataIndex: 'createUserName',
width:100
},
{
title: '审核类型',
align:"center",
dataIndex: 'approvalTypeName',
width:100
},
{
title: '状态',
align:"center",
dataIndex: 'statusName',
width:100
},
];
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: "项目名称",
field: 'projectName',
component: 'Input',
colProps: {span: 6},
},
{
label: "项目类型",
field: 'projectType',
component: 'Input',
colProps: {span: 6},
},
{
label: "执行部门",
field: 'execDepCode',
component: 'Input',
colProps: {span: 6},
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
label: '项目名称',
field: 'projectName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '项目类型',
field: 'projectTypeName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '执行部门',
field: 'execDepName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '负责人',
field: 'headName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '计划开始日期',
field: 'planStartDate',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '计划结束日期',
field: 'planEndDate',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '审核部门',
field: 'approveDepCodeName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '审核人',
field: 'planApproveUserName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicDisabled: true,
},
{
label: '项目描述',
field: 'projectDesc',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicDisabled: true,
componentProps: {
rows: 4
}
},
{
label: '相关附件',
field: 'fileUploadPath',
component: 'JUpload',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
componentProps: { desText:"支持扩展名: .rar .zip .doc .docx .pdf .jpg...",buttonVisible: false},
dynamicDisabled: true,
},
{
label: '变更原因',
field: 'optDes',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicDisabled: true,
show: false,
componentProps: {
rows: 4
}
},
{
label: '审核结果',
field: 'approveFlag',
component: 'RadioGroup',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
componentProps: {
options:[
{
label:"通过",
value:"1"
},{
label:"驳回",
value:"0"
}
]
},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择审核结果!'},
];
},
},
{
label: '审核意见',
field: 'approveDes',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入审核意见!'},
];
},
componentProps: {
rows: 4
}
},
{
label: '',
field: 'planCode',
component: 'Input',
show: false
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false
},
];
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[]{
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
\ No newline at end of file
<template>
<div>
<div class="jeecg-basic-table-form-container" @keyup.enter="searchQuery">
<a-form :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item :label="searchFormSchema[0].label">
<a-input placeholder="请输入" v-model:value="queryParam[searchFormSchema[0].field]" />
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item :label="searchFormSchema[1].label">
<JSearchSelect placeholder="请输入" v-model:value="queryParam[searchFormSchema[1].field]" dict="projecttype" />
</a-form-item>
</a-col>
<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 :lg="6">
<a-form-item>
<a-space :size="5">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset">重置</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!-- <a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新建</a-button> -->
<a-button v-show="showUpBtn" type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button v-show="showUpBtn" type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0 && showUpBtn">
<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)" />
</template>
<!--字段回显插槽-->
<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)"
>下载</a-button
>
</template>
</BasicTable>
<!-- 表单区域 -->
<StPlanApproveModal @register="registerModal" @success="handleSuccess" />
</div>
</div>
</template>
<script lang="ts" name="project-plan-stPlanManChangeList" setup>
import { reactive, ref, toRaw, unref } from 'vue';
import { batchDelete, deleteOne, getExportUrl, getImportUrl, list } from './StPlanApprove.api';
import { columns, searchFormSchema } from './StPlanApprove.data';
import StPlanApproveModal from './components/StPlanApproveModal.vue';
import { JSearchSelect, JSelectDept } from '/@/components/Form';
import { useModal } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { downloadFile } from '/@/utils/common/renderUtils';
const showUpBtn = ref(false);
const checkedKeys = ref<Array<string | number>>([]);
const jSelectDeptVal = ref([]);
//注册model
const [registerModal, { openModal }] = useModal();
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: 'st_plan_approve',
api: list,
columns,
canResize: false,
useSearchForm: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToNumber: [],
fieldMapToTime: [],
},
actionColumn: {
width: 120,
fixed: 'right',
},
showTableSetting: false,
beforeFetch(params) {
params = Object.assign(params, { column: 'createdTime', order: 'desc' });
},
},
exportConfig: {
name: 'st_plan_approve',
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { setProps, reload }, { rowSelection, selectedRowKeys }] = tableContext;
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 8 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
const queryParam = reactive({});
function initParam() {
const schemas = unref(searchFormSchema);
schemas.forEach((item) => {
queryParam[item.field] = '';
});
queryParam['checkClassFiy'] = null;
queryParam['lableCodes'] = '';
jSelectDeptVal.value = [];
}
initParam();
function updateJSelectDept(val) {
if (val.length > 0) {
queryParam[searchFormSchema[2].field] = val[0];
} else {
jSelectDeptVal.value = [];
queryParam[searchFormSchema[2].field] = '';
}
}
function searchQuery() {
setProps({ searchInfo: toRaw(queryParam) });
reload();
}
function searchReset() {
initParam();
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(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),
disabled: !!record['approveFlag'],
},
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [];
}
</script>
<style scoped></style>
import { message } from 'ant-design-vue';
import { BasicColumn, FormSchema } from '/@/components/Table';
//列表数据
export const columns: BasicColumn[] = [
{
title: '项目名称',
align:"center",
dataIndex: 'projectName',
width:150
},
{
title: '项目类型',
align:"center",
dataIndex: 'projectTypeName',
width:150
},
{
title: '执行部门',
align:"center",
dataIndex: 'execDepName',
width:100
},
{
title: '负责人',
align:"center",
dataIndex: 'headName',
width:100
},
{
title: '计划开始日期',
align:"center",
dataIndex: 'planStartDate',
customRender:({text}) =>{
return !text?"":(text.length>10?text.substr(0,10):text)
},
width:130
},
{
title: '计划结束日期',
align:"center",
dataIndex: 'planEndDate',
customRender:({text}) =>{
return !text?"":(text.length>10?text.substr(0,10):text)
},
width:130
},
{
title: '状态',
align:"center",
dataIndex: 'statusName',
width:100
},
];
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: "项目名称",
field: 'projectName',
component: 'Input',
colProps: {span: 6},
},
{
label: "项目类型",
field: 'projectType',
component: 'Input',
colProps: {span: 6},
},
{
label: "执行部门",
field: 'execDepCode',
component: 'Input',
colProps: {span: 6},
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
label: '项目名称',
field: 'projectName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入项目名称!'},
];
},
},
{
label: '项目类型',
field: 'projectType',
component: 'JSearchSelect',
componentProps:{
dict: "projecttype"
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择项目类型!'},
];
},
},
{
label: '执行部门',
field: 'execDepCode',
component: 'JSelectDept',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
multiple: false,
allowClear: false,
onChange: (e: any) => {
const { updateSchema } = formActionType;
if(e === undefined||e===''){
formModel.execDepCode = null
formModel.headCode = null
updateSchema({
field: 'headCode',
componentProps: {
onclick: (e:any) => {
if(!formModel.execDepCode){
message.warn("请先选择执行部门!")
return
}
}
},
});
return
}
if(formModel.execDepCode!=e[0]){
formModel.headCode = null
}
updateSchema({
field: 'headCode',
componentProps: {
dict: "listDuty",
depCode: e[0],
onclick: (e:any) => {
if(!formModel.execDepCode){
message.warn("请先选择执行部门!")
return
}
}
},
});
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择执行部门!'},
];
},
},
{
label: '负责人',
field: 'headCode',
component: 'JSearchSelectDuty',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.execDepCode){
formModel.headCode = null
message.warn("请先选择执行部门!")
return
}
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择负责人!'},
];
},
},
{
label: '计划开始日期',
field: 'planStartDate',
component: 'DatePicker',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择计划开始日期!'},
];
},
},
{
label: '计划结束日期',
field: 'planEndDate',
component: 'DatePicker',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择计划结束日期!'},
];
},
},
{
label: '审核部门',
field: 'approveDepCode',
component: 'JSelectDept',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
multiple: false,
allowClear: false,
onChange: (e: any) => {
const { updateSchema } = formActionType;
if(e === undefined||e===''){
formModel.approveDepCode = null
formModel.approveUser = null
updateSchema({
field: 'approveUser',
componentProps: {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.approveDepCode){
message.warn("请先选择审核部门!")
return
}
}
},
});
return
}
if(formModel.approveDepCode!=e[0]){
formModel.approveUser = null
}
updateSchema({
field: 'approveUser',
componentProps: {
dict: "listDuty",
depCode: e[0],
onclick: (e:any) => {
if(!formModel.approveDepCode){
message.warn("请先选择审核部门!")
return
}
}
},
});
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择审核部门!'},
];
},
},
{
label: '审核人',
field: 'approveUser',
component: 'JSearchSelectDuty',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.approveDepCode){
formModel.approveUser = null
message.warn("请先选择审核部门!")
return
}
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择审核人!'},
];
},
},
{
label: '项目描述',
field: 'projectDesc',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入项目描述!'},
];
},
componentProps: {
rows: 5
}
},
{
label: '相关附件',
field: 'fileUploadPath',
component: 'JUpload',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
componentProps: { desText:"支持扩展名: .rar .zip .doc .docx .pdf .jpg..."},
},
{
label: '变更原因',
field: 'optDes',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入变更原因!'},
];
},
componentProps: {
rows: 5
}
},
{
label: '审核原因',
field: 'approveDes',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
show: false,
componentProps: {
rows: 5
}
},
{
label: '',
field: 'planCode',
component: 'Input',
show: false
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false
},
];
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[]{
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
\ No newline at end of file
<template>
<div>
<div class="jeecg-basic-table-form-container" @keyup.enter="searchQuery">
<a-form :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item :label="searchFormSchema[0].label">
<JInput placeholder="请输入" v-model:value="queryParam[searchFormSchema[0].field]"></JInput>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item :label="searchFormSchema[1].label">
<JSearchSelect placeholder="请输入" v-model:value="queryParam[searchFormSchema[1].field]" dict="projecttype"></JSearchSelect>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item :label="searchFormSchema[2].label">
<JSelectDept placeholder="请输入" v-model:value="jSelectDeptVal" :multiple="false" @change="updateJSelectDept"></JSelectDept>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item>
<a-space :size="5">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery" >查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" >重置</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新建</a-button>-->
<a-button v-show="showUpBtn" type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button v-show="showUpBtn" type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0 && showUpBtn">
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="batchHandleDelete">
<Icon icon="ant-design:delete-outlined"></Icon>
删除
</a-menu-item>
</a-menu>
</template>
<a-button>批量操作
<Icon icon="mdi:chevron-down"></Icon>
</a-button>
</a-dropdown>
</template>
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</template>
<!--字段回显插槽-->
<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)">下载</a-button>
</template>
</BasicTable>
<!-- 表单区域 -->
<StPlanManChangeModal @register="registerModal" @success="handleSuccess"></StPlanManChangeModal>
<StPlanManChangeTranceModal @register="register2" @success="handleSuccess"></StPlanManChangeTranceModal>
</div>
</div>
</template>
<script lang="ts" name="project-plan-stPlanManChangeList" setup>
import { reactive, ref, toRaw, unref } from 'vue';
import { batchDelete, changelist, deleteOne, getExportUrl, getImportUrl } from './StPlanMan.api';
import { columns, searchFormSchema } from './StPlanMan.data';
import StPlanManChangeModal from './components/StPlanManChangeModal.vue';
import StPlanManChangeTranceModal from './components/StPlanManChangeTranceModal.vue';
import { JInput, JSearchSelect, JSelectDept } from '/@/components/Form';
import { useModal } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { downloadFile } from '/@/utils/common/renderUtils';
const showUpBtn = ref(false)
const checkedKeys = ref<Array<string | number>>([]);
const jSelectDeptVal = ref([])
//注册model
const [registerModal, {openModal}] = useModal();
const [register2, { openModal: openModal2 }] = useModal();
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '计划编制',
api: changelist,
columns,
canResize:false,
useSearchForm: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 240,
fixed:'right'
},
showTableSetting: false,
beforeFetch(params) {
params = Object.assign(params,{ column: 'approveTime', order: 'desc'})
},
},
exportConfig: {
name:"计划编制",
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
})
const [registerTable, {setProps,reload},{ rowSelection, selectedRowKeys }] = tableContext
const labelCol = reactive({
xs: {span: 24},
sm: {span: 8},
})
const wrapperCol = reactive({
xs: {span: 24},
sm: {span: 16},
})
const queryParam = reactive({
});
function initParam() {
const schemas = unref(searchFormSchema);
schemas.forEach((item) => {
queryParam[item.field] = ''
});
queryParam['checkClassFiy'] = null
queryParam['lableCodes'] = ''
jSelectDeptVal.value = []
}
initParam()
function updateJSelectDept(val){
if(val.length>0){
queryParam[searchFormSchema[2].field] = val[0]
}else{
jSelectDeptVal.value = []
queryParam[searchFormSchema[2].field] = ''
}
}
function searchQuery(){
setProps({searchInfo:toRaw(queryParam)});
reload()
}
function searchReset(){
initParam()
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件 变更
*/
function handleEdit(record: Recordable) {
openModal(true, {
planFlag:'4', // 变更待审核
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 编辑事件 废止
*/
function handleRepeal(record: Recordable) {
openModal(true, {
planFlag:'7', // 废止待审核
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 变更记录
*/
function handleRecord(record: Recordable) {
openModal2(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: '废止',
disabled: record['planFlag']=='4'||record['planFlag']=='7'||record['planFlag']=='9',
onClick: handleRepeal.bind(null, record),
},
{
label: '变更',
disabled: record['planFlag']=='4'||record['planFlag']=='7'||record['planFlag']=='9',
onClick: handleEdit.bind(null, record),
},
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
{
label: '变更记录',
onClick: handleRecord.bind(null, record),
},
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [
]
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -96,6 +96,27 @@ ...@@ -96,6 +96,27 @@
<TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" /> <TodoIndex v-if="isShowDrawer" ref="refTodoIndex" @callback="handleSuccess" />
</a-drawer> </a-drawer>
</div> </div>
<!-- 流程详情抽屉 -->
<div v-if="isShowDetailDrawer">
<a-drawer
destroyOnClose
v-model:open="isShowDetailDrawer"
class="custom-class"
root-class-name="root-class-name"
:root-style="{ color: 'blue' }"
title="流程详情111"
placement="right"
width="90%"
style="margin: 0px; padding: 0px"
>
<template #extra>
<div style="float: right">
<a-button type="text" @click="handleDetailDrawerClose">关闭</a-button>
</div>
</template>
<Detail ref="refDetail" />
</a-drawer>
</div>
</div> </div>
</template> </template>
...@@ -117,6 +138,8 @@ ...@@ -117,6 +138,8 @@
// 引入待办任务组件 // 引入待办任务组件
import TodoIndex from '../../flowable/task/todo/components/TodoIndex.vue'; import TodoIndex from '../../flowable/task/todo/components/TodoIndex.vue';
import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo'; import { todoList, getMyTaskFlow } from '/@/components/Process/api/todo';
// 引入详情组件
import Detail from '../../flowable/task/myProcess/components/Detail.vue';
const refTodoIndex = ref(); const refTodoIndex = ref();
const isShowDrawer = ref(false); const isShowDrawer = ref(false);
const startUser = ref<string>(''); const startUser = ref<string>('');
...@@ -125,9 +148,9 @@ ...@@ -125,9 +148,9 @@
const taskCache = new Map<string, any>(); const taskCache = new Map<string, any>();
const userStore = useUserStore(); const userStore = useUserStore();
//alert(userStore.getUserInfo.id); // 流程详情抽屉相关
const refDetail = ref();
const checkedKeys = ref<Array<string | number>>([]); const isShowDetailDrawer = ref(false);
//注册model //注册model
const [registerModal, { openModal }] = useModal(); const [registerModal, { openModal }] = useModal();
const jSelectDeptVal = ref([]); const jSelectDeptVal = ref([]);
...@@ -231,6 +254,55 @@ ...@@ -231,6 +254,55 @@
showFooter: false, showFooter: false,
}); });
} }
/**
* 流转记录
*/
async function handleProgressDetail(record: Recordable) {
const dataId = record.id;
const deployId = record.deployId;
if (!dataId || !deployId) {
message.error('未找到业务数据标识');
return;
}
try {
const myTaskFlow = await getMyTaskFlow({ deploymentId: record.deployId, dataId: record.id });
console.log('获取流程任务信息:', myTaskFlow);
// 提取任务流信息,支持多层返回结构(data/result/直接对象)
const taskData = pickStartResult(myTaskFlow);
if (!taskData || !taskData.taskId) {
message.error('未获取到待办任务信息');
return;
}
// 若未指定是否审批,则默认展示审批意见(保持与发起流程一致)
if (taskData.nodeisApprove == null) {
taskData.nodeisApprove = true;
}
// 保存缓存
taskCache.set(String(dataId), taskData);
// 打开流程详情抽屉并初始化数据
isShowDetailDrawer.value = true;
await nextTick();
if (refDetail.value) {
// 使用获取到的taskData,确保包含所有必要参数
refDetail.value.iniData({
...record,
...taskData,
procInsId: taskData.procInsId || taskData.instanceId || record.procInsId,
});
} else {
isShowDetailDrawer.value = false;
}
} catch (e) {
console.error('获取流程任务信息失败:', e);
message.error('获取任务信息失败,请重试');
}
}
async function findTodoTaskByProcInsId(procInsId: string) { async function findTodoTaskByProcInsId(procInsId: string) {
// 启动流程后,待办任务可能存在短暂延迟,做一个轻量重试 // 启动流程后,待办任务可能存在短暂延迟,做一个轻量重试
...@@ -404,6 +476,13 @@ ...@@ -404,6 +476,13 @@
function handleSuccess() { function handleSuccess() {
(selectedRowKeys.value = []) && reload(); (selectedRowKeys.value = []) && reload();
} }
/**
* 关闭详情抽屉
*/
function handleDetailDrawerClose() {
isShowDetailDrawer.value = false;
}
/** /**
* 操作栏 * 操作栏
*/ */
...@@ -437,6 +516,10 @@ ...@@ -437,6 +516,10 @@
label: '详情', label: '详情',
onClick: handleDetail.bind(null, record), onClick: handleDetail.bind(null, record),
}, },
{
label: '流转记录',
onClick: handleProgressDetail.bind(null, record),
},
{ {
label: '删除', label: '删除',
color: 'error', color: 'error',
......
<template>
<div>
<div class="jeecg-basic-table-form-container" @keyup.enter="searchQuery">
<a-form :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-row :gutter="24">
<a-col :lg="6">
<a-form-item :label="searchFormSchema[0].label">
<JInput placeholder="请输入" v-model:value="queryParam[searchFormSchema[0].field]" />
</a-form-item>
</a-col>
<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 :lg="6">
<a-form-item>
<a-space :size="5">
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset">重置</a-button>
</a-space>
</a-form-item>
</a-col>
</a-row>
</a-form>
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--插槽:table标题-->
<template #tableTitle>
<!--
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新建</a-button>
-->
<a-button v-show="showUpBtn" type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button v-show="showUpBtn" type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0 && showUpBtn">
<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)" />
</template>
<!--字段回显插槽-->
<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)"
>下载</a-button
>
</template>
</BasicTable>
<!-- 表单区域 -->
<StPlanManModal @register="registerModal" @success="handleSuccess" :showSelectorBtn="true" @selector-click="handleSelectorClick" />
</div>
</div>
</template>
<script lang="ts" name="project-plan-stPlanManList" setup>
import { reactive, ref, toRaw, unref,onMounted} from 'vue';
import { batchDelete, deleteOne, getExportUrl, getImportUrl, handlePlan, listflow } from './StPlanMan.api';
import { columns, searchFormSchema } from './StPlanMan.data';
import StPlanManModal from './components/StPlanManModal.vue';
import { JInput, JSearchSelect, JSelectDept } from '/@/components/Form';
import { useModal } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { downloadFile } from '/@/utils/common/renderUtils';
import { message } from 'ant-design-vue';
import { useUserStore } from '/@/store/modules/user';
import { defHttp } from '/@/utils/http/axios';
const showUpBtn = ref(false);
const checkedKeys = ref<Array<string | number>>([]);
//注册model
const [registerModal, { openModal }] = useModal();
const jSelectDeptVal = ref([]);
//注册table数据
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
title: '计划编制',
api: listflow,
columns,
canResize: false,
useSearchForm: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter: true,
showAdvancedButton: true,
fieldMapToNumber: [],
fieldMapToTime: [],
},
actionColumn: {
width: 240,
fixed: 'right',
},
showTableSetting: false,
beforeFetch(params) {
params = Object.assign(params, { column: 'createdTime', order: 'desc' ,token: allReportData.value});
},
},
exportConfig: {
name: '计划编制',
url: getExportUrl,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { setProps, reload }, { rowSelection, selectedRowKeys }] = tableContext;
const labelCol = reactive({
xs: { span: 24 },
sm: { span: 8 },
});
const wrapperCol = reactive({
xs: { span: 24 },
sm: { span: 16 },
});
const queryParam = reactive({});
let url = window.location.href;
console.log("----------- ",url); // 输出当前路由的完整路径
let intNumber = url.indexOf("Token=");
intNumber=intNumber+6;
let cctoken=url.substring(intNumber);
console.log("----------- cctoken",cctoken); // 输出当前路由的完整路径
const allReportDataUrl = "/api/jflow/getUserTokey"
const allReportData = ref('');
const gettoken = async () => {
allReportData.value = await defHttp.get({url: allReportDataUrl, params:{Token:cctoken}});
}
onMounted(async () => {
await gettoken();
console.log("-----------St gettoken ",allReportData.value);
});
function initParam() {
const schemas = unref(searchFormSchema);
schemas.forEach((item) => {
queryParam[item.field] = '';
});
queryParam['checkClassFiy'] = null;
queryParam['lableCodes'] = '';
jSelectDeptVal.value = [];
}
initParam();
function updateJSelectDept(val) {
if (val.length > 0) {
queryParam[searchFormSchema[2].field] = val[0];
} else {
jSelectDeptVal.value = [];
queryParam[searchFormSchema[2].field] = '';
}
}
function searchQuery() {
setProps({ searchInfo: toRaw(queryParam) });
reload();
}
function searchReset() {
initParam();
reload();
}
/**
* 新增事件
*/
function handleAdd() {
openModal(true, {
isUpdate: false,
showFooter: true,
});
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: true,
});
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
async function handleSubmit(record) {
if (record.approveDepCode == '' || record.approveUser == '') {
message.warning('请选择审核部门与审核人后进行提交');
} else {
record['planFlag'] = '1';
await handlePlan(record, handleSuccess);
}
}
/**
* 删除事件
*/
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: '删除',
color: 'error',
disabled: record['planFlag'] != '0' && record['planFlag'] != '2' && record['planFlag'] != '9',
popConfirm: {
title: '是否确认删除该计划项',
confirm: handleDelete.bind(null, record),
},
},
{
label: '修改',
disabled: record['planFlag'] != '0' && record['planFlag'] != '2',
onClick: handleEdit.bind(null, record),
},
{
label: '提交',
disabled: record['planFlag'] != '0' && record['planFlag'] != '2',
popConfirm: {
title: '是否确认提交',
confirm: handleSubmit.bind(null, record),
},
},
*/
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
/**
* 下拉操作栏
*/
function getDropDownAction(record) {
return [];
}
</script>
<style scoped></style>
import { message } from 'ant-design-vue';
import { BasicColumn, FormSchema } from '/@/components/Table';
//列表数据
export const columns: BasicColumn[] = [
{
title: '项目名称',
align:"center",
dataIndex: 'projectName',
width:150
},
{
title: '项目类型',
align:"center",
dataIndex: 'projectTypeName',
width:150
},
{
title: '执行部门',
align:"center",
dataIndex: 'execDepName',
width:100
},
{
title: '负责人',
align:"center",
dataIndex: 'headName',
width:100
},
{
title: '生效日期',
align:"center",
dataIndex: 'approveTime',
customRender:({text}) =>{
return !text?"":(text.length>10?text.substr(0,10):text)
},
width:120
},
{
title: '创建人',
align:"center",
dataIndex: 'updateUserName',
width:100
},
];
//查询数据
export const searchFormSchema: FormSchema[] = [
{
label: "项目名称",
field: 'projectName',
component: 'Input',
colProps: {span: 6},
},
{
label: "项目类型",
field: 'projectType',
component: 'Input',
colProps: {span: 6},
},
{
label: "执行部门",
field: 'execDepCode',
component: 'Input',
colProps: {span: 6},
},
];
//表单数据
export const formSchema: FormSchema[] = [
{
label: '项目名称',
field: 'projectName',
component: 'Input',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入项目名称!'},
];
},
},
{
label: '项目类型',
field: 'projectType',
component: 'JSearchSelect',
componentProps:{
dict: "projecttype"
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择项目类型!'},
];
},
},
{
label: '执行部门',
field: 'execDepCode',
component: 'JSelectDept',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
multiple: false,
allowClear: false,
onChange: (e: any) => {
const { updateSchema } = formActionType;
if(e === undefined||e===''){
formModel.execDepCode = null
formModel.headCode = null
updateSchema({
field: 'headCode',
componentProps: {
onclick: (e:any) => {
if(!formModel.execDepCode){
message.warn("请先选择执行部门!")
return
}
}
},
});
return
}
if(formModel.execDepCode!=e[0]){
formModel.headCode = null
}
updateSchema({
field: 'headCode',
componentProps: {
dict: "listDuty",
depCode: e[0],
onclick: (e:any) => {
if(!formModel.execDepCode){
message.warn("请先选择执行部门!")
return
}
}
},
});
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择执行部门!'},
];
},
},
{
label: '负责人',
field: 'headCode',
component: 'JSearchSelectDuty',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.execDepCode){
formModel.headCode = null
message.warn("请先选择执行部门!")
return
}
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择负责人!'},
];
},
},
{
label: '计划开始日期',
field: 'planStartDate',
component: 'DatePicker',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择计划开始日期!'},
];
},
},
{
label: '计划结束日期',
field: 'planEndDate',
component: 'DatePicker',
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择计划结束日期!'},
];
},
},
{
label: '审核部门',
field: 'approveDepCode',
component: 'JSelectDept',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
multiple: false,
allowClear: false,
onChange: (e: any) => {
const { updateSchema } = formActionType;
if(e === undefined||e===''){
formModel.approveDepCode = null
formModel.approveUser = null
updateSchema({
field: 'approveUser',
componentProps: {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.approveDepCode){
message.warn("请先选择审核部门!")
return
}
}
},
});
return
}
if(formModel.approveDepCode!=e[0]){
formModel.approveUser = null
}
updateSchema({
field: 'approveUser',
componentProps: {
dict: "listDuty",
depCode: e[0],
onclick: (e:any) => {
if(!formModel.approveDepCode){
message.warn("请先选择审核部门!")
return
}
}
},
});
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择审核部门!'},
];
},
},
{
label: '审核人',
field: 'approveUser',
component: 'JSearchSelectDuty',
componentProps: ({ schema, tableAction, formActionType, formModel }) => {
return {
dict: "listDuty",
onclick: (e:any) => {
if(!formModel.approveDepCode){
formModel.approveUser = null
message.warn("请先选择审核部门!")
return
}
}
}
},
colProps: {lg: 12},
itemProps:{labelCol:{xs: {span: 24},sm: {span: 6},},wrapperCol:{xs: {span: 24},sm: {span: 18},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请选择审核人!'},
];
},
},
{
label: '项目描述',
field: 'projectDesc',
component: 'InputTextArea',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
dynamicRules: ({model,schema}) => {
return [
{ required: true, message: '请输入项目描述!'},
];
},
componentProps: {
rows: 5
}
},
{
label: '相关附件',
field: 'fileUploadPath',
component: 'JUpload',
itemProps:{labelCol:{xs: {span: 24},sm: {span: 3},},wrapperCol:{xs: {span: 24},sm: {span: 21},}},
componentProps: { desText:"支持扩展名: .rar .zip .doc .docx .pdf .jpg..."},
},
{
label: '',
field: 'planCode',
component: 'Input',
show: false
},
// TODO 主键隐藏字段,目前写死为ID
{
label: '',
field: 'id',
component: 'Input',
show: false
},
];
/**
* 流程表单调用这个方法获取formSchema
* @param param
*/
export function getBpmFormSchema(_formData): FormSchema[]{
// 默认和原始表单保持一致 如果流程中配置了权限数据,这里需要单独处理formSchema
return formSchema;
}
\ No newline at end of file
<template>
<div style="min-height: 400px">
<BasicForm @register="registerForm" />
<div style="width: 100%; text-align: center" v-if="!formDisabled">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
</template>
<script lang="ts">
import { BasicForm, useForm } from '/@/components/Form/index';
import { computed, defineComponent } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
import { getBpmFormSchema } from '../StPlanApprove.data';
import { saveOrUpdate } from '../StPlanApprove.api';
export default defineComponent({
name: 'StPlanApproveForm',
components: {
BasicForm,
},
props: {
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props) {
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const formDisabled = computed(() => {
if (props.formData.disabled === false) {
return false;
}
return true;
});
let formData = {};
const queryByIdUrl = '/plan.approve/stPlanApprove/queryById';
async function initFormData() {
let params = { id: props.formData.dataId };
const data = await defHttp.get({ url: queryByIdUrl, params });
formData = { ...data };
//设置表单的值
await setFieldsValue(formData);
//默认是禁用
await setProps({ disabled: formDisabled.value });
}
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
await saveOrUpdate(params, true);
}
initFormData();
return {
registerForm,
formDisabled,
submitForm,
};
},
});
</script>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue';
import { saveOrUpdate } from '../StPlanApprove.api';
import { formSchema } from '../StPlanApprove.data';
import { BasicForm, useForm } from '/@/components/Form/index';
import { BasicModal, useModalInner } from '/@/components/Modal';
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
const isDetail = ref(false);
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate,updateSchema}] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: 24}
});
//表单赋值
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
isUpdate.value = !!data?.isUpdate;
isDetail.value = !data?.showFooter
if (unref(isUpdate)) {
//表单赋值
await setFieldsValue({
...data.record,
});
}
if(data.record['planFlag']=='4'){
await updateSchema({
label: '变更原因',
field: 'optDes',
show: true
})
}else if(data.record['planFlag']=='7'){
await updateSchema({
label: '废止原因',
field: 'optDes',
show: true
})
}else{
await updateSchema({
label: '废止原因',
field: 'optDes',
show: false
})
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
});
//设置标题
const title = computed(() => (unref(isDetail) ? '计划详情' : '计划审核'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({confirmLoading: true});
//提交表单
await saveOrUpdate(values, isUpdate.value);
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({confirmLoading: false});
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
\ No newline at end of file
<template>
<div style="min-height: 400px">
<BasicForm @register="registerForm" />
<div style="width: 100%; text-align: center" v-if="!formDisabled">
<a-button @click="submitForm" pre-icon="ant-design:check" type="primary">提 交</a-button>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue';
import { saveOrUpdate } from '../StPlanMan.api';
import { getBpmFormSchema } from '../StPlanManChange.data';
import { BasicForm, useForm } from '/@/components/Form/index';
import { defHttp } from '/@/utils/http/axios';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({
name: 'StPlanManChangeForm',
components: {
BasicForm,
},
props: {
formData: propTypes.object.def({}),
formBpm: propTypes.bool.def(true),
},
setup(props) {
const [registerForm, { setFieldsValue, setProps, getFieldsValue }] = useForm({
labelWidth: 150,
schemas: getBpmFormSchema(props.formData),
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
const formDisabled = computed(() => {
if (props.formData.disabled === false) {
return false;
}
return true;
});
let formData = {};
const queryByIdUrl = '/plan.main/stPlanMan/queryById';
async function initFormData() {
let params = { id: props.formData.dataId };
const data = await defHttp.get({ url: queryByIdUrl, params });
formData = { ...data };
//设置表单的值
await setFieldsValue(formData);
//默认是禁用
await setProps({ disabled: formDisabled.value });
}
async function submitForm() {
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
await saveOrUpdate(params, true);
}
initFormData();
return {
registerForm,
formDisabled,
submitForm,
};
},
});
</script>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue';
import { changeOrRepeal } from '../StPlanMan.api';
import { formSchema } from '../StPlanManChange.data';
import { BasicForm, useForm } from '/@/components/Form/index';
import { BasicModal, useModalInner } from '/@/components/Modal';
// Emits声明
const emit = defineEmits(['register', 'success']);
const isUpdate = ref(true);
const handleFlag = ref('');
const isDetail = ref(false);
//表单配置
const [registerForm, { setProps, resetFields, setFieldsValue, validate, updateSchema }] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: { span: 24 },
});
//表单赋值
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({ confirmLoading: false, showCancelBtn: !!data?.showFooter, showOkBtn: !!data?.showFooter });
isUpdate.value = !!data?.isUpdate;
handleFlag.value = data.planFlag;
isDetail.value = !data?.showFooter;
if (unref(isUpdate)) {
if (!unref(isDetail)) {
if (unref(handleFlag) == '4') {
await updateSchema({
label: '变更原因',
field: 'optDes',
component: 'InputTextArea',
itemProps: { labelCol: { xs: { span: 24 }, sm: { span: 3 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 21 } } },
dynamicRules: ({ model, schema }) => {
return [{ required: true, message: '请输入变更原因!' }];
},
dynamicDisabled: false,
show: true,
});
} else if (unref(handleFlag) == '7') {
setProps({ disabled: true });
await updateSchema({
label: '废止原因',
field: 'optDes',
component: 'InputTextArea',
itemProps: { labelCol: { xs: { span: 24 }, sm: { span: 3 } }, wrapperCol: { xs: { span: 24 }, sm: { span: 21 } } },
dynamicRules: ({ model, schema }) => {
return [{ required: true, message: '请输入废止原因!' }];
},
dynamicDisabled: false,
show: true,
});
}
await updateSchema({
field: 'approveDes',
show: false,
});
data.record['optDes'] = '';
await setFieldsValue({
...data.record,
});
} else {
if (data.record['planFlag'] == '3') {
await updateSchema({
field: 'optDes',
show: false,
});
await updateSchema({
field: 'approveDes',
show: false,
});
} else if (data.record['planFlag'] == '4') {
await updateSchema({
label: '变更原因',
field: 'optDes',
dynamicDisabled: true,
show: true,
});
await updateSchema({
field: 'approveDes',
show: false,
});
} else if (data.record['planFlag'] == '7') {
updateSchema({
label: '废止原因',
field: 'optDes',
dynamicDisabled: true,
show: true,
});
await updateSchema({
field: 'approveDes',
show: false,
});
} else if (data.record['planFlag'] == '5' || data.record['planFlag'] == '6') {
await updateSchema({
label: '变更原因',
field: 'optDes',
dynamicDisabled: true,
show: true,
});
await updateSchema({
field: 'approveDes',
show: true,
});
} else if (data.record['planFlag'] == '8' || data.record['planFlag'] == '9') {
updateSchema({
label: '废止原因',
field: 'optDes',
dynamicDisabled: true,
show: true,
});
await updateSchema({
field: 'approveDes',
show: true,
});
}
//表单赋值
data.record['optDes'] = data.record['optDesbak'];
await setFieldsValue({
...data.record,
});
setProps({ disabled: !data?.showFooter });
}
} else {
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter });
}
if (!data?.showFooter) {
updateSchema({ field: 'fileUploadPath', componentProps: { buttonVisible: false } });
} else {
updateSchema({ field: 'fileUploadPath', componentProps: { buttonVisible: true } });
}
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '新建' : unref(handleFlag) == '4' ? '变更' : unref(isDetail) ? '详情' : '废止'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({ confirmLoading: true });
values['planFlag'] = unref(handleFlag);
//提交表单
await changeOrRepeal(values, unref(handleFlag) == '4');
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
:deep(.ant-calendar-picker) {
width: 100%;
}
</style>
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800">
<!--引用表格-->
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
</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)">下载</a-button>
</template>
</BasicTable>
<StPlanManTranceModal @register="registerModal1"></StPlanManTranceModal>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue';
import { trancelist } from '../StPlanMan.api';
import { columns, searchFormSchema } from '../StPlanManTrance.data';
import StPlanManTranceModal from './StPlanManTranceModal.vue';
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
import { BasicTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { downloadFile } from '/@/utils/common/renderUtils';
const [registerModal1, {openModal}] = useModal();
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
const handleFlag = ref('')
const planCode = ref('')
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
isUpdate.value = !!data?.isUpdate;
handleFlag.value = data.planFlag
planCode.value = data.record['planCode']
});
//注册table数据
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
tableProps:{
title: '',
api: trancelist,
columns,
canResize:false,
useSearchForm: false,
formConfig: {
//labelWidth: 120,
schemas: searchFormSchema,
autoSubmitOnEnter:true,
showAdvancedButton:true,
fieldMapToNumber: [
],
fieldMapToTime: [
],
},
actionColumn: {
width: 60,
fixed:'right'
},
showTableSetting: false,
beforeFetch(params) {
params = Object.assign(params,{ column: 'updatedTime', order: 'desc',planCode:planCode.value})
},
}
})
const [registerTable, {setProps,reload},{ rowSelection, selectedRowKeys }] = tableContext
//设置标题
const title = computed(() => (!unref(isUpdate) ? '变更记录' : '变更记录'));
function handleDetail(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
showFooter: false,
});
}
/**
* 操作栏
*/
function getTableAction(record){
return [
{
label: '详情',
onClick: handleDetail.bind(null, record),
},
]
}
/**
* 下拉操作栏
*/
function getDropDownAction(record){
return [
]
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
\ No newline at end of file
<template>
<BasicModal v-bind="$attrs" @register="registerModal" destroyOnClose :title="title" :width="800" @ok="handleSubmit">
<BasicForm @register="registerForm"/>
</BasicModal>
</template>
<script lang="ts" setup>
import { computed, ref, unref } from 'vue';
import { changeOrRepeal } from '../StPlanMan.api';
import { formSchema } from '../StPlanManTrance.data';
import { BasicForm, useForm } from '/@/components/Form/index';
import { BasicModal, useModalInner } from '/@/components/Modal';
// Emits声明
const emit = defineEmits(['register','success']);
const isUpdate = ref(true);
const handleFlag = ref('')
//表单配置
const [registerForm, {setProps,resetFields, setFieldsValue, validate,updateSchema}] = useForm({
//labelWidth: 150,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {span: 24}
});
//表单赋值
const [registerModal, {setModalProps, closeModal}] = useModalInner(async (data) => {
//重置表单
await resetFields();
setModalProps({confirmLoading: false,showCancelBtn:!!data?.showFooter,showOkBtn:!!data?.showFooter});
isUpdate.value = !!data?.isUpdate;
handleFlag.value = data.planFlag
if (unref(isUpdate)) {
data.record['optDes'] = ''
//表单赋值
await setFieldsValue({
...data.record,
});
}
// 隐藏底部时禁用整个表单
setProps({ disabled: !data?.showFooter })
if(!data?.showFooter){
updateSchema({ field: 'fileUploadPath', componentProps: { buttonVisible: false } })
}else{
updateSchema({ field: 'fileUploadPath', componentProps: { buttonVisible: true } })
}
});
//设置标题
const title = computed(() => (!unref(isUpdate) ? '详情' : '详情'));
//表单提交事件
async function handleSubmit(v) {
try {
let values = await validate();
setModalProps({confirmLoading: true});
values['planFlag'] = unref(handleFlag)
//提交表单
await changeOrRepeal(values, (unref(handleFlag)=='4'));
//关闭弹窗
closeModal();
//刷新列表
emit('success');
} finally {
setModalProps({confirmLoading: false});
}
}
</script>
<style lang="less" scoped>
/** 时间和数字输入框样式 */
:deep(.ant-input-number){
width: 100%
}
:deep(.ant-calendar-picker){
width: 100%
}
</style>
\ No newline at end of file
...@@ -69,4 +69,8 @@ public class MyTaskFlow implements Serializable { ...@@ -69,4 +69,8 @@ public class MyTaskFlow implements Serializable {
@Excel(name = "uid", width = 15) @Excel(name = "uid", width = 15)
@Schema(description = "uid") @Schema(description = "uid")
private java.lang.String uid; private java.lang.String uid;
/**taskDefinitionKey*/
@Excel(name = "taskDefinitionKey", width = 15)
@Schema(description = "taskDefinitionKey")
private java.lang.String taskDefinitionKey;
} }
...@@ -201,6 +201,8 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask ...@@ -201,6 +201,8 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
taskFlow.setDeployId(deploymentId); taskFlow.setDeployId(deploymentId);
taskFlow.setFormTableName(sysForm.getFormTableName()); taskFlow.setFormTableName(sysForm.getFormTableName());
taskFlow.setUid(approvalId); taskFlow.setUid(approvalId);
taskFlow.setTaskDefinitionKey(nextTask.getTaskDefinitionKey());
myTaskFlowService.save(taskFlow); myTaskFlowService.save(taskFlow);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论