Compare commits
2 Commits
1c5f3c8cdb
...
f0c3aaa59b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0c3aaa59b | ||
|
|
919e073f78 |
@ -92,7 +92,8 @@ interface RegDictItem {
|
|||||||
remark: string
|
remark: string
|
||||||
}
|
}
|
||||||
// 列表相关
|
// 列表相关
|
||||||
const menuname = ref<string>("仪器全局")
|
const optiontype= ref<string>("SYSTEM")
|
||||||
|
const menuname = ref<string>("系统全局")
|
||||||
const regdictList = ref<RegDictItem[]>([])
|
const regdictList = ref<RegDictItem[]>([])
|
||||||
const originRegdictList = ref<RegDictItem[]>([])
|
const originRegdictList = ref<RegDictItem[]>([])
|
||||||
const loading = ref<boolean>(false)
|
const loading = ref<boolean>(false)
|
||||||
@ -123,7 +124,7 @@ const tableData3 = computed<RegDictItem[]>(() => {
|
|||||||
const getList = async (): Promise<void> => {
|
const getList = async (): Promise<void> => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const response = await paramList({ yq: yq.value })
|
const response = await paramList({ yq: yq.value,optiontype:optiontype.value })
|
||||||
regdictList.value = JSON.parse(JSON.stringify(response.data))
|
regdictList.value = JSON.parse(JSON.stringify(response.data))
|
||||||
originRegdictList.value = JSON.parse(JSON.stringify(response.data))
|
originRegdictList.value = JSON.parse(JSON.stringify(response.data))
|
||||||
total.value = response.data.length
|
total.value = response.data.length
|
||||||
@ -186,7 +187,7 @@ const handleRestoreDefault = async (): Promise<void> => {
|
|||||||
).then(async () => {
|
).then(async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
const res = await getdef({ yq: yq.value })
|
const res = await getdef({optiontype:optiontype.value })
|
||||||
regdictList.value = JSON.parse(JSON.stringify(res.data))
|
regdictList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
originRegdictList.value = JSON.parse(JSON.stringify(res.data))
|
originRegdictList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
total.value = res.data.length
|
total.value = res.data.length
|
||||||
|
|||||||
328
src/views/liswork/xtwh/comopt/components/sysInput.vue
Normal file
328
src/views/liswork/xtwh/comopt/components/sysInput.vue
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
<!-- 系统全局选项 -->
|
||||||
|
<template>
|
||||||
|
<div class="sys_box">
|
||||||
|
<el-row :gutter="10" class="table-toolbar">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="primary" plain icon="Check" @click="handleSave">保存</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="success" plain icon="Edit" @click="handleCancelEdit">取消修改</el-button>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="danger" plain icon="RefreshRight" @click="handleRestoreDefault">还原默认</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 三列表格容器 -->
|
||||||
|
<div class="triple-table-wrapper">
|
||||||
|
<!-- 第一列表格 -->
|
||||||
|
<div class="table-panel table-1">
|
||||||
|
<el-table v-loading="loading" :data="tableData1" @selection-change="handleSelectionChange" class="config-table"
|
||||||
|
fit border height="100%" :cell-spacing="0">
|
||||||
|
<el-table-column label="序号" align="center" prop="configSort" width="50" />
|
||||||
|
<el-table-column :label="`${menuname}名称`" align="left" prop="configName" show-overflow-tooltip
|
||||||
|
min-width="150" />
|
||||||
|
<el-table-column label="参数值" align="center" prop="configDefvalue" show-overflow-tooltip min-width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<DynamicInput :type="scope.row.configOptiontype" v-model="scope.row.configDefvalue"
|
||||||
|
:dict-data="scope.row.remark" :placeholder="`请输入${scope.row.configName}值`" class="edit-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="值码" align="center" prop="configDefvalue" v-if="false" show-overflow-tooltip
|
||||||
|
min-width="100" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 第二列表格 -->
|
||||||
|
<div class="table-panel table-2">
|
||||||
|
<el-table v-loading="loading" :data="tableData2" @selection-change="handleSelectionChange" class="config-table"
|
||||||
|
fit border height="100%" :cell-spacing="0">
|
||||||
|
<el-table-column label="序号" align="center" prop="configSort" width="50" />
|
||||||
|
<el-table-column :label="`${menuname}名称`" align="left" prop="configName" show-overflow-tooltip
|
||||||
|
min-width="150" />
|
||||||
|
<el-table-column label="参数值" align="center" prop="configDefvalue" show-overflow-tooltip min-width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<DynamicInput :type="scope.row.configOptiontype" v-model="scope.row.configDefvalue"
|
||||||
|
:dict-data="scope.row.remark" :placeholder="`请输入${scope.row.configName}值`" class="edit-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="值码" align="center" prop="configDefvalue" v-if="false" show-overflow-tooltip
|
||||||
|
min-width="100" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 第三列表格 -->
|
||||||
|
<div class="table-panel table-3">
|
||||||
|
<el-table v-loading="loading" :data="tableData3" @selection-change="handleSelectionChange" class="config-table"
|
||||||
|
fit border height="100%" :cell-spacing="0">
|
||||||
|
<el-table-column label="序号" align="center" prop="configSort" width="50" />
|
||||||
|
<el-table-column :label="`${menuname}名称`" align="left" prop="configName" show-overflow-tooltip
|
||||||
|
min-width="150" />
|
||||||
|
<el-table-column label="参数值" align="center" prop="configDefvalue" show-overflow-tooltip min-width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<DynamicInput :type="scope.row.configOptiontype" v-model="scope.row.configDefvalue"
|
||||||
|
:dict-data="scope.row.remark" :placeholder="`请输入${scope.row.configName}值`" class="edit-input" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="值码" align="center" prop="configDefvalue" v-if="false" show-overflow-tooltip
|
||||||
|
min-width="100" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ElMessage, ElTree, TreeNode, ElMessageBox, ElBadge } from 'element-plus'
|
||||||
|
import { paramList, paramTree, getdef, updateParam } from '@/api/liswork/xtwh/ComOpt'
|
||||||
|
// @ts-ignore
|
||||||
|
import { getFirstLetter } from '@/utils/pinyin.js'
|
||||||
|
// @ts-ignore
|
||||||
|
import DynamicInput from "@/views/liswork/xtwh/localconfig/components/DynamicInput.vue"
|
||||||
|
const emits = defineEmits(['updateTree'])
|
||||||
|
const yq = defineModel<string>()
|
||||||
|
|
||||||
|
interface RegDictItem {
|
||||||
|
configId: string | number
|
||||||
|
configSort: number
|
||||||
|
configCode: string
|
||||||
|
configName: string
|
||||||
|
configDefvalue: string | number
|
||||||
|
configOptiontype: string
|
||||||
|
remark: string
|
||||||
|
}
|
||||||
|
// 列表相关
|
||||||
|
const optiontype= ref<string>("INPUT")
|
||||||
|
const menuname = ref<string>("界面设定")
|
||||||
|
const regdictList = ref<RegDictItem[]>([])
|
||||||
|
const originRegdictList = ref<RegDictItem[]>([])
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
const total = ref<number>(0)
|
||||||
|
|
||||||
|
// 选择相关
|
||||||
|
const ids = ref<(string | number)[]>([])
|
||||||
|
const single = ref<boolean>(true)
|
||||||
|
const multiple = ref<boolean>(true)
|
||||||
|
|
||||||
|
// ========== 核心:拆分三列表格数据 ==========
|
||||||
|
const tableData1 = computed<RegDictItem[]>(() => {
|
||||||
|
const splitSize = Math.ceil(total.value / 3) // 每列基础行数
|
||||||
|
return regdictList.value.slice(0, splitSize)
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableData2 = computed<RegDictItem[]>(() => {
|
||||||
|
const splitSize = Math.ceil(total.value / 3)
|
||||||
|
return regdictList.value.slice(splitSize, splitSize * 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
const tableData3 = computed<RegDictItem[]>(() => {
|
||||||
|
const splitSize = Math.ceil(total.value / 3)
|
||||||
|
return regdictList.value.slice(splitSize * 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getList = async (): Promise<void> => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await paramList({ yq: yq.value,optiontype:optiontype.value })
|
||||||
|
regdictList.value = JSON.parse(JSON.stringify(response.data))
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(response.data))
|
||||||
|
total.value = response.data.length
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error(`获取列表异常:${(error as Error).message}`)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSelectionChange = (val: RegDictItem[]): void => {
|
||||||
|
ids.value = val.map(item => item.configId)
|
||||||
|
single.value = val.length === 1
|
||||||
|
multiple.value = val.length > 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSave = async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
loading.value = true
|
||||||
|
// 合并三列表格数据提交
|
||||||
|
const allData = [...tableData1.value, ...tableData2.value, ...tableData3.value]
|
||||||
|
const res = await updateParam(allData)
|
||||||
|
if (res.code == 0) {
|
||||||
|
ElMessage.success(res.msg || "保存成功")
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(allData))
|
||||||
|
// 更新树结构状态
|
||||||
|
emits('updateTree')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error(`保存失败:${(error as Error).message}`)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancelEdit = (): void => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
"是否确认取消所有修改,恢复原始数据?",
|
||||||
|
"提示",
|
||||||
|
{
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
regdictList.value = JSON.parse(JSON.stringify(originRegdictList.value))
|
||||||
|
ElMessage.success("已恢复原始数据!")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleRestoreDefault = async (): Promise<void> => {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
"是否确认还原所有默认值?此操作会覆盖当前修改!",
|
||||||
|
"警告",
|
||||||
|
{
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error"
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getdef({optiontype:optiontype.value })
|
||||||
|
regdictList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(res.data))
|
||||||
|
total.value = res.data.length
|
||||||
|
ElMessage.success("还原默认值成功!")
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error(`还原失败:${(error as Error).message}`)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
watch(yq, (newVal) => {
|
||||||
|
if (newVal !== undefined) {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.sys_box {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三列表格容器
|
||||||
|
.triple-table-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
height: calc(100% - 45px); // 减去标题行+工具栏高度
|
||||||
|
display: flex;
|
||||||
|
gap: 0px; // 表格间间距
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
// 单个表格面板
|
||||||
|
.table-panel {
|
||||||
|
flex: 1; // 三列均等分
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
// 细微间距优化
|
||||||
|
&.table-1 {
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-2 {
|
||||||
|
margin: 0 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.table-3 {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 核心:清除表格内上下间隙
|
||||||
|
:deep(.config-table) {
|
||||||
|
// 清除表格整体的边框间距
|
||||||
|
border-collapse: collapse !important;
|
||||||
|
border-spacing: 0 !important;
|
||||||
|
|
||||||
|
// 清除表格头部间距
|
||||||
|
.el-table__header {
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
th {
|
||||||
|
padding: 0 !important;
|
||||||
|
border-bottom: 1px solid #e6e6e6 !important;
|
||||||
|
line-height: 25px !important;
|
||||||
|
height: 25px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除表格内容区间距
|
||||||
|
.el-table__body {
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
// 清除行间距
|
||||||
|
.el-table__row {
|
||||||
|
height: 25px !important;
|
||||||
|
line-height: 25px !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除单元格内边距和间距
|
||||||
|
.el-table__cell {
|
||||||
|
padding: 0 4px !important; // 仅保留左右内边距,上下清零
|
||||||
|
height: 25px !important;
|
||||||
|
line-height: 25px !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
font-size: 12px;
|
||||||
|
border-bottom: 1px solid #e6e6e6 !important;
|
||||||
|
border-right: 1px solid #e6e6e6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最后一列清除右侧边框
|
||||||
|
.el-table__cell:last-child {
|
||||||
|
border-right: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除表格底部间距
|
||||||
|
.el-table__footer {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑输入框适配紧凑布局
|
||||||
|
.edit-input {
|
||||||
|
width: 95%;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
:deep(.el-input__inner) {
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 25px !important; // 缩小输入框高度适配紧凑行高
|
||||||
|
line-height: 25px !important;
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
margin: 0 !important;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: #409eff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -47,6 +47,7 @@ import { paramList, paramTree, getdef, updateParam } from '@/api/liswork/xtwh/Co
|
|||||||
import { getFirstLetter } from '@/utils/pinyin.js'
|
import { getFirstLetter } from '@/utils/pinyin.js'
|
||||||
|
|
||||||
import SysGlobal from './components/sysGlobal.vue'
|
import SysGlobal from './components/sysGlobal.vue'
|
||||||
|
import SysInput from './components/sysInput.vue'
|
||||||
import SysReport from './components/sysReport.vue'
|
import SysReport from './components/sysReport.vue'
|
||||||
|
|
||||||
// ========== TypeScript 类型定义 ==========
|
// ========== TypeScript 类型定义 ==========
|
||||||
@ -102,8 +103,9 @@ const queryParams = ref<QueryParams>({
|
|||||||
|
|
||||||
|
|
||||||
const tabList = [
|
const tabList = [
|
||||||
{ key: 'SysGlobal', label: '系统全局参数', component: SysGlobal },
|
{ key: 'SysGlobal', label: '全局设定', component: SysGlobal },
|
||||||
{ key: 'SysReport', label: '报告界面', component: SysReport },
|
{ key: 'SysInput', label: '界面设定', component: SysInput },
|
||||||
|
{ key: 'SysReport', label: '报告单设置', component: SysReport },
|
||||||
]
|
]
|
||||||
const activeName = ref('SysGlobal')
|
const activeName = ref('SysGlobal')
|
||||||
|
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<!-- 4. 字典多选(3):数组↔逗号分隔字符串 -->
|
<!-- 4. 字典多选(3):数组↔逗号分隔字符串 → 修复核心:仅绑定multipleValue,移除冗余逻辑 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-else-if="type === '3'"
|
v-else-if="type === '3'"
|
||||||
v-model="multipleValue"
|
v-model="multipleValue"
|
||||||
@ -53,6 +53,7 @@
|
|||||||
multiple
|
multiple
|
||||||
@change="handleMultipleChange"
|
@change="handleMultipleChange"
|
||||||
v-loading="dictLoading"
|
v-loading="dictLoading"
|
||||||
|
clearable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in dictOptions"
|
v-for="item in dictOptions"
|
||||||
@ -154,7 +155,7 @@ const emit = defineEmits(["update:modelValue", "change"]);
|
|||||||
|
|
||||||
// 内部状态
|
// 内部状态
|
||||||
const innerValue = ref(null); // 初始值改为null,适配空值
|
const innerValue = ref(null); // 初始值改为null,适配空值
|
||||||
const multipleValue = ref([]); // 多选值(仅type=3用)
|
const multipleValue = ref([]); // 多选值(仅type=3用)→ 核心:初始化为空数组,杜绝默认0
|
||||||
const dictOptions = ref([]); // 下拉/字典选项列表
|
const dictOptions = ref([]); // 下拉/字典选项列表
|
||||||
const dictLoading = ref(false); // 字典加载状态
|
const dictLoading = ref(false); // 字典加载状态
|
||||||
|
|
||||||
@ -172,7 +173,7 @@ const finalPrecision = computed(() => {
|
|||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// ========== 核心:值初始化 + 格式适配 ==========
|
// ========== 核心修复:值初始化 + 格式适配 → 重点优化多选逻辑 ==========
|
||||||
watch(() => props.modelValue, (newVal) => {
|
watch(() => props.modelValue, (newVal) => {
|
||||||
const val = newVal; // 移除兜底空值,保留原始值
|
const val = newVal; // 移除兜底空值,保留原始值
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
@ -187,12 +188,25 @@ watch(() => props.modelValue, (newVal) => {
|
|||||||
innerValue.value = val === null || val === undefined ? "" : String(val);
|
innerValue.value = val === null || val === undefined ? "" : String(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 字典多选:后端逗号字符串→前端数组
|
// 字典多选:核心修复 → 严格过滤空值/无效值,杜绝默认0
|
||||||
case "3":
|
case "3":
|
||||||
multipleValue.value = typeof val === "string" && val
|
// 1. 空值/0/空字符串 → 空数组
|
||||||
? val.split(",").map(item => String(item))
|
if (val === null || val === undefined || val === "" || val === 0) {
|
||||||
: [];
|
multipleValue.value = [];
|
||||||
innerValue.value = val || "";
|
}
|
||||||
|
// 2. 有效字符串 → 分割为数组(过滤空项)
|
||||||
|
else if (typeof val === "string") {
|
||||||
|
multipleValue.value = val.split(",").filter(item => item.trim() !== "").map(item => String(item));
|
||||||
|
}
|
||||||
|
// 3. 数组类型(特殊场景)→ 直接赋值
|
||||||
|
else if (Array.isArray(val)) {
|
||||||
|
multipleValue.value = val.filter(item => item !== null && item !== undefined && item !== "").map(item => String(item));
|
||||||
|
}
|
||||||
|
// 4. 其他类型 → 空数组
|
||||||
|
else {
|
||||||
|
multipleValue.value = [];
|
||||||
|
}
|
||||||
|
// 移除innerValue同步(避免干扰多选)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 数字框:空值处理,支持小数位数
|
// 数字框:空值处理,支持小数位数
|
||||||
@ -226,8 +240,11 @@ watch(() => props.modelValue, (newVal) => {
|
|||||||
}
|
}
|
||||||
}, { immediate: true, deep: true });
|
}, { immediate: true, deep: true });
|
||||||
|
|
||||||
// ========== 同步子组件值到父组件 ==========
|
// ========== 修复:移除innerValue对多选的干扰 → 仅监听非多选类型 ==========
|
||||||
watch(innerValue, (newVal) => {
|
watch(innerValue, (newVal) => {
|
||||||
|
// 多选类型跳过innerValue监听
|
||||||
|
if (props.type === "3") return;
|
||||||
|
|
||||||
let finalVal = newVal;
|
let finalVal = newVal;
|
||||||
|
|
||||||
// 数字框:空值提交空字符串,非空则保留数字类型
|
// 数字框:空值提交空字符串,非空则保留数字类型
|
||||||
@ -247,7 +264,7 @@ watch(innerValue, (newVal) => {
|
|||||||
emit("change", finalVal);
|
emit("change", finalVal);
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
// ========== 字典加载逻辑 ==========
|
// ========== 字典加载逻辑 → 新增:字典加载后重新同步多选值 ==========
|
||||||
watch([() => props.type, () => props.dictData], async () => {
|
watch([() => props.type, () => props.dictData], async () => {
|
||||||
dictOptions.value = [];
|
dictOptions.value = [];
|
||||||
// 数字框(type=6)不需要加载字典
|
// 数字框(type=6)不需要加载字典
|
||||||
@ -255,6 +272,15 @@ watch([() => props.type, () => props.dictData], async () => {
|
|||||||
await parseJsonDict();
|
await parseJsonDict();
|
||||||
} else if (["2", "3"].includes(props.type)) {
|
} else if (["2", "3"].includes(props.type)) {
|
||||||
await loadApiDict();
|
await loadApiDict();
|
||||||
|
// 字典加载完成后,重新同步多选值(修复选不到值的问题)
|
||||||
|
if (props.type === "3") {
|
||||||
|
const val = props.modelValue;
|
||||||
|
if (val === null || val === undefined || val === "" || val === 0) {
|
||||||
|
multipleValue.value = [];
|
||||||
|
} else if (typeof val === "string") {
|
||||||
|
multipleValue.value = val.split(",").filter(item => item.trim() !== "").map(item => String(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true });
|
}, { immediate: true, deep: true });
|
||||||
|
|
||||||
@ -319,34 +345,34 @@ function handleValueChange(val) {
|
|||||||
emit("change", finalVal);
|
emit("change", finalVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 多选值变更处理 ==========
|
// ========== 核心修复:多选值变更处理 → 简化逻辑,杜绝值覆盖 ==========
|
||||||
function handleMultipleChange(val) {
|
function handleMultipleChange(val) {
|
||||||
const strVal = val?.join(",") || "";
|
// 1. 过滤空值,避免提交无效数据
|
||||||
innerValue.value = strVal;
|
const validVal = val.filter(item => item !== null && item !== undefined && item !== "");
|
||||||
multipleValue.value = val;
|
// 2. 转为逗号分隔字符串(后端格式)
|
||||||
|
const strVal = validVal.join(",");
|
||||||
|
// 3. 更新多选值(确保同步)
|
||||||
|
multipleValue.value = validVal;
|
||||||
|
// 4. 触发父组件更新
|
||||||
emit("update:modelValue", strVal);
|
emit("update:modelValue", strVal);
|
||||||
emit("change", strVal);
|
emit("change", strVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 多选值同步监听 ==========
|
// ========== 初始化优化 → 移除多选冗余逻辑,杜绝默认0 ==========
|
||||||
watch(multipleValue, (newVal) => {
|
|
||||||
if (props.type === "3") {
|
|
||||||
const strVal = newVal?.join(",") || "";
|
|
||||||
innerValue.value = strVal;
|
|
||||||
emit("update:modelValue", strVal);
|
|
||||||
}
|
|
||||||
}, {deep: true});
|
|
||||||
|
|
||||||
// ========== 初始化兜底 ==========
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 开关组件初始值兜底
|
// 开关组件初始值兜底
|
||||||
if (props.type === "0" && innerValue.value === null) {
|
if (props.type === "0" && innerValue.value === null) {
|
||||||
innerValue.value = "0"; // 默认关闭
|
innerValue.value = "0"; // 默认关闭
|
||||||
emit("update:modelValue", 0); // 后端默认值:0
|
emit("update:modelValue", 0); // 后端默认值:0
|
||||||
}
|
}
|
||||||
// 多选值初始化
|
// 多选初始化:仅处理有效值,杜绝空值/0转为["0"]
|
||||||
if (props.type === "3" && !multipleValue.value.length && innerValue.value) {
|
if (props.type === "3") {
|
||||||
multipleValue.value = innerValue.value.split(",").map(item => String(item));
|
const val = props.modelValue;
|
||||||
|
if (val === null || val === undefined || val === "" || val === 0) {
|
||||||
|
multipleValue.value = [];
|
||||||
|
} else if (typeof val === "string") {
|
||||||
|
multipleValue.value = val.split(",").filter(item => item.trim() !== "").map(item => String(item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -401,10 +427,15 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 空值时占位符样式 */
|
/* 空值时占位符样式 */
|
||||||
|
|
||||||
.el-input__placeholder {
|
.el-input__placeholder {
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 多选下拉样式优化:避免高度溢出 */
|
||||||
|
:deep(.el-select--multiple .el-select__tags) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
min-height: 32px; /* 匹配small尺寸高度 */
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user