Browse Source

自定义表单列表

v1
超级管理员 2 years ago
parent
commit
6e6edd9ad7
  1. 4
      index.html
  2. 31
      src/api/DesignForm/requestapi.ts
  3. 23
      src/api/DesignForm/type.ts
  4. 3
      src/api/DesignForm/types.ts
  5. 2117
      src/components/DesignForm/formControlAttr.vue
  6. 1576
      src/components/DesignForm/formControlAttres.vue
  7. 16
      src/components/DesignForm/public/form/form.vue
  8. 2
      src/components/DesignForm/public/form/formGroup.vue
  9. 8
      src/components/DesignForm/public/headTools.vue
  10. 1
      src/utils/DesignForm/form.ts
  11. 562
      src/views/sysworkflow/codepage/createform.vue
  12. 572
      src/views/sysworkflow/codepage/index.vue

4
index.html

@ -15,8 +15,8 @@
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
<script type="module" src="/docs/static/plugins/ace/ace.js"></script> <script type="module" src="/docs/static/plugins/ace/ace.js"></script>
<script type="module" src="/docs/static/plugins/ace/ext-language_tools.js"></script> <script type="module" src="/docs/static/plugins/ace/ext-language_tools.js"></script>
<script src="/docs/static/plugins/tinymce/tinymce.min.js?v=6.1.2"></script> <script type="module" src="/docs/static/plugins/tinymce/tinymce.min.js?v=6.1.2"></script>
<script src="/docs/static/plugins/echarts.min.js"></script> <script type="module" src="/docs/static/plugins/echarts.min.js"></script>
</body> </body>
</html> </html>

31
src/api/DesignForm/requestapi.ts

@ -0,0 +1,31 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import {
customerFormCont,
CustomerFormPageResult,
SearchForm,
customerFormConfig
} from './type';
//自定义表单列表
export function getCustomerFormList(queryParams: SearchForm): AxiosPromise<CustomerFormPageResult> {
return request({
url: '/systemapi/customer_form/customer_form_list',
method: 'post',
params: queryParams
});
}
//生成表单基本信息
export function getProductionMarkForm(): AxiosPromise<customerFormConfig> {
return request({
url: '/systemapi/customer_form/production_mark_form',
method: 'post',
});
}
export function saveProductionForm(data: any) {
return request({
url: '/systemapi/customer_form/save_customer_form',
method: 'post',
data: data
});
}

23
src/api/DesignForm/type.ts

@ -0,0 +1,23 @@
//搜索表单
export interface SearchForm extends PageQuery{
keywords?: string;
classify?:number;
}
//自定义表单列表内容
export interface customerFormCont{
id:string;
name:string;
tablename:string;
states:number;
classify:number;
creatername:string;
creatertime:string;
}
export type CustomerFormPageResult = PageResult<customerFormCont[]>;
//初始化表单基本信息
export interface customerFormConfig{
formname:string;
formlogo:string;
}

3
src/api/DesignForm/types.ts

