Compare commits
7 Commits
66022141f3
...
6c4aa13cd4
| Author | SHA1 | Date |
|---|---|---|
|
|
6c4aa13cd4 | |
|
|
fb00c57f4b | |
|
|
7cd925605e | |
|
|
9f0f021368 | |
|
|
84fe53cd75 | |
|
|
bb38116df8 | |
|
|
807ba06ef4 |
|
|
@ -6892,7 +6892,7 @@
|
|||
t && (this.myChart = window.echarts.init(t), setTimeout((function() {
|
||||
e.updateChart(e.option)
|
||||
}), 100))
|
||||
} else console.error("learun[力软信息]提醒你:缺少 echarts 引入")
|
||||
} else console.error("警告:缺少 echarts 引入")
|
||||
},
|
||||
updateChart: function(e) {
|
||||
console.log(e), this.myChart.resize(), e && this.myChart.setOption(e, !0)
|
||||
|
|
@ -7825,7 +7825,7 @@
|
|||
e.exports = n("35e8")
|
||||
},
|
||||
9224: function(e) {
|
||||
e.exports = JSON.parse('{"name":"learun-ui-vue","version":"3.3.2","private":true,"description":"vue ui compontents.","author":"tobin","main":"dist2/lui.common.js","company":"力软信息技术(苏州)有限公司","keywords":["vue","learun","learun-ui","learun-ui-vue"],"scripts":{"dev":"vue-cli-service serve","build":"vue-cli-service build","lint":"vue-cli-service lint","test:unit":"vue-cli-service test:unit","prepublishOnly":"npm run lib","lib":"vue-cli-service build --target lib --name learunui --dest dist2 lib/index.js"},"dependencies":{"countup.js":"^2.0.7","element-resize-detector":"^1.2.2","element-ui":"^2.11.0","vue":"^2.6.14","vue-async-computed":"^3.9.0","vue-router":"^3.0.6","vuedraggable":"^2.24.3"},"devDependencies":{"@vue/cli-plugin-babel":"^3.7.0","@vue/cli-plugin-eslint":"^3.7.0","@vue/cli-service":"^3.7.0","@vue/eslint-config-standard":"^4.0.0","@vue/test-utils":"^1.0.0-beta.29","babel-eslint":"^10.0.1","chai":"^4.2.0","core-js":"^2.6.9","css-loader":"^3.1.0","eslint":"^5.16.0","eslint-plugin-vue":"^5.0.0","highlight.js":"^9.15.8","less":"^3.9.0","less-loader":"^5.0.0","markdown-it-chain":"^1.3.0","markdown-it-container":"^2.0.0","shelljs":"^0.8.3","style-loader":"^0.23.1","transliteration":"^2.1.4","vue-markdown-loader":"^2.4.1","vue-template-compiler":"^2.6.10"},"eslintConfig":{"root":true,"env":{"node":true,"browser":true},"extends":["plugin:vue/essential","eslint:recommended"],"rules":{"vue/no-reserved-keys":0,"no-empty":0,"no-useless-escape":0,"no-console":0},"parserOptions":{"parser":"babel-eslint"}},"eslintIgnore":["/src/docs","dist2"],"postcss":{"plugins":{"autoprefixer":{}}},"babel":{"presets":["@vue/app"]}}')
|
||||
e.exports = JSON.parse('{"name":"learun-ui-vue","version":"3.3.2","private":true,"description":"vue ui compontents.","author":"tobin","main":"dist2/lui.common.js","company":"山东慧创信息科技有限公司","keywords":["vue","learun","learun-ui","learun-ui-vue"],"scripts":{"dev":"vue-cli-service serve","build":"vue-cli-service build","lint":"vue-cli-service lint","test:unit":"vue-cli-service test:unit","prepublishOnly":"npm run lib","lib":"vue-cli-service build --target lib --name learunui --dest dist2 lib/index.js"},"dependencies":{"countup.js":"^2.0.7","element-resize-detector":"^1.2.2","element-ui":"^2.11.0","vue":"^2.6.14","vue-async-computed":"^3.9.0","vue-router":"^3.0.6","vuedraggable":"^2.24.3"},"devDependencies":{"@vue/cli-plugin-babel":"^3.7.0","@vue/cli-plugin-eslint":"^3.7.0","@vue/cli-service":"^3.7.0","@vue/eslint-config-standard":"^4.0.0","@vue/test-utils":"^1.0.0-beta.29","babel-eslint":"^10.0.1","chai":"^4.2.0","core-js":"^2.6.9","css-loader":"^3.1.0","eslint":"^5.16.0","eslint-plugin-vue":"^5.0.0","highlight.js":"^9.15.8","less":"^3.9.0","less-loader":"^5.0.0","markdown-it-chain":"^1.3.0","markdown-it-container":"^2.0.0","shelljs":"^0.8.3","style-loader":"^0.23.1","transliteration":"^2.1.4","vue-markdown-loader":"^2.4.1","vue-template-compiler":"^2.6.10"},"eslintConfig":{"root":true,"env":{"node":true,"browser":true},"extends":["plugin:vue/essential","eslint:recommended"],"rules":{"vue/no-reserved-keys":0,"no-empty":0,"no-useless-escape":0,"no-console":0},"parserOptions":{"parser":"babel-eslint"}},"eslintIgnore":["/src/docs","dist2"],"postcss":{"plugins":{"autoprefixer":{}}},"babel":{"presets":["@vue/app"]}}')
|
||||
},
|
||||
9292: function(e, t, n) {
|
||||
"use strict";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
getPageListModel,
|
||||
stateModel,
|
||||
GetFormModel,
|
||||
formModuleModel,
|
||||
} from './model/formModuleModel';
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
|
||||
|
|
@ -17,6 +18,10 @@ enum Api {
|
|||
Post_DeleteForm = '/api/FormModule/DeleteForm',
|
||||
// 根据主键获取实体数据(编辑时使用)
|
||||
Get_GetForm = '/api/FormModule/GetForm',
|
||||
// 新增实体数据
|
||||
Post_AddForm = '/api/FormModule/AddForm',
|
||||
// 编辑实体数据
|
||||
Post_UpdateForm = '/api/FormModule/UpdateForm',
|
||||
}
|
||||
|
||||
// 获取分页列表
|
||||
|
|
@ -48,3 +53,18 @@ export function fun_GetForm(params) {
|
|||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 新增实体数据
|
||||
export function Post_AddForm(params: formModuleModel) {
|
||||
return defHttp.post<responsesmodel>({
|
||||
url: Api.Post_AddForm,
|
||||
params,
|
||||
});
|
||||
}
|
||||
// 编辑实体数据
|
||||
export function Post_UpdateForm(params: formModuleModel) {
|
||||
return defHttp.post<responsesmodel>({
|
||||
url: Api.Post_UpdateForm,
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,3 +87,106 @@ export interface form {
|
|||
isMain: number;
|
||||
}
|
||||
export type GetFormModel = BasicFetchResult<form>;
|
||||
|
||||
// 表单发布实体数据
|
||||
// 表单发布实体
|
||||
export interface formModuleEntity {
|
||||
id: string;
|
||||
code: string;
|
||||
formCode: string;
|
||||
formVerison: string;
|
||||
icon: string;
|
||||
name: string;
|
||||
type: number;
|
||||
pmoduleId: string;
|
||||
moduleId: string;
|
||||
sortCode: number;
|
||||
enabledMark: number;
|
||||
description: string;
|
||||
createDate: string;
|
||||
createUserId: string;
|
||||
createUserName: string;
|
||||
modifyDate: string;
|
||||
modifyUserId: string;
|
||||
modifyUserName: string;
|
||||
scheme: string;
|
||||
keyWord: string;
|
||||
tenantId: string;
|
||||
isMain: number;
|
||||
}
|
||||
export type formModuleEntityModel = BasicFetchResult<formModuleEntity>;
|
||||
// 表单发布实体
|
||||
export interface elements {
|
||||
id: string;
|
||||
domId: string;
|
||||
name: string;
|
||||
attr: string;
|
||||
script: string;
|
||||
icon: string;
|
||||
class: string;
|
||||
remark: string;
|
||||
sort: number;
|
||||
moduleId: string;
|
||||
}
|
||||
export interface sysModule {
|
||||
id: string;
|
||||
cascadeId: string;
|
||||
name: string;
|
||||
parentId: string;
|
||||
parentName: string;
|
||||
url: string;
|
||||
iconName: string;
|
||||
status: number;
|
||||
sortNo: number;
|
||||
code: string;
|
||||
encode: string;
|
||||
isSys: true;
|
||||
elements: elements;
|
||||
}
|
||||
export type sysModuleModel = BasicFetchResult<sysModule>;
|
||||
// 表单发布实体
|
||||
export interface sysModuleElement {
|
||||
id: string;
|
||||
domId: string;
|
||||
name: string;
|
||||
attr: string;
|
||||
script: string;
|
||||
icon: string;
|
||||
class: string;
|
||||
remark: string;
|
||||
sort: number;
|
||||
moduleId: string;
|
||||
}
|
||||
export type sysModuleElementModel = BasicFetchResult<sysModuleElement>;
|
||||
// 表单发布实体-Column
|
||||
export interface sysModuleColumn {
|
||||
moduleColumnId: string;
|
||||
moduleId: string;
|
||||
parentId: string;
|
||||
encode: string;
|
||||
fullName: string;
|
||||
sortCode: number;
|
||||
tenantId: string;
|
||||
isMain: number;
|
||||
}
|
||||
export type sysModuleColumnModel = BasicFetchResult<sysModuleColumn>;
|
||||
// 表单发布实体
|
||||
export interface sysModuleForm {
|
||||
moduleFormId: string;
|
||||
moduleId: string;
|
||||
parentId: string;
|
||||
encode: string;
|
||||
fullName: string;
|
||||
sortCode: number;
|
||||
tenantId: string;
|
||||
isMain: number;
|
||||
}
|
||||
export type sysModuleFormModel = BasicFetchResult<sysModuleForm>;
|
||||
//
|
||||
export interface formModuleModel {
|
||||
formModuleEntity: formModuleEntityModel;
|
||||
sysModule: sysModuleModel;
|
||||
sysModuleElement: sysModuleElementModel;
|
||||
sysModuleColumn: sysModuleColumnModel;
|
||||
sysModuleForm: sysModuleFormModel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
// WFTask
|
||||
import { defHttp } from '@/utils/http/axios';
|
||||
import {MyUncompletedParams} from './model/WFTaskModel'
|
||||
import {MyUncompletedParams,TaskDetailParam} from './model/WFTaskModel'
|
||||
|
||||
enum Api {
|
||||
// 我的待办
|
||||
|
|
@ -12,6 +12,7 @@ import {MyUncompletedParams} from './model/WFTaskModel'
|
|||
LoadMyReadPage='/api/WFTask/LoadMyReadPage',
|
||||
// 我的委托
|
||||
LoadMyDelegatePage='/api/WFTask/LoadMyDelegatePage',
|
||||
GetTaskDetail='/api/WFTask/Get',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,4 +38,10 @@ import {MyUncompletedParams} from './model/WFTaskModel'
|
|||
*/
|
||||
export function getLoadMyDelegatePage(params?: MyUncompletedParams) {
|
||||
return defHttp.get({ url: Api.LoadMyDelegatePage, params });
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @description: GetTaskDetail
|
||||
*/
|
||||
export function getTaskDetail(params?: TaskDetailParam) {
|
||||
return defHttp.get({ url: Api.GetTaskDetail, params });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,7 @@
|
|||
limit: number;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
}
|
||||
export interface TaskDetailParam {
|
||||
id: string;
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
<a-tab-pane key="1" tab="自定义表单">
|
||||
<a-space direction="vertical" size="middle" class="site-space-compact-wrapper">
|
||||
<a-space-compact block>
|
||||
<a-input v-model:value="formData.formCode" placeholder="请选择表单" readonly />
|
||||
<a-input v-model:value="node.formCode" placeholder="请选择表单" readonly />
|
||||
<a-button >选择</a-button>
|
||||
</a-space-compact>
|
||||
<a-space-compact block>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@
|
|||
<a-button :disabled="data.defaultZoom >= 3.9" :icon="h(ZoomInOutlined)" @click="processZoomIn()">
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
<div class="ml-2 tag-box">
|
||||
<a-tag color="processing">正在审核</a-tag>
|
||||
<a-tag color="success">已审核</a-tag>
|
||||
</div>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
|
|
@ -22,6 +26,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="my-process-designer__container">
|
||||
|
||||
<div class="my-process-designer__canvas" ref="bpmn-canvas" id="view"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -33,6 +38,8 @@
|
|||
import { SaveOutlined, ZoomOutOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||
import BpmnViewer from 'bpmn-js/lib/Viewer'
|
||||
import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas';
|
||||
const emit = defineEmits(['event', 'element-click']);
|
||||
|
||||
const data = reactive({
|
||||
bpmnModeler: null,
|
||||
defaultZoom: 1,
|
||||
|
|
@ -40,7 +47,7 @@
|
|||
|
||||
const props = defineProps({
|
||||
xml: String,
|
||||
flowViewer:{
|
||||
flowViewer: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
finishedTaskSet: [],
|
||||
|
|
@ -48,7 +55,11 @@
|
|||
unfinishedTaskSet: [],
|
||||
rejectedTaskSet: [],
|
||||
})
|
||||
}
|
||||
},
|
||||
events: {
|
||||
type: Array,
|
||||
default: () => ["element.click"]
|
||||
},
|
||||
})
|
||||
watch(
|
||||
() => props.xml,
|
||||
|
|
@ -71,6 +82,19 @@
|
|||
MoveCanvasModule
|
||||
],
|
||||
})
|
||||
initModelListeners()
|
||||
}
|
||||
function initModelListeners() {
|
||||
const EventBus = data.bpmnModerler.get("eventBus");
|
||||
// 注册需要的监听事件, 将. 替换为 - , 避免解析异常
|
||||
props.events.forEach(event => {
|
||||
EventBus.on(event, function (eventObj) {
|
||||
let eventName = event.replace('.', "-");
|
||||
let element = eventObj ? eventObj.element : null;
|
||||
emit(eventName, element, eventObj);
|
||||
emit('event', eventName, element, eventObj);
|
||||
});
|
||||
});
|
||||
}
|
||||
async function createDiagram(xml) {
|
||||
const viewer = data.bpmnModerler
|
||||
|
|
@ -103,6 +127,7 @@
|
|||
// 设置节点颜色
|
||||
function setNodeColor() {
|
||||
const elementRegistry = data.bpmnModerler.get('elementRegistry')
|
||||
console.log(elementRegistry)
|
||||
let { finishedTaskSet, rejectedTaskSet, unfinishedTaskSet, finishedSequenceFlowSet } = props.flowViewer
|
||||
if (Array.isArray(finishedSequenceFlowSet)) {
|
||||
finishedSequenceFlowSet.forEach(item => {
|
||||
|
|
@ -120,6 +145,7 @@
|
|||
}
|
||||
})
|
||||
}
|
||||
console.log(unfinishedTaskSet)
|
||||
if (Array.isArray(unfinishedTaskSet)) {
|
||||
unfinishedTaskSet.forEach(item => {
|
||||
if (elementRegistry._elements[item]) {
|
||||
|
|
@ -161,13 +187,22 @@
|
|||
function getOperationTagType(type) {
|
||||
return 'success';
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.my-process-designer {
|
||||
width: 100%;
|
||||
}
|
||||
.tag-box{
|
||||
float: right;
|
||||
}
|
||||
::v-deep .ant-tag-success{
|
||||
padding: 5px 11px;
|
||||
}
|
||||
::v-deep .ant-tag-processing{
|
||||
padding: 5px 11px;
|
||||
|
||||
}
|
||||
::v-deep .bjs-container a {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@
|
|||
"workflow":{
|
||||
"scheme_preview":"流程模板设计",
|
||||
"create_preview":"流程发起",
|
||||
"task_preview":"流程详情"
|
||||
"task_audit_preview":"审核节点",
|
||||
"task_look_preview":"查看流程"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,21 @@ export const LoginRoute: AppRouteRecordRaw = {
|
|||
title: t('routes.basic.login'),
|
||||
},
|
||||
};
|
||||
export const H5HtmlRoute: AppRouteRecordRaw = {
|
||||
path: '/h5html',
|
||||
name: 'h5html',
|
||||
component: () => import('@/views/demo/h5html/index.vue'),
|
||||
meta: {
|
||||
title: t('routes.basic.h5html'),
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Basic routing without permission
|
||||
// 未经许可的基本路由
|
||||
export const basicRoutes = [
|
||||
H5HtmlRoute,
|
||||
LoginRoute,
|
||||
RootRoute,
|
||||
...mainOutRoutes,
|
||||
|
|
|
|||
|
|
@ -48,17 +48,29 @@ const dashboard: AppRouteModule = {
|
|||
component: () => import('@/views/demo/workflow/create/preview.vue'),
|
||||
},
|
||||
{
|
||||
path: 'task_preview/:id',
|
||||
name: 'TaskPreview',
|
||||
path: 'task_audit_preview/:id',
|
||||
name: 'TaskAuditPreview',
|
||||
meta: {
|
||||
hideMenu: true,
|
||||
title: t('routes.demo.workflow.task_preview'),
|
||||
title: t('routes.demo.workflow.task_audit_preview'),
|
||||
ignoreKeepAlive: true,
|
||||
showMenu: false,
|
||||
currentActiveMenu: '/workflow/create',
|
||||
currentActiveMenu: '/workflow/task',
|
||||
},
|
||||
component: () => import('@/views/demo/workflow/task/detail.vue'),
|
||||
}
|
||||
component: () => import('@/views/demo/workflow/task/process/audit.vue'),
|
||||
},
|
||||
{
|
||||
path: 'task_look_preview/:id',
|
||||
name: 'TaskLookPreview',
|
||||
meta: {
|
||||
hideMenu: true,
|
||||
title: t('routes.demo.workflow.task_look_preview'),
|
||||
ignoreKeepAlive: true,
|
||||
showMenu: false,
|
||||
currentActiveMenu: '/workflow/task',
|
||||
},
|
||||
component: () => import('@/views/demo/workflow/task/process/look.vue'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* 日期格式化
|
||||
*/
|
||||
export function formatDate(v, format) {
|
||||
if (!v) return "";
|
||||
var d = v;
|
||||
if (typeof v === 'string') {
|
||||
if (v.indexOf("/Date(") > -1)
|
||||
d = new Date(parseInt(v.replace("/Date(", "").replace(")/", ""), 10));
|
||||
else
|
||||
d = new Date(Date.parse(v.replace(/-/g, "/").replace("T", " ").split(".")[0]));//.split(".")[0] 用来处理出现毫秒的情况,截取掉.xxx,否则会出错
|
||||
}
|
||||
var o = {
|
||||
"M+": d.getMonth() + 1, //month
|
||||
"d+": d.getDate(), //day
|
||||
"h+": d.getHours(), //hour
|
||||
"H+": d.getHours(), //hour
|
||||
"m+": d.getMinutes(), //minute
|
||||
"s+": d.getSeconds(), //second
|
||||
"q+": Math.floor((d.getMonth() + 3) / 3), //quarter
|
||||
"S": d.getMilliseconds() //millisecond
|
||||
};
|
||||
if (/(y+)/.test(format)) {
|
||||
format = format.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
|
||||
}
|
||||
for (var k in o) {
|
||||
if (new RegExp("(" + k + ")").test(format)) {
|
||||
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
|
||||
}
|
||||
}
|
||||
return format;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export function dateFormat(date,format = 'yyyy-MM-dd hh:mm:ss'){
|
||||
return formatDate(date,format);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ const transform: AxiosTransform = {
|
|||
if (options.errorMessageMode === 'modal') {
|
||||
createErrorModal({ title: t('sys.api.errorTip'), content: timeoutMsg });
|
||||
} else if (options.errorMessageMode === 'message') {
|
||||
createMessage.error(timeoutMsg);
|
||||
// createMessage.error(timeoutMsg);
|
||||
}
|
||||
|
||||
throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'));
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
}
|
||||
getOutKeyList({tableNames: fieldTableValue.value, dbCode: receivedData.dbCode}).then((data: AreaRespVO[]) => {
|
||||
let arr: any[] = []
|
||||
if(data[0]){
|
||||
if(data && data[0]){
|
||||
data[0].db_codecolumnsList.forEach(item =>{
|
||||
arr.push({
|
||||
label: item.dbColumnName,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,43 @@ import { ComponentType } from '@/components/Form/src/types';
|
|||
|
||||
import { componentMap as Cmp } from '../components';
|
||||
import { Component } from 'vue';
|
||||
import { getDeptList,getAccountList,getPosGroupList } from '@/api/demo/system';
|
||||
|
||||
//获取部门列表数据
|
||||
const deptTreeData = await Promise.all([getDeptListData()])
|
||||
function getDeptListData(){
|
||||
let param = {
|
||||
page: 1,
|
||||
limit: 9999
|
||||
};
|
||||
return getDeptList( param ).then( data => {
|
||||
return data
|
||||
})
|
||||
}
|
||||
|
||||
//获取职级列表数据
|
||||
const positionTreeData = await Promise.all([getPositionListData()])
|
||||
function getPositionListData(){
|
||||
let param = {
|
||||
page: 1,
|
||||
limit: 9999
|
||||
};
|
||||
return getPosGroupList( param ).then( data => {
|
||||
return data
|
||||
})
|
||||
}
|
||||
//获取人员选择列表数据
|
||||
const userTreeData = await Promise.all([getUserListData()])
|
||||
function getUserListData(){
|
||||
let param = {
|
||||
page: 1,
|
||||
limit: 9999
|
||||
};
|
||||
return getAccountList( param ).then( data => {
|
||||
return data.items
|
||||
})
|
||||
}
|
||||
|
||||
const componentMap = new Map<string, Component>();
|
||||
|
||||
//如果有其它控件,可以在这里初始化
|
||||
|
|
@ -56,41 +92,33 @@ export const customComponents: IVFormComponent[] = [
|
|||
componentProps: {},
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
label: '公司选择',
|
||||
component: 'TreeSelect',
|
||||
label: '职级选择',
|
||||
icon: 'gg:select',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
fieldNames:{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
},
|
||||
treeData: positionTreeData[0],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Select',
|
||||
component: 'TreeSelect',
|
||||
label: '部门选择',
|
||||
icon: 'gg:select',
|
||||
icon: 'clarity:tree-view-line',
|
||||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
fieldNames:{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
},
|
||||
treeData: deptTreeData[0],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -100,16 +128,11 @@ export const customComponents: IVFormComponent[] = [
|
|||
field: '',
|
||||
colProps: { span: 24 },
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '选项1',
|
||||
value: '1',
|
||||
},
|
||||
{
|
||||
label: '选项2',
|
||||
value: '2',
|
||||
},
|
||||
],
|
||||
fieldNames:{
|
||||
label: 'name',
|
||||
value: 'account',
|
||||
},
|
||||
options: userTreeData[0],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
import { BasicColumn, FormSchema } from '@/components/Table';
|
||||
import { h } from 'vue';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '分类',
|
||||
dataIndex: 'category',
|
||||
},
|
||||
{
|
||||
title: '类型',
|
||||
dataIndex: 'formType',
|
||||
width: 80,
|
||||
customRender: ({ record }) => {
|
||||
const status = record.formType;
|
||||
const enable = ~~status === 0;
|
||||
const color = enable ? '#67c23a' : '#e6a23c';
|
||||
const text = enable ? '常规表单' : '视图表单';
|
||||
return h(Tag, { color: color }, () => text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建人',
|
||||
dataIndex: 'createUserName'
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createDate'
|
||||
},
|
||||
// {
|
||||
// title: '备注',
|
||||
// dataIndex: 'remark',
|
||||
// },
|
||||
];
|
||||
|
||||
export const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'key',
|
||||
label: '关键字',
|
||||
component: 'Input',
|
||||
colProps: { span: 8 },
|
||||
},
|
||||
];
|
||||
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction :actions="[
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: '是否删除该数据',
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
}
|
||||
]" />
|
||||
</template>
|
||||
</template>
|
||||
<template #toolbar>
|
||||
<a-button type="primary" @click="handleAddForm(eFormPreview!)"> 新增 </a-button>
|
||||
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<VformRender ref="eFormPreview" :formConfig="formConfig" @renderdata="renderdata" />
|
||||
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, nextTick, unref,reactive } from 'vue';
|
||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
import { getFormGroupList,getBaseConfigList } from '@/api/formdesign/index';
|
||||
import { columns, searchFormSchema } from './index.data';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import VformRender from '../form-design/components/VformRender/index.vue';
|
||||
import { IFormConfig,IToolbarMethods } from '../form-design/typings/v-form-component';
|
||||
|
||||
const eFormPreview = ref<null | IToolbarMethods>(null);
|
||||
|
||||
const [registerTable, { reload, getSelectRows }] = useTable({
|
||||
title: '表单列表',
|
||||
api: getFormGroupList,
|
||||
rowKey: 'f_Id',
|
||||
columns,
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
bordered: true,
|
||||
beforeFetch: (data) => {
|
||||
// 接口请求前 参数处理
|
||||
var temp = {
|
||||
page: data.page,
|
||||
limit: data.limit,
|
||||
keyWord: data.key,
|
||||
category: data.f_Category
|
||||
};
|
||||
return temp;
|
||||
},
|
||||
afterFetch: (data) => {
|
||||
|
||||
},
|
||||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
},
|
||||
actionColumn: {
|
||||
width: 180,
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
// slots: { customRender: 'action' },
|
||||
fixed: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
const formConfig = ref<IFormConfig>({
|
||||
// 表单配置
|
||||
schemas: [],
|
||||
layout: 'horizontal',
|
||||
labelLayout: 'flex',
|
||||
labelWidth: 100,
|
||||
labelCol: {},
|
||||
wrapperCol: {},
|
||||
currentItem: {
|
||||
component: '',
|
||||
componentProps: {},
|
||||
},
|
||||
activeKey: 1,
|
||||
});
|
||||
|
||||
const handleAddForm = (Modal: IToolbarMethods) => {
|
||||
console.log('formConfig',formConfig)
|
||||
const config = cloneDeep(formConfig.value);
|
||||
Modal?.showModal(config);
|
||||
}
|
||||
function handleEdit(record: Recordable) {
|
||||
|
||||
}
|
||||
function handleDelete(record: Recordable) {
|
||||
// openAccountModal(true, {
|
||||
// record,
|
||||
// });
|
||||
}
|
||||
function getPublicForm(){
|
||||
getBaseConfigList({ id: "ed985a1e-b007-43d1-af14-be4e44018c8b" }).then((res: AreaRespVO[]) =>{
|
||||
let obj = JSON.parse(res.scheme.scheme)
|
||||
console.log('res',obj.formInfo)
|
||||
formConfig.value.schemas = obj.formInfo.schemas
|
||||
})
|
||||
}
|
||||
//表单填写数据
|
||||
function renderdata(e){
|
||||
console.log('renderdata',e)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getPublicForm()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -104,9 +104,14 @@
|
|||
// });
|
||||
}
|
||||
function getPublicForm(){
|
||||
getBaseConfigList({ id: "ed985a1e-b007-43d1-af14-be4e44018c8b" }).then((res: AreaRespVO[]) =>{
|
||||
getBaseConfigList({ id: "e03bd1db-7a4f-43b2-9e8a-f6cd8c2126be" }).then((res: AreaRespVO[]) =>{
|
||||
let obj = JSON.parse(res.scheme.scheme)
|
||||
console.log('res',obj.formInfo)
|
||||
if(obj.formInfo.schemas){
|
||||
obj.formInfo.schemas.forEach(item =>{
|
||||
|
||||
})
|
||||
}
|
||||
formConfig.value.schemas = obj.formInfo.schemas
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,28 +35,48 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="design-content">
|
||||
<ModalForm v-show="stepsCurrent === 0" :isNextSteps="isNextSteps" />
|
||||
<ModalDesign v-show="stepsCurrent === 1" :isSubmitClick="isSubmitClick" />
|
||||
<ModalForm
|
||||
v-show="stepsCurrent == 0"
|
||||
@change-form-verisons="changeFormVerisons"
|
||||
ref="modalFrom_formData"
|
||||
/>
|
||||
<ModalDesign
|
||||
v-show="stepsCurrent == 1"
|
||||
:modalFormVerison="modalFormVerison"
|
||||
ref="modalDesign_config"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import ModalForm from './modalForm.vue';
|
||||
import ModalDesign from './modalDesign.vue';
|
||||
import { Post_AddForm, Post_UpdateForm } from '@/api/demo/formModule';
|
||||
|
||||
// 当前指向页面
|
||||
let stepsCurrent = ref();
|
||||
let stepsCurrent = ref(0);
|
||||
// 是否是第二页
|
||||
let isNextSteps = ref(false);
|
||||
// 提交按钮
|
||||
let isSubmitClick = ref(false);
|
||||
// 是否是编辑
|
||||
let formEdit = ref(false);
|
||||
// 子组件的暴露属性
|
||||
const modalFrom_formData = ref();
|
||||
const modalDesign_config = ref();
|
||||
|
||||
const modalFormVerison = ref('');
|
||||
|
||||
const [registerModal, { closeModal }] = useModalInner((data: any) => {
|
||||
console.log(75, data);
|
||||
formEdit.value = data.formEdit;
|
||||
// if(){
|
||||
|
||||
// }
|
||||
stepsCurrent.value = 0;
|
||||
isSubmitClick.value = false;
|
||||
});
|
||||
|
|
@ -78,10 +98,120 @@
|
|||
isNextSteps.value = false;
|
||||
closeModal();
|
||||
}
|
||||
|
||||
// 提交
|
||||
function submitClick() {
|
||||
async function submitClick() {
|
||||
const postData = getForm();
|
||||
if (formEdit.value) {
|
||||
await Post_UpdateForm(postData);
|
||||
} else {
|
||||
await Post_AddForm(postData);
|
||||
}
|
||||
closeModal();
|
||||
isSubmitClick.value = true;
|
||||
}
|
||||
|
||||
function getForm() {
|
||||
const formData = modalFrom_formData.value.formData;
|
||||
const config = modalDesign_config.value.config;
|
||||
|
||||
// 基本配置信息
|
||||
let formModuleEntity = {};
|
||||
formModuleEntity.id = formData.id;
|
||||
formModuleEntity.code = formData.code;
|
||||
formModuleEntity.formCode = formData.formCode.id;
|
||||
formModuleEntity.formVerison = formData.formVerison.value;
|
||||
formModuleEntity.icon = formData.icon;
|
||||
formModuleEntity.name = formData.name;
|
||||
formModuleEntity.type = formData.type;
|
||||
formModuleEntity.pmoduleId = formData.pmoduleId;
|
||||
formModuleEntity.moduleId = '';
|
||||
formModuleEntity.sortCode = formData.sortCode;
|
||||
formModuleEntity.enabledMark = formData.enabledMark;
|
||||
formModuleEntity.description = formData.description;
|
||||
// formModuleEntity.createDate= ;
|
||||
// formModuleEntity.createUserId= ;
|
||||
// formModuleEntity.createUserName= ;
|
||||
formModuleEntity.modifyDate = new Date();
|
||||
// formModuleEntity.modifyUserId= ;
|
||||
// formModuleEntity.modifyUserName= ;
|
||||
formModuleEntity.scheme = JSON.stringify(config);
|
||||
formModuleEntity.keyWord = '';
|
||||
formModuleEntity.tenantId = '';
|
||||
formModuleEntity.isMain = '';
|
||||
|
||||
// 目录sysModule
|
||||
let sysModule = {};
|
||||
sysModule.id = '';
|
||||
sysModule.cascadeId = '';
|
||||
sysModule.name = formData.name;
|
||||
sysModule.parentId = formData.pmoduleId;
|
||||
sysModule.parentName = '';
|
||||
sysModule.url = '';
|
||||
sysModule.iconName = formData.icon;
|
||||
sysModule.status = 1;
|
||||
sysModule.sortNo = formData.sortCode;
|
||||
sysModule.code = formData.code;
|
||||
sysModule.encode = '';
|
||||
sysModule.isSys = formData.isSys;
|
||||
sysModule.elements = [];
|
||||
|
||||
// 按钮sysModuleElement
|
||||
let sysModuleElement = [];
|
||||
if (config.table.btns) {
|
||||
config.table.btns.forEach((t) => {
|
||||
let temp = {};
|
||||
temp.id = '';
|
||||
temp.domId = t.prop;
|
||||
temp.name = t.label;
|
||||
temp.attr = '';
|
||||
temp.script = '';
|
||||
temp.icon = t.icon;
|
||||
temp.class = t.class;
|
||||
temp.remark = '';
|
||||
temp.sort = t.sort;
|
||||
temp.moduleId = '';
|
||||
sysModuleElement.push(temp);
|
||||
});
|
||||
}
|
||||
// 列sysModuleColumn
|
||||
let sysModuleColumn = [];
|
||||
if (config.table.columns) {
|
||||
config.table.columns.forEach((t) => {
|
||||
let temp = {};
|
||||
temp.encode = t.prop;
|
||||
temp.fullName = t.label;
|
||||
sysModuleColumn.push(temp);
|
||||
});
|
||||
}
|
||||
// 表单sysModuleForm
|
||||
let sysModuleForm = [];
|
||||
if (config.table.querys) {
|
||||
config.table.querys.forEach((t) => {
|
||||
let temp = {};
|
||||
temp.encode = t.key;
|
||||
temp.fullName = t.label;
|
||||
sysModuleForm.push(temp);
|
||||
});
|
||||
}
|
||||
|
||||
// postData
|
||||
let postData = {};
|
||||
postData.formModuleEntity = formModuleEntity;
|
||||
postData.sysModule = sysModule;
|
||||
postData.sysModuleElement = sysModuleElement;
|
||||
postData.sysModuleColumn = sysModuleColumn;
|
||||
postData.sysModuleForm = sysModuleForm;
|
||||
|
||||
console.log('postData', postData);
|
||||
|
||||
return postData;
|
||||
}
|
||||
|
||||
// 子组件modalForm传递数据到父组件,再由父组件传给子组件modalDesign
|
||||
function changeFormVerisons(formVerison) {
|
||||
modalFormVerison.value = formVerison;
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.form-box {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,50 @@
|
|||
@check="handleCheck"
|
||||
/>
|
||||
</template>
|
||||
<BasicTable @register="registerTable" />
|
||||
<BasicTable @register="btnsTable">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'isRowBtn'">
|
||||
<a-switch
|
||||
v-model:checked="record.isRowBtn"
|
||||
:disabled="['Add', 'Import', 'Export'].includes(record.prop)"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'isWFlow'">
|
||||
<div v-if="record.prop == 'Add'">
|
||||
<a-switch v-model:checked="record.isWFlow" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'wFlowCode'">
|
||||
<div v-if="record.prop == 'Add'">
|
||||
<a-select
|
||||
ref="select"
|
||||
placeholder="请选择"
|
||||
size="small"
|
||||
v-model:value="record.wFlowCode"
|
||||
:options="wflist"
|
||||
:field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="column.key === 'class'">
|
||||
<a-select
|
||||
ref="select"
|
||||
placeholder="请选择"
|
||||
size="small"
|
||||
v-model:value="record.class"
|
||||
:options="classList"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="column.key === 'sort'">
|
||||
<a-input-number v-model:value="record.sort" :min="0" />
|
||||
</template>
|
||||
<template v-if="column.key === 'icon'">
|
||||
<div v-if="record.prop in ['Add', 'Import', 'Export']">
|
||||
<IconPicker v-model:value="record.icon" />
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</lrlayout>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
|
|
@ -19,6 +62,7 @@
|
|||
import { BasicTable, useTable } from '@/components/Table';
|
||||
import lrlayout from '@/components/lrLayout';
|
||||
import { BasicTree } from '@/components/Tree';
|
||||
import { IconPicker } from '/@/components/Icon';
|
||||
|
||||
import { btns } from './config.data';
|
||||
|
||||
|
|
@ -33,11 +77,16 @@
|
|||
|
||||
// config
|
||||
const config = inject('formConfig');
|
||||
const btnsData = ref(config.btns);
|
||||
const btnsData = ref(config.table.btns);
|
||||
|
||||
console.log(38, btnsTree);
|
||||
const classList = [
|
||||
{ label: 'primary', value: 'primary' },
|
||||
{ label: 'success', value: 'success' },
|
||||
{ label: 'error', value: 'error' },
|
||||
{ label: 'warning', value: 'warning' },
|
||||
];
|
||||
|
||||
const [registerTable, { reload }] = useTable({
|
||||
const [btnsTable, { reload }] = useTable({
|
||||
rowKey: 'id',
|
||||
dataSource: btnsData,
|
||||
columns: btns(),
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
@check="handleCheck"
|
||||
/>
|
||||
</template>
|
||||
<BasicTable @register="registerTable">
|
||||
<BasicTable @register="columnsTable">
|
||||
<template #toolbar>
|
||||
<span style="margin-right: 8px">是否分页</span>
|
||||
<a-switch class="mars-switch" v-model:checked="config.table.isPage" />
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
{ value: 'right', label: '右' },
|
||||
];
|
||||
|
||||
const [registerTable, { reload }] = useTable({
|
||||
const [columnsTable, { reload }] = useTable({
|
||||
rowKey: 'key',
|
||||
dataSource: columnsData,
|
||||
columns: columns(),
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ export function btns(): BasicColumn[] {
|
|||
{ title: '行按钮', dataIndex: 'isRowBtn', width: '80', align: 'center' },
|
||||
{ title: '创建流程', dataIndex: 'isWFlow', width: '80', align: 'center' },
|
||||
{ title: '流程模版', dataIndex: 'wFlowCode', width: '240' },
|
||||
{ title: '权限标识', dataIndex: 'class', width: '120' },
|
||||
{ title: '排序', dataIndex: 'sort', width: '80' },
|
||||
{ title: '图标', dataIndex: 'icon', width: '240' },
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,280 +0,0 @@
|
|||
<template>
|
||||
<lrlayout style="background: #f1f2f5" :left="240">
|
||||
<template #left>
|
||||
<lrPanel title="列表关联字段" style="padding: 8px 0 0 0">
|
||||
<a-radio class="block-radio" :options="colslist" v-model="config.left.colField" />
|
||||
</lrPanel>
|
||||
</template>
|
||||
<lrPanel title="设置" style="padding: 8px 0 0 4px">
|
||||
<el-form style="padding: 16px; maxwidth: 400px" size="mini" ref="form" label-width="80px">
|
||||
<el-form-item label="树形标题">
|
||||
<el-input v-model="config.left.title" />
|
||||
</el-form-item>
|
||||
<div style="text-align: center; margin-bottom: 16px">
|
||||
<a-radio-group v-model="config.left.dataType" size="mini" @change="handleDataTypeChange">
|
||||
<a-radio-button label="1">静态数据</a-radio-button>
|
||||
<a-radio-button label="2">数据字典</a-radio-button>
|
||||
<a-radio-button label="3">数据源</a-radio-button>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<!--静态数据-->
|
||||
<div v-if="config.left.dataType == 1">
|
||||
<a-tree
|
||||
ref="tree"
|
||||
:data="config.left.options"
|
||||
default-expand-all
|
||||
draggable
|
||||
node-key="value"
|
||||
:expand-on-click-node="false"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<span>{{ node.label }}</span>
|
||||
<span>
|
||||
<a-button
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
@click="handleNodeAdd(data)"
|
||||
/>
|
||||
<a-button
|
||||
class="danger"
|
||||
type="text"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
@click="handleNodeRemove(node, data)"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</a-tree>
|
||||
<div style="margin-left: 22px">
|
||||
<a-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-circle-plus-outline"
|
||||
@click="handleParentNodeAdd"
|
||||
>添加父级</a-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!--数据字典-->
|
||||
<div v-else-if="config.left.dataType == 2">
|
||||
<l-tree-select
|
||||
v-model="config.left.dataCode"
|
||||
:options="lr_dataItemClassifysTree"
|
||||
placeholder="请选择数据字典"
|
||||
size="mini"
|
||||
/>
|
||||
</div>
|
||||
<!--远端数据-->
|
||||
<div v-else>
|
||||
<el-form-item label="数据源">
|
||||
<l-select
|
||||
v-model="config.left.dataCode"
|
||||
placeholder="请选择数据源"
|
||||
size="mini"
|
||||
:options="lr_dataSource"
|
||||
labelKey="f_Name"
|
||||
valueKey="f_Code"
|
||||
@change="handleDataSourceChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联字段">
|
||||
<l-select
|
||||
v-model="config.left.dataValueKey"
|
||||
placeholder="请选择选项关联字段"
|
||||
size="mini"
|
||||
:options="myColNameList"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="显示字段">
|
||||
<l-select
|
||||
v-model="config.left.dataLabelKey"
|
||||
placeholder="请选择选项显示字段"
|
||||
size="mini"
|
||||
:options="myColNameList"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="id字段">
|
||||
<l-select
|
||||
v-model="config.left.dataIdKey"
|
||||
placeholder="请选择选项id字段"
|
||||
size="mini"
|
||||
:options="myColNameList"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="pid字段">
|
||||
<l-select
|
||||
v-model="config.left.dataPIdKey"
|
||||
placeholder="请选择选项父级id字段"
|
||||
size="mini"
|
||||
:options="myColNameList"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</lrPanel>
|
||||
|
||||
<l-dialog
|
||||
:title="dialogTitle"
|
||||
v-model:visible="dialogVisible"
|
||||
:height="200"
|
||||
@close="closeDialog"
|
||||
@ok="handleDialogAdd"
|
||||
>
|
||||
<div class="l-from-body">
|
||||
<el-form
|
||||
:model="dialogForm"
|
||||
size="mini"
|
||||
:rules="dialogRules"
|
||||
ref="dialogForm"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="选项名" prop="label">
|
||||
<el-input v-model="dialogForm.label" />
|
||||
</el-form-item>
|
||||
<el-form-item label="选项值" prop="value">
|
||||
<el-input v-model="dialogForm.value" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</l-dialog>
|
||||
</lrlayout>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { inject, defineProps } from 'vue';
|
||||
import { BasicTable, useTable } from '@/components/Table';
|
||||
import lrlayout from '@/components/lrLayout';
|
||||
import { BasicTree } from '@/components/Tree';
|
||||
import lrPanel from '@/components/lrPanel';
|
||||
|
||||
import { columns } from './config.data';
|
||||
|
||||
// 定义props,树目录
|
||||
const props = defineProps({
|
||||
colslist: {
|
||||
type: Object,
|
||||
default: () => ({}), // 设置默认值为一个空对象
|
||||
},
|
||||
});
|
||||
|
||||
// config
|
||||
const config = inject('formConfig');
|
||||
|
||||
let dialogTitle = '添加选项';
|
||||
let dialogVisible = false;
|
||||
const dialogForm = ref({
|
||||
label: '',
|
||||
value: '',
|
||||
});
|
||||
let dialogRules = {
|
||||
label: { required: true, message: '请输入选项名', trigger: 'null' },
|
||||
value: { required: true, message: '请输入选项值', trigger: 'null' },
|
||||
};
|
||||
let pData = undefined;
|
||||
|
||||
function myColNameList() {
|
||||
if (config.left.dataCode) {
|
||||
const colNameList = config.left.dataCode;
|
||||
return colNameList.map((t) => {
|
||||
return { value: t, label: t };
|
||||
});
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
// created() {
|
||||
// lr_loadDataItemClassifys();
|
||||
// lr_loadDataSourceList();
|
||||
// if (config.left.dataType == 3) {
|
||||
// lr_loadDataSourceColNames(config.left.dataCode);
|
||||
// }
|
||||
// },
|
||||
// methods: {
|
||||
function handleDataTypeChange() {
|
||||
config.left.dataIdKey = '';
|
||||
config.left.dataPIdKey = '';
|
||||
|
||||
config.left.dataCode = '';
|
||||
config.left.dataValueKey = '';
|
||||
config.left.dataLabelKey = '';
|
||||
}
|
||||
|
||||
function handleParentNodeAdd() {
|
||||
pData = undefined;
|
||||
dialogTitle = '添加父级选项';
|
||||
dialogVisible = true;
|
||||
}
|
||||
function handleNodeAdd(data) {
|
||||
pData = data;
|
||||
dialogTitle = `添加【${data.label}】的子选项`;
|
||||
dialogVisible = true;
|
||||
}
|
||||
function handleNodeRemove(node, data) {
|
||||
const parent = node.parent;
|
||||
const children = parent.data.children || parent.data;
|
||||
const index = children.findIndex((d) => d.id === data.id);
|
||||
children.splice(index, 1);
|
||||
}
|
||||
|
||||
// function handleDialogAdd() {
|
||||
// dialogForm.validate((valid) => {
|
||||
// if (valid) {
|
||||
// const { label, value } = dialogForm;
|
||||
// const node = $refs.tree.getNode(value);
|
||||
// if (node) $message.error('选项值重复');
|
||||
// else {
|
||||
// const pData = pData;
|
||||
// const newNode = {
|
||||
// label,
|
||||
// value: dialogInputType == 'number' ? Number(value) : value,
|
||||
// };
|
||||
// if (pData) {
|
||||
// if (!pData.children) $set(pData, 'children', []);
|
||||
// pData.children.push(newNode);
|
||||
// } else {
|
||||
// $set(config.left.options, config.left.options.length, newNode);
|
||||
// }
|
||||
// dialogVisible = false;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
function closeDialog() {
|
||||
dialogForm.clearValidate();
|
||||
dialogForm.value = {};
|
||||
}
|
||||
|
||||
function handleDataSourceChange(val) {
|
||||
config.left.dataValueKey = '';
|
||||
config.left.dataLabelKey = '';
|
||||
config.left.dataIdKey = '';
|
||||
config.left.dataPIdKey = '';
|
||||
|
||||
if (!$validatenull(val)) {
|
||||
// lr_loadDataSourceColNames(val);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.block-radio {
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
.el-radio {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
<lrlayout style="background: #f1f2f5" :left="240">
|
||||
<template #left>
|
||||
<lrPanel title="列表关联字段" style="padding: 8px 0 0 0">
|
||||
<a-radio-group :options="colslist" v-model="config.left.colField" />
|
||||
<a-radio-group :options="colslist" v-model:value="config.left.colField" />
|
||||
</lrPanel>
|
||||
</template>
|
||||
<lrPanel title="设置" style="padding: 8px 0 0 4px">
|
||||
|
|
@ -11,10 +11,15 @@
|
|||
<a-input v-model="config.left.title" />
|
||||
</a-form-item>
|
||||
<div style="text-align: center; margin-bottom: 16px">
|
||||
<a-radio-group v-model="config.left.dataType" size="mini" @change="handleDataTypeChange">
|
||||
<a-radio-button label="1">静态数据</a-radio-button>
|
||||
<a-radio-button label="2">数据字典</a-radio-button>
|
||||
<a-radio-button label="3">数据源</a-radio-button>
|
||||
<a-radio-group
|
||||
v-model:value="config.left.dataType"
|
||||
size="mini"
|
||||
button-style="solid"
|
||||
@change="handleDataTypeChange"
|
||||
>
|
||||
<a-radio-button value="1">静态数据</a-radio-button>
|
||||
<a-radio-button value="2">数据字典</a-radio-button>
|
||||
<a-radio-button value="3">数据源</a-radio-button>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
<!--静态数据-->
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
</template>
|
||||
<a-layout style="background: #f1f2f5">
|
||||
<a-layout-sider :style="{ width: '1000px' }">
|
||||
<BasicTable @register="registerTable">
|
||||
<BasicTable @register="queryTable">
|
||||
<template #toolbar>
|
||||
<div class="l-panel--item" size="mini">
|
||||
<a-radio-group
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
const querysData = ref(config.table.querys);
|
||||
const radioData = ref(config.queryType);
|
||||
|
||||
const [registerTable, { reload }] = useTable({
|
||||
const [queryTable, { reload }] = useTable({
|
||||
canResize: 'true',
|
||||
showIndexColumn: 'false',
|
||||
rowKey: 'key',
|
||||
|
|
|
|||
|
|
@ -261,3 +261,25 @@ export const formSchema: FormSchema[] = [
|
|||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const modalColumns: BasicColumn[] = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
dataIndex: 'scheme',
|
||||
ifShow: false,
|
||||
},
|
||||
{
|
||||
title: '分类',
|
||||
dataIndex: 'category',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'action',
|
||||
width: 80,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,12 +10,17 @@
|
|||
<template #toolbar>
|
||||
<PermissionBtn @btn-event="onBtnClicked" />
|
||||
</template>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'pmoduleId'">
|
||||
{{ findModuleName(pmoduleIds, record.pmoduleId) }}
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<FormModal @submitsuccess="submitsuccess" @register="registerModal" v-if="formModalVisible" />
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, nextTick, ref } from 'vue';
|
||||
import { reactive, nextTick, ref, onMounted } from 'vue';
|
||||
|
||||
import { BasicTable, useTable } from '@/components/Table';
|
||||
|
||||
|
|
@ -23,10 +28,12 @@
|
|||
import PermissionBtn from '@/components/PermissionBtn/index.vue';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { TreeItem } from '@/components/Tree';
|
||||
|
||||
import MenuTree from './FormTree.vue';
|
||||
import FormModal from './FormModal.vue';
|
||||
|
||||
import { getMenuList } from '@/api/demo/system';
|
||||
import { fun_GetPageList, fun_DeleteForm } from '@/api/demo/formModule';
|
||||
import { formModuleColumns, searchFormSchema } from './formModule.data';
|
||||
|
||||
|
|
@ -61,6 +68,8 @@
|
|||
const childRef = ref<any>();
|
||||
// 是否打开弹窗
|
||||
const formModalVisible = ref(true);
|
||||
//
|
||||
const pmoduleIds = ref<TreeItem[]>([]);
|
||||
|
||||
// searchInfo的树分支条件查询
|
||||
function handleSelect(ModuleId = '') {
|
||||
|
|
@ -72,7 +81,9 @@
|
|||
// 表单新增
|
||||
function handleAddForm() {
|
||||
formModalVisible.value = true;
|
||||
openModal(true, {});
|
||||
openModal(true, {
|
||||
formEdit: false,
|
||||
});
|
||||
}
|
||||
// 表单编辑
|
||||
function handleEdit() {
|
||||
|
|
@ -81,9 +92,12 @@
|
|||
return createMessage.warn('请选择一个按钮进行编辑');
|
||||
}
|
||||
const record = rows[0];
|
||||
record.type = '2';
|
||||
// record.type = '2';
|
||||
formModalVisible.value = true;
|
||||
openModal(true, record);
|
||||
openModal(true, {
|
||||
formEdit: true,
|
||||
record: record,
|
||||
});
|
||||
}
|
||||
// 表单删除
|
||||
async function handleDelete() {
|
||||
|
|
@ -137,4 +151,29 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 上级功能
|
||||
function findModuleName(modules, pmoduleId) {
|
||||
for (const module of modules) {
|
||||
if (module.id === pmoduleId) {
|
||||
return module.name;
|
||||
}
|
||||
if (Array.isArray(module.children) && module.children.length > 0) {
|
||||
const foundName = findModuleName(module.children, pmoduleId);
|
||||
if (foundName) {
|
||||
return foundName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 上级
|
||||
async function fetch() {
|
||||
pmoduleIds.value = await getMenuList();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, provide, onMounted } from 'vue';
|
||||
import { ref, provide, defineExpose, watch, defineProps } from 'vue';
|
||||
import WebcodeLayout from './config/layout.vue';
|
||||
import webcodeLefttree from './config/leftTree.vue';
|
||||
import webcodeColumns from './config/columns.vue';
|
||||
|
|
@ -30,6 +30,24 @@
|
|||
import webcodeBtns from './config/btns.vue';
|
||||
import { functionGetPreviewForm, functionGetSchemeInfoEntity } from '@/api/demo/formScheme';
|
||||
|
||||
// 定义props
|
||||
const props = defineProps({
|
||||
modalFormVerison: {
|
||||
type: Object,
|
||||
default: () => ({}), // 设置默认值为一个空对象
|
||||
},
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.modalFormVerison,
|
||||
(newVal) => {
|
||||
validateSteps(newVal.value);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
// 初始数据
|
||||
const pageActiveName = 'tab01';
|
||||
// 左侧树形设置
|
||||
|
|
@ -69,25 +87,53 @@
|
|||
isPage: true,
|
||||
columns: [],
|
||||
querys: [],
|
||||
btns: [],
|
||||
sidx: '',
|
||||
isDESC: false,
|
||||
},
|
||||
btns: [
|
||||
{ label: '新增', id: 'Add', prop: 'Add', icon: 'el-icon-plus', isRowBtn: false },
|
||||
{ label: '导入', id: 'Import', prop: 'Import', icon: 'el-icon-upload2', isRowBtn: false },
|
||||
{ label: '导出', id: 'Export', prop: 'Export', icon: 'el-icon-download', isRowBtn: false },
|
||||
{ label: '编辑', id: 'Edit', prop: 'Edit', isRowBtn: true },
|
||||
{ label: '删除', id: 'Delete', prop: 'Delete', isRowBtn: true },
|
||||
{ label: '详情', id: 'Details', prop: 'Details', isRowBtn: true },
|
||||
{
|
||||
label: '新增',
|
||||
id: 'Add',
|
||||
prop: 'Add',
|
||||
icon: 'el-icon-plus',
|
||||
isRowBtn: false,
|
||||
class: 'primary',
|
||||
sort: 0,
|
||||
},
|
||||
{
|
||||
label: '导入',
|
||||
id: 'Import',
|
||||
prop: 'Import',
|
||||
icon: 'el-icon-upload2',
|
||||
isRowBtn: false,
|
||||
class: 'primary',
|
||||
sort: 1,
|
||||
},
|
||||
{
|
||||
label: '导出',
|
||||
id: 'Export',
|
||||
prop: 'Export',
|
||||
icon: 'el-icon-download',
|
||||
isRowBtn: false,
|
||||
class: 'primary',
|
||||
sort: 2,
|
||||
},
|
||||
{ label: '编辑', id: 'Edit', prop: 'Edit', isRowBtn: true, class: 'success', sort: 3 },
|
||||
{ label: '删除', id: 'Delete', prop: 'Delete', isRowBtn: true, class: 'error', sort: 4 },
|
||||
{ label: '详情', id: 'Details', prop: 'Details', isRowBtn: true, class: 'primary', sort: 5 },
|
||||
],
|
||||
});
|
||||
|
||||
const formScheme = ref('');
|
||||
|
||||
// 表单验证
|
||||
async function validateSteps() {
|
||||
async function validateSteps(keyValue: string) {
|
||||
if (!keyValue) {
|
||||
return;
|
||||
}
|
||||
// 选中的历史记录表单
|
||||
let keyValue: string = '4afddef9-e234-458c-a4a8-f67a9728a634';
|
||||
// let keyValue: string = '4afddef9-e234-458c-a4a8-f67a9728a634';
|
||||
const scheme = await functionGetPreviewForm({ keyValue: keyValue });
|
||||
formScheme.value = JSON.parse(scheme.scheme);
|
||||
console.log(scheme);
|
||||
|
|
@ -146,9 +192,6 @@
|
|||
config.value.table.querys.push({
|
||||
key: t.label + t.field,
|
||||
label: t.label,
|
||||
// width: 120,
|
||||
// align: 'left',
|
||||
// isMinWidth: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -156,16 +199,21 @@
|
|||
const schemeInfo = await functionGetSchemeInfoEntity({ id: scheme.schemeInfoId });
|
||||
if (schemeInfo.formType === 1) {
|
||||
// 如果是视图表单就关闭部分按钮
|
||||
config.value.btns = config.value.btns.filter((t) =>
|
||||
config.value.table.btns = config.value.btns.filter((t) =>
|
||||
['Import', 'Export', 'Details'].includes(t.id),
|
||||
);
|
||||
} else {
|
||||
config.value.table.btns = config.value.btns;
|
||||
}
|
||||
config.value.btns.forEach((t) => {
|
||||
console.log(187, config.value.table.btns);
|
||||
config.value.table.btns.forEach((t) => {
|
||||
btnsTree.value.push(t);
|
||||
});
|
||||
}
|
||||
|
||||
validateSteps();
|
||||
|
||||
provide('formConfig', config.value);
|
||||
|
||||
defineExpose({
|
||||
config,
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<BasicModal
|
||||
@register="registerModal"
|
||||
@ok="modalSubmit"
|
||||
title="选择表单"
|
||||
width="60%"
|
||||
height="800"
|
||||
useWrapper="false"
|
||||
>
|
||||
<template #left>
|
||||
<BasicTree
|
||||
ref="asyncExpandTreeRef"
|
||||
title="表单分类"
|
||||
:treeData="treeData"
|
||||
:defaultExpandAll="true"
|
||||
:fieldNames="{ key: 'itemValue', title: 'label' }"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
</template>
|
||||
<BasicTable @register="registerTable" :searchInfo="searchInfo" style="height: 100%">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'action'">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
label: '预览',
|
||||
onClick: () => {
|
||||
previewModal(record);
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
<!-- <VFormPreview ref="eFormPreview" :formConfig="formConfig" /> -->
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref, defineEmits, reactive } from 'vue';
|
||||
import { BasicModal, useModal } from '@/components/Modal';
|
||||
import { BasicTree, TreeItem } from '@/components/Tree';
|
||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
|
||||
// import { IFormConfig } from '@/views/demo/form-design/typings/v-form-component';
|
||||
// import VFormPreview from '@/views/demo/form-design/components/VFormPreview/index.vue';
|
||||
|
||||
import { functionLoadFormSort, functionLoadFormPage } from '@/api/demo/formScheme';
|
||||
import { modalColumns, searchFormSchema } from './formModule.data';
|
||||
|
||||
const emit = defineEmits(['get-scheme-row']);
|
||||
|
||||
const searchInfo = reactive<Recordable>({});
|
||||
|
||||
// 树分类获取
|
||||
const treeData = ref<TreeItem[]>([]);
|
||||
async function fetch() {
|
||||
treeData.value = await functionLoadFormSort();
|
||||
}
|
||||
function handleSelect(category = '') {
|
||||
searchInfo.category = category;
|
||||
clearSelectedRowKeys();
|
||||
reload();
|
||||
}
|
||||
|
||||
// 列表
|
||||
const [registerTable, { getSelectRows, reload, clearSelectedRowKeys }] = useTable({
|
||||
api: functionLoadFormPage,
|
||||
columns: modalColumns,
|
||||
rowKey: 'id',
|
||||
formConfig: {
|
||||
labelWidth: 120,
|
||||
schemas: searchFormSchema,
|
||||
},
|
||||
searchInfo: {},
|
||||
canResize: true,
|
||||
striped: false,
|
||||
// 使用搜索表单
|
||||
useSearchForm: false,
|
||||
// 显示表格设置工具
|
||||
showTableSetting: false,
|
||||
// 是否显示表格边框
|
||||
bordered: true,
|
||||
// 序号列
|
||||
showIndexColumn: true,
|
||||
tableSetting: { fullScreen: true },
|
||||
isCanResizeParent: true,
|
||||
beforeFetch: (data) => {
|
||||
// 接口请求前 参数处理
|
||||
var temp = {
|
||||
page: data.page,
|
||||
limit: data.limit,
|
||||
isEnabled: '1',
|
||||
type: '1',
|
||||
};
|
||||
return temp;
|
||||
},
|
||||
rowSelection: {
|
||||
//多选框
|
||||
type: 'radio',
|
||||
},
|
||||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
},
|
||||
});
|
||||
|
||||
// 表单
|
||||
const [registerModal, { closeModal }] = useModal();
|
||||
// 表单提交
|
||||
function modalSubmit() {
|
||||
let row = getSelectRows();
|
||||
emit('get-scheme-row', row);
|
||||
closeModal();
|
||||
clearSelectedRowKeys();
|
||||
reload();
|
||||
}
|
||||
|
||||
// // endregion
|
||||
// const formConfig = ref<IFormConfig>({
|
||||
// // 表单配置
|
||||
// schemas: [],
|
||||
// layout: 'horizontal',
|
||||
// labelLayout: 'flex',
|
||||
// labelWidth: 100,
|
||||
// labelCol: {},
|
||||
// wrapperCol: {},
|
||||
// currentItem: {
|
||||
// component: '',
|
||||
// componentProps: {},
|
||||
// },
|
||||
// activeKey: 1,
|
||||
// });
|
||||
|
||||
function previewModal(record) {
|
||||
console.log(record);
|
||||
formConfig.value.schemas = record.scheme;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
</script>
|
||||
|
|
@ -1,83 +1,170 @@
|
|||
<template>
|
||||
<div class="l-rblock">
|
||||
<div class="l-page-pane">
|
||||
<BasicForm ref="formModuleRef" @register="registerForm" :model="formData">
|
||||
<template #bodycell="{ model, field }">
|
||||
{{ model }}
|
||||
{{ field }}
|
||||
<template v-if="field === 'formCode'">
|
||||
<a-input
|
||||
v-model:value="formData.formCode"
|
||||
@change="custmerformChange(model)"
|
||||
@click="modelShow"
|
||||
:span="24"
|
||||
:placeholder="请选择"
|
||||
<lrlayout class="l-tab-page">
|
||||
<div class="l-rblock">
|
||||
<div class="l-page-pane">
|
||||
<a-form
|
||||
ref="formModuleRef"
|
||||
:rules="rules"
|
||||
:model="formData"
|
||||
labelAlign="right"
|
||||
:label-col="labelCol"
|
||||
:wrapper-col="wrapperCol"
|
||||
>
|
||||
<a-form-item label="编号" name="code">
|
||||
<a-input v-model:value="formData.code" />
|
||||
</a-form-item>
|
||||
<a-form-item label="名称" name="code">
|
||||
<a-input v-model:value="formData.name" />
|
||||
</a-form-item>
|
||||
<a-form-item label="图标" name="icon">
|
||||
<IconPicker v-model:value="formData.icon" />
|
||||
</a-form-item>
|
||||
<a-form-item label="表单选择" name="formCode" @click="handleShow">
|
||||
<a-input v-model:value="formData.formCode.name">
|
||||
<template #addonAfter>
|
||||
<FileTextOutlined />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="表单版本" name="formVerison">
|
||||
<a-select v-model:value="formData.formVerison" :options="formVerisons" />
|
||||
</a-form-item>
|
||||
<a-form-item label="上级" name="pmoduleId">
|
||||
<a-tree-select
|
||||
v-model:value="formData.pmoduleId"
|
||||
:tree-data="pmoduleIds"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
/>
|
||||
</template>
|
||||
<template v-if="field === 'formVerison'">
|
||||
<a-select
|
||||
v-model:value="formData.formVerison"
|
||||
:options="formVerisons"
|
||||
:span="24"
|
||||
:placeholder="请选择"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
</BasicForm>
|
||||
<div class="formLine"></div>
|
||||
</a-form-item>
|
||||
<a-form-item label="状态" name="enabledMark">
|
||||
<a-radio-group
|
||||
v-model:value="formData.enabledMark"
|
||||
size="mini"
|
||||
@change="radioChange"
|
||||
button-style="solid"
|
||||
>
|
||||
<a-radio-button value="1">是</a-radio-button>
|
||||
<a-radio-button value="0">否</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="是否系统" name="isSys">
|
||||
<a-radio-group
|
||||
v-model:value="formData.isSys"
|
||||
size="mini"
|
||||
@change="radioChange"
|
||||
button-style="solid"
|
||||
>
|
||||
<a-radio-button value="true">是</a-radio-button>
|
||||
<a-radio-button value="false">否</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="排序" name="sortCode">
|
||||
<a-input-number v-model:value="formData.sortCode" :min="0" />
|
||||
</a-form-item>
|
||||
<a-form-item label="描述" name="description">
|
||||
<a-textarea v-model:value="formData.description" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<div class="formLine"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ModuleModal @register="registerModal" @get-scheme-row="getSchemeRow" />
|
||||
</lrlayout>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, provide, computed } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { FileTextOutlined } from '@ant-design/icons-vue';
|
||||
import { defineEmits, ref, onMounted, watch, defineExpose } from 'vue';
|
||||
import { IconPicker } from '@/components/Icon';
|
||||
import { TreeItem } from '@/components/Tree';
|
||||
import { useModal } from '@/components/Modal';
|
||||
import { getMenuList } from '@/api/demo/system';
|
||||
|
||||
import ModuleModal from './modalForm-Modal.vue';
|
||||
import { functionGetSchemePageList } from '@/api/demo/formScheme';
|
||||
|
||||
import { formSchema } from './formModule.data';
|
||||
// emit
|
||||
const emit = defineEmits(['change-form-verisons']);
|
||||
// 表单栅格
|
||||
const labelCol = { span: 4 };
|
||||
const wrapperCol = { span: 20 };
|
||||
|
||||
const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
baseColProps: { lg: 24, md: 24 },
|
||||
});
|
||||
// 表单选择声明
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const formModuleRef = ref<any>();
|
||||
// 版本options
|
||||
const formVerisons = ref([]);
|
||||
// 上级options
|
||||
const pmoduleIds = ref<TreeItem[]>([]);
|
||||
|
||||
// 参数
|
||||
let formData = {
|
||||
const formData = ref({
|
||||
type: 1,
|
||||
code: '',
|
||||
name: '',
|
||||
icon: 'el-icon-star-off',
|
||||
icon: 'ant-design:star-outlined',
|
||||
formCode: '',
|
||||
formVerison: '',
|
||||
pmoduleId: '',
|
||||
moduleId: '',
|
||||
sortCode: '',
|
||||
enabledMark: 1,
|
||||
isSys: false,
|
||||
sortCode: '0',
|
||||
description: '',
|
||||
});
|
||||
// 规则
|
||||
let rules = {
|
||||
code: [{ required: true, message: '请输入' }],
|
||||
name: [{ required: true, message: '请输入' }],
|
||||
icon: [{ component: 'IconPicker', required: true, message: '请输入' }],
|
||||
formCode: [{ required: true, message: '请输入' }],
|
||||
formVerison: [{ required: true, message: '请选择版本' }],
|
||||
pmoduleId: [{ required: true, message: '请输入' }],
|
||||
enabledMark: [{ required: true }],
|
||||
};
|
||||
|
||||
const formVerisons = ref([]);
|
||||
// 监视formVerison
|
||||
watch(
|
||||
() => formData.value.formVerison,
|
||||
() => {
|
||||
changevalidateSteps();
|
||||
},
|
||||
);
|
||||
|
||||
async function custmerformChange(model) {
|
||||
console.log(model);
|
||||
let versioins = [];
|
||||
let query = {
|
||||
schemeInfoId: model.formCode,
|
||||
};
|
||||
const data = await functionGetSchemePageList(query);
|
||||
data.array.forEach((element) => {
|
||||
versioins.push({
|
||||
label: element.createDate,
|
||||
value: element.id,
|
||||
});
|
||||
});
|
||||
formVerisons.value = versioins;
|
||||
// 表单选择打开
|
||||
function handleShow() {
|
||||
openModal();
|
||||
}
|
||||
// 表单选择回传数据
|
||||
async function getSchemeRow(row) {
|
||||
let formVerisons_temp = [];
|
||||
formData.value.formCode = row[0];
|
||||
// 表单选择回传数据变化后,版本变化
|
||||
const historyData = await functionGetSchemePageList({ schemeInfoId: row[0].id });
|
||||
historyData.items.forEach((t) => {
|
||||
formVerisons_temp.push({ label: t.createDate, value: t.id });
|
||||
});
|
||||
formVerisons.value = formVerisons_temp;
|
||||
formData.value.formVerison = formVerisons_temp[0];
|
||||
}
|
||||
|
||||
// 版本改变后传输数据给父组件
|
||||
function changevalidateSteps() {
|
||||
emit('change-form-verisons', formData.value.formVerison);
|
||||
}
|
||||
|
||||
// 上级
|
||||
async function fetch() {
|
||||
pmoduleIds.value = await getMenuList();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
formData,
|
||||
});
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
|
|
|||
|
|
@ -27,14 +27,11 @@
|
|||
</Upload> -->
|
||||
<a-button type="primary" @click="handleDownByData">导出</a-button>
|
||||
</template>
|
||||
<!-- <template #bodyCell="{ column, record }">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'category'">
|
||||
<Select
|
||||
v-model:value="record.category"
|
||||
:options="categoryOptioins"
|
||||
/>
|
||||
{{ findModuleName(treeData, record.category) }}
|
||||
</template>
|
||||
</template> -->
|
||||
</template>
|
||||
</BasicTable>
|
||||
<!-- 树的橱窗 -->
|
||||
<FormSchemeDrawer @register="registerDrawer" @success="handleSuccess" />
|
||||
|
|
@ -48,9 +45,10 @@
|
|||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, nextTick, ref } from 'vue';
|
||||
import { reactive, nextTick, ref, onMounted } from 'vue';
|
||||
|
||||
import { BasicTable, useTable } from '@/components/Table';
|
||||
import { TreeItem } from '@/components/Tree';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { useDrawer } from '@/components/Drawer';
|
||||
|
|
@ -67,7 +65,12 @@
|
|||
// import { uploadApi } from '/@/api/sys/upload';
|
||||
|
||||
import { columns, searchFormSchema } from './formScheme.data';
|
||||
import { functionLoadFormPage, functionGetForm, functionDeleteForm } from '@/api/demo/formScheme';
|
||||
import {
|
||||
functionLoadFormSort,
|
||||
functionLoadFormPage,
|
||||
functionGetForm,
|
||||
functionDeleteForm,
|
||||
} from '@/api/demo/formScheme';
|
||||
|
||||
const { createConfirm, createMessage } = useMessage();
|
||||
|
||||
|
|
@ -277,4 +280,33 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const treeData = ref<TreeItem[]>([]);
|
||||
|
||||
// 分类
|
||||
function findModuleName(modules, pmoduleId) {
|
||||
|
||||
|
||||
for (const module of modules) {
|
||||
if (module.itemValue === pmoduleId) {
|
||||
return module.itemName;
|
||||
}
|
||||
if (Array.isArray(module.children) && module.children.length > 0) {
|
||||
const foundName = findModuleName(module.children, pmoduleId);
|
||||
if (foundName) {
|
||||
return foundName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// 上级
|
||||
async function fetch() {
|
||||
treeData.value = await functionLoadFormSort();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@
|
|||
beforeFetch: (data) => {
|
||||
// 接口请求前 参数处理
|
||||
var temp = {
|
||||
pageIndex: data.page,
|
||||
pageSize: data.limit,
|
||||
page: data.page,
|
||||
limit: data.limit,
|
||||
keyWord: data.key,
|
||||
dbCode: receiceDbCode.value
|
||||
};
|
||||
|
|
|
|||
|
|
@ -230,29 +230,8 @@ export const formSchema: FormSchema[] = [
|
|||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
// componentProps: () => {
|
||||
// return {
|
||||
// api: getDataBaseCodeList,
|
||||
// // 接口返回数据
|
||||
// resultField: 'result',
|
||||
// labelField: 'text',
|
||||
// valueField: 'value',
|
||||
|
||||
// };
|
||||
// }
|
||||
componentProps: {
|
||||
// api: () => {
|
||||
// return new Promise((resolve) => {
|
||||
// resolve([
|
||||
// {
|
||||
// title: 'Parent Node',
|
||||
// value: '0-0',
|
||||
// },
|
||||
// ]);
|
||||
// });
|
||||
// },
|
||||
api: () => getDataBaseCodeList().then((data: AreaRespVO[]) => {
|
||||
console.log('aaaaadata',data)
|
||||
return new Promise((resolve) => {
|
||||
resolve(data);
|
||||
});
|
||||
|
|
@ -264,15 +243,8 @@ export const formSchema: FormSchema[] = [
|
|||
console.log('ApiTreeSelect====>:', e, v);
|
||||
},
|
||||
onLoadData: ({ treeData, resolve, treeNode }) => {
|
||||
console.log('treeNode====>:', treeNode);
|
||||
console.log('treeData====>:', treeData);
|
||||
setTimeout(() => {
|
||||
// const children: Recordable[] = [
|
||||
// { title: `Child Node ${treeNode.eventKey}-0`, value: `${treeNode.eventKey}-0` },
|
||||
// { title: `Child Node ${treeNode.eventKey}-1`, value: `${treeNode.eventKey}-1` },
|
||||
// ];
|
||||
const children: Recordable[] = []
|
||||
console.log('children',children)
|
||||
treeData.value.forEach(item =>{
|
||||
if(item.id == treeNode.id){
|
||||
if(item.childNodes){
|
||||
|
|
@ -285,7 +257,6 @@ export const formSchema: FormSchema[] = [
|
|||
}
|
||||
}
|
||||
})
|
||||
console.log('children22',children)
|
||||
children.forEach((item) => {
|
||||
item.isLeaf = false;
|
||||
item.children = [];
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
</BasicTable>
|
||||
</BasicDrawer>
|
||||
<a-modal width="90%" height="80%" v-model:open="postOpen" title="流程模板预览" @ok="postHandleOk">
|
||||
<a-modal width="70%" height="80%" v-model:open="postOpen" title="流程模板预览" @ok="postHandleOk">
|
||||
<process-designer :key="designerOpen" style="border:1px solid rgba(0, 0, 0, 0.1);" ref="modelDesigner"
|
||||
v-loading="designerData.loading" :pageFlow="flowContent" :pageView="content" :pageType="'detail'"
|
||||
@save="onSaveDesigner" />
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@
|
|||
},
|
||||
});
|
||||
function handleDetail(record){
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_look_preview/detail?processId=' + record.id);
|
||||
}
|
||||
function handleRevocation(record){
|
||||
console.log(record)
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
},
|
||||
});
|
||||
function handleDetail(record){
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_look_preview/detail?processId=' + record.id);
|
||||
}
|
||||
function handleRevocation(record){
|
||||
console.log(record)
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
<template>
|
||||
<PageWrapper :class="prefixCls">
|
||||
<a-tabs v-model:activeKey="activeName">
|
||||
<a-tab-pane key="form" tab="表单信息">
|
||||
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="flow" tab="流程信息" force-render>
|
||||
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||
<process-viewer :key="`designer-${id}`" :xml="flowContent" :flowViewer="flowViewer"/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
</PageWrapper>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount } from 'vue';
|
||||
import ProcessViewer from '@/components/ProcessViewer/index.vue';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { SendOutlined, SaveOutlined, CloseCircleOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||
import { getBPMN } from '@/api/sys/WFProcess'
|
||||
import { getLoadMyUserList } from '@/api/sys/WFDelegate'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useMultipleTabStore } from '@/store/modules/multipleTab';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { buildGUID } from '@/utils/uuid';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
const { createConfirm, createMessage } = useMessage();
|
||||
|
||||
const prefixCls = 'preview-box'
|
||||
const tabStore = useMultipleTabStore();
|
||||
const router = useRouter();
|
||||
const content = ref('')
|
||||
const flowContent = ref('')
|
||||
const flowViewer = ref({})
|
||||
const route = useRoute()
|
||||
const id = route.query.id
|
||||
const designerOpen = ref(false)
|
||||
const formRef = ref();
|
||||
const labelCol = { span: 7 };
|
||||
const wrapperCol = { span: 13 };
|
||||
|
||||
const designerData = reactive({
|
||||
loading: false,
|
||||
xmlString: '',
|
||||
controlForm: {
|
||||
prefix: 'flowable',
|
||||
},
|
||||
height: document.documentElement.clientHeight - 230.5 + "px;",
|
||||
midVisible: false,
|
||||
isCustmerTitle: false,
|
||||
nodeUsers: [],
|
||||
selectUsersVisible: false,
|
||||
|
||||
isDraft: false,
|
||||
delegateUsers: []
|
||||
})
|
||||
const activeName = ref('flow')
|
||||
async function getDetailInfo() {
|
||||
let data = await getBPMN({ id: id })
|
||||
flowContent.value = data.flowContent
|
||||
flowViewer.value = data.flowViewer
|
||||
// var result = {
|
||||
// // 流程图xml
|
||||
// flowContent: "",
|
||||
// // 流程图节点id
|
||||
// flowViewer: {
|
||||
// // 完成节点id集合
|
||||
// finishedTaskSet: [],
|
||||
// // 完成线条节点id集合
|
||||
// finishedSequenceFlowSet: [],
|
||||
// // 当前节点id集合
|
||||
// unfinishedTaskSet: [],
|
||||
// // 拒绝节点id集合(暂无示例)
|
||||
// rejectedTaskSet: [],
|
||||
// }
|
||||
// // 后续还需确定需不需要节点的一些审核信息,需要的话还需要增加返回字段
|
||||
// }
|
||||
}
|
||||
function closePreview() {
|
||||
if (!id) {
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail', router);
|
||||
} else {
|
||||
// /dashboard/create_preview/add?id=测试1
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail?id=' + id, router);
|
||||
}
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
getDetailInfo()
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.preview-box {
|
||||
background-color: @component-background;
|
||||
|
||||
.btn-box {
|
||||
padding: 10px;
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.form-box {
|
||||
width: 480px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -110,7 +110,7 @@
|
|||
}
|
||||
}
|
||||
function handleDetail(record) {
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_look_preview/detail?processId=' + record.id);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
},
|
||||
});
|
||||
function handleDetail(record) {
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_look_preview/detail?processId=' + record.id);
|
||||
}
|
||||
async function handleUrge(record) {
|
||||
var query = {
|
||||
|
|
|
|||
|
|
@ -1,575 +1,293 @@
|
|||
<template>
|
||||
<l-fullscreen-dialog
|
||||
:title="`${title}`"
|
||||
:visible.sync="midVisible"
|
||||
:showOk="false"
|
||||
<PageWrapper :class="prefixCls">
|
||||
<a-tabs v-model:activeKey="activeName">
|
||||
<a-tab-pane key="form" tab="表单信息">
|
||||
|
||||
@closed="handleClosed"
|
||||
@opened="handleOpened"
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="flow" tab="流程信息(审核)" force-render>
|
||||
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||
<process-viewer :key="`designer-${id}`" :events="[
|
||||
'element.click',
|
||||
]" @element-click="elementClick" :xml="flowContent" :flowViewer="flowViewer" />
|
||||
<div class="info-box" v-if="designerData.nodeLogs.length>0" >
|
||||
<a-drawer v-model:open="infoOpen" class="custom-class" title="记录信息" placement="right">
|
||||
<a-timeline>
|
||||
<a-timeline-item v-for="(item,index) in designerData.nodeLogs" :key="index">
|
||||
<div class="title">{{item.time}}</div>
|
||||
<a-card hoverable size="small">
|
||||
<div class="type-title">{{item.name}}</div>
|
||||
<div class="content">
|
||||
<span class="link" v-for="(userName,index2) in item.userNames">{{userName}}</span>
|
||||
<!-- <l-user v-for="(userId,index2) in item.userIds" :key="index2" :value="userId" ></l-user> -->
|
||||
{{item.des}}
|
||||
</div>
|
||||
</a-card>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</a-drawer>
|
||||
|
||||
ref="formDialog"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<template #headerRight v-if="isRead && task && task.f_State == 1" >
|
||||
<el-button size="mini" type="primary" @click="handleRead" >{{$t('确认阅读')}}</el-button>
|
||||
</template>
|
||||
</PageWrapper>
|
||||
|
||||
<l-layout class="l-tab-page" :right="400">
|
||||
<l-panel :style="{'padding-right':isRead?'':0 }" >
|
||||
<div class="l-auto-window" style="padding: 0 8px;" >
|
||||
<el-tabs v-model="activeName" @tab-click="handleTabClick" >
|
||||
<el-tab-pane v-if="hasWfForm" :label="$t('表单信息')" name="form">
|
||||
<div class="l-rblock" v-loading="formSchemeLoding">
|
||||
<template v-if="showForm" >
|
||||
<l-form-viewer
|
||||
v-if="formType == '1'"
|
||||
:formInfo="formInfo"
|
||||
:isWfForm="true"
|
||||
:authFieldsMap="formAuthFieldsMap"
|
||||
ref="wfForm"
|
||||
></l-form-viewer>
|
||||
<component ref="wfForm" v-else :requiredMap="formRequiredMap" :authFieldsMap="formAuthFieldsMap" :isWfForm="true" :is="sysFormComponent"></component>
|
||||
</template>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('流程信息')" name="wfinfo">
|
||||
<l-layout style="background: #f1f2f5;" :right="320">
|
||||
<l-panel class="flow-panel" style="padding:0;padding-top:0;" >
|
||||
<template #title>
|
||||
<el-button-group>
|
||||
<el-tooltip effect="dark" :content="$t('复原')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-aim" @click="resetZoom"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('放大')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-zoom-in" @click="handlerZoom(0.1)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('缩小')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-zoom-out" @click="handlerZoom(-0.1)"></el-button>
|
||||
</el-tooltip>
|
||||
</el-button-group>
|
||||
|
||||
<div style="float:right;" >
|
||||
<el-tag size="small" effect="plain" style="margin-right: 8px;">正在审核</el-tag>
|
||||
<el-tag size="small" effect="plain" style="margin-right: 8px;" type="success">已审核</el-tag>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<b-wflow-viewer
|
||||
ref="bflow"
|
||||
@elementClick="elementClick"
|
||||
>
|
||||
</b-wflow-viewer>
|
||||
</l-panel>
|
||||
<template #right >
|
||||
<l-panel v-if="nodeLogs.length>0" class="flow-panel" style="padding:0;padding-top:0;" >
|
||||
<template #title >
|
||||
记录信息
|
||||
</template>
|
||||
<div class="l-rblock l-time-line-wraper" style="padding:8px;overflow:hidden auto;" >
|
||||
<el-timeline>
|
||||
<el-timeline-item :type="item.type" v-for="(item,index) in nodeLogs" :key="index" :timestamp="item.time" placement="top">
|
||||
<el-card shadow="hover">
|
||||
<div class="title" >{{item.name}}</div>
|
||||
<div class="content">
|
||||
<l-user v-for="(userId,index2) in item.userIds" :key="index2" :value="userId" ></l-user>
|
||||
{{item.des}}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</l-panel>
|
||||
</template>
|
||||
</l-layout>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('流转记录')" name="wflogs">
|
||||
<div class="l-rblock l-time-line-wraper" style="padding:8px;overflow:hidden auto;" >
|
||||
<el-timeline>
|
||||
<el-timeline-item :type="item.type" v-for="(item,index) in logs" :key="index" :timestamp="item.time" placement="top">
|
||||
<el-card shadow="hover">
|
||||
<div class="title" >{{item.name}}</div>
|
||||
<div class="content">
|
||||
<l-user v-for="(userId,index2) in item.userIds" :key="index2" :value="userId" ></l-user>
|
||||
{{item.des}}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</l-panel>
|
||||
|
||||
<template #right v-if="!isRead">
|
||||
<l-panel style="padding-left:0;" title="审批栏" >
|
||||
<div class="l-rblock" style="padding:8px;" >
|
||||
<el-form :model="formData" :rules="myRules" size="mini" ref="form" >
|
||||
<el-form-item :label="isCreateAgain?'备注':'审批意见'" prop="des">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="formData.des"
|
||||
placeholder="请输入"
|
||||
|
||||
rows="3"
|
||||
>
|
||||
</el-input >
|
||||
</el-form-item>
|
||||
<el-form-item class="l-task-btns" >
|
||||
<el-button v-for="(btn,index) in taskBtns" :key="index" :type="btn.type" @click="handleBtnClick(btn)" >{{btn.name}}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<l-wf-audit-info :data="userLogs" ></l-wf-audit-info>
|
||||
</div>
|
||||
</l-panel>
|
||||
</template>
|
||||
</l-layout>
|
||||
|
||||
|
||||
<l-dialog
|
||||
:width="500"
|
||||
:height="nodeUsers.length * 48 + 88"
|
||||
title="选择下一审核节点人员"
|
||||
:visible.sync="selectUsersVisible"
|
||||
@ok="handleSelectUsersSave"
|
||||
@close="handleSelectUsersCloseForm"
|
||||
|
||||
:showClose="false"
|
||||
>
|
||||
<select-users ref="selectUsers" :nodeList="nodeUsers"></select-users>
|
||||
</l-dialog>
|
||||
|
||||
<l-dialog
|
||||
:title="$t(tUserType == 1?`选择转移人员`:`选择加签人员`)"
|
||||
:visible.sync="selectTUserVisible"
|
||||
:height="480"
|
||||
width="1024px"
|
||||
:hasBtns="false"
|
||||
>
|
||||
<l-user-select-panel @change="handleChange" :multiple="false" ref="userSelectPanel" ></l-user-select-panel>
|
||||
</l-dialog>
|
||||
|
||||
<l-dialog
|
||||
:title="$t('驳回节点选择')"
|
||||
:visible.sync="selectRejectNodeVisible"
|
||||
:height="136"
|
||||
:width="500"
|
||||
|
||||
@ok="handleSelectRejectNodeSave"
|
||||
@close="handleRejectNodeCloseForm"
|
||||
|
||||
:showClose="false"
|
||||
>
|
||||
<select-reject-node ref="selectRejectNode" :nodeList="completedNodes"></select-reject-node>
|
||||
</l-dialog>
|
||||
|
||||
<!--选择签章-->
|
||||
<l-dialog
|
||||
:title="$t('选择签章')"
|
||||
:visible.sync="selectSignVisible"
|
||||
:height="480"
|
||||
:width="508"
|
||||
|
||||
@ok="handleSelectSignSave"
|
||||
@closed="handleSelectSignCloseForm"
|
||||
@opened="handleSelectSignOpenForm"
|
||||
>
|
||||
<select-sign ref="SelectSign" ></select-sign>
|
||||
</l-dialog>
|
||||
</l-fullscreen-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../../../mixins/wf'
|
||||
import SelectUsers from './selectAuditUsers.vue'
|
||||
import SelectRejectNode from './selectRejectNode.vue'
|
||||
import SelectSign from './selectSign.vue'
|
||||
<script lang="ts" setup>
|
||||
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount } from 'vue';
|
||||
import ProcessViewer from '@/components/ProcessViewer/index.vue';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { SendOutlined, SaveOutlined, CloseCircleOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||
import { getBPMN } from '@/api/sys/WFProcess'
|
||||
import { getLoadMyUserList } from '@/api/sys/WFDelegate'
|
||||
import { getTaskDetail } from '@/api/sys/WFTask'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useMultipleTabStore } from '@/store/modules/multipleTab';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { buildGUID } from '@/utils/uuid';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { dateFormat } from '@/utils/base'
|
||||
const { createConfirm, createMessage } = useMessage();
|
||||
|
||||
const api = window.$api.workflow.process
|
||||
const apiStamp = window.$api.workflow.stamp
|
||||
|
||||
export default {
|
||||
mixins:[mixin()],
|
||||
components:{
|
||||
SelectUsers,
|
||||
SelectRejectNode,
|
||||
SelectSign
|
||||
const prefixCls = 'preview-box'
|
||||
const tabStore = useMultipleTabStore();
|
||||
const router = useRouter();
|
||||
const content = ref('')
|
||||
const flowContent = ref('')
|
||||
const flowViewer = ref({})
|
||||
const route = useRoute()
|
||||
const processId = route.query.processId
|
||||
const taskId = route.query.taskId
|
||||
const designerOpen = ref(false)
|
||||
const formRef = ref();
|
||||
const labelCol = { span: 7 };
|
||||
const wrapperCol = { span: 13 };
|
||||
const infoOpen = ref(true)
|
||||
const designerData = reactive({
|
||||
loading: false,
|
||||
xmlString: '',
|
||||
controlForm: {
|
||||
prefix: 'flowable',
|
||||
},
|
||||
props:{
|
||||
isCreateAgain:Boolean,
|
||||
isRead:Boolean
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
midVisible:false,
|
||||
formData:{
|
||||
des:''
|
||||
},
|
||||
rules:{
|
||||
des:[
|
||||
{ required: true, message: '请填写审批意见',trigger: 'blur' }
|
||||
],
|
||||
},
|
||||
height: document.documentElement.clientHeight - 200.5 + "px;",
|
||||
midVisible: false,
|
||||
isCustmerTitle: false,
|
||||
nodeUsers: [],
|
||||
selectUsersVisible: false,
|
||||
|
||||
currentBtn:null,
|
||||
|
||||
nodeUsers:[],
|
||||
selectUsersVisible:false,
|
||||
selectTUserVisible:false,
|
||||
tUserType:1, // 1 转移 2 加签,
|
||||
|
||||
selectRejectNodeVisible:false, // 驳回节点选择
|
||||
selectSignVisible:false, // 选择签章
|
||||
stampList:[]
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
myRules(){
|
||||
if(this.isCreateAgain || this.isRead){
|
||||
return {}
|
||||
}
|
||||
else{
|
||||
return this.rules
|
||||
}
|
||||
},
|
||||
completedNodes(){
|
||||
const nodes = this.$deepClone(this.wfData)
|
||||
return nodes.filter(t=>t.hasFinish && t.id != this.currentNode.id)
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
visible: {
|
||||
handler (n) {
|
||||
this.midVisible = n
|
||||
}
|
||||
},
|
||||
},
|
||||
methods:{
|
||||
resetZoom(){
|
||||
this.$refs.bflow.reset()
|
||||
},
|
||||
handlerZoom(r){
|
||||
this.$refs.bflow.handlerZoom(r)
|
||||
},
|
||||
elementClick(node){
|
||||
if(node){
|
||||
this.nodeLogs = this.nodeMap[node.id] || []
|
||||
}
|
||||
else{
|
||||
this.nodeLogs = []
|
||||
}
|
||||
},
|
||||
|
||||
resetFormToMe(){
|
||||
this.$refs.form && this.$refs.form.resetFields()
|
||||
this.taskBtns = []
|
||||
},
|
||||
setForm(){
|
||||
this.$refs.form && this.$refs.form.clearValidate()
|
||||
this.currentNode = this.wfData.find(t=>t.id == this.task.f_UnitId)
|
||||
|
||||
// 设置审核按钮
|
||||
const btns = []
|
||||
if(this.currentNode.type =='startEvent'){
|
||||
btns.push({
|
||||
code:'learun_create',
|
||||
name:'提交',
|
||||
type:'primary'
|
||||
})
|
||||
}
|
||||
else{
|
||||
this.currentNode.btnlist.forEach(btn => {
|
||||
if(btn.code == 'agree'){
|
||||
btn.type = 'primary'
|
||||
}
|
||||
else if(btn.code == 'disagree'){
|
||||
btn.type = 'danger'
|
||||
}
|
||||
btns.push(btn)
|
||||
})
|
||||
|
||||
if(this.currentNode.isAddSign){
|
||||
btns.push({
|
||||
code:'learun_sign',
|
||||
name:'加签',
|
||||
type:'success'
|
||||
})
|
||||
}
|
||||
|
||||
if(this.currentNode.isTransfer){
|
||||
btns.push({
|
||||
code:'learun_transfer',
|
||||
name:'转移',
|
||||
type:'success'
|
||||
})
|
||||
}
|
||||
}
|
||||
this.taskBtns = btns
|
||||
},
|
||||
|
||||
validateForm(){
|
||||
return this.$formValidateWraper(this.$refs.form)
|
||||
},
|
||||
|
||||
handleBtnClick(btn){
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
this.$nextTick(async ()=>{
|
||||
this.currentBtn = btn
|
||||
|
||||
if(!(await this.validateForm())){
|
||||
this.$refs.formDialog.hideLoading()
|
||||
return
|
||||
}
|
||||
|
||||
if(!(await this.validateWfForm())){
|
||||
this.$refs.formDialog.hideLoading()
|
||||
return
|
||||
}
|
||||
|
||||
if(!(await this.saveWfForm(btn.code))){
|
||||
this.$refs.formDialog.hideLoading()
|
||||
return
|
||||
}
|
||||
let res
|
||||
switch(btn.code){
|
||||
case 'learun_create':
|
||||
res = await this.$awaitWraper(api.createAgain({
|
||||
processId:this.processId,
|
||||
des:`重新提交${this.formData.des?'-':''}${this.formData.des}`
|
||||
}))
|
||||
break
|
||||
case 'learun_sign':
|
||||
this.tUserType = 2
|
||||
this.selectTUserVisible = true
|
||||
break
|
||||
case 'learun_transfer':
|
||||
this.tUserType = 1
|
||||
this.selectTUserVisible = true
|
||||
break
|
||||
default:
|
||||
if(this.task.f_Type == 6){// 加签审核
|
||||
res = await this.$awaitWraper(api.signAudit(this.taskId,{
|
||||
code:btn.code,
|
||||
name:btn.name,
|
||||
des:this.formData.des
|
||||
}))
|
||||
}
|
||||
else {
|
||||
if(this.currentNode.rejectType == '2' && btn.code == 'disagree'){
|
||||
this.selectRejectNodeVisible = true
|
||||
this.$refs.formDialog.hideLoading()
|
||||
return
|
||||
}
|
||||
|
||||
if(btn.isSign){
|
||||
// 加载签章数据
|
||||
const stampList = await this.$awaitWraper(apiStamp.getList(this.loginInfo.f_UserId))
|
||||
|
||||
if(stampList && stampList.length >0){
|
||||
this.stampList = stampList
|
||||
this.selectSignVisible = true
|
||||
this.$refs.formDialog.hideLoading()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
res = await this.audit()
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
this.$refs.formDialog.hideLoading()
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
this.$emit('refresh')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async audit(){
|
||||
// 获取接下来节点审核人
|
||||
if(this.currentBtn.isNextAuditor){
|
||||
const res = await api.getNextUsers({processId:this.processId,nodeId:this.currentNode.id})
|
||||
const nodeUserMap = res.data.data
|
||||
const nodeUsers = []
|
||||
for(let key in nodeUserMap){
|
||||
const nodeUserItem = nodeUserMap[key]
|
||||
if(nodeUserItem.length > 1){
|
||||
nodeUsers.push({
|
||||
name:this.wfData.find(t=>t.id == key).name,
|
||||
id:key,
|
||||
options:nodeUserItem.map(t=>{return{value:t.id,label:t.name} })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.nodeUsers = nodeUsers
|
||||
|
||||
if(this.nodeUsers.length > 0){
|
||||
this.selectUsersVisible = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return await this.$awaitWraper(api.audit(this.taskId,{
|
||||
code:this.currentBtn.code,
|
||||
name:this.currentBtn.name,
|
||||
des:this.formData.des
|
||||
}))
|
||||
},
|
||||
|
||||
|
||||
|
||||
handleSelectUsersSave(){
|
||||
this.selectUsersVisible = false
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
const nextUsers = this.$refs.selectUsers.getForm()
|
||||
this.$nextTick(async ()=>{
|
||||
const res = await this.$awaitWraper(api.audit(this.taskId,{
|
||||
code:this.currentBtn.code,
|
||||
name:this.currentBtn.name,
|
||||
nextUsers: nextUsers,
|
||||
des:this.formData.des
|
||||
}))
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
}
|
||||
this.$refs.formDialog.hideLoading()
|
||||
this.$emit('refresh')
|
||||
})
|
||||
},
|
||||
handleSelectUsersCloseForm(){
|
||||
this.$refs.selectUsers.resetForm()
|
||||
},
|
||||
handleChange(userInfo){
|
||||
if(userInfo){
|
||||
const title = this.tUserType == 1?'转移':'加签'
|
||||
if(this.loginInfo.f_UserId == userInfo.f_UserId){
|
||||
this.$message({
|
||||
type: 'warning',
|
||||
message: `${title}不能给自己本人`
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
this.$confirm(`是否确定${title}给${userInfo.f_RealName}?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.selectTUserVisible = false
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
|
||||
this.$nextTick(async ()=>{
|
||||
let res
|
||||
|
||||
if(this.tUserType == 1){
|
||||
res = await this.$awaitWraper(api.transferUser(this.taskId,{
|
||||
toUserId:userInfo.f_UserId,
|
||||
des:`转移给${userInfo.f_RealName}${this.formData.des?'-':''}${this.formData.des}`
|
||||
}))
|
||||
}
|
||||
else{
|
||||
res = await this.$awaitWraper(api.sign(this.taskId,{
|
||||
toUserId:userInfo.f_UserId,
|
||||
des:`加签给${userInfo.f_RealName}${this.formData.des?'-':''}${this.formData.des}`
|
||||
}))
|
||||
}
|
||||
|
||||
this.$refs.formDialog.hideLoading()
|
||||
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
this.$emit('refresh')
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: `已取消${title}`
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
async handleSelectRejectNodeSave(){
|
||||
if(await this.$refs.selectRejectNode.validateForm()){
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
const nextId = this.$refs.selectRejectNode.getForm()
|
||||
this.selectRejectNodeVisible = false
|
||||
this.$nextTick(async ()=>{
|
||||
const res = await this.$awaitWraper(api.audit(this.taskId,{
|
||||
code:this.currentBtn.code,
|
||||
name:this.currentBtn.name,
|
||||
nextId: nextId,
|
||||
des:this.formData.des
|
||||
}))
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
}
|
||||
this.$refs.formDialog.hideLoading()
|
||||
this.$emit('refresh')
|
||||
})
|
||||
}
|
||||
},
|
||||
handleRejectNodeCloseForm(){
|
||||
this.$refs.selectRejectNode.resetForm()
|
||||
},
|
||||
|
||||
async handleRead(){
|
||||
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
const res = await this.$awaitWraper(api.readAudit(this.taskId))
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
}
|
||||
this.$refs.formDialog.hideLoading()
|
||||
this.$emit('refresh')
|
||||
},
|
||||
|
||||
|
||||
// 签章
|
||||
async handleSelectSignSave(){
|
||||
if(await this.$refs.SelectSign.validateForm()){
|
||||
this.$refs.formDialog.showLoading('流程处理中...')
|
||||
const {f_StampId,f_Password} = this.$refs.SelectSign.getForm()
|
||||
this.selectSignVisible = false
|
||||
this.$nextTick(async ()=>{
|
||||
const res = await this.$awaitWraper(api.audit(this.taskId,{
|
||||
code:this.currentBtn.code,
|
||||
name:this.currentBtn.name,
|
||||
stampImg:f_StampId,
|
||||
stampPassWord:f_Password,
|
||||
des:this.formData.des
|
||||
}))
|
||||
if(res){
|
||||
this.midVisible = false
|
||||
}
|
||||
this.$refs.formDialog.hideLoading()
|
||||
this.$emit('refresh')
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
handleSelectSignCloseForm(){
|
||||
this.$refs.SelectSign.resetForm()
|
||||
},
|
||||
handleSelectSignOpenForm(){
|
||||
this.$refs.SelectSign.setForm(this.stampList)
|
||||
}
|
||||
isDraft: false,
|
||||
delegateUsers: [],
|
||||
task: null,
|
||||
process: null,
|
||||
logs: [],// 流程日志信息
|
||||
nodeMap: {},// 需要处理的任务
|
||||
userLogs: [],// 人员日志信息
|
||||
nodeLogs: [],
|
||||
taskBtns: [],
|
||||
})
|
||||
const activeName = ref('flow')
|
||||
function elementClick(element) {
|
||||
console.log('elementClick')
|
||||
console.log(element)
|
||||
if (element) {
|
||||
designerData.nodeLogs = designerData.nodeMap[element.id] || []
|
||||
infoOpen.value = true
|
||||
}
|
||||
}
|
||||
else {
|
||||
designerData.nodeLogs = []
|
||||
}
|
||||
}
|
||||
async function getDetailInfo() {
|
||||
let data = await getBPMN({ id: processId })
|
||||
flowContent.value = data.flowContent
|
||||
flowViewer.value = data.flowViewer
|
||||
}
|
||||
async function getTaskInfo() {
|
||||
let data = await getTaskDetail({ id: taskId })
|
||||
designerData.process = data.process
|
||||
designerData.task = data.task
|
||||
setLogsAndTasks(data.logs, data.tasks)
|
||||
}
|
||||
function setLogsAndTasks(logs, tasks) {
|
||||
const res = []
|
||||
const taskMap = {}
|
||||
const nodeMap = {}
|
||||
const userLogs = []
|
||||
|
||||
tasks.forEach(task => {
|
||||
nodeMap[task.unitId] = nodeMap[task.unitId] || [{
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
userNames: [],
|
||||
des: '正在审核',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary',
|
||||
isFinish: false
|
||||
}]
|
||||
|
||||
if (task.type == 2) {
|
||||
|
||||
taskMap[task.unitId + task.type] = taskMap[task.unitId + task.type] || {
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
userNames: [],
|
||||
des: '正在查阅',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary'
|
||||
}
|
||||
taskMap[task.unitId + task.type].userIds.push(task.userId)
|
||||
taskMap[task.unitId + task.type].userNames.push(task.userName)
|
||||
|
||||
if (nodeMap[task.unitId].length == 1) {
|
||||
nodeMap[task.unitId].push({
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
userNames: [],
|
||||
des: '正在查阅',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary',
|
||||
isFinish: true
|
||||
})
|
||||
}
|
||||
nodeMap[task.unitId][1].userIds.push(task.userId)
|
||||
nodeMap[task.unitId][1].userNames.push(task.userName)
|
||||
|
||||
}
|
||||
else {
|
||||
taskMap[task.unitId] = taskMap[task.unitId] || {
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
userNames: [],
|
||||
des: '正在审核',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary'
|
||||
}
|
||||
taskMap[task.unitId].userIds.push(task.userId)
|
||||
nodeMap[task.unitId][0].userIds.push(task.userId)
|
||||
taskMap[task.unitId].userNames.push(task.userName)
|
||||
nodeMap[task.unitId][0].userNames.push(task.userName)
|
||||
}
|
||||
})
|
||||
|
||||
for (let key in taskMap) {
|
||||
res.push(taskMap[key])
|
||||
}
|
||||
|
||||
for (let key in nodeMap) {
|
||||
nodeMap[key] = nodeMap[key].filter(t => t.userIds.length > 0)
|
||||
}
|
||||
|
||||
|
||||
|
||||
logs.forEach(log => {
|
||||
res.push({
|
||||
unitId: log.unitId,
|
||||
name: log.unitName,
|
||||
userIds: [log.userId],
|
||||
userNames: [log.userName],
|
||||
des: log.des ? log.des : log.f_OperationName,
|
||||
time: dateFormat(log.createDate),
|
||||
type: 'info'
|
||||
})
|
||||
|
||||
nodeMap[log.unitId] = nodeMap[log.unitId] || []
|
||||
nodeMap[log.unitId].push({
|
||||
unitId: log.unitId,
|
||||
name: log.unitName,
|
||||
userIds: [log.userId],
|
||||
userNames: [log.userName],
|
||||
time: dateFormat(log.createDate),
|
||||
des: log.des ? log.des : log.f_OperationName,
|
||||
type: 'info',
|
||||
isFinish: true
|
||||
})
|
||||
|
||||
if (log.f_TaskType == 1 && !['sign'].includes(log.f_OperationCode)) { // 右侧显示审核记录
|
||||
const userLogIndex = userLogs.findIndex(t => t.id == log.unitId)
|
||||
if (userLogIndex == -1) {
|
||||
userLogs.push({
|
||||
id: log.unitId,
|
||||
name: log.unitName,
|
||||
user: log.f_UserName,
|
||||
time: dateFormat(log.createDate),
|
||||
des: log.des,
|
||||
img: log.f_StampImg
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
designerData.logs = res
|
||||
designerData.nodeMap = nodeMap
|
||||
designerData.userLogs = userLogs.sort(function (a, b) {
|
||||
return b.time < a.time ? -1 : 1
|
||||
})
|
||||
|
||||
|
||||
//console.log(logs,'logs')
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
if (!id) {
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail', router);
|
||||
} else {
|
||||
// /dashboard/create_preview/add?id=测试1
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail?id=' + id, router);
|
||||
}
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
getDetailInfo()
|
||||
getTaskInfo()
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.info-box {
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
margin-top: 40px;
|
||||
|
||||
<style lang="scss">
|
||||
.l-task-btns{
|
||||
.el-button{
|
||||
margin: 0;
|
||||
margin-top: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ant-timeline-item-content {
|
||||
.title {
|
||||
color: #909399;
|
||||
line-height: 1;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.type-title {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.link{
|
||||
color:#409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-box {
|
||||
background-color: @component-background;
|
||||
height: 100%;
|
||||
|
||||
.btn-box {
|
||||
padding: 10px;
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.form-box {
|
||||
width: 480px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,153 +1,229 @@
|
|||
<template>
|
||||
<l-fullscreen-dialog
|
||||
:title="`${$t('查看流程')}【${title}】`"
|
||||
:visible.sync="midVisible"
|
||||
:showOk="false"
|
||||
|
||||
@closed="handleClosed"
|
||||
@opened="handleOpened"
|
||||
|
||||
ref="formDialog"
|
||||
>
|
||||
<l-layout class="l-tab-page" :right="400">
|
||||
<l-panel :style="{ 'padding-right':userLogs.length >0?0:''}" >
|
||||
<div class="l-auto-window" style="padding: 0 8px;" >
|
||||
<el-tabs v-model="activeName" @tab-click="handleTabClick" >
|
||||
<el-tab-pane v-if="hasWfForm" :label="$t('表单信息')" name="form">
|
||||
<div class="l-rblock" v-loading="formSchemeLoding">
|
||||
<template v-if="showForm" >
|
||||
<l-form-viewer
|
||||
v-if="formType == '1'"
|
||||
:formInfo="formInfo"
|
||||
:isWfForm="true"
|
||||
:authFieldsMap="formAuthFieldsMap"
|
||||
ref="wfForm"
|
||||
></l-form-viewer>
|
||||
<component ref="wfForm" v-else :requiredMap="formRequiredMap" :authFieldsMap="formAuthFieldsMap" :isWfForm="true" :is="sysFormComponent"></component>
|
||||
</template>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('流程信息')" name="wfinfo">
|
||||
<l-layout style="background: #f1f2f5;" :right="320">
|
||||
<l-panel class="flow-panel" style="padding:0;padding-top:0;" >
|
||||
<template #title>
|
||||
<el-button-group>
|
||||
<el-tooltip effect="dark" :content="$t('复原')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-aim" @click="resetZoom"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('放大')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-zoom-in" @click="handlerZoom(0.1)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="$t('缩小')" placement="bottom">
|
||||
<el-button size="mini" icon="el-icon-zoom-out" @click="handlerZoom(-0.1)"></el-button>
|
||||
</el-tooltip>
|
||||
</el-button-group>
|
||||
|
||||
<div style="float:right;" >
|
||||
<el-tag size="small" effect="plain" style="margin-right: 8px;">正在审核</el-tag>
|
||||
<el-tag size="small" effect="plain" style="margin-right: 8px;" type="success">已审核</el-tag>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<b-wflow-viewer
|
||||
ref="bflow"
|
||||
@elementClick="elementClick"
|
||||
>
|
||||
</b-wflow-viewer>
|
||||
</l-panel>
|
||||
<template #right >
|
||||
<l-panel v-if="nodeLogs.length>0" class="flow-panel" style="padding:0;padding-top:0;" >
|
||||
<template #title >
|
||||
记录信息
|
||||
</template>
|
||||
<div class="l-rblock l-time-line-wraper" style="padding:8px;overflow:hidden auto;" >
|
||||
<el-timeline>
|
||||
<el-timeline-item :type="item.type" v-for="(item,index) in nodeLogs" :key="index" :timestamp="item.time" placement="top">
|
||||
<el-card shadow="hover">
|
||||
<div class="title" >{{item.name}}</div>
|
||||
<div class="content">
|
||||
<l-user v-for="(userId,index2) in item.userIds" :key="index2" :value="userId" ></l-user>
|
||||
{{item.des}}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</l-panel>
|
||||
</template>
|
||||
</l-layout>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('流转记录')" name="wflogs">
|
||||
<div class="l-rblock l-time-line-wraper" style="padding:8px;overflow:hidden auto;" >
|
||||
<el-timeline>
|
||||
<el-timeline-item :type="item.type" v-for="(item,index) in logs" :key="index" :timestamp="item.time" placement="top">
|
||||
<el-card shadow="hover">
|
||||
<div class="title" >{{item.name}}</div>
|
||||
<div class="content">
|
||||
<l-user v-for="(userId,index2) in item.userIds" :key="index2" :value="userId" ></l-user>
|
||||
{{item.des}}
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</l-panel>
|
||||
<template #right >
|
||||
<l-panel v-if="userLogs.length >0" style="padding-left:0;" title="审批信息" >
|
||||
<div class="l-rblock" style="padding:8px;" >
|
||||
<l-wf-audit-info :data="userLogs" ></l-wf-audit-info>
|
||||
</div>
|
||||
</l-panel>
|
||||
</template>
|
||||
</l-layout>
|
||||
</l-fullscreen-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mixin from '../../../mixins/wf'
|
||||
export default {
|
||||
mixins:[mixin()],
|
||||
data () {
|
||||
return {
|
||||
midVisible:false,
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
visible: {
|
||||
handler (n) {
|
||||
this.midVisible = n
|
||||
}
|
||||
},
|
||||
},
|
||||
methods:{
|
||||
resetZoom(){
|
||||
this.$refs.bflow.reset()
|
||||
},
|
||||
handlerZoom(r){
|
||||
this.$refs.bflow.handlerZoom(r)
|
||||
},
|
||||
elementClick(node){
|
||||
if(node){
|
||||
this.nodeLogs = this.nodeMap[node.id] || []
|
||||
}
|
||||
else{
|
||||
this.nodeLogs = []
|
||||
}
|
||||
},
|
||||
setForm(){
|
||||
if(this.type == 'look' && this.task)
|
||||
{
|
||||
this.currentNode = this.wfData.find(t=>t.id == this.task.f_UnitId)
|
||||
|
||||
}
|
||||
else{
|
||||
this.currentNode = this.wfData.find(t=>t.type == 'startEvent')
|
||||
}
|
||||
|
||||
}
|
||||
<PageWrapper :class="prefixCls">
|
||||
<a-tabs v-model:activeKey="activeName">
|
||||
<a-tab-pane key="form" tab="表单信息">
|
||||
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="flow" tab="流程信息" force-render>
|
||||
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||
<process-viewer :key="`designer-${id}`" :events="[
|
||||
'element.click',
|
||||
]" @element-click="elementClick" :xml="flowContent" :flowViewer="flowViewer" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
</PageWrapper>
|
||||
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount } from 'vue';
|
||||
import ProcessViewer from '@/components/ProcessViewer/index.vue';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { SendOutlined, SaveOutlined, CloseCircleOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
|
||||
import { getBPMN } from '@/api/sys/WFProcess'
|
||||
import { getLoadMyUserList } from '@/api/sys/WFDelegate'
|
||||
import { getTaskDetail } from '@/api/sys/WFTask'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useMultipleTabStore } from '@/store/modules/multipleTab';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { buildGUID } from '@/utils/uuid';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import {dateFormat} from '@/utils/base'
|
||||
const { createConfirm, createMessage } = useMessage();
|
||||
|
||||
const prefixCls = 'preview-box'
|
||||
const tabStore = useMultipleTabStore();
|
||||
const router = useRouter();
|
||||
const content = ref('')
|
||||
const flowContent = ref('')
|
||||
const flowViewer = ref({})
|
||||
const route = useRoute()
|
||||
const processId = route.query.processId
|
||||
const taskId = route.query.taskId
|
||||
const designerOpen = ref(false)
|
||||
const formRef = ref();
|
||||
const labelCol = { span: 7 };
|
||||
const wrapperCol = { span: 13 };
|
||||
|
||||
const designerData = reactive({
|
||||
loading: false,
|
||||
xmlString: '',
|
||||
controlForm: {
|
||||
prefix: 'flowable',
|
||||
},
|
||||
height: document.documentElement.clientHeight - 230.5 + "px;",
|
||||
midVisible: false,
|
||||
isCustmerTitle: false,
|
||||
nodeUsers: [],
|
||||
selectUsersVisible: false,
|
||||
|
||||
isDraft: false,
|
||||
delegateUsers: [],
|
||||
task: null,
|
||||
process: null,
|
||||
logs: [],// 流程日志信息
|
||||
nodeMap: {},// 需要处理的任务
|
||||
userLogs: [],// 人员日志信息
|
||||
nodeLogs: [],
|
||||
taskBtns: [],
|
||||
})
|
||||
const activeName = ref('flow')
|
||||
function elementClick(element) {
|
||||
console.log('elementClick')
|
||||
console.log(element)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
async function getDetailInfo() {
|
||||
let data = await getBPMN({ id: processId })
|
||||
flowContent.value = data.flowContent
|
||||
flowViewer.value = data.flowViewer
|
||||
}
|
||||
async function getTaskInfo() {
|
||||
let data = await getTaskDetail({ id: taskId })
|
||||
designerData.process = data.process
|
||||
designerData.task = data.task
|
||||
setLogsAndTasks(data.logs, data.tasks)
|
||||
}
|
||||
function setLogsAndTasks(logs, tasks) {
|
||||
const res = []
|
||||
const taskMap = {}
|
||||
const nodeMap = {}
|
||||
const userLogs = []
|
||||
|
||||
tasks.forEach(task => {
|
||||
nodeMap[task.unitId] = nodeMap[task.unitId] || [{
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
des: '正在审核',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary',
|
||||
isFinish: false
|
||||
}]
|
||||
|
||||
if (task.type == 2) {
|
||||
|
||||
taskMap[task.unitId + task.type] = taskMap[task.unitId + task.type] || {
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
des: '正在查阅',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary'
|
||||
}
|
||||
taskMap[task.unitId + task.type].userIds.push(task.userId)
|
||||
|
||||
if (nodeMap[task.unitId].length == 1) {
|
||||
nodeMap[task.unitId].push({
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
des: '正在查阅',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary',
|
||||
isFinish: true
|
||||
})
|
||||
}
|
||||
nodeMap[task.unitId][1].userIds.push(task.userId)
|
||||
|
||||
}
|
||||
else {
|
||||
taskMap[task.unitId] = taskMap[task.unitId] || {
|
||||
unitId: task.unitId,
|
||||
name: task.unitName,
|
||||
userIds: [],
|
||||
des: '正在审核',
|
||||
time: `当前-创建时间:${dateFormat(task.createDate)}`,
|
||||
type: 'primary'
|
||||
}
|
||||
taskMap[task.unitId].userIds.push(task.userId)
|
||||
nodeMap[task.unitId][0].userIds.push(task.userId)
|
||||
}
|
||||
})
|
||||
|
||||
for (let key in taskMap) {
|
||||
res.push(taskMap[key])
|
||||
}
|
||||
|
||||
for (let key in nodeMap) {
|
||||
nodeMap[key] = nodeMap[key].filter(t => t.userIds.length > 0)
|
||||
}
|
||||
|
||||
|
||||
|
||||
logs.forEach(log => {
|
||||
res.push({
|
||||
unitId: log.unitId,
|
||||
name: log.unitName,
|
||||
userIds: [log.userId],
|
||||
des: log.des ? log.des : log.f_OperationName,
|
||||
time: dateFormat(log.createDate),
|
||||
type: 'info'
|
||||
})
|
||||
|
||||
nodeMap[log.unitId] = nodeMap[log.unitId] || []
|
||||
nodeMap[log.unitId].push({
|
||||
unitId: log.unitId,
|
||||
name: log.unitName,
|
||||
userIds: [log.userId],
|
||||
time: dateFormat(log.createDate),
|
||||
des: log.des ? log.des : log.f_OperationName,
|
||||
type: 'info',
|
||||
isFinish: true
|
||||
})
|
||||
|
||||
if (log.f_TaskType == 1 && !['sign'].includes(log.f_OperationCode)) { // 右侧显示审核记录
|
||||
const userLogIndex = userLogs.findIndex(t => t.id == log.unitId)
|
||||
if (userLogIndex == -1) {
|
||||
userLogs.push({
|
||||
id: log.unitId,
|
||||
name: log.unitName,
|
||||
user: log.f_UserName,
|
||||
time: dateFormat(log.createDate),
|
||||
des: log.des,
|
||||
img: log.f_StampImg
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
designerData.logs = res
|
||||
designerData.nodeMap = nodeMap
|
||||
designerData.userLogs = userLogs.sort(function (a, b) {
|
||||
return b.time < a.time ? -1 : 1
|
||||
})
|
||||
|
||||
|
||||
//console.log(logs,'logs')
|
||||
}
|
||||
|
||||
function closePreview() {
|
||||
if (!id) {
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail', router);
|
||||
} else {
|
||||
// /dashboard/create_preview/add?id=测试1
|
||||
tabStore.closeTabByKey('/dashboard/task_preview/detail?id=' + id, router);
|
||||
}
|
||||
}
|
||||
onBeforeMount(() => {
|
||||
getDetailInfo()
|
||||
getTaskInfo()
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.preview-box {
|
||||
background-color: @component-background;
|
||||
|
||||
.btn-box {
|
||||
padding: 10px;
|
||||
justify-content: flex-end;
|
||||
display: flex;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.form-box {
|
||||
width: 480px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
},
|
||||
});
|
||||
function handleDetail(record){
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_look_preview/detail?processId=' + record.id);
|
||||
}
|
||||
function handleRevocation(record){
|
||||
console.log(record)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue'
|
||||
import { reactive ,h} from 'vue'
|
||||
import { BasicTable, useTable, TableAction } from '@/components/Table';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { getLoadMyUncompletedPage } from '@/api/sys/WFTask'
|
||||
|
|
@ -103,7 +103,7 @@
|
|||
},
|
||||
});
|
||||
function handleDetail(record){
|
||||
go('/dashboard/task_preview/detail?id=' + record.id);
|
||||
go('/dashboard/task_audit_preview/detail?processId=' + record.processId+"&taskId="+record.id);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@
|
|||
const userInfo = await userStore.login({
|
||||
password: data.password,
|
||||
account: data.account,
|
||||
mode: 'modal', //不要默认的错误提示
|
||||
mode: 'none', //不要默认的错误提示
|
||||
});
|
||||
console.log(userInfo)
|
||||
localStorage.setItem('fireUserLoginName',userInfo.name)
|
||||
|
|
|
|||
Loading…
Reference in New Issue