Browse Source

合并秦东分支,功能为新版自定义表单和工作流

yjf_v3
超级管理员 2 years ago
parent
commit
28501d979c
  1. 11
      node_modules/.package-lock.json
  2. 13
      package-lock.json
  3. 4
      package.json
  4. 28
      src/api/DesignForm/gromGroup/api.ts
  5. 128
      src/api/DesignForm/gromGroup/data.ts
  6. 46
      src/api/DesignForm/gromGroup/types.ts
  7. 1
      src/api/DesignForm/type.ts
  8. 8
      src/api/DesignForm/types.ts
  9. 33
      src/api/workflowapi/index.ts
  10. BIN
      src/assets/images/3.png
  11. 948
      src/assets/scss/form.css
  12. 1
      src/assets/scss/form.min.css
  13. 6
      src/assets/scss/form.scss
  14. 2319
      src/components/DesignForm/formControlAttr.vue
  15. 177
      src/components/DesignForm/layoutPage/index.vue
  16. 1
      src/components/DesignForm/public/form/form.vue
  17. 108
      src/components/workflow/dialog/matrix.vue
  18. 46
      src/components/workflow/drwer/analysisForm.ts
  19. 185
      src/components/workflow/drwer/approverDrawer.vue
  20. 180
      src/components/workflow/drwer/promoterDrawer.vue
  21. 4
      src/components/workflow/nodeWrap.vue
  22. 7
      src/types/components.d.ts
  23. 60
      src/utils/lowCodeForm/index.ts
  24. 32
      src/views/sysworkflow/codepage/createform.vue
  25. 88
      src/views/sysworkflow/lowcodepage/group.vue
  26. 92
      src/views/sysworkflow/lowcodepage/index.vue
  27. 223
      src/views/sysworkflow/lowcodepage/lowCodeFormGroupPage.vue
  28. 230
      src/views/sysworkflow/lowcodepage/lowCodeFormPage.vue
  29. 743
      src/views/sysworkflow/lowcodepage/pageDesign.vue
  30. 637
      src/views/sysworkflow/lowcodepage/pageDesignes.vue
  31. 635
      src/views/sysworkflow/lowcodepage/workFlow.vue
  32. 160
      vite.config.ts.timestamp-1709682894861-ae70bc75df1f3.mjs

11
node_modules/.package-lock.json

@ -1027,6 +1027,12 @@
"integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==",
"dev": true
},
"node_modules/@types/spark-md5": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/spark-md5/-/spark-md5-3.0.4.tgz",
"integrity": "sha512-qtOaDz+IXiNndPgYb6t1YoutnGvFRtWSNzpVjkAPCfB2UzTyybuD4Tjgs7VgRawum3JnJNRwNQd4N//SvrHg1Q==",
"dev": true
},
"node_modules/@types/svgo": {
"version": "2.6.4",
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
@ -8191,6 +8197,11 @@
"deprecated": "See https://github.com/lydell/source-map-url#deprecated",
"dev": true
},
"node_modules/spark-md5": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/spark-md5/-/spark-md5-3.0.2.tgz",
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.2.0.tgz",

13
package-lock.json

@ -30,6 +30,7 @@
"path-to-regexp": "^6.2.0",
"pinia": "^2.1.6",
"screenfull": "^6.0.0",
"spark-md5": "^3.0.2",
"tinymce": "^6.8.1",
"ts-md5": "^1.3.1",
"uuid": "^9.0.1",
@ -47,6 +48,7 @@
"@types/md5": "^2.3.2",
"@types/nprogress": "^0.2.0",
"@types/path-browserify": "^1.0.0",
"@types/spark-md5": "^3.0.4",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
@ -1421,6 +1423,12 @@
"integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==",
"dev": true
},
"node_modules/@types/spark-md5": {
"version": "3.0.4",
"resolved": "https://registry.npmmirror.com/@types/spark-md5/-/spark-md5-3.0.4.tgz",
"integrity": "sha512-qtOaDz+IXiNndPgYb6t1YoutnGvFRtWSNzpVjkAPCfB2UzTyybuD4Tjgs7VgRawum3JnJNRwNQd4N//SvrHg1Q==",
"dev": true
},
"node_modules/@types/svgo": {
"version": "2.6.4",
"resolved": "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz",
@ -8598,6 +8606,11 @@
"deprecated": "See https://github.com/lydell/source-map-url#deprecated",
"dev": true
},
"node_modules/spark-md5": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/spark-md5/-/spark-md5-3.0.2.tgz",
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
},
"node_modules/spdx-correct": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.2.0.tgz",

4
package.json

@ -49,9 +49,9 @@
"@wecom/jssdk": "^1.3.2",
"axios": "^1.4.0",
"clipboard": "^2.0.11",
"echarts": "^5.4.3",
"element-plus": "^2.3.4",
"font-awesome": "^4.7.0",
"echarts": "^5.4.3",
"js-beautify": "^1.14.8",
"js-md5": "^0.7.3",
"mapv-three": "^1.0.18",
@ -61,6 +61,7 @@
"path-to-regexp": "^6.2.0",
"pinia": "^2.1.6",
"screenfull": "^6.0.0",
"spark-md5": "^3.0.2",
"tinymce": "^6.8.1",
"ts-md5": "^1.3.1",
"uuid": "^9.0.1",
@ -78,6 +79,7 @@
"@types/md5": "^2.3.2",
"@types/nprogress": "^0.2.0",
"@types/path-browserify": "^1.0.0",
"@types/spark-md5": "^3.0.4",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",

28
src/api/DesignForm/gromGroup/api.ts

