9 changed files with 2440 additions and 10 deletions
@ -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-item的prop值,用于子表校验用 |
||||
|
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 根据条件搜索,select远程搜索里data有值 |
||||
|
const getAxiosOptions = debounce((data?: any) => { |
||||
|
//console.log(props.data) |
||||
|
const { |
||||
|
optionsType, |
||||
|
optionsFun, |
||||
|
method = 'post', |
||||
|
afterResponse, |
||||
|
beforeRequest, |
||||
|
label, |
||||
|
value, |
||||
|
debug // =true可用于调试,不存sessionStorage |
||||
|
} = 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() |
||||
|
} |
||||
|
) |
||||
|
// 处理自定义校验规则,将customRules转换后追加到rules里 |
||||
|
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) { |
||||
|
// 当使用validator校验时,如果存在message字段则不能使用 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*/ |
||||
|
} |
||||
|
) |
||||
|
// 对单选多选select设置options |
||||
|
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> |
||||
@ -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, // 以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入 |
||||
|
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', //分别对应三个类型文件的上传:link插件,image和axupimgs插件,media插件。想屏蔽某个插件的上传就去掉对应的参数 |
||||
|
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> |
||||
@ -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 |
||||
|
} |
||||
|
} |
||||
|
// 如果当前字段的name值存在于表单数据的vIf中,则不显示 |
||||
|
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"){//tabs标签页有可能再嵌套一层flex或者table |
||||
|
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> |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue