Browse Source

改版自定义表单

yjf_v3
超级管理员 2 years ago
parent
commit
7b08aa6ffa
  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. BIN
      src/assets/images/3.png
  8. 948
      src/assets/scss/form.css
  9. 1
      src/assets/scss/form.min.css
  10. 6
      src/assets/scss/form.scss
  11. 5
      src/components/DesignForm/formControlAttr.vue
  12. 2
      src/components/DesignForm/layoutPage/index.vue
  13. 1
      src/components/DesignForm/public/form/form.vue
  14. 10
      src/types/components.d.ts
  15. 60
      src/utils/lowCodeForm/index.ts
  16. 32
      src/views/sysworkflow/codepage/createform.vue
  17. 88
      src/views/sysworkflow/lowcodepage/group.vue
  18. 91
      src/views/sysworkflow/lowcodepage/index.vue
  19. 223
      src/views/sysworkflow/lowcodepage/lowCodeFormGroupPage.vue
  20. 186
      src/views/sysworkflow/lowcodepage/lowCodeFormPage.vue
  21. 743
      src/views/sysworkflow/lowcodepage/pageDesign.vue
  22. 598
      src/views/sysworkflow/lowcodepage/pageDesignes.vue
  23. 88
      src/views/sysworkflow/lowcodepage/workFlow.vue
  24. 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;
}

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;}
}

5
src/components/DesignForm/formControlAttr.vue

@ -2318,14 +2318,17 @@
<!-- 轮播图设置弹窗 liwenxuan 20240122 end -->
</template>
<style>
<style lang='scss' scoped>
.form_cont{
padding: 0 10px;
}
</style>
<style >
.sidebar-tools .el-tabs__content{
padding: 0;
}
.el-collapse-item__header {
padding-left: 10px;

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

@ -104,7 +104,7 @@
</script>
<template>
<div class="jhk_kjh">
<!-- 当前组件类别======>{{props.place}} -->
当前组件类别======>{{props.place}}
<el-collapse v-model="activeName" accordion>
<el-collapse-item title="边框设置" name="1">

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) {

10
src/types/components.d.ts

@ -21,11 +21,13 @@ declare module '@vue/runtime-core' {
DesignLayoutPage: typeof import('./../components/DesignForm/designLayout/designLayoutPage.vue')['default']
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']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
ElCard: typeof import('element-plus/es')['ElCard']
ElCarousel: typeof import('element-plus/es')['ElCarousel']
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
@ -53,18 +55,22 @@ declare module '@vue/runtime-core' {
ElImageViewer: typeof import('element-plus/es')['ElImageViewer']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElProgress: typeof import('element-plus/es')['ElProgress']
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']
ElSelectV2: typeof import('element-plus/es')['ElSelectV2']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
@ -99,15 +105,19 @@ declare module '@vue/runtime-core' {
HeadToolsNew: typeof import('./../components/DesignForm/public/headToolsNew.vue')['default']
IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
IEpCaretTop: typeof import('~icons/ep/caret-top')['default']
IEpClose: typeof import('~icons/ep/close')['default']
IEpDelete: typeof import('~icons/ep/delete')['default']
IEpEdit: typeof import('~icons/ep/edit')['default']
IEpMessageBox: typeof import('~icons/ep/message-box')['default']
IEpOperation: typeof import('~icons/ep/operation')['default']
IEpPicture: typeof import('~icons/ep/picture')['default']
IEpPlus: typeof import('~icons/ep/plus')['default']
IEpRefresh: typeof import('~icons/ep/refresh')['default']
IEpSearch: typeof import('~icons/ep/search')['default']
IEpSetting: typeof import('~icons/ep/setting')['default']
IEpUser: typeof import('~icons/ep/user')['default']
IEpView: typeof import('~icons/ep/view')['default']
LangSelect: typeof import('./../components/LangSelect/index.vue')['default']
LayoutPage: typeof import('./../components/DesignForm/layoutPage/index.vue')['default']
List: typeof import('./../components/DesignForm/public/form/components/list.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>

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

@ -0,0 +1,91 @@
<!--
@ 作者: 秦东
@ 时间: 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" :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>

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

@ -0,0 +1,186 @@
<!--
@ 作者: 秦东
@ 时间: 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 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:{}
}
},
editor: {},
loading: false,
formDataPreview: {},
previewVisible: false, //
designType: route.type, // search
formDict: {},
formOtherData: {
source: route.source || '',
formName: formConfigCont.formName
}
})
const judgeFormIsEdit = (val:boolean) => {
pageDesignIsWrite.value = val;
}
const handleClick = (tab: TabsPaneContext, event: Event) =>{
console.log(tabsActive.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){
PreOperation()
}
break;
case 4:
if (creetTabsActive.value != 4){
PreOperation()
}
break;
default:
break;
}
}
/**
@ 作者: 秦东
@ 时间: 2024-03-09 13:42:24
@ 功能: 判断tabs要执行得前置操作
*/
const PreOperation = () =>{
switch (creetTabsActive.value) {
case 2:
break;
case 3:
break;
case 4:
break;
default:
// if(pageDesignIsWrite.value){
// ElMessageBox.alert('', '', {
// confirmButtonText: 'OK',
// callback: (action: Action) => {
// tabsActive.value = 1
// }
// });
// }else{
// creetTabsActive.value = tabsActive.value
// }
return true;
break;
}
}
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
}
</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">
<PageDesignEs v-model:state="state" :form-key="props.formKey" :formconfigcont="formConfigCont" @judgeFormIsEdit="judgeFormIsEdit" @runNextWindows="runNextWindows" @closeFormPage="closeFormPage" />
</el-tab-pane>
<el-tab-pane label="流程设计" :name="2">
<WorkFlow v-model:state="state" :form-key="props.formKey" @judgeFormIsEdit="judgeFormIsEdit" @runNextWindows="runNextWindows" @closeFormPage="closeFormPage" />
</el-tab-pane>
<el-tab-pane label="列表设计" :name="3"></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>

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

