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

392 lines
11 KiB

<!--
@ 作者: 秦东
@ 时间: 2023-12-05 09:40:32
@ 备注: 链接地址组件
-->
<script lang='ts' setup>
import { ref, computed, watch } from 'vue';
import { ElMessage } from 'element-plus'
import {
constControlChange,
constFormProps,
} from '@/api/DesignForm/utils'
import validate from '@/api/DesignForm/validate'
import { FormItem, FormList } from '@/api/DesignForm/types'
import Tooltips from '@/components/DesignForm/tooltip.vue'
import areaObj from './pca.json';
import { nodePoweInfo,powerAryInfo } from "@/api/taskapi/types";
const props = withDefaults(
defineProps<{
data: FormList
tablekey: any
numrun?: number
modelValue?: any // 子表和弹性布局时时有传
tProp?: string // 子表时的form-item的prop值,用于子表校验用
}>(),
{}
)
const emits = defineEmits<{
(e: 'update:modelValue', numVal: any): void
}>()
const formProps = inject(constFormProps, {}) as any
const type = computed(() => {
return formProps.value.type
})
const control = computed(() => {
return props.data.control || {}
// return props.data
})
const config = computed(() => {
return props.data.config || {}
})
const changeEvent = inject(constControlChange, '') as any
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 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
})
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 getLabel = (ele: FormItem) => {
const showColon = formProps.value.showColon ? ':' : ''
if (ele) {
return ele.showLabel ? '' : ele.label + showColon
} else {
return ''
}
}
// 返回当前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
})
// 处理自定义校验规则,将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
}
const addressBox = ref(false)
// 省
const provinceArr = Object.keys(areaObj)
const province = ref(provinceArr[0])
// 市
const cityArr = computed(() => {
return Object.keys(areaObj[province.value])
})
const city = ref(cityArr.value[0])
// 监听省份变化
watch(province, (newVal) => {
city.value = Object.keys(areaObj[newVal])[0];
if(value.value != "" && value.value != null){
let ads = value.value.split(" - ")
if(ads.length >=2){
city.value = ads[1]
}else{
city.value = Object.keys(areaObj[newVal])[0];
}
}else{
city.value = Object.keys(areaObj[newVal])[0];
}
});
// 区
const areaArr = computed(() => {
return areaObj[province.value][city.value]
})
const area = ref(areaArr.value[0])
// 监听市变化
watch(city, (newVal) => {
if(value.value != "" && value.value != null){
let ads = value.value.split(" - ")
if(ads.length >=3){
area.value = ads[2]
}else{
area.value = areaObj[province.value][newVal][0]
}
}else{
area.value = areaObj[province.value][newVal][0]
}
})
const fullAddress = ref<string>("")
//打开地址选择弹窗
const openAddress = () =>{
if(value.value != "" && value.value != null){
let ads = value.value.split(" - ")
// console.log(ads)
if(ads.length >= 4){
province.value = ads[0]
fullAddress.value = ads[3]
}else if(ads.length >0){
province.value = ads[0]
}
}else{
province.value = provinceArr[0]
city.value = cityArr.value[0]
area.value = areaArr.value[0]
fullAddress.value = ""
}
addressBox.value=true
}
//关闭地址选择弹窗
const addressBoxClose = () => {
addressBox.value=false
initAddressData()
}
//确定选择地址
const submitAddress = () => {
// console.log(province.value,city.value,area.value,fullAddress.value)
if(province.value == "" || province.value == null){
ElMessage.error('未选择省份!')
return
}
if(city.value == "" || city.value == null){
ElMessage.error('未选择市/区!')
return
}
if(area.value == "" || area.value == null){
ElMessage.error('未选择县/市!')
return
}
if(fullAddress.value == "" || fullAddress.value == null){
ElMessage.error('未填写详细信息!')
return
}
value.value = province.value + " - " + city.value + " - " + area.value + " - " + fullAddress.value
addressBoxClose()
}
const initAddressData = () =>{
province.value = provinceArr[0]
fullAddress.value = ""
}
const allNodePwoer = inject('flowNodePower') as any
const currentNodePowerKey = inject('currentNodeKey') as any
//获取当前节点授权
const curNodePowerAry = () => {
if(currentNodePowerKey && currentNodePowerKey.value && currentNodePowerKey.value != ""){
if(allNodePwoer.value && Array.isArray(allNodePwoer.value) && allNodePwoer.value.length > 0){
let powerAry: any[] = []
allNodePwoer.value.forEach((item:nodePoweInfo) => {
if(item.nodeKey == currentNodePowerKey.value){
powerAry = item.powerAry
}
})
return powerAry
}else{
return []
}
}else{
return []
}
}
/**
@ 作者: 秦东
@ 时间: 2025-11-06 14:03:21
@ 功能: 判断此组件是否可见
*/
const judgeIsShow = (key: string) => {
let myPower = curNodePowerAry() //获取权限数组
if(Array.isArray(myPower) && myPower.length > 0){
let isOk = true
myPower.forEach((item:powerAryInfo) => {
if(key == item.id){
isOk = item.isLook
}
})
return isOk
}else{
return true
}
}
/**
@ 作者: 秦东
@ 时间: 2025-11-06 14:03:21
@ 功能: 判断此组件是否可编辑
*/
const judgeIsEdit = (key: string) => {
let myPower = curNodePowerAry() //获取权限数组
if(Array.isArray(myPower) && myPower.length > 0){
let isOk = false
myPower.forEach((item:powerAryInfo) => {
if(key == item.id){
isOk = !item.isEdit
}
})
return isOk
}else{
return false
}
}
</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)"
v-if="judgeIsShow(data.name)"
>
<template v-if="config.help" #label >
{{ getLabel(data.item) }}
<Tooltips :content="config.help" />
</template>
<div v-if="type === 4" class="form-value" v-html="value"></div>
<template v-else>
<el-input v-model="value" :disabled="editDisabled" clearable placeholder="请选择地址" @click="openAddress" />
</template>
</el-form-item>
<el-dialog
v-model="addressBox"
title="填写地址"
width="600px"
:modal="false"
:before-close="addressBoxClose"
>
<el-row>
<el-col :span="3">所在地区:</el-col>
<el-col :span="21">
<el-row :gutter="20">
<el-col :span="8">
<el-select v-model="province" class="m-2" placeholder="省">
<el-option v-for="item in provinceArr" :key="item" :label="item" :value="item" />
</el-select>
</el-col>
<el-col :span="8">
<el-select v-model="city" class="m-2" placeholder="市">
<el-option v-for="item in cityArr" :key="item" :label="item" :value="item" />
</el-select>
</el-col>
<el-col :span="8">
<el-select v-model="area" class="m-2" placeholder="区/县">
<el-option v-for="item in areaArr" :key="item" :label="item" :value="item" />
</el-select>
</el-col>
</el-row>
</el-col>
</el-row>
<el-row>
<el-col :span="3">详细地址:</el-col>
<el-col :span="21">
<el-input
v-model="fullAddress"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
placeholder="请输入详细地址"
style="width:100%"
/>
</el-col>
</el-row>
<template #footer>
<span class="dialog-footer">
<el-button @click="addressBoxClose">取消</el-button>
<el-button type="primary" @click="submitAddress">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<style lang='scss' scoped>
</style>