数通智联化工云平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

744 lines
20 KiB

<!--
@ 作者: 秦东
@ 时间: 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) => {
// 生成脚本预览和导入json,都是将编辑器内容更新至state.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) {
// 带有问号参数时,放在path传是有问题的,将id=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>