@ -0,0 +1,598 @@
<!--
@ 作者: 秦东
@ 时间: 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:""
},
formconfigcont:{
type:Object,
default(){
return {}
}
},
state:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits<{
(e: 'update:state', val: formStruct): 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)
}
});
//
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()
}
});
}
})
})
}
/**
@ 作者: 秦东
@ 时间: 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(props.formKey != ""){
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);
//
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 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("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 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:props.formKey.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 (props.formKey) {
state.value.loading = true
getOneProductionForm({id: props.formKey.toString()})
.then((res:any) => {
if(res.code == 0){
const result = res.data
// res.data=''
if (result.mastesform) {
state.value.formData = stringToObj(result.mastesform)
}
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)
}
}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()
}
});
}
})
})
.catch((res: any) => {
// console.log(res)
ElMessage.error(res.msg || '加载异常')
state.value.loading = false
})
}
}
onMounted(() => {
if (route.source) {
formControlAttrEl.value.getFormFieldBySource(route.source)
}
getInitData()
})
</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
: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="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>

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

@ -0,0 +1,88 @@
<!--
@ 作者: 秦东
@ 时间: 2024-03-11 14:46:00
@ 备注: 工作流
-->
<script lang='ts' setup>
import { useStore } from '@/store/workflow/index'
import { flowversion } from '@/api/workflowapi/types'
import { initializeWorkFlow,setWorkFlowData,gainFlowVersionList,saveFlowCont,gainFlowInfo,editFlowCont,saveNewFlow,switchFlowVersion } from '@/api/workflowapi/index'
import FlowImgSrc from '@/assets/images/3.png'
const props = defineProps({
formKey:{
type:String,
default:""
},
state:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits<{
(e: 'update:state', val: formStruct): 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 flowIsTrue = ref(false)
/**
@ 作者: 秦东
@ 时间: 2024-03-11 16:33:49
@ 功能: 开启流程
*/
const createFormFlow = () =>{
flowIsTrue.value = true
}
</script>
<template>
<div class="design_flow_work">
<el-row v-if="flowIsTrue" >
<el-col :span="24">1</el-col>
<el-col :span="24">2</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;
}
</style>

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

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