Browse Source

增加web显示

lwx_v11
hreenshan112 1 year ago
parent
commit
367f11c959
  1. 11
      src/components/DesignForm/public/form/calculate/cssInfo.ts
  2. 53
      src/components/DesignForm/public/form/form.vue
  3. 877
      src/components/DesignForm/public/form/web/formItem.vue
  4. 195
      src/components/DesignForm/public/form/web/tinymce.vue
  5. 900
      src/components/DesignForm/public/form/webformGroup.vue
  6. 2
      src/components/DesignForm/public/headToolsApp.vue
  7. 20
      src/views/sysworkflow/lowcodepage/appPage/appPageForm/pageForm.vue
  8. 196
      vite.config.ts.timestamp-1728864900350-747b70aad68c5.mjs
  9. 196
      vite.config.ts.timestamp-1729123960837-9e5f8fdba4273.mjs

11
src/components/DesignForm/public/form/calculate/cssInfo.ts

@ -174,7 +174,15 @@ export const AnalysisCss = (ele:any) =>{
if(ele['fontColor'] && ele['fontColor'] != ""){ if(ele['fontColor'] && ele['fontColor'] != ""){
styleObject['color'] = ele['fontColor']; styleObject['color'] = ele['fontColor'];
} }
// console.log("分析css==>",styleObject); // console.log("分析css==>",styleObject);
// console.log("=============start================");
// console.log(ele);
// // console.log(sty);
// console.log(Object.keys(styleObject).length);
// console.log("=============end================");
// if(Object.keys(styleObject).length === 0){
// styleObject['margin-top'] = "10px";
// }
return styleObject return styleObject
} }
@ -577,5 +585,6 @@ export const AnalysisInputCss = (ele:any,sty:number) =>{
if(ele["transparency"] || ele["transparency"] == 0) { if(ele["transparency"] || ele["transparency"] == 0) {
styleObject['opacity'] = ele['transparency']/100; styleObject['opacity'] = ele['transparency']/100;
} }
return styleObject; return styleObject;
} }

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

