|
|
|
|
<!--
|
|
|
|
|
@ 作者: 秦东
|
|
|
|
|
@ 时间: 2023-07-14 08:50:36
|
|
|
|
|
@ 备注: 表单项目
|
|
|
|
|
-->
|
|
|
|
|
<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 './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 AKSelect from './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 TextImg from "@/assets/image/tinymce.png"
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
|
defineProps<{
|
|
|
|
|
data: FormList
|
|
|
|
|
modelValue?: any // 子表和弹性布局时时有传
|
|
|
|
|
tProp?: string // 子表时的form-item的prop值,用于子表校验用
|
|
|
|
|
}>(),
|
|
|
|
|
{}
|
|
|
|
|
)
|
|
|
|
|
const emits = defineEmits<{
|
|
|
|
|
(e: 'update:modelValue', 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 || {}
|
|
|
|
|
})
|
|
|
|
|
const control = computed(() => {
|
|
|
|
|
return props.data.control
|
|
|
|
|
})
|
|
|
|
|
const options = ref(props.data.options)
|
|
|
|
|
const changeEvent = inject(constControlChange, '') as any
|
|
|
|
|
const updateModel = (val: any) => {
|
|
|
|
|
changeEvent &&
|
|
|
|
|
changeEvent({
|
|
|
|
|
key: props.data.name,
|
|
|
|
|
value: val,
|
|
|
|
|
data: props.data,
|
|
|
|
|
tProp: props.tProp
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
const value = computed({
|
|
|
|
|
get() {
|
|
|
|
|
if (props.tProp) {
|
|
|
|
|
// 表格和弹性布局
|
|
|
|
|
return props.modelValue
|
|
|
|
|
} 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)
|
|
|
|
|
}
|
|
|
|
|
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 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) => {
|
|
|
|
|
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 }
|
|
|
|
|
}
|
|
|
|
|
getRequest(sourceFun, newData, { method: method })
|
|
|
|
|
.then((res: any) => {
|
|
|
|
|
const result = res.data.list || res.data
|
|
|
|
|
let formatRes: any = result
|
|
|
|
|
// 这里做数据转换,很多时候后端并不能提供完全符合且一样的数据
|
|
|
|
|
if (typeof afterResponse === 'string' && afterResponse) {
|
|
|
|
|
formatRes = formatResult(result, afterResponse)
|
|
|
|
|
} else if (typeof afterResponse === 'function') {
|
|
|
|
|
// 没有return时,使用原来的,相当于没处理
|
|
|
|
|
formatRes = afterResponse(result) ?? result
|
|
|
|
|
} else if (label || value) {
|
|
|
|
|
// 没有设置afterResponse时,这里将数据转换为[{label:'',value:''}]形式。只处理一级
|
|
|
|
|
formatRes = []
|
|
|
|
|
result.forEach((item: any) => {
|
|
|
|
|
formatRes.push({
|
|
|
|
|
label: item[label] || item.label,
|
|
|
|
|
value: item[value] || item.value
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
if (formatRes === false) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// console.log('formatRes', formatRes)
|
|
|
|
|
if (props.data.type === 'treeSelect') {
|
|
|
|
|
control.value.data = formatRes
|
|
|
|
|
} else {
|
|
|
|
|
options.value = formatRes
|
|
|
|
|
}
|
|
|
|
|
if (typeof formatRes === 'object') {
|
|
|
|
|
window.sessionStorage.setItem(key, JSON.stringify(formatRes)) //缓存,例如子表添加时不用每添加一行就请求一次
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((res: any) => {
|
|
|
|
|
if (props.data.type === 'treeSelect') {
|
|
|
|
|
control.value.data = []
|
|
|
|
|
} else {
|
|
|
|
|
options.value = []
|
|
|
|
|
}
|
|
|
|
|
console.log(res)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
setFormDict(formProps.value.dict) // 表格里新增时行时需要重新设一次
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
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) => {
|
|
|
|
|
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) => {
|
|
|
|
|
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]
|
|
|
|
|
if (imgVal && typeof imgVal === 'string') {
|
|
|
|
|
const temp: any = []
|
|
|
|
|
imgVal.split(',').forEach((item: string) => {
|
|
|
|
|
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)
|
|
|
|
|
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: ''
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
/****input slot处理结束***/
|
|
|
|
|
// treeSelect
|
|
|
|
|
// const filterMethod = (val: string) => {
|
|
|
|
|
// if (props.data.type === 'treeSelect') {
|
|
|
|
|
// // 请求参数名,可使用config.queryName传进来
|
|
|
|
|
// const queryName = config.value.queryName || 'name'
|
|
|
|
|
// control.value.filterMethod && control.value.filterMethod(val)
|
|
|
|
|
// getAxiosOptions({ [queryName]: val })
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
getAxiosOptions()
|
|
|
|
|
})
|
|
|
|
|
onUnmounted(() => {})
|
|
|
|
|
</script>
|
|
|
|
|
<template>
|
|
|
|
|
|
|
|
|
|
<el-form-item
|
|
|
|
|
v-bind="data.item"
|
|
|
|
|
:prop="tProp || data.name"
|
|
|
|
|
:class="config.className"
|
|
|
|
|
:rules="itemRules as any"
|
|
|
|
|
:label="getLabel(data.item as FormItem)"
|
|
|
|
|
>
|
|
|
|
|
<template #label v-if="config.help">
|
|
|
|
|
{{ getLabel(data.item) }}
|
|
|
|
|
<Tooltips :content="config.help" />
|
|
|
|
|
</template>
|
|
|
|
|
<div class="form-value" v-if="type === 4" v-html="value"></div>
|
|
|
|
|
<template v-else>
|
|
|
|
|
<el-input
|
|
|
|
|
v-bind="control"
|
|
|
|
|
v-model="value"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
:type="data.type === 'password' ? 'password' : 'text'"
|
|
|
|
|
v-if="['input', 'password'].includes(data.type)"
|
|
|
|
|
>
|
|
|
|
|
<template #prepend v-if="config.prepend">
|
|
|
|
|
<div v-if="getInputSlot('p')">
|
|
|
|
|
<AKSelect
|
|
|
|
|
:data="getInputSlot('p')"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
:transform-option="transformOption"
|
|
|
|
|
@change="inputSlotChange"
|
|
|
|
|
type="slot"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else>{{ config.prepend }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
<template #append v-if="config.append">
|
|
|
|
|
<div v-if="getInputSlot()">
|
|
|
|
|
<AKSelect
|
|
|
|
|
:data="getInputSlot()"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
:transform-option="transformOption"
|
|
|
|
|
type="slot"
|
|
|
|
|
@change="inputSlotChange"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else>{{ config.append }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
<el-input
|
|
|
|
|
v-bind="control"
|
|
|
|
|
v-model="value"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
type="textarea"
|
|
|
|
|
v-if="data.type === 'textarea'"
|
|
|
|
|
/>
|
|
|
|
|
<el-radio-group
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
v-model="value"
|
|
|
|
|
v-if="data.type === 'radio'"
|
|
|
|
|
>
|
|
|
|
|
<el-radio
|
|
|
|
|
:key="index"
|
|
|
|
|
:label="transformOption(item.value)"
|
|
|
|
|
v-for="(item, index) in options"
|
|
|
|
|
>
|
|
|
|
|
{{ item.label }}
|
|
|
|
|
</el-radio>
|
|
|
|
|
</el-radio-group>
|
|
|
|
|
<el-checkbox-group
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
v-model="value"
|
|
|
|
|
v-if="data.type === 'checkbox'"
|
|
|
|
|
>
|
|
|
|
|
<el-checkbox
|
|
|
|
|
v-for="(item, index) in options"
|
|
|
|
|
:key="index"
|
|
|
|
|
:label="transformOption(item.value)"
|
|
|
|
|
>
|
|
|
|
|
{{ item.label }}
|
|
|
|
|
</el-checkbox>
|
|
|
|
|
</el-checkbox-group>
|
|
|
|
|
<AKSelect
|
|
|
|
|
v-if="
|
|
|
|
|
data.type === 'select' || (type === 5 && data.type === 'inputSlot')
|
|
|
|
|
"
|
|
|
|
|
:data="data"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
v-model="value"
|
|
|
|
|
:options="options"
|
|
|
|
|
:remote-method="getAxiosOptions"
|
|
|
|
|
:transformOption="transformOption"
|
|
|
|
|
/>
|
|
|
|
|
<el-upload
|
|
|
|
|
class="upload-style"
|
|
|
|
|
v-if="data.type === 'upload'"
|
|
|
|
|
:action="uploadUrl"
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:name="control.file || 'file'"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
:file-list="fileList as any"
|
|
|
|
|
:class="{limit: control.limit <= fileList.length}"
|
|
|
|
|
:on-error="uploadError"
|
|
|
|
|
:on-success="uploadSuccess"
|
|
|
|
|
:on-remove="uploadRemove"
|
|
|
|
|
>
|
|
|
|
|
<el-button type="primary" v-if="config?.btnText">
|
|
|
|
|
{{ config?.btnText }}
|
|
|
|
|
</el-button>
|
|
|
|
|
<i class="icon-plus" v-else></i>
|
|
|
|
|
<template #tip v-if="config?.tip">
|
|
|
|
|
<div class="el-upload__tip">
|
|
|
|
|
{{ config?.tip }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-upload>
|
|
|
|
|
<component
|
|
|
|
|
v-if="['cascader', 'treeSelect'].includes(data.type)"
|
|
|
|
|
:is="currentComponent"
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
:options="options"
|
|
|
|
|
v-model="value"
|
|
|
|
|
/>
|
|
|
|
|
<component
|
|
|
|
|
v-if="
|
|
|
|
|
[
|
|
|
|
|
'rate',
|
|
|
|
|
'slider',
|
|
|
|
|
'switch',
|
|
|
|
|
'inputNumber',
|
|
|
|
|
'colorPicker',
|
|
|
|
|
'timePicker',
|
|
|
|
|
'datePicker',
|
|
|
|
|
'component',
|
|
|
|
|
'expand-user'
|
|
|
|
|
].includes(data.type)
|
|
|
|
|
"
|
|
|
|
|
:is="currentComponent"
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
v-model="value"
|
|
|
|
|
/>
|
|
|
|
|
<template v-if="data.type === 'tinymce'">
|
|
|
|
|
<!-- 设计模式时拖动会出现异常,设计模式暂用图片代替-->
|
|
|
|
|
<tinymce-edit
|
|
|
|
|
v-bind="control"
|
|
|
|
|
:config="config"
|
|
|
|
|
:disabled="editDisabled"
|
|
|
|
|
v-model="value"
|
|
|
|
|
v-if="[1, 2, 3].includes(type as number)"
|
|
|
|
|
/>
|
|
|
|
|
<img
|
|
|
|
|
alt=""
|
|
|
|
|
:src="TextImg"
|
|
|
|
|
v-if="type === 5"
|
|
|
|
|
style="max-width: 100%"
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
</template>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</template>
|
|
|
|
|
<style lang='scss' scoped>
|
|
|
|
|
|
|
|
|
|
</style>
|