@ -92,7 +92,8 @@ export interface formData{
list: any[]; list: any[];
form: { form: {
size: any; size: any;
name:any name:any,
formName:any
}; };
config: any; config: any;
events?:any events?:any

2117
src/components/DesignForm/formControlAttr.vue

File diff suppressed because it is too large

1576
src/components/DesignForm/formControlAttres.vue

File diff suppressed because it is too large

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

@ -53,14 +53,18 @@ const props = withDefaults(
dict: () => { dict: () => {
return {} return {}
}, },
isSearch: false isSearch: false,
issave:{
type:Boolean,
default:true
},
} }
) )
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'btnClick', type: string): void (e: 'btnClick', type: string): void
(e: 'change', val: any): void // (e: 'change', val: any): void //
(e: 'update:issave', type: boolean): void
}>() }>()
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
@ -93,6 +97,14 @@ const setWindowEvent = (bool?: boolean) => {
} }
} }
} }
watch(
() => props.formData,
() => {
console.log("监听数据----->1",props.formData)
emits('update:issave', false)
},
{ deep: true }
)
watch( watch(
() => props.formData.config, () => props.formData.config,
() => { () => {

2
src/components/DesignForm/public/form/formGroup.vue

@ -423,7 +423,7 @@ const dataList = ref<any>(props.data)
</div> </div>
<div class="drag-move icon-move"></div> <div class="drag-move icon-move"></div>
</div> </div>
<div class="tooltip">{{ element.name }}</div> <div class="tooltip" style="display: none;">{{ element.name }}</div>
</template> </template>

8
src/components/DesignForm/public/headTools.vue

@ -31,8 +31,9 @@ const btnList = computed(() => {
{ icon: 'del', label: '清空', key: 1 }, { icon: 'del', label: '清空', key: 1 },
{ icon: 'eye', label: '预览', key: 2 }, { icon: 'eye', label: '预览', key: 2 },
{ icon: 'json', label: '生成脚本预览', key: 3 }, { icon: 'json', label: '生成脚本预览', key: 3 },
{ icon: 'vue', label: '导出vue文件', key: 4 }, // { icon: 'vue', label: 'vue', key: 4 },
{ icon: 'save', label: '保存', key: 5 } { icon: 'save', label: '保存', key: 5 },
{ icon: 'close', label: '关闭', key: 6 }
] ]
if (props.showKey?.length) { if (props.showKey?.length) {
// key // key
@ -54,10 +55,11 @@ const btnList = computed(() => {
<slot></slot> <slot></slot>
<el-button <el-button
link link
type="primary"
@click="btnClick(item.icon)" @click="btnClick(item.icon)"
v-for="item in btnList" v-for="item in btnList"
:key="item.icon" :key="item.icon"
:type="item.key==6?'danger':item.key==5?'success':'primary'"
> >
<i :class="['icon-' + item.icon]"></i>{{ item.label }} <i :class="['icon-' + item.icon]"></i>{{ item.label }}
</el-button> </el-button>

1
src/utils/DesignForm/form.ts

@ -57,6 +57,7 @@ export function obj2string(o: any) {
} }
export function objToStringify(obj: any, isBeautify?: boolean) { export function objToStringify(obj: any, isBeautify?: boolean) {
// console.log("EDITTYPE--->",EDITTYPE,isBeautify)
if (EDITTYPE === 'javascript') { if (EDITTYPE === 'javascript') {
if (isBeautify) { if (isBeautify) {
return jsBeautify('opt=' + obj2string(obj), { return jsBeautify('opt=' + obj2string(obj), {

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

@ -0,0 +1,562 @@
<!--
@ 作者: 秦东
@ 时间: 2023-05-26 10:35:30
@ 备注:
-->
<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 DragControl from '@/components/DesignForm/dragControl.vue';
import HeadTools from '@/components/DesignForm/public/headTools.vue';
import FormDesign from '@/components/DesignForm/public/form/form.vue'
import FormControlAttr from '@/components/DesignForm/formControlAttr.vue';
import VueFile from '@/components/DesignForm/vueFile.vue'
import AceDrawer from '@/components/DesignForm/aceDrawer.vue'
import { ref, reactive, provide, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { useLayoutStore } from '@/store/DesignForm/layout'
import { FormData,formStruct,DrawerStruct } from '@/api/DesignForm/types'
import { saveProductionForm } from '@/api/DesignForm/requestapi'
const isSave = ref(false)
const props = defineProps({
draweropenclose:{
type:Boolean,
default:true
},
formconfigcont:{
type:Object,
default(){
return {}
}
}
});
const emits = defineEmits(["update:draweropenclose","handlequery"]);
/**
* 弹窗显示控制
*/
const openShow = computed({
get: () => props.draweropenclose,
set: (val) => {
emits("update:draweropenclose", val);
},
});
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: {}
},
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)
const getInitData = () => {
const id = route.id // id
if (id) {
//
state.loading = true
getRequest('designById', { id: id })
.then(res => {
const result = res.data
// res.data=''
if (result.data) {
state.formData = stringToObj(result.data)
}
state.formDict = string2json(result.dict)
//
state.formOtherData.source = result.source
state.formOtherData.formName = result.name
if (result.source && state.designType !== 'search') {
//
formControlAttrEl.value.getFormFieldBySource(result.source)
}
state.loading = false
})
.catch((res: any) => {
// console.log(res)
ElMessage.error(res.message || '加载异常')
state.loading = false
})
}
}
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) //
// 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();
saveDataNew();
break
case 'vue':
vueFileEl.value.open(state.formData)
emits("update:draweropenclose", false);
break
case 'close':
console.log("关闭")
if(isSave.value){
emits("update:draweropenclose", false);
}else{
ElMessageBox.confirm(
'表单已做设计或修改!请问是否保存?',
'温馨提示!',
{
confirmButtonText: '保存',
cancelButtonText: '不保存',
type: 'warning',
draggable: true,
})
.then(() => {
saveDataNew();
})
.catch(() => {
emits("update:draweropenclose", false);
})
}
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 '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)
}
}
//()
const saveDataNew = () => {
isSave.value = true
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);
//
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) &&
state.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)
}
getInitData()
// source
onMounted(() => {
if (route.source) {
formControlAttrEl.value.getFormFieldBySource(route.source)
}
})
onMounted(() => {
console.log("监听数据",route.type,props.formconfigcont.formname,props.formconfigcont.formlogo,state)
state.formOtherData.formName = props.formconfigcont.formname
state.formData.form.name = props.formconfigcont.formlogo
state.formData.form.formName = props.formconfigcont.formname
})
/**
* 监听数据
*/
watch(() => props.draweropenclose,() => {
console.log("监听数据",props.draweropenclose,state)
if(props.draweropenclose){
state.formOtherData.formName = props.formconfigcont.formName
state.formData.form.name = props.formconfigcont.formlogo
state.formData.form.formName = props.formconfigcont.formName
}else{
state.formOtherData.formName = "未命名表单"
state.formData.form.name = props.formconfigcont.formlogo
state.formData.form.formName = "未命名表单"
}
});
</script>
<template>
<div class="design-container">
<DragControl
:formid="state.formOtherData.source"
@click-check="searchCheckField"
@click="selectTemplate"
/>
<div class="main-body">
<HeadTools @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"
@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-dialog v-model="state.previewVisible" title="预览" :fullscreen="true">
<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-dialog>
</div>
</template>
<style lang='scss' scoped>
.design-container{
padding: 0;
}
</style>

572
src/views/sysworkflow/codepage/index.vue

@ -1,423 +1,185 @@
<!-- <!--
@ 作者: 秦东 @ 作者: 秦东
@ 时间: 2023-05-26 10:35:30 @ 时间: 2023-08-28 14:47:07
@ 备注: @ 备注: 表单设计
--> -->
<script lang='ts' setup> <script lang='ts' setup>
import '@/assets/scss/element-var.scss' import { SearchForm,customerFormCont,customerFormConfig } from "@/api/DesignForm/type";
import '@/assets/scss/index.scss' import { getCustomerFormList,getProductionMarkForm } from '@/api/DesignForm/requestapi'
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 DragControl from '@/components/DesignForm/dragControl.vue'; import CreateForm from '@/views/sysworkflow/codepage/createform.vue'
import HeadTools from '@/components/DesignForm/public/headTools.vue';
import FormDesign from '@/components/DesignForm/public/form/form.vue'
import FormControlAttr from '@/components/DesignForm/formControlAttr.vue';
import VueFile from '@/components/DesignForm/vueFile.vue'
import AceDrawer from '@/components/DesignForm/aceDrawer.vue'
import { ref, reactive, provide, onMounted } from 'vue' const queryParams = reactive<SearchForm>({
import { ElMessage } from 'element-plus' page: 1,
import { useLayoutStore } from '@/store/DesignForm/layout' pagesize:15
import { FormData,formStruct,DrawerStruct } from '@/api/DesignForm/types' });
const ids = ref<number[]>([]); //
const loading =ref(false); //
const drawerOpenOrClose = ref(false);
const total = ref(0); //
const contList = ref<customerFormCont[]>()
const drawerWith = ref<number>(0);
const formConfigCont = reactive<customerFormConfig>({
formname:"",
formlogo:""
})
//
function handleQuery(){
getCustomerFormList(queryParams)
.then(({ data }) => {
console.log("搜索表单-->",data);
total.value = data.total
contList.value = data.list
})
.finally(() => {})
}
//
function resetQuery(){}
//
function openDialog(){
getProductionMarkForm()
.then(({data})=>{
formConfigCont.formlogo = data.formlogo
formConfigCont.formname = data.formname
console.log("新增表单",formConfigCont)
})
.finally(()=>{
drawerOpenOrClose.value = true;
})
const layoutStore = useLayoutStore() }
layoutStore.changeBreadcrumb([{ label: '系统工具' }, { label: '表单设计' }]) //
function handleDelete(){}
/**
* 行checkbox change事件
*/
function handleSelectionChange(selection: any) {
ids.value = selection.map((item: any) => item.id);
}
//
function setupCustomerForm(cont:customerFormCont){
const store = useDesignFormStore() }
const router = useRouter() onMounted(()=>{
const route: any = useRoute().query || {} handleQuery();
const state = reactive<formStruct>({ drawerWith.value = window.innerWidth - 220
formData: { });
list: [], window.addEventListener("resize", function(){
form: { drawerWith.value = window.innerWidth -220
size: 'default', console.log("搜索表单-->",window.innerWidth);
name:''
},
config: {}
},
editor: {},
loading: false,
formDataPreview: {},
previewVisible: false, //
designType: route.type, // search
formDict: {},
formOtherData: {
source: route.source || '',
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)
const getInitData = () => {
const id = route.id // id
if (id) {
//
state.loading = true
getRequest('designById', { id: id })
.then(res => {
const result = res.data
// res.data=''
if (result.data) {
state.formData = stringToObj(result.data)
}
state.formDict = string2json(result.dict)
//
state.formOtherData.source = result.source
state.formOtherData.formName = result.name
if (result.source && state.designType !== 'search') {
//
formControlAttrEl.value.getFormFieldBySource(result.source)
}
state.loading = false
})
.catch((res: any) => {
// console.log(res)
ElMessage.error(res.message || '加载异常')
state.loading = false
})
}
}
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) //
// 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()
break
case 'vue':
vueFileEl.value.open(state.formData)
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 '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)
}
}
//
const saveData = () => {
// url
const { addUrl, editUrl, requestUrl } = state.formData.config
if (
!state.formOtherData.source &&
(!addUrl || !editUrl || !requestUrl) &&
state.designType !== 'search'
) {
ElMessage.error('请选择数据源或配置接口url地址,否则表单无法提交保存')
return
}
let params: any = {
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)
}
getInitData()
// source
onMounted(() => {
if (route.source) {
formControlAttrEl.value.getFormFieldBySource(route.source)
}
})
</script> </script>
<template> <template>
<div class="design-container"> <div class="app-container">
<DragControl <div class="search">
:formid="state.formOtherData.source" <el-form ref="queryFormRef" :model="queryParams" :inline="true">
@click-check="searchCheckField" <el-form-item label="关键字" prop="keywords">
@click="selectTemplate" <el-input
/> v-model="queryParams.keywords"
<div class="main-body"> placeholder="表单名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery"
><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-card shadow="never">
<template #header>
<el-button type="success" @click="openDialog()"><i-ep-plus />新增表单</el-button>
<el-button
type="danger"
:disabled="ids.length === 0"
@click="handleDelete()"
>
<i-ep-delete />删除表单
</el-button>
</template>
<el-table
v-loading="loading"
highlight-current-row
:data="contList"
border
@selection-change="handleSelectionChange"
>
<el-table-column fixed type="selection" width="55" align="center" />
<el-table-column fixed label="表单名称" prop="name" />
<el-table-column label="分类" align="center" width="150">
<template #default="scope">
<el-tag v-if="scope.row.classify === 1" effect="plain">表单</el-tag>
<el-tag v-else effect="plain">流程表单</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" align="center" width="100">
<template #default="scope">
<el-tag v-if="scope.row.states === 1" type="success">启用</el-tag>
<el-tag v-else type="info">禁用</el-tag>
</template>
</el-table-column>
<el-table-column label="创建人" prop="creatername" width="140" />
<el-table-column label="创建时间" prop="creatertime" />
<el-table-column fixed="right" label="操作" align="center" width="280">
<template #default="scope">
<el-button
type="success"
link
size="small"
@click.stop="setupCustomerForm(scope.row)"
><i-ep-Setting />设置</el-button
>
<el-button
type="warning"
link
size="small"
@click.stop="setupCustomerForm(scope.row)"
><i-ep-MessageBox />数据结构</el-button
>
<el-button
<HeadTools @click="headToolClick" /> type="primary"
<div v-loading="state.loading" class="main-form"> link
<div v-if="state.formData.list.length === 0" class="empty-tips"> size="small"
从左侧拖拽来添加组件
</div> ><i-ep-edit />编辑</el-button
<FormDesign >
:type="5" <el-button
:form-data="state.formData"
:dict="state.formDict" type="danger"
/> link
</div> size="small"
</div>
<!--面版右侧--> ><i-ep-delete />删除</el-button
<form-control-attr >
ref="formControlAttrEl" </template>
v-model:formOtherData="state.formOtherData" </el-table-column>
:form-data="state.formData.form" </el-table>
:form-config="state.formData.config" <pagination
@open-dialog="openAceEditDrawer" v-if="total > 0"
/> v-model:total="total"
<ace-drawer v-model:page="queryParams.page"
v-model="drawer.visible" v-model:limit="queryParams.pagesize"
:title="drawer.title" @pagination="handleQuery"
: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-dialog v-model="state.previewVisible" title="预览" :fullscreen="true">
<form-design
v-if="state.previewVisible"
ref="previewForm"
:form-data="state.formDataPreview"
:dict="state.formDict"
:type="1"
/> />
<template #footer> </el-card>
<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-dialog>
</div> </div>
<el-drawer v-model="drawerOpenOrClose" title="I am the title" :with-header="false" :close-on-click-modal="false" :close-on-press-escape="false" :destroy-on-close="true" :size="drawerWith" class="drawerClass">
<CreateForm v-model:draweropenclose="drawerOpenOrClose" :formconfigcont="formConfigCont" @handlequery="handleQuery" />
</el-drawer>
</template> </template>
<style lang='scss' scoped> <style lang='scss' scoped>
.drawerClass{
.el-drawer__body{
padding: 0;
}
}
</style> </style>

Loading…
Cancel
Save