@ -8,6 +8,7 @@ import '@/assets/scss/element-var.scss'
import '@/assets/scss/index.scss' import '@/assets/scss/index.scss'
// import FormGroup from './formGroup.vue' // import FormGroup from './formGroup.vue'
import FormGroup from '@/components/DesignForm/public/form/formGroup.vue' import FormGroup from '@/components/DesignForm/public/form/formGroup.vue'
import WebFormGroup from '@/components/DesignForm/public/form/webformGroup.vue'
import { FormData,FormList,FormDataStyle } from '@/api/DesignForm/types' import { FormData,FormList,FormDataStyle } from '@/api/DesignForm/types'
import { getRequest } from '@/api/DesignForm' import { getRequest } from '@/api/DesignForm'
@ -57,6 +58,7 @@ const props = withDefaults(
signCode?: string // signCode?: string //
versionId?: string // versionId?: string //
mastesformjson?: string // mastesformjson?: string //
isWeb: boolean //
}>(), }>(),
{ {
type: 1, // 123 4 5 type: 1, // 123 4 5
@ -1962,9 +1964,39 @@ defineExpose({
getEditData, getEditData,
submitEdit submitEdit
}) })
const webPage = computed({
get: () => {
// console.log("value-get",props.modelValue)
// userlist.value = props.modelValue
return props.isWeb
// return false
},
set: (newVal: any) => {
return newVal
}
})
</script> </script>
<template> <template>
<div v-loading="loading"> <div v-if="webPage" class="webBox">
<el-form
v-bind="formData.form"
ref="ruleForm"
:model="model as any"
:disabled="disabled || type === 3"
class="add-form"
:class="{
'design-form': type === 5,
'detail-form': type === 3 || type === 4 || type === 1
}"
>
<WebFormGroup :tableinfo="formData.form" :numrun="numrun" :data="formData.list" :alldata="formData" @optionsValue3Get2="optionsValue3Get2"/>
<slot></slot>
</el-form>
</div>
<div v-else v-loading="loading" class="pcBox">
<el-form <el-form
v-bind="formData.form" v-bind="formData.form"
@ -1986,5 +2018,22 @@ defineExpose({
</div> </div>
</template> </template>
<style lang='scss' scoped> <style lang='scss' scoped>
.webBox{
background: #FFFFFF;
margin: 0px auto 0 auto;
max-width: 380px;
border: 1px dashed #999;
height: calc(100vh - 105px);
overflow-y: auto;
overflow-x: hidden;
position: relative;
}
.pcBox{
background: #FFFFFF;
border: 1px dashed #999;
height: calc(100vh - 105px);
overflow-y: auto;
overflow-x: hidden;
position: relative;
}
</style> </style>

877
src/components/DesignForm/public/form/web/formItem.vue

@ -0,0 +1,877 @@
<!--
@ 作者: 秦东
@ 时间: 2024-10-17 09:36:08
@ 备注: 自定义表单组件
-->
<script lang='ts' setup>
import {
inject,
onMounted,
computed,
watch,
onUnmounted,
markRaw
} from 'vue'
import { Md5 } from 'ts-md5'
import { ElMessage } from 'element-plus'
import Tooltips from '@/components/DesignForm/tooltip.vue'
import TinymceEdit from '@/components/DesignForm/public/form/tinymce.vue'
import { FormItem, FormList } from '@/api/DesignForm/types'
import {
formatNumber,
objectToArray,
constControlChange,
constSetFormOptions,
constFormProps,
constGetControlByName
} from '@/api/DesignForm/utils'
import validate from '@/api/DesignForm/validate'
import ExpandUser from '@/components/DesignForm/public/expand/user.vue'
import OrgCentent from '@/components/DesignForm/public/expand/org.vue'
import LokOrgCentent from '@/widget/org/cont.vue'
import DigitpagePage from '@/components/DesignForm/public/expand/digitpage.vue'
import LowcodeImagePage from '@/components/DesignForm/public/expand/lowcodeImage.vue'
// import LowcodeImagePage from '@/widget/lowcodeimage/index.vue'
import UploadPage from '@/components/DesignForm/public/expand/uploadPage.vue'
import UploadPageList from '@/components/DesignForm/public/expand/uploadPageList.vue'
import OrgCitys from '@/components/DesignForm/public/expand/orgCitys.vue'
import DatePickerPage from '@/components/DesignForm/public/expand/datePicker.vue'
import CascaderPage from '@/components/DesignForm/public/expand/cascader.vue'
import AKSelect from '@/components/DesignForm/public/form/select.vue'
import { uploadUrl,getRequest } from '@/api/DesignForm'
import formatResult from '@/utils/DesignForm/formatResult'
import { debounce } from '@/utils/DesignForm/index'
import { useRoute } from 'vue-router'
import { json2string,objToStringify,string2json,stringToObj } from '@/utils/DesignForm/form'
import TextImg from "@/assets/image/tinymce.png"
import { AnalysisCss,AnalysisInputCss } from '@/components/DesignForm/public/form/calculate/cssInfo.ts'
import request from '@/utils/request';
import { getgovcont } from '@/api/hr/org/index'
const props = withDefaults(
defineProps<{
data: FormList
modelValue?: any //
tProp?: string // form-itemprop
nodeKey?:string
purview?:any[]
optionsValue3Get1?:any
tablekey?:any
numrun?:any
}>(),
{}
)
const emits = defineEmits<{
(e: 'update:modelValue', val: any): void
(e: 'optionsValue3Get1', val: any,fieldName: string): void
(e: 'asfValueChanged', val: any): void
}>()
const route = useRoute()
const formProps = inject(constFormProps, {}) as any
const type = computed(() => {
return formProps.value.type
})
const config = computed(() => {
return props.data.config || {}
})
//css
const configStyle = computed(() => {
return props.data.styles || {}
})
const control = computed(() => {
if(props.data.type == "upload"){
props.data.control.action = uploadUrl
}
return props.data.control
// return props.data
})
const options = ref(props.data.options)
//console.log("FormItem*********************************************************"+JSON.stringify(props.data))
const changeEvent = inject(constControlChange, '') as any
const updateModel = (val: any) => {
let controlAttribute = ""
if(props.data.control){
if(props.data.control.type){
controlAttribute = props.data.control.type
}
}
changeEvent &&
changeEvent({
key: props.data.name,
value: val,
data: props.data,
tProp: props.tProp,
type: props.data.type,
attribute: controlAttribute
})
}
const value = computed({
get() {
if (props.tProp) {
//
return props.modelValue
} else {
if(props.data.type == "checkbox"){
if (formProps.value.model[props.data.name] == null || formProps.value.model[props.data.name] == ""){
// formProps.value.model[props.data.name] = []
// return formProps.value.model[props.data.name]
return []
}else{
return formProps.value.model[props.data.name]
}
}else{
return formProps.value.model[props.data.name]
}
}
},
set(newVal: any) {
if (props.tProp) {
emits('update:modelValue', newVal)
}
updateModel(newVal)
}
})
//
const transformOption = (val: string | number, type?: string) => {
switch (config.value.transformData || type) {
case 'none':
return val
case 'string':
try {
return val.toString()
} catch (e) {
return val
}
}
return formatNumber(val)
}
// toRefs
const getControlByName = inject(constGetControlByName) as any
const sourceFunKey = computed(() => {
const iReg = new RegExp('(?<=\\${)(.*?)(?=})', 'g')
//const iReg = new RegExp('\\${.*?}', 'g') // =>${name}
const apiUrl = config.value.optionsFun
const replace = apiUrl?.match(iReg)
return replace && replace[0]
})
const getLabel = (ele: FormItem) => {
const showColon = formProps.value.showColon ? ':' : ''
if (ele) {
return ele.showLabel ? '' : ele.label + showColon
} else {
return ''
}
}
const currentComponent = computed(() => {
if (props.data.type === 'component') {
//
return config.value.componentName
}
if (props.data.type === 'expand-user') {
return markRaw(ExpandUser)
}
if (props.data.type === 'orgCentent') {
return markRaw(OrgCentent)
}
if (props.data.type === 'digitpage') {
return markRaw(DigitpagePage)
}
if (props.data.type === 'lowcodeImage') {
return markRaw(LowcodeImagePage)
}
if (props.data.type === 'upload') {
return markRaw(UploadPage)
}
if (props.data.type === 'organization') {
return markRaw(OrgCitys)
}
if (props.data.type === 'datePicker') {
props.data.control.valueFormat="x"
// props.data.control.align="right"
// props.data.control.appendToBody =true
return markRaw(DatePickerPage)
}
if(props.data.type === 'cascader'){
return markRaw(CascaderPage)
}
if (props.data.type === 'switch') {
if(typeof props.data.control.activeValue === "number"){
props.data.control.activeValue=props.data.control.activeValue.toString()
}
if(typeof props.data.control.inactiveValue === "number"){
props.data.control.inactiveValue=props.data.control.inactiveValue.toString()
}
}
// if (props.data.type === 'timePicker') {
// props.data.control.valueFormat="timestamp"
// }
// console.log("",props.data)
return `el-${props.data.type}`
})
//
const editDisabled = computed(() => {
if (type.value === 3) {
return true //
}
if (type.value === 1 && config.value.addDisabled) {
return true
}
if (type.value === 2 && config.value.editDisabled) {
return true //
}
// return judgeIsDisabled(key)
return control.value.disabled
})
// item
const itemRules = computed(() => {
let temp
const itemR: any = props.data.item?.rules || []
const customR = formatCustomRules()
// undefined
if (itemR?.length || customR?.length) {
temp = [...customR, ...itemR]
}
return temp
})
// data selectdata
const getAxiosOptions = debounce((data?: any) => {
//console.log(props.data)
const {
optionsType,
optionsFun,
method = 'post',
afterResponse,
beforeRequest,
label,
value,
debug // =truesessionStorage
} = config.value
if (optionsType !== 0) {
let sourceFun = optionsFun
//
if (optionsType === 1 && sourceFun) {
// data=true
let md5Object:any = new Md5()
md5Object.appendAsciiStr(JSON.stringify(sourceFun + data))
let md5Str = md5Object.end()
// const key = 'getOptions_' + props.data.name + md5(sourceFun + data)
const key = 'getOptions_' + props.data.name + md5Str
const storage = window.sessionStorage.getItem(key)
if (storage && !data && !debug) {
const val = JSON.parse(storage)
if (props.data.type === 'treeSelect') {
control.value.data = val
} else {
options.value = val
}
} else {
// url,${name}name
if (sourceFunKey.value) {
const val = formProps.value.model[sourceFunKey.value]
const string = '${' + sourceFunKey.value + '}'
sourceFun = sourceFun.replace(string, val)
}
//
//let newData = Object.assign({}, data || {}, queryParams)
let newData = data || {}
if (typeof beforeRequest === 'function') {
newData =
beforeRequest(newData, route, formProps.value.model) ?? data
}
if (newData === false) {
return
}
if (method === 'get') {
newData = { params: newData }
}
}
}else if(optionsType === 3){//liwenxuan 20240611
/*
在这里请求后台获取字段
*/
//console.log("formItem---291",props.data.control.optionsValue3Field)
if(props.data.control.optionsValue3Field && props.data.control.optionsValue3Field != "" && props.data.control.optionsValue3Field != null && props.data.control.optionsValue3Field != "undefined"){
getFieldRecord(props.data.control.optionsValue3Field).then(({ data }) => {
let fieldName = props.data.name
emits('optionsValue3Get1',data,fieldName)
})
}
}
setFormDict(formProps.value.dict) //
}
})
watch(
() => props.data.control.optionsValue3Field,
(val:any) => {
console.log("监听--optionsValue3Field-》",val)
getAxiosOptions()
}
)
watch(
() => props.data.config.optionsType,
() => {
getAxiosOptions()
}
)
function getFieldRecord(param1: any) {
return request({
url: '/javasys/lowCode/AssociatedForms/getFieldRecord',
method: 'post',
data: {
optionsValue3Field:param1
},
});
}
watch(
() => formProps.value.model[sourceFunKey.value],
() => {
getAxiosOptions()
}
)
// customRulesrules
const formatCustomRules = () => {
const rulesReg: any = {}
validate &&
validate.forEach(item => {
rulesReg[item.type] = item.regExp
})
// 使provide
const temp: any = []
props.data.customRules?.forEach((item: any) => {
if (!item.message && item.type !== 'methods') {
return //
}
let obj = {}
if (item.type === 'required') {
obj = { required: true }
} else if (item.type === 'rules') {
//
obj = { pattern: item.rules }
} else if (item.type === 'methods') {
//
const methods: any = item.methods
if (methods) {
obj = { validator: inject(methods, {}) }
}
} else if (item.type) {
obj = { pattern: rulesReg[item.type as string] }
}
// push
let message: any = { message: item.message }
if (!item.message) {
// 使validatormessage使 callback(new Error('x'));
message = {}
}
temp.push(
Object.assign(
{
trigger: item.trigger || 'blur'
},
obj,
message
)
)
})
return temp
}
// options
const setFormDict = (val: any) => {
// console.log("options",val)
if (val && config.value.optionsType === 2) {
const opt = val[config.value.optionsFun] || val[props.data.name] //
if (opt !== undefined) {
options.value = objectToArray(opt)
}
}
}
// dict
watch(
() => formProps.value.dict,
(val: any) => {
setFormDict(val)
},
{
/*deep: true*/
}
)
// selectoptions
const formOptions = inject(constSetFormOptions, {}) as any
watch(
() => formOptions.value,
(val: any) => {
// console.log("",val)
const opt = val[props.data.name]
//
if (val && opt !== undefined) {
if (props.data.type === 'treeSelect') {
// data
control.value.data = objectToArray(opt)
} else {
options.value = objectToArray(opt)
}
}
}
)
// -----------------------
const fileList = computed<any>(() => {
const imgVal = formProps.value.model[props.data.name]
// console.log("-->",imgVal)
if (imgVal && typeof imgVal === 'string') {
// console.log("-2->",imgVal)
const temp: any = []
imgVal.split(',').forEach((item: string) => {
// console.log("-3->",item)
temp.push({
name: item,
url: item
})
})
return temp
}
return imgVal || [] // array([name:'',url:''])
})
//
const uploadSuccess = (response: any, uploadFile: any, uploadFiles: any) => {
// console.log("response==>",response)
// console.log("uploadFile==>",uploadFile)
// console.log("uploadFiles==>",uploadFiles)
const oldList = []
fileList.value.forEach((item: any) => {
oldList.push(item.url)
})
// oldList.push(response.path)
oldList.push(response.data.url)
updateModel(oldList.join(','))
control.value.onSuccess &&
control.value.onSuccess(response, uploadFile, uploadFiles)
// console.log("uploadSuccess===>",control.value)
// console.log("uploadSuccess=fileList==>",fileList)
}
//
const uploadRemove = (uploadFile: any, uploadFiles: any) => {
const oldList: any = []
fileList.value.forEach((item: any) => {
if (item.url !== uploadFile.url) {
oldList.push(item.url)
}
})
updateModel(oldList.join(','))
control.value.onRemove && control.value.onRemove(uploadFile, uploadFiles)
// todo
}
//
const uploadError = (err: any, file: any, fileList: any) => {
// console.log('uploadError')
ElMessage.error(file.name + '上传失败')
control.value.onError && control.value.onError(err, file, fileList)
}
// -----------------------------
/****input slot处理***/
const getInputSlot = (key?: string) => {
const slot = key === 'p' ? config.value.prepend : config.value.append
const has = slot.indexOf('key:') === 0
if (!has) {
return false
}
const slotKey = slot.replace('key:', '')
const control = getControlByName(slotKey)
if (!control || Object.keys(control)?.length === 0) {
return false
}
return control
}
const inputSlotChange = (val: string | number, name: string) => {
changeEvent &&
changeEvent({
key: name,
value: val,
data: {},
tProp: ''
})
}
onMounted(() => {
getAxiosOptions()
})
onUnmounted(() => {})
/**
@ 作者: 秦东
@ 时间: 2024-03-01 09:07:11
@ 功能: 布局处理
*/
const getFormItemLableStyle = (ele: any) => {
if(ele?.labelStyle){
// console.log("3",AnalysisCss(ele?.labelStyle))
return AnalysisCss(ele?.labelStyle)
}
}
const getFormItemInputStyle = (ele: any,sty:number) => {
if(ele?.inputStyle){
// console.log("4",AnalysisInputCss(ele?.inputStyle,sty))
return AnalysisInputCss(ele?.inputStyle,sty)
}
}
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API+"/api/upordown"
/**
@ 作者: 秦东
@ 时间: 2024-07-27 14:17:16
@ 功能: 判断此组件是否可见
*/
const judgeIsShow = (key:string) => {
// console.log("---->",key)
if(props.nodeKey != undefined && props.purview != undefined && props.purview != null && props.purview != null && props.purview != "" && props.purview != "") {
if(props.purview.length < 1){
return true;
}else{
let isShow = false;
if(Array.isArray(props.purview)){
props.purview.forEach((item)=>{
if(item.nodeKey == props.nodeKey){
if(item.powerAry && item.powerAry.length > 0){
item.powerAry.forEach((itm)=>{
if(itm.id == key){
// console.log("",itm,itm.id == key,"--------->",itm.isLook)
isShow = itm.isLook
}
})
}
}
})
}
return isShow
}
}else{
return true;
}
}
/**
@ 作者: 秦东
@ 时间: 2024-07-27 15:11:42
@ 功能: 判断是否禁用
*/
const judgeIsDisabled = (key:string) => {
if (type.value === 3) {
return true //
}
if (type.value === 1 && config.value.addDisabled) {
return true
}
if (type.value === 2 && config.value.editDisabled) {
return true //
}
if(props.nodeKey != undefined && props.purview != undefined && props.purview != null && props.purview != null && props.purview != "" && props.purview != "") {
if(props.purview.length < 1){
return false;
}else{
let isShow = true;
props.purview.forEach((item)=>{
if(item.nodeKey == props.nodeKey){
if(item.powerAry && item.powerAry.length > 0){
item.powerAry.forEach((itm)=>{
if(itm.id == key){
console.log("判断此组件是否禁用",itm,itm.id == key,"--------->",itm.isLook)
isShow = !itm.isEdit
}
})
}
}
})
return isShow
}
}else{
return false;
}
}
/**
@ 作者: 秦东
@ 时间: 2024-08-02 13:02:49
@ 功能: 将时间戳转换成字符串
*/
const timeToString = (timeVal:any,types:int) => {
// console.log("",timeVal,types)
let timeStr = ""
if(Array.isArray(timeVal)){
if(timeVal.length >= 2){
let startTime = timeToAry(timeVal[0])
let endTime = timeToAry(timeVal[1])
switch(types){
case "year": //
timeStr = `${startTime.year}${endTime.year}`;
break;
case "month": //
timeStr = `${startTime.year}-${startTime.month}${endTime.year}-${endTime.month}`;
break;
case "datetime": //+
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} ${startTime.hours}:${startTime.minutes}:${startTime.seconds}${endTime.year}-${endTime.month}-${endTime.day} ${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
break;
case "week": //
let startWeek = getYearWeek(startTime)
let endWeek = getYearWeek(endTime)
timeStr = `${startWeek}${endWeek}`;
break;
case "timeCalss": //
timeStr = `${startTime.hours}:${startTime.minutes}:${startTime.seconds}${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
break;
case "datetimerange":
timeStr = `${startTime.year}-${startTime.month}-${startTime.day} ${startTime.hours}:${startTime.minutes}:${startTime.seconds}${endTime.year}-${endTime.month}-${endTime.day} ${endTime.hours}:${endTime.minutes}:${endTime.seconds}`;
break;
case "daterange":
timeStr = `${startTime.year}-${startTime.month}-${startTime.day}${endTime.year}-${endTime.month}-${endTime.day}`;
break;
case "monthrange":
timeStr = `${startTime.year}-${startTime.month}${endTime.year}-${endTime.month}`;
break;
default:
timeStr = `${startTime.year}-${startTime.month}-${startTime.day}${endTime.year}-${endTime.month}-${endTime.day}`;
break;
}
}else if(timeVal.length == 1){
let {year,month,day,hours,minutes,seconds} = timeToAry(timeVal[0])
switch(types){
case "year": //
timeStr = `${year}`;
break;
case "month": //
timeStr = `${year}-${month}`;
break;
case "datetime": //+
timeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
break;
case "week": //
timeStr = getYearWeek(timeVal)
break;
case "timeCalss": //
timeStr = `${hours}:${minutes}:${seconds}`;
break;
default:
timeStr = `${year}-${month}-${day}`
break;
}
}else{
timeStr = "未知时间"
}
}else{
let {year,month,day,hours,minutes,seconds} = timeToAry(timeVal)
switch(types){
case "year": //
timeStr = `${year}`;
break;
case "month": //
timeStr = `${year}-${month}`;
break;
case "datetime": //+
timeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
break;
case "week": //
timeStr = getYearWeek(timeVal)
break;
case "timeCalss": //
timeStr = `${hours}:${minutes}:${seconds}`;
break;
default:
timeStr = `${year}-${month}-${day}`
break;
}
}
return timeStr
}
/**
@ 作者: 秦东
@ 时间: 2024-08-02 13:22:14
@ 功能: 时间戳转换对象
*/
const timeToAry = (timestamp:number) => {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
const hours = ('0' + date.getHours()).slice(-2);
const minutes = ('0' + date.getMinutes()).slice(-2);
const seconds = ('0' + date.getSeconds()).slice(-2);
return {
year:year,
month:month,
day:day,
hours:hours,
minutes:minutes,
seconds
}
}
/**
@ 作者: 秦东
@ 时间: 2024-08-02 13:21:05
@ 功能: 计算当前时间戳是今年第几周
*/
const getYearWeek = (timestamp:number) => {
const date = new Date(timestamp);
const firstDayOfYear = new Date(date.getFullYear(), 0, 1);
const pastDaysOfYear = (date - firstDayOfYear) / 86400000;
const weekNumber = Math.ceil((pastDaysOfYear + firstDayOfYear.getDay() + 1) / 7);
return weekNumber;
}
/**
@ 作者: 秦东
@ 时间: 2024-08-02 13:42:22
@ 功能: 判断单选值
*/
const judgeRadio = (val:any,list:any) => {
let valStr = ""
if(Array.isArray(list)){
if(list.length > 0){
list.forEach((item) => {
if(item.value == val){
valStr = item.label
}
})
}
}
return valStr
}
/**
@ 作者: 秦东
@ 时间: 2024-08-02 13:42:22
@ 功能: 判断多选值
*/
const judgeCheckbox = (val:any,list:any) => {
let valAry = []
if(Array.isArray(val)){
if(val.length > 0){
if(Array.isArray(list)){
val.forEach((item) => {
list.forEach((ltem) => {
if(item == ltem.value){
valAry.push(ltem.label)
}
})
})
}
}
}
return valAry
}
/**
@ 作者: 秦东
@ 时间: 2024-08-05 10:00:31
@ 功能: 下拉菜单处理
*/
const selectValue = (val:any,list:any) => {
// console.log("",val,list)
let valAry = []
if(val && val != "" && val != null ){
let pickSelect = val
if(Array.isArray(val)){
pickSelect = val
}else{
pickSelect = JSON.parse(val)
}
// console.log("-----3------->",pickSelect)
if(Array.isArray(pickSelect)){
if(pickSelect.length > 0){
if(Array.isArray(list)){
pickSelect.forEach((item) => {
list.forEach((ltem) => {
if(item*1 == ltem.value*1){
valAry.push(ltem.label)
}
})
})
}
}
}else{
if(Array.isArray(list)){
list.forEach((ltem) => {
if(val == ltem.value){
valAry.push(ltem.label)
}
})
}
}
}else{
// console.log("-4->",val)
}
// console.log("-2->",valAry)
return valAry
}
/**
@ 作者: 秦东
@ 时间: 2024-08-06 08:34:05
@ 功能: 选择用户
*/
const pickUserVal = (val:any) => {
// console.log("-2->",val)
if(Array.isArray(val)){
return val
}else{
// let valAry = string2json(val)
// console.log("-2->",valAry)
return val
}
}
function asfValueChanged(val:any){
//console.log("asfValueChanged",val)
emits("asfValueChanged",val)
}
/**
@ 作者: 秦东
@ 时间: 2024-09-17 14:30:37
@ 功能: 解析下载图片
*/
const uploadPic = (val:any) => {
console.log("解析下载图片-->",val)
if(val != ""){
let urlAry = string2json(val)
// let urlAry = val.toString().split(",")
console.log("解析下载图片-2->",urlAry)
return urlAry
}else{
return [];
}
}
</script>
<template>
<div></div>
</template>
<style lang='scss' scoped>
</style>

195
src/components/DesignForm/public/form/web/tinymce.vue

@ -0,0 +1,195 @@
<!--
@ 作者: 秦东
@ 时间: 2023-09-19 13:09:24
@ 备注:
-->
<script lang='ts' setup>
import { onMounted, watch, ref, computed, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { newUploadFileApi } from '@/api/file/index'
const props = withDefaults(
defineProps<{
modelValue: string
placeholder?: string
width?: string
height?: string
blobUrl?: string
imgUrl?: string
config?: any
}>(),
{
modelValue: '',
placeholder: '请输入内容',
width: '100%',
height: '300px',
blobUrl: '',
imgUrl: '',
config: () => {
return {}
}
}
)
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
const contentValue = ref(props.modelValue)
//
// eslint-disable-next-line max-len
const buttonPlugins ='preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media code codesample table charmap pagebreak nonbreaking anchor insertdatetime advlist lists wordcount autosave '
//
// eslint-disable-next-line max-len
const toolbar ='fullscreen undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor table image | alignleft aligncenter alignright alignjustify outdent indent | styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | media charmap emoticons pagebreak insertdatetime print preview | code selectall searchreplace visualblocks | indent2em lineheight formatpainter axupimgs'
const toolbarSimple ='undo cut copy paste pastetext |forecolor backcolor bold italic underline strikethrough|alignleft aligncenter alignright alignjustify|'
const commInit = {
selector: '#myTextarea',
cleanup: true,
language: 'zh_CN', //
fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px', //
lineheight_formats: '0.5 0.8 1 1.2 1.5 1.75 2 2.5 3 4 5', // "12px 14px 16px 20px"
branding: false, // tiny
resize: false, // false-,true-'both'-
// statusbar: false, //
elementpath: false, //
height: props.height, // placeholder
width: props.width,
placeholder: props.placeholder,
init_instance_callback: (editor: any) => {
// editor.setContent('')
editor.on('NodeChange Change KeyUp SetContent', () => {
contentValue.value = editor.getContent()
emits('update:modelValue', editor.getContent())
})
}
}
//
const imgUploadFn = (blobInfo: any, progress: number) =>
new Promise((resolve, reject) => {
// https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#images_upload_handler
// console.log("",progress)
const params = new FormData()
params.append('file', blobInfo.blob())
params.append('type',"1")
let options = {}
if (props.imgUrl) {
options = {
url: props.imgUrl
}
}
newUploadFileApi(params)
.then(res =>{
// console.log("",res.data)
resolve(res.data.url)
})
.catch(()=>{
reject('上传出错,请查看你上传的文件是否符合要求!')
})
})
const fileUpload = (callback: any, value: string, meta: any) => {
const filetype ='.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'
//
const input = document.createElement('input') //
input.setAttribute('type', 'file')
input.setAttribute('accept', filetype)
input.click()
input.onchange = () => {
const file = input?.files && input.files[0] //
let attr = {}
if (meta.filetype === 'file') {
attr = { text: file?.name }
}
if (meta.filetype === 'image') {
attr = { alt: file?.name }
}
if (meta.filetype === 'media') {
// attr={source2: 'alt.ogg', poster: 'image.jpg'}
}
const params = new FormData()
params.append('file', file as any)
let options = {}
if (props.blobUrl) {
options = {
url: props.blobUrl
}
}
newUploadFileApi(params)
.then(res =>{
// console.log("",res.data)
callback(res.data.url, attr)
})
.catch(res => {
ElMessage.error(res.data?.msg)
})
}
}
const defaultInit = {
plugins: buttonPlugins, //
toolbar: toolbar, // false
menubar: false, // false-- http://tinymce.ax-z.cn/configure/editor-appearance.php --
//emoticons_database_url: './tinymce/emoticons/js/emojis.js',
// eslint-disable-next-line max-len
font_formats:'微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;', // =Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif, =simsun,serif,仿=FangSong,=SimHei,Arial=arial,
// content_style: 'p {margin-block-start: 0; margin-block-end: 0; color: #606D81; font-size: 14px;}; table { border: 1px}', // css
content_css: false, // csscsscss
paste_data_images: true, //
// placeholder
// base64
urlconverter_callback: (url: string, node: string) => {
if (node === 'img' && url.startsWith('blob:')) {
// @ts-ignore
tinymce.activeEditor && tinymce.activeEditor.uploadImages()
}
return url
},
//
images_upload_handler: imgUploadFn,
file_picker_types: 'file image media', //linkimageaxupimgsmedia
file_picker_callback: fileUpload
}
const simpleInit = {
plugins: '', //
toolbar: toolbarSimple, // false
menubar: false, // false--
font_formats: '',
paste_data_images: false //
}
const myInit = computed(() => {
const styleType =
props.config?.style === 'simple' ? simpleInit : defaultInit
return Object.assign(commInit, styleType)
})
onMounted(() => {
// @ts-ignore
tinymce.init(myInit.value)
})
onUnmounted(() => {
// @ts-ignore
tinymce.remove()
})
// v-model contentValue
watch(
() => props.modelValue,
(n: any) => {
if (n && n !== contentValue.value) {
contentValue.value = n
}
}
)
</script>
<template>
<textarea id="myTextarea" v-model="contentValue"></textarea>
</template>
<style lang='scss' scoped>
.tox-tinymce-aux {
z-index: 99999 !important; /*el-dialog层为2014,默认时在el弹出层显示不了编辑器里的弹窗*/
z-index: 99999;
}
</style>

900
src/components/DesignForm/public/form/webformGroup.vue

@ -0,0 +1,900 @@
<!--
@ 作者: 秦东
@ 时间: 2024-10-17 09:10:53
@ 备注: 手机版页面布局
-->
<script lang='ts' setup>
import { computed, watch, inject, onUnmounted } from 'vue'
import Draggable from 'vuedraggable-es'
// import FormItem from '@/components/DesignForm/public/form/web/formItem.vue'
import FormItem from './formItem.vue'
import ChildTable from './childTable.vue'
import Tooltips from '@/components/DesignForm/tooltip.vue'
import FlexBox from './flexBox.vue'
import { useDesignFormStore } from '@/store/DesignForm/designForm'
import { FormList,formTableInfo } from '@/api/DesignForm/types'
import {
constFormBtnEvent,
constFormProps
} from '@/api/DesignForm/utils'
import WebFormGroup from '@/components/DesignForm/public/form/webformGroup.vue'
import { Md5 } from 'ts-md5';
import { jsonParseStringify } from '@/utils/DesignForm'
import request from '@/utils/request';
import { AnalysisCss } from '@/components/DesignForm/public/form/calculate/cssInfo.ts'
const props = withDefaults(
defineProps<{
data: FormList[]
tableinfo:formTableInfo
numrun?:number
nodeKey?:string
purview?:any[]
alldata?:any
}>(),
{
data: () => {
return []
}
}
)
let emits = defineEmits(['optionsValue3Get2','asfValueChanged']);
const store = useDesignFormStore() as any //
const formProps = inject(constFormProps, {}) as any
const type = computed(() => { //
return formProps.value.type
})
const state = reactive({
clone: true, // clone
gridAdd: false
})
const dataList = ref<any>(props.data)
watch(
() => props.data,
(v: FormList[]) => {
dataList.value = v
// console.log("++++++++++>",v)
},
{
deep: true
}
)
const activeKey = computed(() => {
return store.activeKey
})
//
const notNested = (type: string) => {
// const controlType = ['grid', 'table', 'tabs', 'div', 'flex', 'card']
const controlType = ['grid', 'tabs', 'div', 'card']
// let kjkdh = controlType.includes(type)
// console.log("",kjkdh,controlType)
return controlType.includes(type)
// return false
}
const notNestedTableFlex = (type: string) => {
const controlType = ['grid', 'table', 'tabs', 'div', 'flex', 'card']
// let kjkdh = controlType.includes(type)
// console.log("",kjkdh,controlType)
return controlType.includes(type)
// return false
}
/**
@ 作者: 秦东
@ 时间: 2024-06-22 15:03:31
@ 功能: 判断不能重复出现的组件
*/
const determineDuplicates = (type: string) => {
const controlType = ["founder","founderTime","editTime","owner","deptOrg"]
// console.log("",dataList);
if(dataList.value.length > 0){
let jibuqi = 0;
dataList.value.forEach((item:any)=>{
// console.log("",item);
if(controlType.includes(type)){
if(type == item.type){
jibuqi++
}
}
})
// console.log("",jibuqi);
if(jibuqi > 1){
ElMessage({
showClose: true,
message: '此类控件在表单中只能出现一次!不可重复添加!',
type: 'error',
})
return true;
}else{
return false
}
}else{
return false
}
// return controlType.includes(type)
}
//
const click = (action: string, index: number, item?: any) => {
if (type.value !== 5) {
return //
}
if (action === 'clone') {
const key = item.type + new Date().getTime().toString()
const newItem = jsonParseStringify(item)
dataList.value.splice(index, 0, Object.assign(newItem, { name: key }))
} else if (action === 'del') {
dataList.value.splice(index, 1)
//
store.setActiveKey('')
store.setControlAttr({})
} else if (action === 'gridAdd') {
item.columns.push({
list: [],
attr: { span: 12 }
})
} else if (action === 'delGridChild') {
item.splice(index, 1)
}
}
const draggableAdd = (evt: any) => {
if (type.value !== 5) {
return //
}
const newIndex = evt.newIndex
const key = new Date().getTime().toString()
const obj: any = dataList.value[newIndex]
const isNested = evt.target && evt.target.getAttribute('data-type') //
// console.log("-----1------->",newIndex)
// console.log("-----2------->",key)
// console.log("-----3------->",obj)
// console.log("-----4------->",isNested)
// console.log("-----4------->",dataList.value)
if ((isNested === 'not-nested' && notNested(obj.type)) || ((isNested === 'not-table' || isNested === 'not-flex') && notNestedTableFlex(obj.type)) || determineDuplicates(obj.type)) {
dataList.value.splice(newIndex, 1)
return
}
if (!obj) {
return
}
const label = obj.label || obj.item.label
delete obj.label
delete obj.icon
let objectItem = {}
// item
const notNeedItem = [
'txt',
'title',
'button',
'table',
'grid',
'tabs',
'flex',
'div'
]
// console.log("-->",obj.type)
if (!notNeedItem.includes(obj.type)) {
objectItem = {
item: {
label: label
}
}
}
// name
let nameObj = {}
const notNeedName = [
'txt',
'title',
'button',
'grid',
'tabs',
'divider',
'div',
'card'
]
switch(obj.type){
case "founder":
nameObj = {
name: "creater"
}
// console.log("founder--->creater",nameObj)
break
case "founderTime":
nameObj = {
name: "creater_time"
}
// console.log("founderTime-->creater_time",nameObj)
break
case "editTime":
nameObj = {
name: "edit_time"
}
// console.log("editTime--->edit_time",nameObj)
break
case "owner":
nameObj = {
name: "owner"
}
// console.log("owner------>owner",nameObj)
break
case "deptOrg":
nameObj = {
name:"org"
}
// console.log("deptOrg---->org",nameObj)
break
default:
if (!notNeedName.includes(obj.type) && !obj.name) {
nameObj = {
name: obj.type + key
}
}
}
// console.log("-----5------->",obj)
// console.log("-----6------->",nameObj)
// console.log("-----7------->",objectItem)
Object.assign(obj, nameObj, objectItem)
// console.log("-----8------->",obj)
groupClick(obj)
}
const getGroupName = (item: any) => {
if (item.name) {
return item.name
} else {
let md5Object:any = new Md5()
md5Object.appendAsciiStr(JSON.stringify(item))
let md5Str = md5Object.end()
return md5Str
}
}
//
/**
* styles:{
divStyle:{},
labelStyle:{},
inputStyle:{}
}
*/
const groupClick = (item: any, ele?: string) => {
//
if (type.value !== 5) {
return
}
if (ele) {
item.type = ele
}
if(!item.styles){
item.styles={
divStyle:{},
labelStyle:{},
inputStyle:{}
}
}
// console.log("--->",getGroupName(item))
store.setActiveKey(getGroupName(item))
store.setControlAttr(item)
// grid
state.gridAdd = item.type === 'grid'
// state.clone = !notNested(item.type)
state.clone = !notNestedTableFlex(item.type)
}
//
const getFormItemStyle = (ele: FormList) => {
let styleClass = {}
// console.log("311---->",ele)
if (ele.config?.span === 0) {
styleClass['width'] = "auto"
styleClass['margin'] = "0 5px"
// return { width: 'auto', margin: '0 5px' }
}
if (ele.config && ele.config.span) {
// return { width: (ele.config.span / 24) * 100 + '%' }
styleClass['width'] = "100%"
// return "100%"
}
if(ele.styles?.divStyle){
// console.log("3",AnalysisCss(ele.styles.divStyle))
let styleObject = AnalysisCss(ele.styles.divStyle)
if(Object.keys(styleObject).length > 0){
Object.keys(styleObject).forEach((key:string)=>{
// console.log("110-"+key+"--->",styleObject[key])
styleClass[key] = styleObject[key]
})
}
return AnalysisCss(ele.styles.divStyle)
}
return styleClass
}
//
const linksShow = (el: FormList, index: number) => {
/*
*/
//
if (!el.config) {
return true
}
const key = el.config.linkKey
//liwenxuan
//console.log("linksShow--------"+index+"--------"+JSON.stringify(el))
//
const value = el.config.linkValue
const linkResult = el.config.linkResult
if (key && value && type.value !== 5) {
const Fn = new Function('$', `return (${value})`)
// console.log(Fn)
const pass = Fn(formProps.value.model)
if (linkResult === 'disabled') {
// disabled
dataList.value[index].control.disabled = pass
return true
} else {
return pass
}
}
return true
}
//
const linksIf = (obj: FormList) => {
const { type } = formProps.value
const { config: { disabledAdd, disabledEdit, disabledDetail } = {} } = obj
if (type === 1) {
if (disabledAdd) {
// ||
return false //
}
} else if (type === 2) {
//
if (disabledEdit) {
return false
}
} else if (type === 4 || type === 3) {
//
if (disabledDetail) {
return false
}
}
// namevIf
const vIf: string | string[] = formProps.value.hideField
if (vIf?.length > 0 && obj.name) {
return vIf.indexOf(obj.name) === -1 // false
}
return true
}
//
const injectBtnEvent:any = inject(constFormBtnEvent)
const clickBtn = (control: any) => {
// console.log(control)
// 0: '',
// 1: '',
// 2: '',
// 3: '()'
if (type.value !== 5) {
//
injectBtnEvent && injectBtnEvent(control)
}
}
onUnmounted(() => {
dataList.value = {}
store.setActiveKey('')
store.setControlAttr({})
})
const asfs: any[] = []
const tables: any[] = []
onMounted(()=>{
// console.log('',props.nodeKey,"---------------->",props.purview)
// console.log('formGroup onMounted',props.data,dataList.value,props.tableinfo)
setTimeout(()=>{
if(dataList&&Array.isArray(dataList.value)&&dataList.value.length>0){
for(let i = 0;i<dataList.value.length;i++){
if(dataList.value[i].type=="associatedForms"){
asfs.push(dataList.value[i])
}else if(dataList.value[i].type=="card"||dataList.value[i].type=="flex"||dataList.value[i].type=="div"||dataList.value[i].type=="table"){
if(dataList.value[i].type=="table"){
tables.push(dataList.value[i])
}
dataList.value[i].list.forEach((element:any) => {
if(element.type=="associatedForms"){
asfs.push(element)
}
});
}else if(dataList.value[i].type=="grid"){
let columns = JSON.parse(JSON.stringify(dataList.value[i].columns));
//console.log(columns)
if(columns.length>0){
for(let z = 0;z<columns.length;z++){
for(let x = 0; x<columns[z].list.length;x++){
let a = JSON.parse(JSON.stringify(columns[z].list[x]));
//console.log(a)
if(a.type=="associatedForms"){
asfs.push(a)
}
}
}
}
}else if(dataList.value[i].type=="tabs"){//tabsflextable
let columns = JSON.parse(JSON.stringify(dataList.value[i].columns));
if(columns.length>0){
for(let z = 0;z<columns.length;z++){
for(let x = 0; x<columns[z].list.length;x++){
let a = JSON.parse(JSON.stringify(columns[z].list[x]));
//console.log(a)
if(a.type=="associatedForms"){
asfs.push(a)
}else if(a.type=="flex"||a.type=="table"){
if(a.type=="table"){
tables.push(dataList.value[i])
}
if(a.list.length>0){
for(let m = 0;m<a.list.length;m++){
let q = JSON.parse(JSON.stringify(a.list[m]))
//console.log(q)
if(q.type=="associatedForms"){
asfs.push(q)
}
}
}
}
}
}
}
}
}
/* if(asfs.length>0){
//console.log(asfs)
} */
/* if(tables.length>0){
console.log(tables)
} */
}
},500)
})
function getNewObject(obj:any, arr:any) {
//console.log(obj)
//console.log(arr)
let key = arr[0];
let newKey = arr[1];
if (obj[key]) {
return { [newKey]: obj[key] };
}
return {};
}
function asfValueChanged(val:any){
/* console.log("asfValueChanged",val)
console.log(val.currentVal)
console.log(val.fillFieldsMaster)
console.log(val.fillFieldsChild) */
let fillFieldsMaster = ""
let masterFillRoleFieldsArray1: any[] = [];
if(val.fillFieldsMaster.length>0){
fillFieldsMaster = val.fillFieldsMaster.substring(0, val.fillFieldsMaster.length - 1);
let masterFillRoleFieldsArray = fillFieldsMaster.split(";");
//console.log(masterFillRoleFieldsArray)
masterFillRoleFieldsArray.forEach((item:any)=>{
let itemArray = item.split("_");
itemArray.splice(0, 1);
itemArray = itemArray.map((item1:any) => item1.split(':').pop());
//console.log(itemArray)
masterFillRoleFieldsArray1.push(itemArray)
})
}
if(val.fillFieldsChild.length>0){
/* console.log(val.asfFormId)
console.log(val.masterOnField) */
let fillFieldsChild = JSON.parse(val.fillFieldsChild);
if (fillFieldsChild && fillFieldsChild.length > 0) {
fillFieldsChild = fillFieldsChild.filter((element:any)=>{
if(containsDangerousWords(element.filterCondition.gongShi.mathsFormula)){
//alert("")
console.log("筛选条件非法===>"+element.filterCondition.conditionHtml)
}else{
return element
}
})
}
//console.log(fillFieldsChild)
getAsfTableFill(val.asfFormId,val.glbbddbd,val.currentVal,fillFieldsChild).then(({ data }) => {
//console.log(data)
if(data&&data.length>0){
data.forEach((dataElement:any) => {
tables.forEach((tableItem: any) => {
if(dataElement.tableName==tableItem.name){
//console.log(formProps.value.model)
//console.log(tableItem)
//console.log(dataElement)
let tableName = dataElement.tableName
//console.log(tableName)
if(tableItem.list.length>0){
let tableRowArray: { type: any; name: any }[] = []
tableItem.list.forEach((listItem:any) => {
//console.log(listItem)
tableRowArray.push({
type:listItem.type,
name:listItem.name
})
});
//console.log(tableRowArray)
const result = generateXResult(dataElement, tableRowArray);
//console.log(result);
formProps.value.model[tableName] = result
}
}
});
});
}
});
}
//emits("asfValueChanged",val)
if(val.options.length>0){
//console.log(val.options)
if(val.options[0].fillRolesFieldsMap){
val.options.forEach((item:any)=>{
if(item.fillRolesFieldsMap.value == val.currentVal){
if(masterFillRoleFieldsArray1.length>0){
masterFillRoleFieldsArray1.forEach((item1:any)=>{
//console.log(item.fillRolesFieldsMap)
//console.log(item1)
let x = convertObjectToArray(getNewObject(item.fillRolesFieldsMap,item1))
//console.log(x)
let strOrNumber = convertToStringOrNumber(x[1])
let strOrNumberOrArray
if(isString(strOrNumber)&&strOrNumber.includes("[")){
strOrNumberOrArray = convertIfValidNumberArray(strOrNumber)
}
/* console.log(x[1])
console.log(strOrNumberOrArray)
console.log(formProps.value.model[x[0]]) */
if(strOrNumberOrArray){
formProps.value.model[x[0]] = strOrNumberOrArray
}else{
formProps.value.model[x[0]] = strOrNumber
}
//console.log(formProps.value.model[x[0]])
})
}
}
})
}
}
}
interface DetailObject {
[key: string]: any
}
interface TableRow {
type: string;
name: string;
}
function generateXResult(dataElement: { tableDetail: DetailObject[] }, tableRowArray: TableRow[]): DetailObject[] {
const xResult: DetailObject[] = [];
const propertyNames = tableRowArray.map(item => item.name);
for (const detail of dataElement.tableDetail) {
const obj: DetailObject = {};
propertyNames.forEach(name => {
let strOrNumber = convertToStringOrNumber(detail[name])
let strOrNumberOrArray
if(isString(strOrNumber)&&strOrNumber.includes("[")){
strOrNumberOrArray = convertIfValidNumberArray(strOrNumber)
}
if(strOrNumberOrArray){
obj[name] = strOrNumberOrArray
}else{
obj[name] = strOrNumber
}
});
xResult.push(obj);
}
return xResult;
}
function getAsfTableFill(asfFormId:any,glbbddbd:any,currentVal:any,fillFieldsChild:any){
/* console.log(asfFormId)
console.log(glbbddbd)
console.log(fillFieldsChild) */
/* asfFormId = JSON.stringify(asfFormId)
glbbddbd = JSON.stringify(glbbddbd)
currentVal = JSON.stringify(currentVal) */
fillFieldsChild = JSON.stringify(fillFieldsChild)
return request({
url: '/javasys/lowCode/AssociatedForms/getAsfTableFill',
method: 'post',
data: {
asfFormId:asfFormId,
glbbddbd:glbbddbd,
currentVal:currentVal,
fillFieldsChild:fillFieldsChild,
},
});
}
function containsDangerousWords(str: string | undefined): boolean {
if (str === undefined) {
return false;
}
const dangerousWords = new Set<string>([
"drop",
"table",
"where",
"select",
"insert",
"update",
"delete",
"and",
"or",
"union",
"order by",
"group by",
"having",
"exec",
"execute",
]);
const words = str.split(" ");
for (const word of words) {
if (dangerousWords.has(word.toLowerCase())) {
return true;
}
}
return false;
}
function isString(value: any): value is string {
return typeof value === 'string';
}
function convertIfValidNumberArray(str: string): number[] | null {
const regex = /^\[(\d+(,\d+)*)?\]$/;
if (regex.test(str)) {
const numbersStr = str.slice(1, -1);
if (numbersStr.length === 0) {
return [];
}
return numbersStr.split(',').map(item => Number(item));
} else {
return null;
}
}
function convertToStringOrNumber(str: string): number | string {
const isOnlyNumbers = /^\d+$/.test(str);
return isOnlyNumbers? Number(str) : str;
}
function convertObjectToArray(obj:any) {
for (let key in obj) {
return [key, obj[key]];
}
return [];
}
const getFormItemLableStyle = (ele: any) => {
if(ele?.labelStyle){
// console.log("3",AnalysisCss(ele))
return AnalysisCss(ele?.labelStyle)
}
}
function optionsValue3Get1(data: any,fieldName: string){
emits('optionsValue3Get2',data,fieldName)
}
/*
*/
</script>
<template>
<draggable
itemKey="id"
:list="dataList"
name="fade"
class="drag"
v-bind="{
group: 'form',
ghostClass: 'ghost',
animation: 200,
handle: '.drag-move',
disabled: type !== 5
}"
@add="draggableAdd"
>
<template #item="{ element, index }">
<div
class="group"
:class="{
['group-' + element.type]: true,
active: activeKey === getGroupName(element)
}"
:style="getFormItemStyle(element)"
@click.stop="groupClick(element)"
v-show="linksShow(element, index)"
v-if="linksIf(element)"
>
<!--选项卡组件-->
<template v-if="element.type === 'tabs'">
<div class="form-tabs">
<el-tabs
v-bind="element.control"
:class="[element.config?.className]"
>
<el-tab-pane
v-for="(item, tIndex) in element.columns"
:label="item.label"
:key="tIndex"
>
<WebFormGroup :data="item.list" data-type="not-nested" />
</el-tab-pane>
</el-tabs>
</div>
</template>
<!--标题组件-->
<template v-else-if="element.type === 'title'">
<div
class="title"
:class="[element.config.className]"
v-bind="element.control"
:style="getFormItemLableStyle(element.styles)"
>
<span v-html="element.control.modelValue"></span>
<Tooltips
:content="element.config.help"
v-if="element.config.help"
/>
</div>
</template>
<!--文字组件-->
<template v-else-if="element.type === 'txt'">
<div
v-bind="element.control"
:class="[element.config.className]"
v-html="element.control.modelValue"
>
</div>
</template>
<!--表格组件-->
<template v-else-if="element.type === 'table'">
</template>
<!--格栅布局-->
<template v-else-if="element.type === 'grid'">
<el-row class="form-row" :style="type === 5?'padding: 0 0 20px 0;':''" :class="[element.className]">
<el-col
class="form-col"
:class="{
'active-col': activeKey === getGroupName(col),
[col.className]: col.className
}"
v-for="(col, i) in element.columns"
:key="i"
@click.stop="groupClick(col, 'gridChild')"
>
<WebFormGroup :data="col.list" data-type="not-nested" />
<div class="drag-control" v-if="type === 5">
<div class="item-control">
<i
class="icon-del"
@click.stop="click('delGridChild', i as number, element.columns)"
>
</i>
</div>
</div>
</el-col>
</el-row>
</template>
<!--卡片布局-->
<template v-else-if="element.type === 'card'">
<el-collapse model-value="1">
<el-collapse-item :title="element.item.label" name="1">
<template #title v-if="element.help">
{{ element.item.label }}
<Tooltips :content="element.help" />
</template>
<WebFormGroup :data="element.list" data-type="not-nested" />
</el-collapse-item>
</el-collapse>
</template>
<!--div容器-->
<template v-else-if="element.type === 'div'">
<div
class="div-layout"
v-bind="element.control"
>
<WebFormGroup :data="element.list" data-type="not-nested" />
</div>
</template>
<!--弹性布局-->
<template v-else-if="element.type === 'flex'">
<WebFormGroup
:data="element.list"
data-type="not-flex"
v-if="type === 5"
/>
<flex-box :data="element" v-else />
<el-button
style="position: relative; top: -28px; left: 10px"
v-if="element.config.addBtnText && type === 5"
size="small"
>
{{ element.config.addBtnText }}
</el-button>
</template>
<!--按钮-->
<template v-else-if="element.type === 'button'">
<div
:class="[element.config?.className]"
:style="{ 'text-align': element.config?.textAlign }"
>
<el-button
v-bind="element.control"
@click="clickBtn(element.control)"
color="#626aef"
>
<td :style="getFormItemLableStyle(element.styles)">{{ element.control?.label }}</td>
</el-button>
</div>
</template>
<!--分割线-->
<template v-else-if="element.type === 'divider'">
<el-divider v-bind="element.control">{{ element.item && element.item.label }}</el-divider>
</template>
<!--其他组件-->
<FormItem v-else :data="element" @optionsValue3Get1="optionsValue3Get1" :purview="props.purview" :node-key="props.nodeKey" :tablekey="props.tableinfo" :numrun="props.numrun" @asf-value-changed="asfValueChanged" />
<!--组件设计外功能框架-->
<template v-if="type === 5">
<div class="drag-control">
<div class="item-control">
<i
class="icon-plus"
@click.stop="click('gridAdd', index, element)"
v-if="state.gridAdd"
title="添加列"
></i>
<i
class="icon-clone"
@click.stop="click('clone', index, element)"
v-if="state.clone"
title="克隆"
></i>
<i class="icon-del" @click.stop="click('del', index)"></i>
</div>
<div class="drag-move icon-move"></div>
</div>
<!-- <div class="tooltip" style="display: black;">{{ element.name }}</div> -->
<div class="tooltip" style="display: black;"></div>
</template>
</div>
</template>
</draggable>
</template>
<style lang='scss' scoped>
</style>

2
src/components/DesignForm/public/headToolsApp.vue

@ -25,6 +25,8 @@ const props = withDefaults(
const emits = defineEmits<{(e: 'click', value: string): void}>(); const emits = defineEmits<{(e: 'click', value: string): void}>();
const btnList = computed(() => { const btnList = computed(() => {
const list = [ const list = [
{ icon: 'monitor',iconFont:"fa-desktop", label: 'PC端', key: 101 },
{ icon: 'iphone',iconFont:"fa-mobile", label: '手机端', key: 102 },
{ icon: 'del',iconFont:"", label: '清空', key: 1 }, { icon: 'del',iconFont:"", label: '清空', key: 1 },
{ icon: 'eye',iconFont:"", label: '预览', key: 2 }, { icon: 'eye',iconFont:"", label: '预览', key: 2 },
{ icon: 'json',iconFont:"", label: '生成脚本预览', key: 3 }, { icon: 'json',iconFont:"", label: '生成脚本预览', key: 3 },

20
src/views/sysworkflow/lowcodepage/appPage/appPageForm/pageForm.vue

@ -210,6 +210,7 @@ const dialogCancel = () => {
drawer.callback = '' drawer.callback = ''
drawer.content = '' drawer.content = ''
} }
const isWeb = ref(false)
/** /**
@ 作者: 秦东 @ 作者: 秦东
@ 时间: 2024-05-13 14:40:40 @ 时间: 2024-05-13 14:40:40
@ -254,6 +255,13 @@ const buttonCallbackEvent = (type: string) => {
break break
case 'branch': // case 'branch': //
saveOtherVersionIng(); saveOtherVersionIng();
case 'monitor':
isWeb.value = false;
// console.log("monitor",isWeb); //
break
case 'iphone':
isWeb.value = true;
// console.log("iphone",isWeb); //
break break
} }
} }
@ -643,6 +651,7 @@ const dialogConfirmTree = (val:treeStruct[]) => {
<el-main class="mainBox rightBox"> <el-main class="mainBox rightBox">
<HeadToolsApp v-loading="state.loading" :customerformid="props.appPageKey" @click="buttonCallbackEvent" /> <HeadToolsApp v-loading="state.loading" :customerformid="props.appPageKey" @click="buttonCallbackEvent" />
<div v-loading="state.loading" class="main_form"> <div v-loading="state.loading" class="main_form">
<div v-if="state.formData.list.length === 0" class="empty-tips"> <div v-if="state.formData.list.length === 0" class="empty-tips">
从左侧拖拽来添加组件<br> 从左侧拖拽来添加组件<br>
@ -659,6 +668,7 @@ const dialogConfirmTree = (val:treeStruct[]) => {
:type="5" :type="5"
:form-data="state.formData" :form-data="state.formData"
:dict="state.formDict" :dict="state.formDict"
v-model:is-web="isWeb"
@optionsValue3Get3="optionsValue3Get3" @optionsValue3Get3="optionsValue3Get3"
/> />
</div> </div>
@ -715,13 +725,9 @@ const dialogConfirmTree = (val:treeStruct[]) => {
height: calc(100vh - 80px); height: calc(100vh - 80px);
} }
.main_form { .main_form {
background: #fff; background: #EDEFF3;
border: 1px dashed #999; padding: 10px 0 0 0;
margin: 10px; height: calc(100vh - 80px);
height: calc(100vh - 105px);
overflow-y: auto;
overflow-x: hidden;
position: relative;
} }
.main_form .empty-tips { .main_form .empty-tips {
text-align: center; text-align: center;

196
vite.config.ts.timestamp-1728864900350-747b70aad68c5.mjs

File diff suppressed because one or more lines are too long

196
vite.config.ts.timestamp-1729123960837-9e5f8fdba4273.mjs

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