@ -0,0 +1,28 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { fromGroupSearch,fromGroupInfo,editFromGroupInfo,shareId } from "@/api/DesignForm/gromGroup/types";
/**
@ 作者: 秦东
@ 时间: 2024-03-09 10:10:55
@ 功能: 获取分组内容
*/
export function gainFormGroupInfo(data:shareId){
return request({
url: '/systemapi/customer_form/gainFormGroupInfo',
method: 'post',
data: data
});
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 13:05:37
@ 功能: 添加表单分组内容
*/
export function addCustomerFormGroup(data:fromGroupInfo){
return request({
url: '/systemapi/customer_form/addCustomerFormGroup',
method: 'post',
data: data
});
}

128
src/api/DesignForm/gromGroup/data.ts

@ -0,0 +1,128 @@
/**
@ 作者: 秦东
@ 时间: 2024-03-06 16:59:53
@ 功能: 状态数组
*/
export const groupStateAry = [
{
"key":1,
"label":"启用",
"value":1
},
{
"key":2,
"label":"禁用",
"value":2
}
]
/**
@ 作者: 秦东
@ 时间: 2024-03-09 14:31:45
@ 功能: 保存按钮
*/
export const submitButton = {
type: "div",
control:{},
config:{
textAlign: "center",
span: ""
},
list: [
{
type: "button",
control:
{
label: "保存",
type: "primary",
key: "submit"
},
config:
{
textAlign: "center"
},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
}
]
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 14:33:07
@ 功能: 返回按钮
*/
export const cancelButton = {
type: "div",
control:{},
config:{
textAlign: "center",
span: ""
},
list: [
{
type: "button",
control:{
label: "返回",
type: "danger",
key: "cancel"
},
config:{
textAlign: "center"
},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
}
]
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 14:34:15
@ 功能: 保存和提交
*/
export const submitAndCancelButton = {
type: "div",
control:{},
config:{
span: 24,
textAlign: "center"
},
list: [
{
type: "button",
control:{
label: "保存",
type: "primary",
key: "submit"
},
config:{
span: 0
},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
},
{
type: "button",
control:{
label: "返回",
type: "danger",
key: "cancel"
},
config:{
span: 0
},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
}
]
};

46
src/api/DesignForm/gromGroup/types.ts

@ -0,0 +1,46 @@
/**
@ 作者: 秦东
@ 时间: 2024-03-09 10:00:17
@ 功能: 通用ID
*/
export interface shareId{
id: string|number;
}
/**
@ 作者?: 秦东
@ 时间: 2024-03-06 16:24:01
@ 功能: 搜索自定义表单分组条件
*/
export interface fromGroupSearch {
name?:string;
orgid?:string;
superior?:string;
state?:number;
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 10:01:23
@ 功能: 表单分组内容
*/
export interface fromGroupInfo {
title?:string;
icon?:string;
sort?:number;
ordid?:string;
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 10:03:05
@ 功能: 编辑表单分组内容
*/
export interface editFromGroupInfo extends fromGroupInfo {
id: string|number;
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 10:03:05
@ 功能: 编辑表单分组状态
*/
export interface editFromGroupState extends shareId {
status: number;
}

1
src/api/DesignForm/type.ts

@ -133,6 +133,7 @@ export interface hanziToPinyin{
title:string;
types:number;
connector:string;
formJson?:string;
}
//获取工作流步进节点
export interface nodeFlow extends enableVersionId{

8
src/api/DesignForm/types.ts

@ -106,7 +106,13 @@ export interface formData{
formName:any
};
config: any;
events?:any
events?:any;
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
};
purview?:any[];
}
//表单基本信息
export interface formTableInfo{

33
src/api/workflowapi/index.ts

@ -95,3 +95,36 @@ export function switchFlowVersion(data: any) {
data: data
});
}
//判断是否已经存在工作流以及是否开启
export function judgeFormFlowIsOpen(data: any) {
return request({
url: '/systemapi/task_flow/judgeFormFlowIsOpen',
method: 'post',
data: data
});
}
//开启或关闭表单流程
export function openFormFlow(data: any) {
return request({
url: '/systemapi/task_flow/openFormFlow',
method: 'post',
data: data
});
}
//获取所有组件状态
export function analysisForm(data: any) {
return request({
url: '/systemapi/task_flow/analysisForm',
method: 'post',
data: data
});
}
//编辑节点权限
export function setFlowFormKeyPower(data: any) {
return request({
url: '/systemapi/task_flow/setFlowFormKeyPower',
method: 'post',
data: data
});
}

BIN
src/assets/images/3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

948
src/assets/scss/form.css

@ -0,0 +1,948 @@
@charset "UTF-8";
.design-container {
margin: 10px !important;
display: flex;
background-color: #FFFFFF;
}
.components-list {
width: 250px;
padding: 8px 0;
overflow-y: auto;
height: calc(100vh - 40px);
position: relative;
overflow-x: hidden;
}
.components-list .title {
padding: 8px 12px;
position: relative;
}
.components-list .title .template {
position: absolute;
right: 12px;
top: 0;
padding: 8px;
cursor: pointer;
}
.components-list ul {
position: relative;
overflow: hidden;
padding: 0 10px 10px;
margin: 0;
}
.components-list ul li {
font-size: 13px;
display: flex;
width: 48%;
line-height: 28px;
position: relative;
float: left;
left: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 0 1% 5px;
color: #333;
padding: 0 10px;
border: 1px solid transparent;
background: #f4f6fc;
user-select: none;
align-items: center;
}
.components-list ul li i {
margin-right: 5px;
}
.components-list ul li:hover {
color: #66b1ff;
border: 1px dashed #66b1ff;
cursor: move;
}
.components-list ul li.title {
padding: 0 10px;
}
.components-list .content {
margin-left: 12px;
}
.use-template {
position: absolute;
left: -100%;
top: 0;
width: 100%;
bottom: 0;
background: #fff;
opacity: 0;
}
.use-template.active {
animation: templateAni .5s forwards;
}
.use-template .close {
position: absolute;
right: 5px;
top: 5px;
font-size: 14px;
cursor: pointer;
}
.use-template .list {
padding: 30px 10px;
overflow-y: auto;
}
.use-template .list .item {
box-shadow: 0 0 4px rgba(0, 21, 41, 0.1);
padding: 10px;
text-align: center;
transition: all .5s;
cursor: pointer;
margin-bottom: 10px;
}
.use-template .list .item img {
display: block;
width: 100%;
margin: 0 auto 10px;
}
.use-template .list .item:hover {
box-shadow: 0 0 4px rgba(0, 21, 41, 0.25);
}
.use-template .no-date {
text-align: center;
padding-top: 20px;
color: #999;
}
@keyframes templateAni {
100% {
opacity: 1;
left: 0;
}
}
.main-body {
flex: 2;
border-left: 1px solid #e0e0e0;
border-right: 1px solid #e0e0e0;
margin: 0;
overflow: hidden;
}
.main-body .empty-tips {
text-align: center;
width: 100%;
font-size: 20px;
color: #ccc;
position: absolute;
left: 0;
top: 100px;
}
.main-body .main-form {
background: #fff;
border: 1px dashed #999;
margin: 10px;
height: calc(100vh - 105px);
overflow-y: auto;
overflow-x: hidden;
position: relative;
}
.main-tools {
line-height: 26px;
border-bottom: 2px solid #e4e7ed;
margin-right: 10px;
padding: 8px 0;
display: flex;
align-items: center;
justify-content: flex-end;
}
.main-tools button {
color: #66b1ff;
}
.main-tools button i {
padding-right: 5px;
}
.add-form {
padding: 0px;
box-sizing: border-box;
}
.add-form .form-row .form-col.active-col {
border: 3px solid #66b1ff;
position: relative;
}
.add-form .form-row .form-col.active-col > .drag-control {
display: block;
}
.add-form .form-row .form-col.active-col > .tooltip {
display: block;
}
.add-form .title {
border-bottom: 1px solid #ddd;
font-weight: 700;
font-size: 14px;
height: 30px;
padding: 0 5px;
margin-bottom: 22px;
}
.add-form .form-tabs .drag {
min-height: 80px;
}
.add-form .group-card .el-collapse {
border: 0;
}
.add-form .group-card .el-collapse-item__header {
font-weight: 700;
border-bottom: 1px solid #ddd;
margin-bottom: 20px;
}
.add-form .group-card .el-collapse-item__wrap {
border: 0;
}
.add-form .group-inputSlot {
display: none;
}
.add-form .form-table {
margin-bottom: 22px;
}
.add-form .form-table .drag {
border: 0;
display: flex;
overflow-x: auto;
white-space: nowrap;
padding: 0;
flex-wrap: nowrap;
}
.add-form .form-table .drag > div {
min-width: 150px;
width: auto;
}
.add-form .form-table .el-form-item {
display: block;
}
.add-form .table-btn {
padding-top: 10px;
}
.add-form .el-collapse-item__content {
padding-bottom: 5px;
}
.add-form .form-table-add .el-form-item__label {
display: none;
}
.add-form .form-table-add .el-form-item {
margin: 0;
}
.add-form .form-table-add .el-table .cell {
overflow: inherit;
}
.add-form .form-table-add .el-table .cell .el-form-item__error {
padding-top: 0;
}
.add-form .gray {
color: #999;
}
.add-form > .drag {
border: 0 !important;
}
.add-form .group-flex .flex-group {
display: flex;
justify-content: space-between;
}
.add-form .group-flex .flex-group button {
margin-left: 10px;
}
.add-form .group-flex .flex-item {
flex: 2;
}
.add-form .group-txt {
margin-bottom: 18px;
}
.add-form .div-layout {
/*&.inline {
.drag {display: inline-flex}
.group {width: auto;margin-right: 10px}
}*/
}
.add-form .div-layout.right .drag {
text-align: right;
justify-content: flex-end;
}
.add-form .div-layout.center .drag {
text-align: center;
justify-content: center;
}
.add-form .el-select {
width: 100%;
}
.add-form .el-select .el-input__wrapper .el-input__suffix {
position: absolute;
right: 10px;
}
.add-form .group {
width: 100%;
}
.add-form .drag {
display: flex;
flex-wrap: wrap;
}
.add-form.form-row-2 .group {
width: 50%;
}
.add-form.form-row-3 .group {
width: 33%;
}
.add-form.form-row-4 .group {
width: 25%;
}
.sidebar-tools {
width: 300px;
right: 0;
top: 0;
overflow-y: auto;
box-sizing: border-box;
padding-bottom: 10px;
bottom: 0;
height: calc(100vh - 40px);
}
.sidebar-tools .form .el-form-item {
margin-bottom: 10px;
}
.sidebar-tools .h3 {
font-size: 14px;
margin-bottom: 10px;
display: flex;
align-items: center;
}
.sidebar-tools .h3 h3 {
font-size: 14px;
}
.sidebar-tools .el-tabs__nav-wrap {
padding: 0 10px;
}
.sidebar-tools .el-tabs__content {
padding: 0 10px;
}
.sidebar-tools .icon-del {
cursor: pointer;
}
.sidebar-tools .option-radio > label {
margin-right: 8px;
}
.sidebar-tools .event-btn button {
margin: 0 12px 5px 0;
}
#editJson, #editJsonCopy {
width: 100%;
height: calc(100vh - 65px);
}
#editJsonCopy {
height: calc(100vh - 350px);
}
.ace-dialog {
background: #1e1e1e;
}
.ace-dialog .el-drawer__body {
padding: 0;
}
.ace-dialog .el-drawer__header {
margin: 0;
color: #e9e9e9;
font-size: 12px;
padding: 3px 10px;
}
.ace-dialog .dialog-footer {
text-align: center;
padding-top: 5px;
}
.export-dialog .el-dialog__body {
padding: 0 20px;
}
.design-form {
min-height: calc(100vh - 170px);
}
.design-form > div {
height: 100%;
}
.design-form > .drag {
min-height: calc(100vh - 170px) !important;
}
.design-form .ghost {
background: #F56C6C;
border: 2px solid #F56C6C;
outline-width: 0;
height: 3px;
box-sizing: border-box;
font-size: 0;
content: '';
overflow: hidden;
padding: 0;
width: 100%;
}
.design-form .group {
border: 1px dashed #ddd;
margin: 2px 0px 10px 0px;
padding: 5px;
position: relative;
min-height: 50px;
}
.design-form .group.active {
border: 3px solid #66b1ff;
position: relative;
}
.design-form .group.active > .drag-control {
display: block;
}
.design-form .group.active > .tooltip {
display: block;
}
.design-form .group:hover {
border-color: #66b1ff;
background: #ecf5ff;
}
.design-form .group > div {
margin-bottom: 0;
}
.design-form .group:after {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
opacity: 0;
z-index: 1;
display: block;
}
.design-form .group.group-grid:after, .design-form .group.group-tabs:after, .design-form .group.group-card:after, .design-form .group.group-flex:after, .design-form .group.group-div:after, .design-form .group.group-table:after {
display: none;
}
.design-form .group-inputSlot {
border-color: #eebe77;
display: inline-block;
}
.design-form .group-inputSlot:hover, .design-form .group-inputSlot.active {
border-color: #eebe77 !important;
}
.design-form .tooltip {
display: none;
position: absolute;
font-size: 12px;
top: 0;
right: 0;
z-index: 5;
}
.design-form .drag-control {
display: none;
}
.design-form .drag-control .item-control {
position: absolute;
right: 0;
bottom: 0;
z-index: 2;
display: flex;
align-items: center;
height: 24px;
background: #66b1ff;
}
.design-form .drag-control .item-control i {
width: 24px;
height: 24px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.design-form .drag-control .drag-move {
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 24px;
height: 24px;
background: #66b1ff;
color: #fff;
text-align: center;
line-height: 24px;
cursor: move;
}
.design-form .drag {
height: 100%;
border: 1px dashed #ddd;
min-height: 40px;
margin: 0 2px;
padding: 5px;
align-content: flex-start;
}
.design-form.form-row-2 .group {
width: 48%;
}
.design-form.form-row-3 .group {
width: 32%;
}
.design-form.form-row-4 .group {
width: 23%;
}
.detail-form {
min-height: calc(100vh - 170px);
}
.detail-form > div {
height: 100%;
}
.detail-form > .drag {
min-height: calc(100vh - 170px) !important;
}
.detail-form .ghost {
background: #F56C6C;
border: 2px solid #F56C6C;
outline-width: 0;
height: 3px;
box-sizing: border-box;
font-size: 0;
content: '';
overflow: hidden;
padding: 0;
width: 100%;
}
.detail-form .group {
border: 0px dashed #ddd;
margin: 2px 0px 10px 0px;
padding: 5px;
position: relative;
min-height: 50px;
}
.detail-form .group > div {
margin-bottom: 0;
}
.detail-form .group-inputSlot {
border-color: #eebe77;
display: inline-block;
}
.detail-form .group-inputSlot:hover, .detail-form .group-inputSlot.active {
border-color: #eebe77 !important;
}
.detail-form .tooltip {
display: none;
position: absolute;
font-size: 12px;
top: 0;
right: 0;
z-index: 5;
}
.detail-form .drag-control {
display: none;
}
.detail-form .drag-control .item-control {
position: absolute;
right: 0;
bottom: 0;
z-index: 2;
display: flex;
align-items: center;
height: 24px;
background: #66b1ff;
}
.detail-form .drag-control .item-control i {
width: 24px;
height: 24px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.detail-form .drag-control .drag-move {
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 24px;
height: 24px;
background: #66b1ff;
color: #fff;
text-align: center;
line-height: 24px;
cursor: move;
}
.detail-form .drag {
height: 100%;
border: 0px dashed #ddd;
min-height: 40px;
margin: 0 2px;
padding: 5px;
align-content: flex-start;
}
.detail-form.form-row-2 .group {
width: 48%;
}
.detail-form.form-row-3 .group {
width: 32%;
}
.detail-form.form-row-4 .group {
width: 23%;
}
/*表格设计*/
.design-table .main-body {
border-left: 0;
}
.design-table .header {
position: relative;
}
.design-table .header .field {
position: absolute;
left: 10px;
top: 7px;
display: flex;
}
.design-table .components-list .content {
padding: 0 12px;
}
.design-table .components-list .content > div {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.design-table .components-list .content > div label {
margin: 0 10px 8px 0 !important;
}
.design-table .main-table {
padding: 10px 20px;
}
.design-table .main-table .add-form {
min-height: auto;
display: flex;
}
.design-table .main-table .add-form > .drag {
height: auto;
min-height: auto !important;
}
.design-table .main-table .el-divider {
margin: 8px 0 0;
}
.design-table .main-table .table-tip {
color: #999;
padding: 30px 0;
line-height: 22px;
}
.design-table .main-table .search-box {
position: relative;
}
.design-table .main-table .search-box:after {
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
z-index: 2;
cursor: pointer;
}
.design-table .main-table .search-box .group {
width: auto;
margin-right: 10px;
}
.design-table .main-table .control-btn {
padding: 10px 0;
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.design-table .main-table .tip {
border: 1px dotted #ddd;
padding: 3px 5px;
border-radius: 5px;
color: #999;
text-align: center;
cursor: pointer;
}
.design-table .main-table .el-table__header th .cell {
position: relative;
}
.design-table .main-table .el-table__header th .icon-close {
display: none;
font-size: 12px;
margin-left: 12px;
cursor: pointer;
position: absolute;
}
.design-table .main-table .el-table__header th:hover .icon-close {
display: inline-block;
}
.design-table .table-tag .el-form-item__content {
display: flex;
}
.design-table .table-tag .el-form-item__content > div {
flex: 2;
margin-right: 5px;
}
.table-field-list h3 {
font-size: 14px;
}
.table-field-list .item {
margin-bottom: 20px;
}
.table-field-list .list {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
.table-field-list .list label {
width: 25%;
margin: 0;
}
.table-list-comm {
display: flex;
justify-content: space-between;
}
.table-list-comm .tree-sidebar {
width: 180px;
border-right: 1px solid #ddd;
padding-right: 10px;
margin-right: 10px;
flex-shrink: 0;
}
.table-list-comm .tree-sidebar .el-input {
margin-bottom: 10px;
}
.table-list-comm .table-list {
display: block;
width: 100%;
}
.table-list-comm .table-main {
margin-bottom: 20px;
}
.table-list-comm .table-main.hide-vertical-scroll .el-scrollbar__wrap {
overflow: hidden;
}
.table-list-comm .table-main.hide-vertical-scroll .is-vertical {
display: none !important;
}
.table-list-comm .table-main .table-operate-btn {
display: flex;
align-items: center;
}
.table-list-comm .table-search {
position: relative;
}
.table-list-comm .table-search form {
display: flex;
flex-wrap: wrap;
padding-bottom: 0;
border-bottom: 1px solid #dcdfe6;
margin-bottom: 10px;
}
.table-list-comm .table-search .drag {
display: flex;
flex-wrap: wrap;
}
.table-list-comm .table-search .drag > div {
margin-right: 10px;
}
.table-list-comm .table-search .group {
width: auto;
}
.table-list-comm .table-search .search-icon {
margin-left: 10px;
height: 30px;
cursor: pointer;
position: absolute;
right: 0;
top: 0;
}
.table-list-comm .table-search .autoHeight-enter-active,
.table-list-comm .table-search .autoHeight-leave-active {
max-height: 200px;
transition: all .6s;
overflow: hidden;
}
.table-list-comm .table-search .autoHeight-enter-from,
.table-list-comm .table-search .autoHeight-leave-to {
max-height: 0;
}
.table-list-comm .control-btn {
margin-bottom: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
/*图片文件上传*/
.upload-style .limit .el-upload {
display: none;
}
.upload-style .el-upload-list__item-preview {
display: none !important;
}
.upload-style .el-upload--picture .icon-plus {
font-size: 28px;
display: flex;
align-items: center;
justify-content: center;
color: #8c939d;
width: 148px;
height: 148px;
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
overflow: hidden;
background: #fbfdff;
}
/*分页*/
.table-page {
padding-top: 10px;
display: flex;
justify-content: flex-end;
}

1
src/assets/scss/form.min.css

File diff suppressed because one or more lines are too long

6
src/assets/scss/form.scss

@ -2,7 +2,7 @@
// 左侧栏
$mainColor: #66b1ff;
.design-container {margin: 10px !important;display: flex; background-color: #FFFFFF;}
.components-list {width: 250px;padding: 8px 0;overflow-y: auto;height: calc(100vh - 20px);position: relative;overflow-x: hidden;
.components-list {width: 250px;padding: 8px 0;overflow-y: auto;height: calc(100vh - 40px);position: relative;overflow-x: hidden;
.title {padding: 8px 12px;position: relative;
.template {position: absolute;right: 12px;top: 0;padding: 8px;cursor: pointer}
}
@ -35,7 +35,7 @@ $mainColor: #66b1ff;
.main-body {flex: 2; border-left: 1px solid #e0e0e0;border-right: 1px solid #e0e0e0;margin: 0;overflow: hidden;
.empty-tips {text-align: center;width: 100%;font-size: 20px;color: #ccc;position: absolute;left: 0;top: 100px;
}
.main-form { background: #fff;border: 1px dashed #999;margin: 10px;height: calc(100vh - 85px);overflow-y: auto;overflow-x: hidden;position: relative}
.main-form { background: #fff;border: 1px dashed #999;margin: 10px;height: calc(100vh - 105px);overflow-y: auto;overflow-x: hidden;position: relative}
}
// 中间按钮工具
.main-tools {line-height: 26px;border-bottom: 2px solid #e4e7ed;margin-right: 10px;padding: 8px 0;display: flex;align-items: center;justify-content: flex-end;
@ -119,7 +119,7 @@ $mainColor: #66b1ff;
.group {width: 25%}
}
}
.sidebar-tools {width: 300px;right: 0;top: 0;overflow-y: auto;box-sizing: border-box;padding-bottom: 10px;bottom: 0; height: calc(100vh - 30px);
.sidebar-tools {width: 300px;right: 0;top: 0;overflow-y: auto;box-sizing: border-box;padding-bottom: 10px;bottom: 0; height: calc(100vh - 40px);
.form {
.el-form-item {margin-bottom: 10px;}
}

2319
src/components/DesignForm/formControlAttr.vue

File diff suppressed because it is too large

177
src/components/DesignForm/layoutPage/index.vue

@ -1,4 +1,5 @@
<!--
<<<<<<< HEAD
@ 作者: 秦东
@ 时间: 2024-02-29 14:18:54
@ 备注: 样式布局
@ -172,3 +173,179 @@ const activeName = ref('0')
background-color: rgb(229, 229, 229);
}
</style>
=======
@ 作者: 秦东
@ 时间: 2024-02-29 14:18:54
@ 备注: 样式布局
-->
<script lang='ts' setup>
import DesignLayout from "@/components/DesignForm/designLayout/designLayoutPage.vue"
import BianXian from "@/components/DesignForm/designLayout/bianXian.vue"
import YuanJiao from "@/components/DesignForm/designLayout/yuanjao.vue"
import UnitBackGround from "@/components/DesignForm/designLayout/unitBackGround.vue"
import PageSize from "@/components/DesignForm/designLayout/pageSize.vue"
import PageSizeSmail from "@/components/DesignForm/designLayout/pageSizeSmail.vue"
import TextPage from "@/components/DesignForm/designLayout/textPage.vue"
const props = defineProps({
stylesVal:{
type:Object,
default(){
return {}
}
},
place:{
type:String,
default:""
}
});
const buttionShow = ref(false)
const unitIsShow = ref(true)
const labelIsShow = ref(true)
const inputUnitTitle = (val:string) => {
console.log("inputUnitTitle",val);
switch (val) {
case "radio":
return "输入设置"
break;
case "select":
unitIsShow.value = false;
break;
case "datePicker":
unitIsShow.value = false;
break;
case "timePicker":
unitIsShow.value = false;
break;
case "switch":
unitIsShow.value = false;
break;
case "inputNumber":
unitIsShow.value = false;
break;
case "cascader":
unitIsShow.value = false;
break;
case "rate":
unitIsShow.value = false;
break;
case "slider","upload","tinymce":
unitIsShow.value = false;
break;
case "treeSelect","colorPicker","signaturemap":
unitIsShow.value = false;
break;
case "txt","table","videoUpAndPlay","lowcodeCarsusel","grid","tabs":
unitIsShow.value = false;
labelIsShow.value = false;
break;
case "title":
unitIsShow.value = false;
break;
case "button":
buttionShow.value = true;
unitIsShow.value = false;
labelIsShow.value = false;
break;
default:
unitIsShow.value = true;
labelIsShow.value = true;
return "输入设置"
break;
}
return "输入设置"
}
// const divStyle = reactive<any>({})
// watch(()=>divStyle,(val : any)=>{
// // console.log("-----1--->",val)
// props.stylesVal[props.place] = val
// // Object.assign(store.controlAttr.styles.divStyle, val)
// },
// {
// deep: true
// });
watch(()=>props.place,(val : any)=>{
console.log("格式布局-----1--->",val)
inputUnitTitle(val);
// props.stylesVal[props.place] = val
// Object.assign(store.controlAttr.styles.divStyle, val)
},
{
deep: true
});
const activeName = ref('0')
</script>
<template>
<div class="jhk_kjh">
当前组件类别======>{{props.place}}
<el-collapse v-model="activeName" accordion>
<el-collapse-item title="边框设置" name="1">
<el-divider content-position="left">外框</el-divider>
<DesignLayout v-model:layouyt-style="props.stylesVal.divStyle" />
<el-divider content-position="left">圆角</el-divider>
<YuanJiao v-model:layouyt-style="props.stylesVal.divStyle" />
<el-divider content-position="left">边线</el-divider>
<BianXian v-model:dataVal="props.stylesVal.divStyle" />
<el-divider content-position="left">背景</el-divider>
<UnitBackGround v-model:layouyt-style="props.stylesVal.divStyle" />
<el-divider content-position="left">尺寸</el-divider>
<PageSize v-model:layouyt-style="props.stylesVal.divStyle" :place="'div'" />
<el-divider v-if="props.place=='txt'" content-position="left">文本</el-divider>
<TextPage v-if="props.place=='txt'" v-model:layouyt-style="props.stylesVal.divStyle" :place="'div'" />
</el-collapse-item>
<el-collapse-item v-if="labelIsShow" title="标签设置" name="2">
<el-divider content-position="left">外框</el-divider>
<DesignLayout v-model:layouyt-style="props.stylesVal.labelStyle" />
<el-divider content-position="left">圆角</el-divider>
<YuanJiao v-model:layouyt-style="props.stylesVal.labelStyle" />
<el-divider content-position="left">边线</el-divider>
<BianXian v-model:dataVal="props.stylesVal.labelStyle" />
<el-divider content-position="left">背景</el-divider>
<UnitBackGround v-model:layouyt-style="props.stylesVal.labelStyle" />
<el-divider content-position="left">尺寸</el-divider>
<PageSizeSmail v-model:layouyt-style="props.stylesVal.labelStyle" :place="'div'" />
<el-divider content-position="left">文本</el-divider>
<TextPage v-model:layouyt-style="props.stylesVal.labelStyle" :place="'div'" />
</el-collapse-item>
<el-collapse-item v-if="unitIsShow" :title="inputUnitTitle(props.place)" name="3">
<el-divider content-position="left">外框</el-divider>
<DesignLayout v-model:layouyt-style="props.stylesVal.inputStyle" />
<el-divider content-position="left">边线</el-divider>
<BianXian v-model:dataVal="props.stylesVal.inputStyle" />
<el-divider content-position="left">背景</el-divider>
<UnitBackGround v-model:layouyt-style="props.stylesVal.inputStyle" />
<el-divider content-position="left">尺寸</el-divider>
<PageSizeSmail v-model:layouyt-style="props.stylesVal.inputStyle" :place="'div'" />
<el-divider content-position="left">文本</el-divider>
<TextPage v-model:layouyt-style="props.stylesVal.inputStyle" :place="'div'" />
</el-collapse-item>
<el-collapse-item v-if="buttionShow" title="输入设置" name="2">
<el-divider content-position="left">尺寸</el-divider>
<PageSizeSmail v-model:layouyt-style="props.stylesVal.labelStyle" :place="'div'" />
<el-divider content-position="left">文本</el-divider>
<TextPage v-model:layouyt-style="props.stylesVal.labelStyle" :place="'div'" />
</el-collapse-item>
</el-collapse>
</div>
</template>
<style >
.jhk_kjh .el-collapse-item__header{
padding-left: 10px;
background-color: rgb(229, 229, 229);
}
</style>
>>>>>>> v7_master

1
src/components/DesignForm/public/form/form.vue

@ -90,6 +90,7 @@ let eventName = ''
let getValueEvent = ''
// window
const setWindowEvent = (bool?: boolean) => {
// console.log("window",props,props.formData)
if (props.formData.list.length > 0) {
const formName = props.formData.form?.name
if (!formName) {

108
src/components/workflow/dialog/matrix.vue

@ -146,57 +146,62 @@ onMounted(()=>{
})
</script>
<template>
<el-descriptions
v-if="isShow"
title="权限矩阵"
direction="vertical"
:column="2"
:size="size"
border
>
<el-descriptions-item label="可用矩阵" width="50%">
<el-row v-loading="loading">
<el-col :span="24" class="materBody">
<ul>
<li v-for="item in matrixContList" :key="item.id" :class="matrixIsClick.matrixid==item.id?'active':''" @click="pickmatirval(item)">
<el-text class="mx-1">{{item.name}}</el-text> <el-text class="mx-1">{{item.orgname}}</el-text>
</li>
</ul>
</el-col>
<el-col :span="24">
<el-pagination v-model:total="total" v-model:current-page="searchArchiveQuery.page" small layout="prev, pager, next" :page-size="searchArchiveQuery.pagesize" :pager-count="5" />
</el-col>
</el-row>
<div>
<el-divider content-position="left">矩阵选项</el-divider>
<el-descriptions
v-if="isShow"
title=""
direction="vertical"
:column="2"
:size="size"
border
class="suojin"
>
<el-descriptions-item label="可用矩阵" width="50%">
<el-row v-loading="loading">
<el-col :span="24" class="materBody">
<ul>
<li v-for="item in matrixContList" :key="item.id" :class="matrixIsClick.matrixid==item.id?'active':''" @click="pickmatirval(item)">
<el-text class="mx-1">{{item.name}}</el-text> <el-text class="mx-1">{{item.orgname}}</el-text>
</li>
</ul>
</el-col>
<el-col :span="24">
<el-pagination v-model:total="total" v-model:current-page="searchArchiveQuery.page" small layout="prev, pager, next" :page-size="searchArchiveQuery.pagesize" :pager-count="5" />
</el-col>
</el-row>
</el-descriptions-item>
</el-descriptions-item>
<el-descriptions-item label="矩阵选项" width="50%">
<el-row v-loading="loadingVal">
<el-col :span="24">
<el-select v-model="matrixIsClick.factorid" filterable placeholder="Select" style="width:100%" @change="pickSelect">
<el-option
:key="0"
label="请选择"
:value="0"
/>
<el-option
v-for="item in factorList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-col>
<el-col :span="24" class="materBody">
<ul>
<li v-for="item in outcomeList" :key="item.id" :class="matrixIsClick.outcomeid==item.id?'active':''" @click="pickval(item)">
<el-text class="mx-1">{{item.name}}</el-text> <el-text class="mx-1">{{}}{{item.pinyin}}</el-text>
</li>
</ul>
</el-col>
</el-row>
</el-descriptions-item>
</el-descriptions>
<el-descriptions-item label="矩阵选项" width="50%">
<el-row v-loading="loadingVal">
<el-col :span="24">
<el-select v-model="matrixIsClick.factorid" filterable placeholder="Select" style="width:100%" @change="pickSelect">
<el-option
:key="0"
label="请选择"
:value="0"
/>
<el-option
v-for="item in factorList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-col>
<el-col :span="24" class="materBody">
<ul>
<li v-for="item in outcomeList" :key="item.id" :class="matrixIsClick.outcomeid==item.id?'active':''" @click="pickval(item)">
<el-text class="mx-1">{{item.name}}</el-text> <el-text class="mx-1">{{}}{{item.pinyin}}</el-text>
</li>
</ul>
</el-col>
</el-row>
</el-descriptions-item>
</el-descriptions>
</div>
</template>
<style lang='scss' scoped>
.materBody{
@ -212,4 +217,7 @@ onMounted(()=>{
color:#409EFF;
}
}
.suojin{
padding: 0px 20px;
}
</style>

46
src/components/workflow/drwer/analysisForm.ts

@ -0,0 +1,46 @@
import { formData } from '@/api/DesignForm/types'
/**
@ 作者: 秦东
@ 时间: 2024-03-13 08:31:44
@ 功能: 分析自定义表格数据
*/
export const AnalysisForm = (formData:formData) => {
let mastAry = new Array
console.log("组件---->", formData)
if(formData.list && formData.list.length > 0) {
formData.list.forEach((item:any) => {
switch(item.type) {
case "tabs":
break;
case "title":
break;
case "txt":
break;
case "table":
break;
case "grid":
break;
case "card":
break;
case "divider":
break;
case "div":
break;
case "flex":
break;
case "button":
break;
default:
console.log("组件", item)
mastAry.push(
{
name:item.name,
value:4
}
)
break;
}
})
}
console.log("mastAry组件", mastAry)
}

185
src/components/workflow/drwer/approverDrawer.vue

@ -7,7 +7,7 @@
import $func from '@/utils/workflow/index'
import { setTypes, selectModes, selectRanges } from '@/utils/workflow/const'
import { useStore } from '@/store/workflow/index'
import { getAllParentNode,judgeOptionalNode } from '@/api/workflowapi/index'
import { getAllParentNode,judgeOptionalNode,analysisForm,setFlowFormKeyPower } from '@/api/workflowapi/index'
import PositionDialog from '@/components/workflow/dialog/positionDialog.vue'
import FormWord from '@/components/workflow/dialog/formWord.vue'
@ -33,6 +33,16 @@ let props = defineProps({
type:String,
default:""
},
formVersion:{
type:String,
default:""
},
formData:{
type:Object,
default(){
return {}
}
}
});
const isExecutor = ref(false)
const nodeTitle = ref<string>("审批人设置")
@ -51,6 +61,12 @@ let store = useStore()
let { setApproverConfig, setApprover } = store
let approverConfig1 = computed(():any=> store.approverConfig1)
let approverDrawer = computed(():any=> store.approverDrawer)
const emits = defineEmits<{
(e: 'update:formData', val: any): void
}>()
let visible = computed({
get(){
return approverDrawer.value
@ -59,12 +75,29 @@ let visible = computed({
closeDrawer()
}
})
const matrixIsShow = ref(false)
watch(visible,(val:any)=>{
// if(val)
const formData = computed({
get() {
return props.formData
},
set(val: formStruct) {
emits('update:formData', val)
}
});
const powerUnitAry = ref<any>({
nodeKey:"",
recUnitAry:{
masterUnitList:[],
sunUnitList:[],
unitAllKey:[],
unitAllState:[]
}
})
const matrixIsShow = ref(false)
watch(approverConfig1, (val:any)=>{
val.value.attribute = val.value.attribute*1
@ -166,6 +199,55 @@ const saveApprover = ()=> {
flag: true,
id: approverConfig1.value.id
})
let powerAry = [];
if(powerUnitAry.value.recUnitAry.masterUnitList && powerUnitAry.value.recUnitAry.masterUnitList.length > 0){
powerUnitAry.value.recUnitAry.masterUnitList.forEach((item:any)=>{
powerAry.push(item)
})
}
if(powerUnitAry.value.recUnitAry.sunUnitList && powerUnitAry.value.recUnitAry.sunUnitList.length > 0){
powerUnitAry.value.recUnitAry.sunUnitList.forEach((item:any)=>{
if(item.masterUnitList && item.masterUnitList.length > 0){
item.masterUnitList.forEach((itemSun:any) => {
// powerAry.push(item)
if(!powerAry.includes(itemSun)){
powerAry.push(itemSun)
}
})
}
});
}
console.log("正确",formData.value)
if(formData.value.purview){
console.log("正确")
let isNew = true
formData.value.purview.forEach((item:any)=>{
console.log("正确---->",item.nodeKey)
if(item.nodeKey == approverConfig1.value.value.nodeNumber){
item.powerAry=powerAry
isNew = false
}
});
if(isNew){
formData.value.purview.push({
nodeKey: approverConfig1.value.value.nodeNumber,
powerAry:powerAry
})
}
}else{
formData.value.purview = [{
nodeKey: approverConfig1.value.value.nodeNumber,
powerAry:powerAry
}]
}
let sendInfo: any = {
formKey:props.customerFormKey.toString(),
formVersion:props.formVersion.toString(),
formData:JSON.stringify(formData.value),
formPower:JSON.stringify(formData.value.purview)
}
// console.log("sendInfo",sendInfo)
setFlowFormKeyPower(sendInfo)
closeDrawer()
}
const closeDrawer = ()=> {
@ -196,10 +278,31 @@ const sureFormTableApprover = (data:any)=> {
const updateMatrix = (val:any) =>{
approverConfig.value.matrix = val;
}
/**
@ 作者: 秦东
@ 时间: 2024-03-13 08:24:54
@ 功能: 解析表单
*/
const jieForm = () => {
console.log("nodeKey:approverConfig1.nodeNumber",approverConfig1.value.value.nodeNumber
);
analysisForm({nodeKey:approverConfig1.value.value.nodeNumber,nodeJson:JSON.stringify(formData.value)})
.then((data)=>{
if(data.code == 0){
powerUnitAry.value = data.data
}
})
}
watch(()=>visible.value,(val:boolean)=>{
if(val){
jieForm();
}
})
</script>
<template>
<el-drawer v-model="visible" :append-to-body="true" :title="nodeTitle" class="set_promoter" :show-close="false" :size="550" :before-close="saveApprover">
<el-drawer v-model="visible" :append-to-body="true" :title="nodeTitle" class="set_promoter" :show-close="false" :size="550" :before-close="closeDrawer">
<div class="demo-drawer__content">
<!--审批人设置主体-->
@ -212,6 +315,7 @@ const updateMatrix = (val:any) =>{
</el-radio-group>
</div>
<!--指定成员-->
<el-divider v-if="approverConfig.settype==1" content-position="left">指定成员</el-divider>
<div v-if="approverConfig.settype==1" class="approver_manager">
<el-button type="primary" @click="addApprover">添加/修改成员</el-button>
<p class="selected_list">
@ -220,6 +324,7 @@ const updateMatrix = (val:any) =>{
</p>
</div>
<!--主管-->
<el-divider v-if="approverConfig.settype==2" content-position="left">主管</el-divider>
<div v-if="approverConfig.settype==2" class="approver_manager">
<p>
<el-row :gutter="10">
@ -240,8 +345,8 @@ const updateMatrix = (val:any) =>{
<p class="tip">找不到主管时由上级主管代审批</p>
</div>
<!--行政岗位-->
<el-divider v-if="approverConfig.settype==3" content-position="left">指定行政岗位</el-divider>
<div v-if="approverConfig.settype==3" class="approver_manager">
<p>指定行政岗位</p>
<el-row>
<el-col :span="18">
<el-button type="primary" @click="addApproverPost">添加/修改行政岗位</el-button>
@ -259,6 +364,7 @@ const updateMatrix = (val:any) =>{
</p>
</div>
<!--发起人自选-->
<el-divider v-if="approverConfig.settype==4" content-position="left">发起人自选</el-divider>
<div v-show="approverConfig.settype==4" class="approver_self_select">
<el-radio-group v-model="approverConfig.selectMode" style="width: 100%;">
<el-radio v-for="({value, label}) in selectModes" :key="value" :label="value">{{label}}</el-radio>
@ -277,12 +383,13 @@ const updateMatrix = (val:any) =>{
</template>
</div>
<!--发起人自己-->
<el-divider v-if="approverConfig.settype==5" content-position="left">发起人自选</el-divider>
<div v-if="approverConfig.settype==5" class="approver_self">
<p>该审批节点设置发起人自己审批人默认为发起人</p>
</div>
<!--连续多级主管-->
<el-divider v-if="approverConfig.settype==6" content-position="left">连续多级主管</el-divider>
<div v-if="approverConfig.settype==6" class="approver_manager">
<p>审批终点</p>
<p style="padding-bottom:20px">
<el-row :gutter="10">
<el-col v-if="isExecutor" :span="6">
@ -301,6 +408,7 @@ const updateMatrix = (val:any) =>{
</p>
</div>
<!--指定审批节点为本节点设置审批人-->
<el-divider v-if="approverConfig.settype==7" content-position="left">可选节点列表</el-divider>
<div v-if="approverConfig.settype==7" class="approver_manager">
<p>可选节点列表</p>
<el-radio-group v-model="approverConfig.customNode" class="clear">
@ -310,8 +418,8 @@ const updateMatrix = (val:any) =>{
</el-radio-group>
</div>
<!--根据关联表单设置指定审批字段-->
<el-divider v-if="approverConfig.settype==8" content-position="left">指定审批字段</el-divider>
<div v-if="approverConfig.settype==8" class="approver_manager">
<p>指定审批字段</p>
<el-button type="primary" @click="formTableField">添加/修改审批字段</el-button>
<p class="selected_list">
<el-tag v-for="(item,index) in approverConfig.nodeUserList" :key="index" closable type="info" effect="plain" class="tag_us" @close="$func.removeEle(approverConfig.nodeUserList,item,'targetId')">{{item.name}}</el-tag>
@ -324,40 +432,73 @@ const updateMatrix = (val:any) =>{
<option value="1">发起人</option>
<option value="2">执行人</option>
</select>
<MatrixPage
v-model:isshow="matrixIsShow"
:data="matrixFieldList"
@change="updateMatrix"
/>
</div>
<MatrixPage
v-if="approverConfig.settype==9"
v-model:isshow="matrixIsShow"
:data="matrixFieldList"
@change="updateMatrix"
/>
<!--补充审批信息-->
<el-divider v-if="(approverConfig.settype==1&&approverConfig.nodeUserList.length>1)||approverConfig.settype==2||approverConfig.settype==6||(approverConfig.settype==4&&approverConfig.selectMode==2)||approverConfig.settype==8||approverConfig.settype==9" content-position="left">多人审批时采用的审批方式</el-divider>
<div v-if="(approverConfig.settype==1&&approverConfig.nodeUserList.length>1)||approverConfig.settype==2||approverConfig.settype==6||(approverConfig.settype==4&&approverConfig.selectMode==2)||approverConfig.settype==8||approverConfig.settype==9" class="approver_some">
<p>多人审批时采用的审批方式</p>
<el-radio-group v-model="approverConfig.examineMode" class="clear">
<el-radio :label="1">依次审批</el-radio>
<el-radio v-if="approverConfig.settype!=2" :label="2">会签(须所有审批人同意)</el-radio>
<el-radio v-if="approverConfig.settype!=2" :label="3">或签(有一位审批人同意即可)</el-radio>
</el-radio-group>
</div>
<el-divider v-if="approverConfig.settype==2||approverConfig.settype==6||approverConfig.settype==9" content-position="left">审批人为空时</el-divider>
<div v-if="approverConfig.settype==2||approverConfig.settype==6||approverConfig.settype==9" class="approver_some">
<p>审批人为空时</p>
<el-radio-group v-model="approverConfig.noHanderAction" class="clear">
<el-radio :label="1">自动审批通过/不允许发起</el-radio>
<br/>
<el-radio :label="2">转交给审核管理员</el-radio>
</el-radio-group>
</div>
<el-divider content-position="left">退回设置</el-divider>
<div class="approver_some">
<p>退回设置</p>
<el-radio-group v-model="approverConfig.sendBackNode" class="clear">
<el-radio label="beginnode" >发起人</el-radio>
<el-radio v-for="item in nodeOptional" :key="item.nodeNumber" :label="item.nodeNumber" >{{ item.nodeName }}编号{{ item.nodeNumber }}</el-radio>
</el-radio-group>
</div>
<el-divider content-position="left">操作权限</el-divider>
<div class="info_box">
<div class="table_name"><el-text class="mx-1" type="primary">主表</el-text></div>
<el-table v-if="powerUnitAry.recUnitAry.masterUnitList" :data="powerUnitAry.recUnitAry.masterUnitList" size="small" style="width: 100%; --el-table-border-color: none;" :header-cell-style="{background:'#eef1f6',color:'#606266'}" class="customer-no-border-table" >
<el-table-column prop="name" label="字段" />
<el-table-column label="可见" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isLook" label="" />
</template>
</el-table-column>
<el-table-column label="可编辑" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isEdit" label="" />
</template>
</el-table-column>
</el-table>
<el-row v-if="powerUnitAry.recUnitAry.sunUnitList" v-for="(item,index) in powerUnitAry.recUnitAry.sunUnitList" :key="index">
<el-col :span="24" class="table_name"><el-text class="mx-1" type="primary">{{item.name}}</el-text></el-col>
<el-col :span="24">
<el-table v-if="item.masterUnitList" :data="item.masterUnitList" size="small" style="width: 100%; --el-table-border-color: none;" :header-cell-style="{background:'#eef1f6',color:'#606266'}">
<el-table-column prop="name" label="字段" />
<el-table-column label="可见" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isLook" label="" />
</template>
</el-table-column>
<el-table-column label="可编辑" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isEdit" label="" />
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</div>
@ -416,7 +557,7 @@ const updateMatrix = (val:any) =>{
}
}
.approver_manager,.approver_self_select,.approver_some,.approver_self{
border-top: 1px solid #f2f2f2;
border-top: 0px solid #f2f2f2;
}
.approver_self_select,
.approver_content{
@ -487,5 +628,7 @@ const updateMatrix = (val:any) =>{
margin-top: 15px;
}
}
.info_box{
padding: 0 20px;
}
</style>

180
src/components/workflow/drwer/promoterDrawer.vue

@ -5,10 +5,45 @@
-->
<script lang='ts' setup>
import employeesDialog from '@/components/workflow/dialog/employeesDialog.vue'
import { AnalysisForm } from '@/components/workflow/drwer/analysisForm'
import $func from '@/utils/workflow/index'
import { useStore } from '@/store/workflow/index'
import { analysisForm,setFlowFormKeyPower } from '@/api/workflowapi/index'
const props = defineProps({
formData:{
type:Object,
default(){
return {}
}
},
formKey:{
type:String,
default:""
},
formVersion:{
type:String,
default:""
},
});
const emits = defineEmits<{
(e: 'update:formData', val: any): void
}>()
const formData = computed({
get() {
return props.formData
},
set(val: formStruct) {
emits('update:formData', val)
}
});
//
// const
let flowPermission = ref([])
let promoterVisible = ref(false)
let checkedList = ref([])
@ -43,19 +78,147 @@ const savePromoter = () => {
flag: true,
id: flowPermission1.value.id
})
let powerAry = [];
if(powerUnitAry.value.recUnitAry.masterUnitList && powerUnitAry.value.recUnitAry.masterUnitList.length > 0){
powerUnitAry.value.recUnitAry.masterUnitList.forEach((item:any)=>{
powerAry.push(item)
})
}
if(powerUnitAry.value.recUnitAry.sunUnitList && powerUnitAry.value.recUnitAry.sunUnitList.length > 0){
powerUnitAry.value.recUnitAry.sunUnitList.forEach((item:any)=>{
if(item.masterUnitList && item.masterUnitList.length > 0){
item.masterUnitList.forEach((itemSun:any) => {
// powerAry.push(item)
if(!powerAry.includes(itemSun)){
powerAry.push(itemSun)
}
})
}
});
}
// console.log("",formData.value)
if(formData.value.purview){
// console.log("")
let isNew = true
formData.value.purview.forEach((item:any)=>{
// console.log("---->",item.nodeKey)
if(item.nodeKey == "begin"){
item.powerAry=powerAry
isNew = false
}
});
if(isNew){
formData.value.purview.push({
nodeKey: "begin",
powerAry:powerAry
})
}
}else{
formData.value.purview = [{
nodeKey: "begin",
powerAry:powerAry
}]
}
// formData.value.purview.push({
// nodeKey: "begin",
// powerAry:powerAry
// }) {{props.formKey}}=>{{props.formVersion}}
let sendInfo: any = {
formKey:props.formKey.toString(),
formVersion:props.formVersion.toString(),
formData:JSON.stringify(formData.value),
formPower:JSON.stringify(formData.value.purview)
}
// console.log("sendInfo",sendInfo)
setFlowFormKeyPower(sendInfo)
// console.log("formDataAll",formData)
// console.log("formData",formData.value.purview)
closeDrawer()
}
const closeDrawer = () => {
setPromoter(false)
}
const powerUnitAry = ref<any>({
nodeKey:"",
recUnitAry:{
masterUnitList:[],
sunUnitList:[],
unitAllKey:[],
unitAllState:[]
}
})
/**
@ 作者: 秦东
@ 时间: 2024-03-13 08:24:54
@ 功能: 解析表单
*/
const jieForm = () => {
analysisForm({nodeKey:"begin",nodeJson:JSON.stringify(formData.value)})
.then((data)=>{
if(data.code == 0){
powerUnitAry.value = data.data
}
})
}
watch(()=>visible.value,(val:boolean)=>{
if(val){
jieForm();
}
})
</script>
<template>
<el-drawer v-model="visible" :append-to-body="true" title="发起人" class="set_promoter" :show-close="false" :size="550" :before-close="savePromoter">
<el-drawer v-model="visible" :append-to-body="true" title="发起人" class="set_promoter" :show-close="false" :size="550" :before-close="closeDrawer">
<div class="demo-drawer__content">
<div class="promoter_content drawer_content">
<p>{{ $func.arrToStr(flowPermission) || '所有人' }}</p>
<el-button type="primary" @click="addPromoter">添加/修改发起人</el-button>
<el-divider content-position="left">节点属性</el-divider>
<div class="info_box">
<p>{{ $func.arrToStr(flowPermission) || '所有人' }}</p>
<el-button type="primary" @click="addPromoter">添加/修改发起人</el-button>
</div>
<el-divider content-position="left">操作权限</el-divider>
<div class="info_box">
<div class="table_name"><el-text class="mx-1" type="primary">主表</el-text></div>
<el-table v-if="powerUnitAry.recUnitAry.masterUnitList" :data="powerUnitAry.recUnitAry.masterUnitList" size="small" style="width: 100%; --el-table-border-color: none;" :header-cell-style="{background:'#eef1f6',color:'#606266'}" class="customer-no-border-table" >
<el-table-column prop="name" label="字段" />
<el-table-column label="可见" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isLook" label="" />
</template>
</el-table-column>
<el-table-column label="可编辑" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isEdit" label="" />
</template>
</el-table-column>
</el-table>
<el-row v-if="powerUnitAry.recUnitAry.sunUnitList" v-for="(item,index) in powerUnitAry.recUnitAry.sunUnitList" :key="index">
<el-col :span="24" class="table_name"><el-text class="mx-1" type="primary">{{item.name}}</el-text></el-col>
<el-col :span="24">
<el-table v-if="item.masterUnitList" :data="item.masterUnitList" size="small" style="width: 100%; --el-table-border-color: none;" :header-cell-style="{background:'#eef1f6',color:'#606266'}">
<el-table-column prop="name" label="字段" />
<el-table-column label="可见" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isLook" label="" />
</template>
</el-table-column>
<el-table-column label="可编辑" align="center" width="80">
<template #default="scope">
<el-checkbox v-model="scope.row.isEdit" label="" />
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
<!-- {{formData}} -->
</div>
<div class="demo-drawer__footer clear">
<el-button type="primary" @click="savePromoter"> </el-button>
<el-button @click="closeDrawer"> </el-button>
@ -72,7 +235,10 @@ const closeDrawer = () => {
<style lang='scss' scoped>
.set_promoter {
.promoter_content {
padding: 0 20px;
padding: 0 0px;
.info_box{
padding: 0 20px;
}
.el-button {
margin-bottom: 20px;
}
@ -84,4 +250,8 @@ const closeDrawer = () => {
}
}
}
.table_name{
padding : 10px 0
}
</style>

4
src/components/workflow/nodeWrap.vue

@ -135,6 +135,10 @@ const reData = (data: any, addData: any) => {
};
const setPerson = (priorityLevel: any) => {
var { type } = props.nodeConfig;
console.log("选中节点--->",type,props.nodeConfig)
if (type == 0) {
setPromoter(true);
setFlowPermission({

7
src/types/components.d.ts

@ -22,7 +22,10 @@ declare module '@vue/runtime-core' {
DiyIconfont: typeof import('./../components/DesignForm/public/expand/diy-iconfont.vue')['default']
DragControl: typeof import('./../components/DesignForm/dragControl.vue')['default']
ElAffix: typeof import('element-plus/es')['ElAffix']
<<<<<<< HEAD
ElAlert: typeof import('element-plus/es')['ElAlert']
=======
>>>>>>> v7_master
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
@ -67,6 +70,7 @@ declare module '@vue/runtime-core' {
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElResult: typeof import('element-plus/es')['ElResult']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
@ -127,8 +131,11 @@ declare module '@vue/runtime-core' {
IEpRefreshLeft: typeof import('~icons/ep/refresh-left')['default']
IEpSearch: typeof import('~icons/ep/search')['default']
IEpSetting: typeof import('~icons/ep/setting')['default']
<<<<<<< HEAD
IEpTop: typeof import('~icons/ep/top')['default']
IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
=======
>>>>>>> v7_master
IEpUser: typeof import('~icons/ep/user')['default']
IEpView: typeof import('~icons/ep/view')['default']
LangSelect: typeof import('./../components/LangSelect/index.vue')['default']

60
src/utils/lowCodeForm/index.ts

@ -0,0 +1,60 @@
/**
* storage
* @param key key
* @param hour 使true
* @param expired undefined
*/
export const getStorage = (key: string, hour?: boolean, expired?: string) => {
let data: any
if (hour) {
data = window.localStorage.getItem(key)
try {
data = JSON.parse(data)
if (typeof data === 'object' && data.__value && data.__time) {
// 使用了时间的
// 在当前时间后,表示没过期
if (new Date().getTime() < data.__time) {
data = data.__value
} else {
// 过期了
data = expired || undefined
}
}
} catch (e) {
/* empty */
}
} else {
//保存时没传时间的,存在session里
data = window.sessionStorage.getItem(key)
}
try {
return JSON.parse(data)
} catch (e) {
return data
}
}
/** localStorage hour
* hour空时使用原始sessionStorage(key,value)
* hour=0使localStorage
* hour>0localStorage添加时间控制
* */
export function setStorage(key: string, data: any, hour?: number | null): void {
let newData = data
if (typeof data === 'object') {
newData = JSON.stringify(data)
}
if (hour === 0) {
window.localStorage.setItem(key, newData)
} else if (hour && hour > 0) {
const now = new Date()
const valueDate: string = JSON.stringify({
__value: data,
__time: now.setSeconds(now.getSeconds() + hour * 3600)
})
window.localStorage.setItem(key, valueDate)
} else {
window.sessionStorage.setItem(key, newData)
}
}

32
src/views/sysworkflow/codepage/createform.vue

@ -930,7 +930,35 @@ const editversionstaus = (id:string) =>{
@confirm="dialogConfirm"
/>
<vue-file v-if="!['search'].includes(state.designType)" ref="vueFileEl" />
<el-dialog v-model="state.previewVisible" title="预览" :fullscreen="true">
<el-drawer
v-model="state.previewVisible"
title="预览"
:append-to-body="true"
size="50%"
>
<form-design
v-if="state.previewVisible"
ref="previewForm"
:form-data="state.formDataPreview"
:dict="state.formDict"
:type="1"
/>
<template #footer>
<div class="dialog-footer">
<el-button size="small" type="primary" @click="previewSubmit">
提交
</el-button>
<el-button size="small" @click="state.previewVisible = false">
取消
</el-button>
</div>
</template>
</el-drawer>
<!-- <el-dialog v-model="state.previewVisible" title="预111览" :fullscreen="false" top="0" right="0" width="595px">
<form-design
v-if="state.previewVisible"
ref="previewForm"
@ -948,7 +976,7 @@ const editversionstaus = (id:string) =>{
</el-button>
</div>
</template>
</el-dialog>
</el-dialog> -->
</div>
</template>
<style lang='scss' scoped>

88
src/views/sysworkflow/lowcodepage/group.vue

@ -0,0 +1,88 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-06 11:44:26
@ 备注: 低代码表单分组管理
-->
<script lang='ts' setup>
import { fromGroupSearch } from "@/api/DesignForm/gromGroup/types.ts";
import { groupStateAry } from "@/api/DesignForm/gromGroup/data.ts";
const searchArg =reactive<fromGroupSearch>({})
const queryFormRef = ref(ElForm);
const loading = ref(false)
/**
@ 作者: 秦东
@ 时间: 2024-03-06 16:39:41
@ 功能: 执行搜索
*/
const searchRun = () => {
}
/**
@ 作者: 秦东
@ 时间: 2024-03-06 16:46:04
@ 功能: 重置查询条件
*/
function resetQuery() {
queryFormRef.value.resetFields();
searchRun();
}
</script>
<template>
<div class="app-container">
<el-affix :offset="120">
<el-button type="primary">Offset top 120px</el-button>
</el-affix>
<!--搜索区域-->
<div class="search leftAndRight">
<el-form ref="queryFormRef" :model="searchArg" :inline="true">
<el-form-item label="分组名称" prop="keywords">
<el-input
v-model="searchArg.name"
placeholder="请输入分组名称"
clearable
@keyup.enter="searchRun"
/>
</el-form-item>
<el-form-item label="状态" prop="keywords">
<el-select v-model="searchArg.state" placeholder="请选择分组状态" clearable>
<el-option
v-for="item in groupStateAry"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="searchRun">
<template #icon><i-ep-search /></template>搜索
</el-button>
<el-button @click="resetQuery">
<template #icon><i-ep-refresh /></template>重置
</el-button>
</el-form-item>
</el-form>
<div>
<el-form>
<el-form-item>
<el-button type="warning" >
<template #icon><i-ep-plus /></template>新增
</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<style lang='scss' scoped>
.leftAndRight{
display: flex;
justify-content: space-between;
align-items: center;
padding-right:10px;
}
</style>

92
src/views/sysworkflow/lowcodepage/index.vue

@ -0,0 +1,92 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-06 11:43:49
@ 备注: 表单列表
-->
<script lang='ts' setup>
import { SearchForm,customerFormCont,customerFormConfig } from "@/api/DesignForm/type";
import { getCustomerFormList,getProductionMarkForm,editProductionFormStatus } from '@/api/DesignForm/requestapi'
/**
@ 作者: 秦东
@ 时间: 2024-03-09 08:59:37
@ 功能: 引入组件页面
*/
import LowCodeFormPage from "@/views/sysworkflow/lowcodepage/lowCodeFormPage.vue"
import LowCodeFormGroupPage from "@/views/sysworkflow/lowcodepage/lowCodeFormGroupPage.vue"
const contbody = ref() //
const addFormIsShow = ref(false)
const addFormGroupIsShow = ref(false)
const drawerWith = ref(); //
const formKey = ref<string>("") //
const groupKey = ref<string>("") //
/**
@ 作者: 秦东
@ 时间: 2024-03-09 09:06:32
@ 功能: 选择添加项目
*/
const handleCommand = (command: string) => {
// ElMessage(`click on item ${command}`)
if (command == "addForm"){
formKey.value = ""
// addFormIsShow.value = true
drawerWith.value = contbody.value?.clientWidth
addFormIsShow.value = true;
}else{
addFormGroupIsShow.value = true
drawerWith.value = 400
}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 09:06:44
@ 功能: 刷新页面
*/
const refreshPage = (pageType:string) =>{
if(pageType == "formPage"){
addFormIsShow.value = false;
}else{
addFormGroupIsShow.value = false;
}
}
</script>
<template>
<div ref="contbody" class="box_content">
<el-affix :offset="100" class="affix_box">
<el-dropdown @command="handleCommand">
<el-button type="primary" class="fa fa-plus" circle ></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="addForm">创建新表单</el-dropdown-item>
<el-dropdown-item command="addFormGroup">创建表单分组</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-affix>
<LowCodeFormPage v-if="addFormIsShow" :drawer-with="drawerWith" v-model:form-key="formKey" @refreshPage="refreshPage" />
<LowCodeFormGroupPage v-if="addFormGroupIsShow" :drawer-with="drawerWith" :group-key="groupKey" @refreshPage="refreshPage" />
</div>
</template>
<style lang='scss' scoped>
.box_content{
width: 100%;
height: calc(100vh - 90px);
overflow: hidden;
overflow-y: auto;
}
.affix_box{
margin-left: 10px;
}
</style>

223
src/views/sysworkflow/lowcodepage/lowCodeFormGroupPage.vue

@ -0,0 +1,223 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-09 08:58:58
@ 备注: 表单分组
-->
<script lang='ts' setup>
import { fromGroupSearch,fromGroupInfo,editFromGroupInfo } from "@/api/DesignForm/gromGroup/types";
import { gainFormGroupInfo,addCustomerFormGroup } from "@/api/DesignForm/gromGroup/api";
const props = defineProps({
drawerWith:{
type:Number,
default:0
},
groupKey:{
type:String,
default:""
}
});
const emits = defineEmits(["refreshPage"]);
const drawerOpenClose = ref(true)
const formGroupContent = reactive<fromGroupInfo>({
title:"",
icon:"",
ordid:"",
sort:50
})
const ruleFormGroup = ref(ElForm)
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API+"/api/upordown" //
const butLoading = ref(false)
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:13:08
@ 功能: 表单验证规则
*/
const rules = reactive<FormRules<RuleForm>>({
title: [
{ required: true, message: '分组名称不能为空', trigger: 'blur' },
{ min: 1, max: 50, message: '名称长度为1-50个字符', trigger: 'blur' },
],
})
/**
@ 作者: 秦东
@ 时间: 2024-03-09 09:55:53
@ 功能: 关闭
*/
const handleClose = (done: () => void) => {
if(formGroupContent.title != "" || formGroupContent.icon != "" || formGroupContent.sort != 50 || formGroupContent.ordid != ""){
ElMessageBox.confirm('编辑好的数据是否提交?')
.then(() => {
// done()
submitForm();
})
.catch(() => {
// catch error
emits("refreshPage","formPageGroup");
});
}else{
emits("refreshPage","formPageGroup");
}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:51:28
@ 功能: 提交数据
*/
const submitForm = () => {
butLoading.value = true;
ruleFormGroup.value.validate((isValid: boolean) => {
if (isValid) {
addCustomerFormGroup(formGroupContent)
.then((data) =>{
ElMessage({
message: data.msg,
type: 'success',
})
closeFormGroupBox();
})
.finally(() =>{
butLoading.value = false;
});
}else{
butLoading.value = false;
}
})
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:30:15
@ 功能: 检查图片上传
*/
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
console.log("检查图片上传---1--->",rawFile.type)
if (rawFile.type !== 'image/jpeg' && rawFile.type !== 'image/png' ) {
ElMessage.error('Avatar picture must be JPG format!')
return false
}
return true
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:30:43
@ 功能: 上传成功
*/
const handleAvatarSuccess: UploadProps['onSuccess'] = (response,uploadFile,uploadFiles) => {
// console.log("---1--->",response)
// console.log("---2--->",uploadFile)
// console.log("----3-->",uploadFiles)
// console.log("----4-->",response.url)
// console.log("----5-->",URL.createObjectURL(uploadFile.raw!))
// formGroupContent.icon = URL.createObjectURL(uploadFile.raw!)
formGroupContent.icon = response.data.url
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:44:06
@ 功能: 关闭抽屉
*/
const closeFormGroupBox = () => {
emits("refreshPage","formPageGroup");
initializeData();
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 11:45:08
@ 功能: 初始化数据
*/
const initializeData = () => {
formGroupContent.title=""
formGroupContent.icon=""
formGroupContent.sort=50
formGroupContent.ordid=""
ruleFormGroup.value.resetFields();
}
onMounted(()=>{
if(props.groupKey != "") {
gainFormGroupInfo({id: props.groupKey})
.then(({data})=>{
console.log("编辑表单分组",data);
formGroupContent.title=data.title
formGroupContent.icon=data.icon
formGroupContent.sort=data.sort
formGroupContent.ordid=data.ordid
})
}
})
</script>
<template>
<el-drawer
v-model="drawerOpenClose"
title="编辑表单分组"
:before-close="handleClose"
class="drawerGroupClass"
>
<div class="formGroupBox">
<el-form ref="ruleFormGroup" :model="formGroupContent" :rules="rules" label-width="auto" style="max-width: 600px">
<el-form-item label="分组名称" prop="title">
<el-input v-model="formGroupContent.title" />
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="formGroupContent.sort" controls-position="right" />
</el-form-item>
<el-form-item label="封面">
<el-upload
class="avatar-uploader"
:action="imgUploadApiUrl"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload"
>
<img v-if="formGroupContent.icon" :src="formGroupContent.icon" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</el-form-item>
</el-form>
</div>
<template #footer>
<div style="flex: auto">
<el-button type="primary" :loading="butLoading" @click="submitForm()">提交</el-button>
<el-button @click="closeFormGroupBox">取消</el-button>
</div>
</template>
</el-drawer>
</template>
<style scoped>
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
<style lang='scss' scoped>
.formGroupBox{
padding: 0 10px;
}
</style>
<style>
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}
</style>

230
src/views/sysworkflow/lowcodepage/lowCodeFormPage.vue

@ -0,0 +1,230 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-09 08:58:23
@ 备注: 编辑表单页面
-->
<script lang='ts' setup>
import { useRoute, useRouter } from 'vue-router'
import { formStruct } from '@/api/DesignForm/types'
import { customerFormConfig } from "@/api/DesignForm/type";
import { getProductionMarkForm } from '@/api/DesignForm/requestapi'
// import PageDesign from "@/views/sysworkflow/lowcodepage/pageDesign.vue"
import PageDesignEs from "@/views/sysworkflow/lowcodepage/pageDesignes.vue"
import WorkFlow from "@/views/sysworkflow/lowcodepage/workFlow.vue"
const props = defineProps({
drawerWith:{
type:Number,
default:true
},
formKey:{
type:String,
default:""
}
});
const formConfigCont = reactive<customerFormConfig>({
formName:"",
formlogo:""
})
const loading = ref(false)
const pageDesignIsWrite = ref(true);
const flowIsWrite = ref(true);
const emits = defineEmits(["refreshPage"]);
const drawerOpenOrClose = ref(true);
const tabsActive = ref(1);
const creetTabsActive = ref(1);
const route: any = useRoute().query || {}
const state = reactive<formStruct>({
formData: {
list: [],
form: {
size: 'default',
name:'',
formName: formConfigCont.formName
},
config: {},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
},
purview:[]
},
editor: {},
loading: false,
formDataPreview: {},
previewVisible: false, //
designType: route.type, // search
formDict: {},
formOtherData: {
source: route.source || '',
formName: formConfigCont.formName
}
})
//ID
const formKeyStr = computed({
get() {
return props.formKey
},
set(val: formStruct) {
emits('update:formKey', val)
}
});
//ID
const formVersion = ref<string>("")
const judgeFormIsEdit = (val:boolean) => {
pageDesignIsWrite.value = val;
}
const handleClick = (tab: TabsPaneContext, event: Event) =>{
console.log("选项卡--->",creetTabsActive.value,tab.paneName, event)
switch (tab.paneName) {
case 2:
if (creetTabsActive.value != 2){
if(PreOperation()){
creetTabsActive.value = tab.paneName
}
}
break;
case 3:
if (creetTabsActive.value != 3){
if(PreOperation()){
creetTabsActive.value = tab.paneName
}
}
break;
case 4:
if (creetTabsActive.value != 4){
if(PreOperation()){
creetTabsActive.value = tab.paneName
}
}
break;
default:
tabsActive.value = 1
creetTabsActive.value = 1
break;
}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 13:42:24
@ 功能: 判断tabs要执行得前置操作
*/
const PreOperation = () =>{
switch (creetTabsActive.value) {
case 2:
if(flowIsWrite.value){
ElMessageBox.alert('你设置的流程还未保存!', '温馨提示!', {
confirmButtonText: 'OK',
callback: (action: Action) => {
tabsActive.value = 2
creetTabsActive.value = 2
}
});
flowIsWrite.value = true
}else{
creetTabsActive.value = tabsActive.value
console.log("选项卡-1-->",tabsActive.value,creetTabsActive.value)
}
return true;
break;
case 3:
return true;
break;
case 4:
return true;
break;
default:
if(pageDesignIsWrite.value){
ElMessageBox.alert('你设置的表单还未保存!', '温馨提示!', {
confirmButtonText: 'OK',
callback: (action: Action) => {
tabsActive.value = 1
creetTabsActive.value = 1
}
});
pageDesignIsWrite.value = true
}else{
creetTabsActive.value = tabsActive.value
tabsActive.value = 1
}
return true;
break;
}
}
const judgeFlowIsEdit = (val:boolean) => {
flowIsWrite.value = val;
// creetTabsActive.value = 2
}
const closeFormPage = () => {
emits("refreshPage","formPage");
}
onBeforeMount(() => {
getProductionMarkForm()
.then(({data})=>{
formConfigCont.formlogo = data.formlogo
formConfigCont.formName = data.formname
state.formData.form.name = data.formlogo
state.formData.form.formName = data.formname
state.formOtherData.formName = data.formname
})
.finally(()=>{
})
})
/**
@ 作者: 秦东
@ 时间: 2024-03-11 08:44:43
@ 功能: 执行下一个窗口
*/
const runNextWindows = (val:number) => {
creetTabsActive.value = val
tabsActive.value = val
}
onMounted(()=>{
formKeyStr.value = "16"
})
</script>
<template>
<div class="drawerClass">
<el-drawer v-model="drawerOpenOrClose" title="设置/编辑自定义表单" :with-header="false" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true" :size="props.drawerWith">
<el-tabs v-model="tabsActive" @tab-click="handleClick" stretch class="tabsMain">
<el-tab-pane label="页面设计" :name="1">
{{creetTabsActive}} == {{tabsActive}}
<PageDesignEs v-model:state="state" v-model:form-key="formKeyStr" v-model:form-version="formVersion" :formconfigcont="formConfigCont" @judgeFormIsEdit="judgeFormIsEdit" @runNextWindows="runNextWindows" @closeFormPage="closeFormPage" />
</el-tab-pane>
<el-tab-pane label="流程设计" :name="2">
{{creetTabsActive}} == {{tabsActive}}
<WorkFlow v-model:state="state" v-model:form-key="formKeyStr" v-model:form-version="formVersion" @judgeFlowIsEdit="judgeFlowIsEdit" @runNextWindows="runNextWindows" @closeFormPage="closeFormPage" />
</el-tab-pane>
<el-tab-pane label="列表设计" :name="3">{{creetTabsActive}} == {{tabsActive}}</el-tab-pane>
<el-tab-pane label="页面设置" :name="4"></el-tab-pane>
</el-tabs>
</el-drawer>
</div>
</template>
<style lang='scss' scoped>
.drawerClass{
::v-deep .el-tabs__header{
margin: 0px;
}
::v-deep .el-drawer__body{
padding: 0;
}
}
</style>
<style>
::v-deep
</style>

743
src/views/sysworkflow/lowcodepage/pageDesign.vue

@ -0,0 +1,743 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-09 13:21:52
@ 备注: 页面设计
-->
<script lang='ts' setup>
import '@/assets/scss/element-var.scss'
import '@/assets/scss/index.scss'
import '@/assets/iconfont/iconfont.css'
import 'element-plus/dist/index.css'
import { useDesignFormStore } from '@/store/DesignForm/designForm'
import { useRoute, useRouter } from 'vue-router'
import { json2string,objToStringify,string2json,stringToObj } from '@/utils/DesignForm/form'
import { getRequest } from '@/api/DesignForm'
import { afterResponse, beforeRequest, onChange } from '@/api/DesignForm/utils'
import { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout'
import { FormData,formStruct,DrawerStruct, VideoMsg } from '@/api/DesignForm/types'
import { customerFormVersionCont } from '@/api/DesignForm/type'
import { saveProductionForm,getOneProductionForm,haveCustomerFormVersion,editCustomerFormInfo,saveAsNewVersion,enableVersion,judgeSubmitCancel } from '@/api/DesignForm/requestapi'
import { submitAndCancelButton,cancelButton,submitButton } from "@/api/DesignForm/gromGround/data";
//
import DragControl from '@/components/DesignForm/dragControl.vue';
import HeadTools from '@/components/DesignForm/public/headTools.vue';
// import HeadTools from '@/components/DesignForm/public/headToolsNew.vue';
import FormDesign from '@/components/DesignForm/public/form/form.vue'
import VueFile from '@/components/DesignForm/vueFile.vue'
import AceDrawer from '@/components/DesignForm/aceDrawer.vue'
const props = defineProps({
formKey:{
type:String,
default:""
},
formconfigcont:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits(["judgeFormIsEdit",'closeDrawer','runNextWindows']);
const isSave = ref(false)
const versionCont = ref<customerFormVersionCont[]>([]) //
const versionId = ref<string>("") //
const layoutStore = useLayoutStore()
layoutStore.changeBreadcrumb([{ label: '系统工具' }, { label: '表单设计' }])
const store = useDesignFormStore()
const router = useRouter()
const route: any = useRoute().query || {}
const state = reactive<formStruct>({
formData: {
list: [],
form: {
size: 'default',
name:'',
formName: props.formconfigcont.formName
},
config: {},
styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
},
editor: {},
loading: false,
formDataPreview: {},
previewVisible: false, //
designType: route.type, // search
formDict: {},
formOtherData: {
source: route.source || '',
formName: props.formconfigcont.formName
}
})
const drawer = reactive<DrawerStruct>({
visible: false,
type: '',
title: '',
codeType: '',
direction: undefined, //rtl / ltr
callback: ''
})
const vueFileEl = ref()
const formControlAttrEl = ref()
//
provide('formDesignType', state.designType)
/**
@ 作者: 秦东
@ 时间: 2024-03-09 16:10:23
@ 功能: 按钮操作
*/
const headToolClick = (type: string) => {
switch (type) {
case 'del':
state.formData.list = []
store.setActiveKey('')
store.setControlAttr({})
break
case 'eye':
//
store.setActiveKey('')
store.setControlAttr({})
state.previewVisible = true
// eslint-disable-next-line no-case-declarations
let stringPreview = objToStringify(state.formData) //
console.log("预览数据",stringPreview);
// eslint-disable-next-line no-case-declarations
const formName = state.formData.form.name
// eslint-disable-next-line no-case-declarations
const reg = new RegExp(`get${formName}ControlByName`, 'g')
stringPreview = stringPreview.replace(
reg,
`getPreview${formName}ControlByName`
)
state.formDataPreview = stringToObj(stringPreview)
state.formDataPreview.form.name = `Preview${formName}` //
break
case 'json':
//
openAceEditDrawer({
direction: 'rtl',
content: state.formData,
title: '可编辑修改或将已生成的脚本粘贴进来'
})
break
case 'save':
// saveData();
if(props.formid != ""){
editSaveData();
}else{
saveDataNew();
}
break
case 'branch':
saveOtherData();
break
case 'vue':
vueFileEl.value.open(state.formData)
// emits("update:draweropenclose", false);
// emits("closeDrawer");
emits("runNextWindows",2);
break
case 'close':
console.log("关闭")
if(isSave.value){
state.formData.list = []
store.setActiveKey('')
store.setControlAttr({})
// emits("update:draweropenclose", false);
emits("closeDrawer");
}else{
ElMessageBox.confirm('表单已做设计或修改!请问是否保存?','温馨提示!',{
confirmButtonText: '保存',
cancelButtonText: '不保存',
type: 'warning',
draggable: true,
})
.then(() => {
saveDataNew();
})
.catch(() => {
state.formData.list = []
store.setActiveKey('')
store.setControlAttr({})
// emits("update:draweropenclose", false);
emits("closeDrawer");
})
}
break
}
}
//
const dialogConfirm = (editVal: string) => {
// jsonstate.formData
try {
if (typeof drawer.callback === 'function') {
// callback
const newObj =
drawer.codeType === 'json'? string2json(editVal): stringToObj(editVal)
drawer.callback(newObj)
} else {
switch (drawer.type) {
case 'css':
//
if (!state.formData.config) {
state.formData.config = {}
}
state.formData.config.style = editVal
break
case 'dict':
state.formDict = string2json(editVal)
break
case 'beforeRequest':
case 'beforeSubmit':
case 'afterResponse':
case 'afterSubmit':
case 'closeSubmit':
case 'change':
if (!state.formData.events) {
state.formData.events = {}
}
state.formData.events[drawer.type] = stringToObj(editVal)
break
default:
state.formData = stringToObj(editVal)
}
}
dialogCancel()
} catch (res) {
// console.log(res.message)
//ElMessage.error(res.message)
}
}
//
function othenSaveFormCont(){
let params: any = {
jsondata:JSON.stringify(state.formData),
data: objToStringify(state.formData),
source: state.formOtherData.source, //
name: state.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.formDict)
}
state.loading = true
saveAsNewVersion(params)
.then((res: any) => {
// console.log("", res)
if(res.code == 0){
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
//
store.setActiveKey('')
store.setControlAttr({})
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.loading = false
})
}
//
const editSaveData = () =>{
writeDataFormNwe()
}
function writeDataFormNwe(){
let params: any = {
jsondata:JSON.stringify(state.formData),
data: objToStringify(state.formData),
source: state.formOtherData.source, //
name: state.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.formDict),
id:props.formid.toString(),
version:versionId.value.toString(),
}
state.loading = true
editCustomerFormInfo(params)
.then((res: any) => {
if(res.code == 0){
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
//
store.setActiveKey('')
store.setControlAttr({})
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.loading = false
})
}
//()
const saveDataNew = () => {
isSave.value = true
writeDataForm()
}
//
function writeDataForm(){
let params: any = {
jsondata:JSON.stringify(state.formData),
data: objToStringify(state.formData),
source: state.formOtherData.source, //
name: state.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.formDict)
}
let apiKey = 'designSave'
if (route.id) {
// id
Object.assign(params, { id: route.id })
apiKey = 'designEdit'
}
//
if (state.designType === 'search') {
params = {
data: objToStringify(state.formData),
dict: json2string(state.formDict),
id: route.id
}
}
state.loading = true
saveProductionForm(params)
.then((res: any) => {
// console.log("", res)
if(res.code == 0){
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
//
store.setActiveKey('')
store.setControlAttr({})
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.loading = false
})
}
//
const saveData = () => {
// url
const { addUrl, editUrl, requestUrl } = state.formData.config
if (!state.formOtherData.source &&(!addUrl || !editUrl || !requestUrl) && tate.designType !== 'search') {
ElMessage.error('请选择数据源或配置接口url地址,否则表单无法提交保存')
return
}
let params: any = {
jsondata:JSON.stringify(state.formData),
data: objToStringify(state.formData),
source: state.formOtherData.source, //
name: state.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.formDict)
}
let apiKey = 'designSave'
if (route.id) {
// id
Object.assign(params, { id: route.id })
apiKey = 'designEdit'
}
//
if (state.designType === 'search') {
params = {
data: objToStringify(state.formData),
dict: json2string(state.formDict),
id: route.id
}
}
state.loading = true
getRequest(apiKey, params)
.then((res: any) => {
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
//
const path = route.redirect || '/design/form/list'
const query: any = {}
if (route.redirect && route.redirect.indexOf('?') !== -1) {
// pathid=1{id:1}
const p = route.redirect.split('?')[1]
const pSplit = p.split('&')
pSplit.forEach((item: string) => {
const splitItem = item.split('=')
query[splitItem[0]] = splitItem[1]
})
}
router.push({ path: path, query: query })
state.loading = false
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.loading = false
})
// session
if (!route.id) {
//
window.sessionStorage.removeItem('formMenuList')
}
//
store.setActiveKey('')
store.setControlAttr({})
}
//
const openAceEditDrawer = (params: any) => {
const { type, direction, codeType, title, callback, content } = params
drawer.direction = direction // ltr/rtl
drawer.type = type // type
drawer.codeType = codeType || '' //
drawer.title = title ? `提示:${title}` : ''
drawer.visible = true
drawer.callback = callback
let editData =codeType === 'json'? json2string(content, true): objToStringify(content, true)
switch (type) {
case 'css':
editData = state.formData.config?.style || ''
break
case 'dict':
//
editData = json2string(state.formDict, true)
break
case 'beforeRequest':
case 'beforeSubmit':
case 'afterResponse':
case 'afterSubmit':
case 'change':
// eslint-disable-next-line no-case-declarations
const beforeData = state.formData.events || {}
if (beforeData[type]) {
editData = objToStringify(beforeData[type], true)
} else {
if (['afterResponse', 'afterSubmit'].includes(type)) {
editData = afterResponse
} else if (type === 'change') {
editData = onChange
} else {
editData = beforeRequest
}
}
break
// case 'afterResponse':
// case 'afterSubmit':
// const newData = state.formData.events || {}
// if (newData[type]) {
// editData = objToStringify(newData[type], true)
// } else {
// editData = afterResponse
// }
// break
case 'optionsParams':
if (!content) {
editData = beforeRequest
}
break
case 'optionsResult':
if (!content) {
editData = afterResponse
}
break
}
drawer.content = editData
}
const drawerBeforeClose = () => {
dialogCancel()
}
const dialogCancel = () => {
drawer.visible = false
drawer.type = ''
drawer.title = ''
drawer.codeType = ''
drawer.callback = ''
drawer.content = ''
}
//
const previewForm = ref()
const previewSubmit = () => {
previewForm.value.validate((valid: boolean, fields: any) => {
if (valid) {
// alert('')
ElMessage.success('校验通过')
console.log(fields)
} else {
// alert('')
// console.log('error submit!', fields)
ElMessage.error('校验不通过')
return false
}
})
}
//
const selectTemplate = (data: FormData) => {
state.formData = stringToObj(objToStringify(data))
}
//
const searchCheckField = (data: FormData) => {
state.formData.list.push(data)
}
onMounted(()=>{
if (route.source) {
formControlAttrEl.value.getFormFieldBySource(route.source)
}
// emits("judgeFormIsEdit",false);
state.formOtherData.formName = props.formconfigcont.formName
state.formData.form.name = props.formconfigcont.formlogo
state.formData.form.formName = props.formconfigcont.formName
getInitData()
})
watch(()=>props.formconfigcont,(val : any)=>{
state.formOtherData.formName = val.formName
state.formData.form.name = val.formlogo
state.formData.form.formName = val.formName
getInitData()
},
{
deep: true
});
watch(()=>state.formData.list,(val:any)=>{
if(val.length > 0){
isSave.value = true
emits("judgeFormIsEdit",true);
}
},
{
deep: true
});
/**
@ 作者: 秦东
@ 时间: 2024-03-09 16:05:19
@ 功能: 获取表单数据
*/
const getInitData = () => {
const id = props.formKey // id
if (id) {
//
state.loading = true
getOneProductionForm({id: id.toString()})
.then((res:any) => {
state.loading = false
console.log(" 获取初始表单数据",res)
if(res.code == 0){
const result = res.data
// res.data=''
if (result.mastesform) {
state.formData = stringToObj(result.mastesform)
}
state.formDict = string2json(result.dict)
//
state.formOtherData.source = result.source
state.formOtherData.formName = result.name
state.formOtherData.formName = result.name
state.formData.form.name = result.tablekey
state.formData.form.formName = result.name
if (result.source && state.designType !== 'search') {
//
formControlAttrEl.value.getFormFieldBySource(result.source)
}
}else{
ElMessage.error(res.msg || '加载异常')
}
})
.finally(()=>{
isSave.value = true
haveCustomerFormVersion({id:state.formData.form.name})
.then(({data})=>{
// console.log("-------------->",data)
versionCont.value = data
if(data.length > 0){
data.forEach((item:any) => {
if(item.status == 1){
versionId.value = item.id.toString()
}
});
}
})
})
.catch((res: any) => {
// console.log(res)
ElMessage.error(res.msg || '加载异常')
state.loading = false
})
}
}
//
watch(() => versionId.value,()=>{
console.log("经停版本变化----》",versionId.value,versionCont.value)
if(versionCont.value.length > 0){
versionCont.value.forEach(item=>{
let versionIdStr = item.id.toString()
if(versionIdStr == versionId.value){
console.log("经停版本变化--1--》",item)
if (item.mastesform) {
state.formData = stringToObj(item.mastesform)
}
state.formDict = string2json(item.dict)
}
})
}
})
//
const editversionstaus = (id:string) =>{
// console.log("--1--",id)
enableVersion({id:id.toString()})
.then(() =>{
haveCustomerFormVersion({id:state.formData.form.name})
.then(({data})=>{
console.log("加载异常-------------->",data)
versionCont.value = data
if(data.length > 0){
data.forEach((item:any) => {
if(item.status == 1){
versionId.value = item.id.toString()
}
});
}
})
})
}
</script>
<template>
<div class="design_container">
<DragControl
v-model:versionid="versionId"
:formid="state.formOtherData.source"
:versioncont="versionCont"
@click-check="searchCheckField"
@click="selectTemplate"
@editversionstaus="editversionstaus"
/>
<div class="main-body">
<HeadTools v-loading="state.loading" :customerformid="props.formKey" @click="headToolClick" />
<div v-loading="state.loading" class="main-form">
<div v-if="state.formData.list.length === 0" class="empty-tips">
从左侧拖拽来添加组件
</div>
<FormDesign
v-model:issave="isSave"
:type="5"
:form-data="state.formData"
:dict="state.formDict"
/>
</div>
</div>
<form-control-attr
ref="formControlAttrEl"
v-model:formOtherData="state.formOtherData"
:form-data="state.formData.form"
:form-config="state.formData.config"
:customerformid="props.formKey"
:form-list="state.formData.list"
@open-dialog="openAceEditDrawer"
/>
<ace-drawer
v-model="drawer.visible"
:title="drawer.title"
:direction="drawer.direction"
:content="drawer.content"
:code-type="drawer.codeType"
@before-close="drawerBeforeClose"
@confirm="dialogConfirm"
/>
<vue-file v-if="!['search'].includes(state.designType)" ref="vueFileEl" />
<el-drawer
v-model="state.previewVisible"
title="预览"
:append-to-body="true"
size="50%"
>
<form-design
v-if="state.previewVisible"
ref="previewForm"
:form-data="state.formDataPreview"
:dict="state.formDict"
:type="1"
/>
<template #footer>
<div class="dialog-footer">
<el-button size="small" type="primary" @click="previewSubmit">
提交
</el-button>
<el-button size="small" @click="state.previewVisible = false">
取消
</el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<style lang='scss' scoped>
.design_container{
display: flex;
background-color: #FFFFFF;
}
</style>

637
src/views/sysworkflow/lowcodepage/pageDesignes.vue

@ -0,0 +1,637 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-11 09:01:36
@ 备注: 自定义表单
-->
<script lang='ts' setup>
import { useDesignFormStore } from '@/store/DesignForm/designForm'
import { useRoute, useRouter } from 'vue-router'
import { json2string,objToStringify,string2json,stringToObj } from '@/utils/DesignForm/form'
import { getRequest } from '@/api/DesignForm'
import { afterResponse, beforeRequest, onChange } from '@/api/DesignForm/utils'
import { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout'
import { FormData,formStruct,DrawerStruct, VideoMsg } from '@/api/DesignForm/types'
import { customerFormVersionCont } from '@/api/DesignForm/type'
import { saveProductionForm,getOneProductionForm,haveCustomerFormVersion,editCustomerFormInfo,saveAsNewVersion,enableVersion,judgeSubmitCancel } from '@/api/DesignForm/requestapi'
import { submitAndCancelButton,cancelButton,submitButton } from "@/api/DesignForm/gromGround/data";
//
import DragControl from '@/components/DesignForm/dragControl.vue';
import HeadTools from '@/components/DesignForm/public/headTools.vue';
// import HeadTools from '@/components/DesignForm/public/headToolsNew.vue';
import FormDesign from '@/components/DesignForm/public/form/form.vue'
import VueFile from '@/components/DesignForm/vueFile.vue'
import AceDrawer from '@/components/DesignForm/aceDrawer.vue'
const props = defineProps({
formKey:{
type:String,
default:""
},
formVersion:{
type:String,
default:""
},
formconfigcont:{
type:Object,
default(){
return {}
}
},
state:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits<{
(e: 'update:state', val: formStruct): void
(e: 'update:formKey', val: string): void
(e: 'update:formVersion', val: string): void
(e: 'judgeFormIsEdit', val: boolean): void
(e: 'runNextWindows', val: number): void
(e: 'closeFormPage'): void
}>()
const state = computed({
get() {
return props.state
},
set(val: formStruct) {
emits('update:state', val)
}
});
const formKeyVal = computed({
get() {
return props.formKey
},
set(val: formStruct) {
emits('update:formKey', val)
}
});
//
provide('formDesignType', state.value.designType)
const vueFileEl = ref()
const formControlAttrEl = ref()
const drawer = reactive<DrawerStruct>({
visible: false,
type: '',
title: '',
codeType: '',
direction: undefined, //rtl / ltr
callback: ''
})
const versionCont = ref<customerFormVersionCont[]>([]) //
const versionId = ref<string>("") //
const store = useDesignFormStore()
const router = useRouter()
const route: any = useRoute().query || {}
//
const searchCheckField = (data: FormData) => {
state.value.formData.list.push(data)
}
//
const selectTemplate = (data: FormData) => {
state.value.formData = stringToObj(objToStringify(data))
}
//
const editversionstaus = (id:string) =>{
// console.log("--1--",id)
enableVersion({id:id.toString()})
.then(() =>{
haveCustomerFormVersion({id:state.value.formData.form.name})
.then(({data})=>{
// console.log("-------------->",data)
versionCont.value = data
if(data.length > 0){
data.forEach((item:any) => {
if(item.status == 1){
versionId.value = item.id.toString()
emits('update:formVersion', item.id.toString())
}
});
}
})
})
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 16:10:23
@ 功能: 按钮操作
*/
const headToolClick = (type: string) => {
switch (type) {
case 'del': //
state.value.formData.list = []
store.setActiveKey('')
store.setControlAttr({})
break
case 'eye': //
store.setActiveKey('')
store.setControlAttr({})
let stringPreview = objToStringify(state.value.formData) //
const formName = state.value.formData.form.name
const reg = new RegExp(`get${formName}ControlByName`, 'g')
stringPreview = stringPreview.replace(
reg,
`getPreview${formName}ControlByName`
)
state.value.formDataPreview = stringToObj(stringPreview)
state.value.formDataPreview.form.name = `Preview${formName}` //
// console.log("",state.value.formDataPreview);
state.value.previewVisible = true
break
case 'json': //
openAceEditDrawer({
direction: 'rtl',
content: state.value.formData,
title: '可编辑修改或将已生成的脚本粘贴进来'
})
break
case 'save': //
// saveData();
if(formKeyVal.value != ""){
editSaveData();
}else{
saveDataNew();
}
break
case 'branch': //
saveOtherData();
break
case 'vue':
vueFileEl.value.open(state.value.formData)
break
case 'close':
state.value.formData.list = []
store.setActiveKey('')
store.setControlAttr({})
emits('closeFormPage')
// if(state.value.formData.list.length > 0){
// ElMessageBox.confirm('','',{
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning',
// draggable: true,
// })
// .then(() => {
// saveDataNew();
// })
// .catch(() => {
// state.value.formData.list = []
// store.setActiveKey('')
// store.setControlAttr({})
// // emits("update:draweropenclose", false);
// emits("closeDrawer");
// })
// }else{
// state.value.formData.list = []
// store.setActiveKey('')
// store.setControlAttr({})
// emits('closeFormPage')
// }
break
}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-11 13:44:38
@ 功能: 另存为新版本
*/
const saveOtherData = () => {
let params: any = {
jsondata:JSON.stringify(state.value.formData),
data: objToStringify(state.value.formData),
source: state.value.formOtherData.source, //
name: state.value.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.value.formDict)
}
state.value.loading = true
saveAsNewVersion(params)
.then((res: any) => {
// console.log("", res)
if(res.code == 0){
emits('judgeFormIsEdit', false)
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
versionId.value = res.data.id.toString()
emits('update:formVersion', res.data.id.toString())
//
store.setActiveKey('')
store.setControlAttr({})
getInitData()
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.value.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.value.loading = false
})
}
//()
const saveDataNew = () => {
let params: any = {
jsondata:JSON.stringify(state.value.formData),
data: objToStringify(state.value.formData),
source: state.value.formOtherData.source, //
name: state.value.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.value.formDict)
}
let apiKey = 'designSave'
if (route.id) {
// id
Object.assign(params, { id: route.id })
apiKey = 'designEdit'
}
//
if (state.value.designType === 'search') {
params = {
data: objToStringify(state.value.formData),
dict: json2string(state.value.formDict),
id: route.id
}
}
state.value.loading = true
saveProductionForm(params)
.then((res: any) => {
console.log("数据保存", res)
if(res.code == 0){
emits('judgeFormIsEdit', false)
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
emits('update:formKey', res.data.customerFormCont.id)
emits('update:formVersion', res.data.formVersion.id.toString())
versionId.value = res.data.formVersion.id.toString()
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
//
store.setActiveKey('')
store.setControlAttr({})
getInitData()
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.value.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.value.loading = false
})
}
//
const editSaveData = () =>{
let params: any = {
jsondata:JSON.stringify(state.value.formData),
data: objToStringify(state.value.formData),
source: state.value.formOtherData.source, //
name: state.value.formOtherData.formName, //
type: 1, // 1 2
dict: json2string(state.value.formDict),
id:formKeyVal.value.toString(),
version:versionId.value.toString(),
}
state.value.loading = true
editCustomerFormInfo(params)
.then((res: any) => {
if(res.code == 0){
emits('judgeFormIsEdit', false)
ElMessage({
message: res.message || '保存成功!',
type: 'success'
})
// emits("handlequery");
// emits("update:draweropenclose", false);
emits("runNextWindows",2);
//
store.setActiveKey('')
store.setControlAttr({})
}else{
ElMessage({
message: res.msg || '保存失败!',
type: 'error'
})
}
})
.finally(() => {
state.value.loading=false;
})
.catch((res: any) => {
ElMessage.error(res.message || '保存异常')
state.value.loading = false
})
}
//
const openAceEditDrawer = (params: any) => {
const { type, direction, codeType, title, callback, content } = params
drawer.direction = direction // ltr/rtl
drawer.type = type // type
drawer.codeType = codeType || '' //
drawer.title = title ? `提示:${title}` : ''
drawer.visible = true
drawer.callback = callback
let editData =codeType === 'json'? json2string(content, true): objToStringify(content, true)
switch (type) {
case 'css':
editData = state.value.formData.config?.style || ''
break
case 'dict':
//
editData = json2string(state.value.formDict, true)
break
case 'beforeRequest':
case 'beforeSubmit':
case 'afterResponse':
case 'afterSubmit':
case 'change':
// eslint-disable-next-line no-case-declarations
const beforeData = state.value.formData.events || {}
if (beforeData[type]) {
editData = objToStringify(beforeData[type], true)
} else {
if (['afterResponse', 'afterSubmit'].includes(type)) {
editData = afterResponse
} else if (type === 'change') {
editData = onChange
} else {
editData = beforeRequest
}
}
break
// case 'afterResponse':
// case 'afterSubmit':
// const newData = state.formData.events || {}
// if (newData[type]) {
// editData = objToStringify(newData[type], true)
// } else {
// editData = afterResponse
// }
// break
case 'optionsParams':
if (!content) {
editData = beforeRequest
}
break
case 'optionsResult':
if (!content) {
editData = afterResponse
}
break
}
drawer.content = editData
}
//
const dialogCancel = () => {
drawer.visible = false
drawer.type = ''
drawer.title = ''
drawer.codeType = ''
drawer.callback = ''
drawer.content = ''
}
//
const dialogConfirm = (editVal: string) => {
// jsonstate.formData
try {
if (typeof drawer.callback === 'function') {
// callback
const newObj =
drawer.codeType === 'json'? string2json(editVal): stringToObj(editVal)
drawer.callback(newObj)
} else {
switch (drawer.type) {
case 'css':
//
if (!state.value.formData.config) {
state.value.formData.config = {}
}
state.value.formData.config.style = editVal
break
case 'dict':
state.value.formDict = string2json(editVal)
break
case 'beforeRequest':
case 'beforeSubmit':
case 'afterResponse':
case 'afterSubmit':
case 'closeSubmit':
case 'change':
if (!state.value.formData.events) {
state.value.formData.events = {}
}
state.value.formData.events[drawer.type] = stringToObj(editVal)
break
default:
state.value.formData = stringToObj(editVal)
}
}
dialogCancel()
} catch (res) {
// console.log(res.message)
//ElMessage.error(res.message)
}
}
//
const previewForm = ref()
const previewSubmit = () => {
previewForm.value.validate((valid: boolean, fields: any) => {
if (valid) {
// alert('')
ElMessage.success('校验通过')
// console.log(fields)
} else {
// alert('')
// console.log('error submit!', fields)
ElMessage.error('校验不通过')
return false
}
})
}
/**
@ 作者: 秦东
@ 时间: 2024-03-11 15:12:03
@ 功能: 获取表单内容
*/
const getInitData = () => {
if (formKeyVal.value) {
state.value.loading = true
getOneProductionForm({id: formKeyVal.value.toString()})
.then((res:any) => {
if(res.code == 0){
const result = res.data
// res.data=''
if (result.mastesform) {
state.value.formData = stringToObj(result.mastesform)
}
console.log("初始设计搜索时",state.value.formData)
if(result.mastesformjson){
let kjdkjksd = string2json(result.mastesformjson)
console.log("初始设计搜索时-begin-->",state.value.formData.purview)
state.value.formData.purview=kjdkjksd.purview
console.log("初始设计搜索时--->",kjdkjksd)
}
console.log("初始设计搜索时--end->",state.value.formData)
state.value.formDict = string2json(result.dict)
//
state.value.formOtherData.source = result.source
state.value.formOtherData.formName = result.name
state.value.formOtherData.formName = result.name
state.value.formData.form.name = result.tablekey
state.value.formData.form.formName = result.name
if (result.source && state.value.designType !== 'search') {
//
formControlAttrEl.value.getFormFieldBySource(result.source)
}
emits('judgeFormIsEdit', false)
}else{
ElMessage.error(res.msg || '加载异常')
}
state.value.loading = false
})
.finally(()=>{
haveCustomerFormVersion({id:state.value.formData.form.name})
.then(({data})=>{
versionCont.value = data
if(data.length > 0){
data.forEach((item:any) => {
if(item.status == 1){
versionId.value = item.id.toString()
emits('update:formVersion', item.id.toString())
}
});
}
})
})
.catch((res: any) => {
// console.log(res)
ElMessage.error(res.msg || '加载异常')
state.value.loading = false
})
}
}
onMounted(() => {
if (route.source) {
formControlAttrEl.value.getFormFieldBySource(route.source)
}
getInitData()
})
//
// watch(() =>versionId.value ,(val:string)=>{
// emits('update:formVersion', val)
// })
</script>
<template>
<div class="design_container">
<DragControl
v-model:versionid="versionId"
:formid="state.formOtherData.source"
:versioncont="versionCont"
@click-check="searchCheckField"
@click="selectTemplate"
@editversionstaus="editversionstaus"
/>
<div class="main-body">
<HeadTools v-loading="state.loading" :customerformid="formKeyVal" @click="headToolClick" />
<div v-loading="state.loading" class="main-form">
<div v-if="state.formData.list.length === 0" class="empty-tips">
从左侧拖拽来添加组件
</div>
<FormDesign
:type="5"
:form-data="state.formData"
:dict="state.formDict"
/>
</div>
</div>
<form-control-attr
ref="formControlAttrEl"
v-model:formOtherData="state.formOtherData"
:form-data="state.formData.form"
:form-config="state.formData.config"
:customerformid="formKeyVal"
:form-list="state.formData.list"
:form-info="state.formData"
@open-dialog="openAceEditDrawer"
/>
<ace-drawer
v-model="drawer.visible"
:title="drawer.title"
:direction="drawer.direction"
:content="drawer.content"
:code-type="drawer.codeType"
@before-close="dialogCancel"
@confirm="dialogConfirm"
/>
<vue-file v-if="!['search'].includes(state.designType)" ref="vueFileEl" />
<el-drawer
v-model="state.previewVisible"
title="预览"
:append-to-body="true"
size="50%"
>
<form-design
v-if="state.previewVisible"
ref="previewForm"
:form-data="state.formDataPreview"
:dict="state.formDict"
:type="1"
/>
<template #footer>
<div class="dialog-footer">
<el-button size="small" type="primary" @click="previewSubmit">
提交
</el-button>
<el-button size="small" @click="state.previewVisible = false">
取消
</el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<style lang='scss' scoped>
.design_container{
display: flex;
background-color: #FFFFFF;
}
</style>

635
src/views/sysworkflow/lowcodepage/workFlow.vue

@ -0,0 +1,635 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-11 14:46:00
@ 备注: 工作流
-->
<script lang='ts' setup>
import '@/styles/workflowcss/workflow.scss'
import { useStore } from '@/store/workflow/index'
import { flowversion } from '@/api/workflowapi/types'
import { initializeWorkFlow,setWorkFlowData,gainFlowVersionList,saveFlowCont,gainFlowInfo,editFlowCont,saveNewFlow,switchFlowVersion,judgeFormFlowIsOpen,openFormFlow } from '@/api/workflowapi/index'
import FlowImgSrc from '@/assets/images/3.png'
const props = defineProps({
formKey:{
type:String,
default:""
},
formVersion:{
type:String,
default:""
},
state:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits<{
(e: 'update:state', val: formStruct): void
(e: 'update:formKey', val: string): void
(e: 'update:formVersion', val: string): void
(e: 'judgeFlowIsEdit', val: boolean): void
(e: 'runNextWindows', val: number): void
(e: 'closeFormPage'): void
}>()
const state = computed({
get() {
return props.state
},
set(val: formStruct) {
emits('update:state', val)
}
});
const formKeyVal = computed({
get() {
return props.formKey
},
set(val: formStruct) {
emits('update:formKey', val)
}
});
let { setTableId, setIsTried } = useStore()
const flowIsTrue = ref(false)
const isRead = ref(false) //
const openOfClise = ref(false) //
const versionList = reactive<flowversion[]>([]); //
const enableVersion = ref<string>("1"); //
const enableFlow = ref<any>();
const activeTabs = ref<string>(""); //
const isFormFlow = ref(true); //
const closeOrOpenVersion = ref(false); //
let nowVal = ref(100); //
let nodeConfig = ref<any>({}); //
let flowPermission = ref([]); //
let processConfig = ref<any>({}); //
let directorMaxLeveling = ref<number>(0); //
let workFlowDef = ref({}); //
let tipList = ref<any>([]); //
let tipVisible = ref(false);
let oneIsTrue = true;
/**
@ 作者: 秦东
@ 时间: 2024-03-11 16:33:49
@ 功能: 开启流程
*/
const createFormFlow = () =>{
if(formKeyVal.value == ""){
flowIsTrue.value = false;
ElMessageBox.alert('您还未设置表单!请先设置完表单后,在创建流程!','温馨提示!',{
confirmButtonText: '确定',
callback: (action: Action) => {
emits("runNextWindows",1);
},
})
}else{
openOrCloseFormFlow(1)
getFlowVerList()
flowIsTrue.value = true
emits('judgeFlowIsEdit', true)
}
emits('judgeFlowIsEdit', true)
// flowIsTrue.value = true
}
const openOrCloseFormFlow = (val:number) => {
openFormFlow({id:formKeyVal.value.toString(),status:val})
}
//
const initWorkFlowData = async() => {
let { data } = await initializeWorkFlow({name:state.value.formData.form.formName})
// console.log("data-=------>",data)
processConfig.value = data;
let {
nodeConfig:nodes,
flowPermission:flowPermissiones,
directorMaxLevel:levels,
workFlowDef:workName,
tableId,
} = data;
processConfig.value.workFlowDef.formKey = formKeyVal.value
nodeConfig.value = nodes;
flowPermission.value = flowPermissiones;
directorMaxLeveling = levels;
workFlowDef.value = workName;
setTableId(tableId);
// console.log("max--1->",data)
// console.log("max--6->",tableId)
// console.log("max--2->",flowPermission)
// console.log("max--3->",nodeConfig)
// console.log("max--4->",directorMaxLevel)
// console.log("max--5->",processConfig)
}
//
const zoomSize = (type:number) => {
if (type == 1) {
if (nowVal.value == 50) {
return;
}
nowVal.value -= 10;
} else {
if (nowVal.value == 300) {
return;
}
nowVal.value += 10;
}
};
//
const getFlowVerList = ()=>{
gainFlowVersionList({id:formKeyVal.value.toString()})
.then(({data})=>{
console.log("获取工作流版本列表-->",data)
// versionList = data;
versionList.splice(0,versionList.length)
if(data){
if(data.length>0){
data.forEach((item:any)=>{
if(item.state == 1){
activeTabs.value = item.id
enableFlow.value = item
enableVersion.value = item.id
}
versionList.push({
id:item.id,
key:item.key,
state:item.state,
version:item.version
})
})
if(versionList.length > 1){
closeOrOpenVersion.value = true
}else{
closeOrOpenVersion.value = false
}
// console.log("--1-1-->",enableFlow.value);
if(enableFlow.value == "" || enableFlow.value == undefined){
enableFlow.value = versionList[0]
// activeTabs.value = versionList[0].id
enableVersion.value = versionList[0].id
}
isRead.value = true
}else{
isRead.value = false
}
}
// console.log("---1-->",activeTabs.value);
// console.log("---2-->",enableFlow.value);
// console.log("---3-->",enableVersion.value);
// console.log("---3-1->",versionList[0],versionList);
})
.finally(()=>{
if(isRead.value == true){
gainFlowCont();
}else{
clearCanvas(1);
}
clickOpenOrClose();
})
}
//
const clickOpenOrClose = () => {
console.log("判断当前工作流版本是否启用",enableFlow,activeTabs.value)
if(enableFlow.value.id==activeTabs.value){
openOfClise.value = true
}else{
openOfClise.value = false
}
// console.log("openOfClise",openOfClise.value)
// console.log("enableFlow.version=1=activeTabs",enableFlow.value,activeTabs.value)
}
//
const gainFlowCont = () =>{
gainFlowInfo({id:enableVersion.value.toString()})
.then((data:any)=>{
// console.log("-1->",data,enableFlow.value)
if(data.code == 0){
processConfig.value = data.data;
processConfig.value.workFlowDef.formKey = formKeyVal.value
nodeConfig.value = data.data.nodeConfig;
flowPermission.value = data.data.flowPermission;
directorMaxLeveling = data.data.directorMaxLevel;
workFlowDef.value = data.data.workFlowDef;
setTableId(data.data.tableId);
flowIsTrue.value = true;
// console.log("max--1->",data)
// console.log("max--6->",data.data.tableId)
// console.log("max--2->",data.data.flowPermission)
// console.log("max--3->",nodeConfig)
// console.log("max--4->",data.data.directorMaxLevel)
// console.log("max--5->",processConfig.value)
}else{
clearCanvas(1);
}
// initWorkFlowData();
})
}
//
const clearCanvas = (isOk?:any) =>{
if(isOk==1){
initWorkFlowData()
setIsTried(false);
tipList.value = []
}else{
ElMessageBox.confirm('确定要清空画布?')
.then(() => {
initWorkFlowData()
setIsTried(false);
tipList.value = []
})
}
enableFlow.value = ""
}
//
const reErr = ({ childNode }:any) => {
if (childNode) {
let { type, error, nodeName, conditionNodes } = childNode;
if (type == 1 || type == 2 || type == 3) {
if (error) {
tipList.value.push({
name: nodeName,
type: ["", "审核人", "抄送人", "执行人"][type],
});
}
reErr(childNode);
} else if (type == 4) {
reErr(childNode);
} else if (type == 5) {
reErr(childNode);
for (var i = 0; i < conditionNodes.length; i++) {
if (conditionNodes[i].error) {
tipList.value.push({ name: conditionNodes[i].nodeName, type: "条件" });
}
reErr(conditionNodes[i]);
}
}
} else {
childNode = null;
}
};
//
const clickFormTable = (val:any) =>{
console.log("切换表单",val,activeTabs.value)
enableVersion.value = val
gainFlowCont();
clickOpenOrClose();
// getTableFieldList(versionIndex.value,val)
}
//
const setupState = (val:number) =>{
let sendCont = {
id:enableVersion.value.toString(),
status:val
}
if(val == 1){
activeTabs.value = enableVersion.value
}
switchFlowVersion(sendCont)
.then((data:any)=>{
ElMessage.success(data.msg);
// activeTabs.value = enableVersion.value
// enableFlow.value.id = enableVersion.value
if(versionList.length > 0){
versionList.forEach(item=>{
if(item.id == enableVersion.value){
enableFlow.value = item
}
})
}
})
.finally(()=>{
clickOpenOrClose();
})
// console.log("enableFlow.version==activeTabs",enableFlow.version,activeTabs)
}
//
const saveSet = async () => {
setIsTried(true);
tipList.value = [];
reErr(nodeConfig.value);
if (tipList.value.length != 0) {
tipVisible.value = true;
return;
}
processConfig.value.flowPermission = flowPermission.value;
// eslint-disable-next-line no-console
console.log("processConfig",processConfig.value);
console.log("flowPermission",flowPermission.value);
console.log("nodeConfig",nodeConfig.value);
saveFlowCont(processConfig.value)
.then((data:any) => {
if(data.code == 0){
ElMessage.success("设置成功");
emits('judgeFlowIsEdit', false)
emits("runNextWindows",3);
// clearCanvas(1);
}
})
.finally(()=>{
// emits("chanerequest");
getFlowVerList()
})
// let res = await setWorkFlowData(processConfig.value);
// if (res.code == 200) {
// ElMessage.success("")
// setTimeout(function () {
// window.location.href = "";
// }, 200);
// }
};
//
const saveEdit =()=>{
setIsTried(true);
tipList.value = [];
reErr(nodeConfig.value);
if (tipList.value.length != 0) {
tipVisible.value = true;
return;
}
processConfig.value.flowPermission = flowPermission.value;
// eslint-disable-next-line no-console
console.log("processConfig",flowPermission);
// console.log("flowPermission",flowPermission.value);
console.log("activeTabs",enableFlow.value);
let sendCont = {
id:enableVersion.value.toString(),
flowinfo:processConfig.value
}
editFlowCont(sendCont)
.then((data:any) => {
if(data.code == 0){
ElMessage.success("设置成功");
// emits("update:openDrawer", false);
// clearCanvas(1);
emits('judgeFlowIsEdit', false)
emits("runNextWindows",3);
}
})
.finally(()=>{
// emits("chanerequest");
getFlowVerList()
})
}
//
const saveNew = () => {
setIsTried(true);
tipList.value = [];
reErr(nodeConfig.value);
if (tipList.value.length != 0) {
tipVisible.value = true;
return;
}
processConfig.value.flowPermission = flowPermission.value;
// eslint-disable-next-line no-console
// console.log("processConfig",flowPermission);
// console.log("flowPermission",flowPermission.value);
// console.log("activeTabs",enableFlow.value);
let sendCont = {
id:enableVersion.value.toString(),
flowinfo:processConfig.value
}
saveNewFlow(sendCont)
.then((data:any) => {
if(data.code == 0){
ElMessage.success("设置成功");
emits('judgeFlowIsEdit', false)
emits("runNextWindows",3);
}
})
.finally(()=>{
getFlowVerList()
})
}
watch(()=>nodeConfig,()=>{
console.log("变动流程")
if(oneIsTrue){
oneIsTrue = false;
emits('judgeFlowIsEdit', false)
}else{
emits('judgeFlowIsEdit', true)
}
},
{
deep: true
})
/**
@ 作者: 秦东
@ 时间: 2024-03-12 15:49:35
@ 功能: 关闭表单流程
*/
const closwFormFlow = () => {
flowIsTrue.value = false;
emits('judgeFlowIsEdit', false)
openOrCloseFormFlow(2)
}
onMounted(()=>{
console.log("判断是否已经存在工作流以及是否开启",formKeyVal.value)
if(formKeyVal.value == ""){
flowIsTrue.value = false;
}else{
judgeFormFlowIsOpen({id:formKeyVal.value.toString()})
.then((data)=>{
console.log("判断是否已经存在工作流以及是否开启",data)
if(data.data.isOpen == 1){
flowIsTrue.value = true;
emits('judgeFlowIsEdit', false)
getFlowVerList()
}else{
flowIsTrue.value = false;
emits('judgeFlowIsEdit', false)
}
})
}
})
</script>
<template>
<div class="design_flow_work">
<el-row v-if="flowIsTrue" style="height: 100%;">
<el-col :span="24">
<table class="table_box">
<tr>
<td class="table_td_title"><el-text v-if="isRead">版本</el-text></td>
<td class="table_td_info">
<div class="tabs_box">
<el-tabs v-if="isRead" v-model="activeTabs" @tab-change="clickFormTable">
<el-tab-pane v-for="item in versionList" :key="item.id" :name="item.id">
<template #label>
<el-icon><Share /></el-icon>
<span class="my-label">V{{item.version}}</span>
</template>
</el-tab-pane>
</el-tabs>
</div>
<div class="but_box">
<el-button v-if="isRead && !openOfClise && closeOrOpenVersion" type="success" size="small" plain @click="setupState(1)">
<el-icon class="el-icon--left"><Delete /></el-icon>
启用
</el-button>
<el-button v-if="isRead && openOfClise && closeOrOpenVersion" type="warning" size="small" plain @click="setupState(2)">
<el-icon class="el-icon--left"><Delete /></el-icon>
禁用
</el-button>
<el-button size="small" plain @click="clearCanvas">
<el-icon class="el-icon--left"><Delete /></el-icon>
清空
</el-button>
<el-button v-if="!isRead" size="small" plain @click="saveSet">
<el-icon class="el-icon--left"><Promotion /></el-icon>
发布
</el-button>
<el-button v-if="isRead" size="small" plain @click="saveEdit">
<el-icon class="fa fa-save" style="margin-right:5px"></el-icon>
保存
</el-button>
<el-button v-if="isRead" type="warning" size="small" @click="saveNew">
<el-icon class="el-icon--left"><Share /></el-icon>
另存为新版
</el-button>
<el-button type="danger" size="small" @click="closwFormFlow">
<el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
关闭流程
</el-button>
</div>
</td>
</tr>
</table>
</el-col>
<el-col :span="24">
<section class="dingflow-design" style="top:40px">
<div class="zoom">
<div class="zoom-out" :class="nowVal == 50 && 'disabled'" @click="zoomSize(1)"></div>
<span>{{ nowVal }}%</span>
<div class="zoom-in" :class="nowVal == 300 && 'disabled'" @click="zoomSize(2)"></div>
</div>
<div class="box-scale" :style="`transform: scale(${ nowVal / 100});`">
<nodeWrap v-model:nodeConfig="nodeConfig" v-model:flowPermission="flowPermission" />
<div class="end-node">
<div class="end-node-circle"></div>
<div class="end-node-text">流程结束</div>
</div>
</div>
</section>
<errorDialog v-model:visible="tipVisible" :list="tipList" />
<promoterDrawer v-model:form-data="state.formData" :form-key="formKeyVal" :form-version="formVersion" />
<approverDrawer :directormaxlevel="directorMaxLeveling" :node-config="nodeConfig" :is-form-flow="isFormFlow" :customer-form-key="formKeyVal" v-model:form-data="state.formData" :form-version="formVersion" />
<copyerDrawer />
<conditionDrawer :is-form-flow="isFormFlow" :customer-form-key="formKeyVal" />
</el-col>
</el-row>
<div v-else class="flow_work_begin">
<el-result title="" sub-title="">
<template #icon>
流程可实现需要多人流转的业务场景<br>绘制流程图设定数据流转方式即可搭建线上工作流<br><br>
<el-image
:src="FlowImgSrc"
/>
</template>
<template #extra>
<el-button type="primary" @click="createFormFlow">开启流程</el-button>
</template>
</el-result>
</div>
</div>
</template>
<style lang='scss' scoped>
.design_flow_work{
height: calc(100vh - 40px);
width: inherit;
overflow: hidden;
overflow-y: auto;
}
.flow_work_begin{
height: calc(100vh - 40px);
display: flex;
align-items: center;
justify-content: center;
}
/* 去掉tabs标签栏下的下划线 */
::v-deep .el-tabs__nav-wrap::after {
position: static !important;
/* background-color: #fff; */
}
::v-deep .el-tabs__item{
padding:0 10px;
}
.version_but{
display: flex;
align-items: center;
justify-content: space-between;
}
.tabs_box{
max-width: 60%;
min-width:30%
}
.but_box{
max-width: 50%;
min-width: 40%;
overflow: hidden;
overflow-x: auto;
padding:5px 10px 5px 0;
text-align: right;
}
.table_box{
width: 100%;
}
.table_td_title{
width: 60px;
text-align: right;
align-items: center;
vertical-align: middle;
}
.table_td_info{
display: flex;
// width: calc(100% - 100px);
align-items: center;
justify-content: space-between;
}
</style>
<style>
.canvas_body{
height: 100%;
width: inherit;
}
.flow_version{
}
.flow_version > .el-tabs__content{
padding: 0px;
height:0px;
}
.flow_version > .el-tabs__header{
margin:0px;
}
.flow_version .custom-tabs-label span {
padding:0 10px;
}
.right_kongx{
margin-right:50px
}
</style>

160
vite.config.ts.timestamp-1709682894861-ae70bc75df1f3.mjs

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save