本地选项设置菜单模块
This commit is contained in:
parent
f3c715875d
commit
8bb03cbe3a
45
src/api/liswork/xtwh/localconfigApi.ts
Normal file
45
src/api/liswork/xtwh/localconfigApi.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
//本地参数设置
|
||||||
|
// @ts-ignore
|
||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 查询字典列表
|
||||||
|
export function listlocalconfig(params:any) {
|
||||||
|
return request({
|
||||||
|
url: '/localconfig/list',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export function getLocalConfigDefault(params:any) {
|
||||||
|
return request({
|
||||||
|
url: '/localconfig/resetdef',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询字典下拉框内容
|
||||||
|
export function getoptionselect(params:any) {
|
||||||
|
return request({
|
||||||
|
url: '/localconfig/optionselect',
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 修改字典
|
||||||
|
export function updatelocalconfig(params:any) {
|
||||||
|
return request({
|
||||||
|
url: '/localconfig',
|
||||||
|
method: 'put',
|
||||||
|
data:params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 批量保存所有结果
|
||||||
|
export function savelocalconfig(params:any) {
|
||||||
|
return request({
|
||||||
|
url: '/localconfig/editall',
|
||||||
|
method: 'put',
|
||||||
|
data:params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@ -88,8 +88,8 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
<el-row :gutter="5" class="table-container">
|
||||||
<el-table v-loading="loading" :data="regdictList" @selection-change="handleSelectionChange" class="config-table">
|
<el-table v-loading="loading" :data="regdictList" @selection-change="handleSelectionChange" class="config-table" height="100%">
|
||||||
<el-table-column type="selection" width="55" align="center" />
|
<el-table-column type="selection" width="55" align="center" />
|
||||||
<el-table-column :label="`${menuname}编号`" align="center" prop="configId" v-if="false"/>
|
<el-table-column :label="`${menuname}编号`" align="center" prop="configId" v-if="false"/>
|
||||||
<el-table-column :label="`${menuname}类别`" align="center" prop="configType" width="100" show-overflow-tooltip>
|
<el-table-column :label="`${menuname}类别`" align="center" prop="configType" width="100" show-overflow-tooltip>
|
||||||
@ -141,15 +141,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
</el-row>
|
||||||
<pagination
|
|
||||||
v-show="total > 0"
|
|
||||||
:total="total"
|
|
||||||
v-model:page="queryParams.pageNum"
|
|
||||||
v-model:limit="queryParams.pageSize"
|
|
||||||
@pagination="getList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 添加或修改字典对话框 -->
|
<!-- 添加或修改字典对话框 -->
|
||||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||||
|
|
||||||
@ -271,8 +263,6 @@ const menuname = ref("参数");
|
|||||||
const data = reactive({
|
const data = reactive({
|
||||||
form: {},
|
form: {},
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 15,
|
|
||||||
configCode: undefined,
|
configCode: undefined,
|
||||||
configName: undefined,
|
configName: undefined,
|
||||||
configType:undefined,
|
configType:undefined,
|
||||||
@ -293,8 +283,8 @@ function getList() {
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
listconfigdict(queryParams.value).then(response => {
|
listconfigdict(queryParams.value).then(response => {
|
||||||
console.log('response:', response);
|
console.log('response:', response);
|
||||||
regdictList.value = response.rows;
|
regdictList.value = response.data;
|
||||||
total.value = response.total;
|
total.value = response.data.length;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -391,6 +381,23 @@ function handleExport() {
|
|||||||
getList();
|
getList();
|
||||||
</script>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.app-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 90vh;
|
||||||
|
/* 容器高度等于窗口高度 */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.mb8 {
|
||||||
|
height: 30px;
|
||||||
|
/* 固定高度 */
|
||||||
|
}
|
||||||
|
.table-container {
|
||||||
|
flex: 1;
|
||||||
|
/* 占满剩余高度 */
|
||||||
|
overflow: hidden;
|
||||||
|
/* 避免表格超出容器 */
|
||||||
|
}
|
||||||
/* 1. 减小表格行高(核心) */
|
/* 1. 减小表格行高(核心) */
|
||||||
:deep(.config-table .el-table__row) {
|
:deep(.config-table .el-table__row) {
|
||||||
height: 30px !important; /* 原默认行高约40px,按需调整(建议28-35px) */
|
height: 30px !important; /* 原默认行高约40px,按需调整(建议28-35px) */
|
||||||
|
|||||||
371
src/views/liswork/xtwh/localconfig/components/DynamicInput.vue
Normal file
371
src/views/liswork/xtwh/localconfig/components/DynamicInput.vue
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dynamic-input-container">
|
||||||
|
<!-- 1. 开关组件(替代原单选框 type=0:是/否 → 开启/关闭) -->
|
||||||
|
<el-switch
|
||||||
|
active-text="开"
|
||||||
|
inactive-text="关"
|
||||||
|
class="custom-switch"
|
||||||
|
v-if="type === '0'"
|
||||||
|
v-model="innerValue"
|
||||||
|
active-color="#13ce66"
|
||||||
|
inactive-color="#ff4949"
|
||||||
|
active-value="1"
|
||||||
|
inactive-value="0"
|
||||||
|
@change="handleSwitchChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 2. 下拉框(1):直接绑定value -->
|
||||||
|
<el-select
|
||||||
|
v-else-if="type === '1'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
clearable
|
||||||
|
@change="handleValueChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in dictOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 3. 字典单选(2):绑定zddh(value),显示zdmc(label) -->
|
||||||
|
<el-select
|
||||||
|
v-else-if="type === '2'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
clearable
|
||||||
|
@change="handleValueChange"
|
||||||
|
v-loading="dictLoading"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in dictOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 4. 字典多选(3):数组↔逗号分隔字符串 -->
|
||||||
|
<el-select
|
||||||
|
v-else-if="type === '3'"
|
||||||
|
v-model="multipleValue"
|
||||||
|
size="small"
|
||||||
|
multiple
|
||||||
|
@change="handleMultipleChange"
|
||||||
|
v-loading="dictLoading"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in dictOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
<!-- 5. 特殊(4) -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="type === '4'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
disabled
|
||||||
|
@change="handleValueChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 6. 文本框(5) -->
|
||||||
|
<el-input
|
||||||
|
v-else-if="type === '5'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@change="handleValueChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 7. 数字框(6) -->
|
||||||
|
<el-input-number
|
||||||
|
v-else-if="type === '6'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
:min="minNum"
|
||||||
|
:precision="precisionNum"
|
||||||
|
controls-position="right"
|
||||||
|
@change="handleValueChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 8. 日期框(7):适配yyyy/mm/dd -->
|
||||||
|
<el-date-picker
|
||||||
|
v-else-if="type === '7'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
type="date"
|
||||||
|
format="YYYY/MM/DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@change="handleValueChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 9. 时间框(8):适配hh:mm(修复标签闭合问题) -->
|
||||||
|
<el-time-picker
|
||||||
|
v-else-if="type === '8'"
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
format="HH:mm"
|
||||||
|
value-format="HH:mm:ss"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@change="handleValueChange"
|
||||||
|
:picker-options="{ selectableRange: '00:00:00 - 23:59:59' }"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 兜底:默认文本框 -->
|
||||||
|
<el-input
|
||||||
|
v-else
|
||||||
|
v-model="innerValue"
|
||||||
|
size="small"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
@change="handleValueChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="DynamicInput">
|
||||||
|
import { ref, watch, defineProps, defineEmits, onMounted } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { getoptionselect } from "@/api/liswork/xtwh/localconfigApi.ts";
|
||||||
|
|
||||||
|
// 字典缓存:key=字典类型,value=映射后的{label,value}列表
|
||||||
|
const dictCache = ref({});
|
||||||
|
|
||||||
|
// Props定义
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: { // Vue3 规范:v-model 绑定 modelValue
|
||||||
|
type: [String, Number, Boolean],
|
||||||
|
required: true,
|
||||||
|
default: "" // 开关默认值:0(关闭)
|
||||||
|
},
|
||||||
|
type: { type: String, required: true, default: "5" },
|
||||||
|
dictData: { type: [String, Object, Array], default: "" },
|
||||||
|
placeholder: { type: String, default: "请输入值" },
|
||||||
|
minNum: { type: Number, default: 0 },
|
||||||
|
precisionNum: { type: Number, default: 2 }
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("子组件接收的props:", {
|
||||||
|
type: props.type,
|
||||||
|
value: props.modelValue,
|
||||||
|
dictData: props.dictData,
|
||||||
|
valueType: typeof props.modelValue
|
||||||
|
});
|
||||||
|
|
||||||
|
// Emits定义(统一触发 update:modelValue)
|
||||||
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
|
|
||||||
|
// 内部状态
|
||||||
|
const innerValue = ref(""); // 单值组件绑定(开关/下拉/文本等)
|
||||||
|
const multipleValue = ref([]); // 多选值(仅type=3用)
|
||||||
|
const dictOptions = ref([]); // 下拉/字典选项列表
|
||||||
|
const dictLoading = ref(false); // 字典加载状态
|
||||||
|
|
||||||
|
// ========== 核心:值初始化 + 格式适配 ==========
|
||||||
|
watch(() => props.modelValue, (newVal) => {
|
||||||
|
const val = newVal ?? ""; // 开关兜底默认值:0
|
||||||
|
switch (props.type) {
|
||||||
|
// 开关组件(替代原单选框):后端1/0 → 前端"是"/"否"
|
||||||
|
case "0":
|
||||||
|
innerValue.value = (val === 1 || val === "1" || val === true) ? "1" : "0";
|
||||||
|
break;
|
||||||
|
// 下拉框/字典单选:直接绑定value(zddh)
|
||||||
|
case "1":
|
||||||
|
case "2":
|
||||||
|
innerValue.value = String(val); // 强制字符串,匹配选项value类型
|
||||||
|
break;
|
||||||
|
// 字典多选:后端逗号字符串→前端数组
|
||||||
|
case "3":
|
||||||
|
multipleValue.value = typeof val === "string" && val
|
||||||
|
? val.split(",").map(item => String(item))
|
||||||
|
: [];
|
||||||
|
innerValue.value = val;
|
||||||
|
break;
|
||||||
|
// 数字框:确保是数字类型
|
||||||
|
case "6":
|
||||||
|
innerValue.value = !isNaN(Number(val)) ? Number(val) : 0;
|
||||||
|
break;
|
||||||
|
// 日期框:后端 yyyy/mm/dd → 前端 yyyy-MM-dd
|
||||||
|
case "7":
|
||||||
|
innerValue.value = typeof val === "string" && val.includes("/")
|
||||||
|
? val.replace(/\//g, "-")
|
||||||
|
: val;
|
||||||
|
break;
|
||||||
|
// 时间框:后端 hh:mm → 前端 hh:mm:ss
|
||||||
|
case "8":
|
||||||
|
innerValue.value = typeof val === "string" && val.includes(":") && val.split(":").length === 2
|
||||||
|
? `${val}:00`
|
||||||
|
: val;
|
||||||
|
break;
|
||||||
|
// 其他类型:直接赋值
|
||||||
|
default:
|
||||||
|
innerValue.value = val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, { immediate: true, deep: true });
|
||||||
|
|
||||||
|
// ========== 同步子组件值到父组件 ==========
|
||||||
|
watch(innerValue, (newVal) => {
|
||||||
|
let finalVal = newVal;
|
||||||
|
// 数字框:确保数字类型
|
||||||
|
if (props.type === "6") {
|
||||||
|
finalVal = !isNaN(Number(newVal)) ? Number(newVal) : 0;
|
||||||
|
}
|
||||||
|
// 日期框:前端 yyyy-MM-dd → 后端 yyyy/mm/dd
|
||||||
|
else if (props.type === "7" && typeof newVal === "string" && newVal.includes("-")) {
|
||||||
|
finalVal = newVal.replace(/-/g, "/");
|
||||||
|
}
|
||||||
|
// 时间框:前端 hh:mm:ss → 后端 hh:mm
|
||||||
|
else if (props.type === "8" && typeof newVal === "string" && newVal.includes(":")) {
|
||||||
|
finalVal = newVal.split(":").slice(0, 2).join(":");
|
||||||
|
}
|
||||||
|
emit("update:modelValue", finalVal);
|
||||||
|
emit("change", finalVal);
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
// ========== 字典加载逻辑 ==========
|
||||||
|
watch([() => props.type, () => props.dictData], async () => {
|
||||||
|
dictOptions.value = [];
|
||||||
|
if (props.type === "1") {
|
||||||
|
await parseJsonDict();
|
||||||
|
} else if (["2", "3"].includes(props.type)) {
|
||||||
|
await loadApiDict();
|
||||||
|
}
|
||||||
|
}, { immediate: true, deep: true });
|
||||||
|
|
||||||
|
// 解析下拉框JSON数组(type=1)
|
||||||
|
async function parseJsonDict() {
|
||||||
|
if (!props.dictData) return;
|
||||||
|
try {
|
||||||
|
let jsonStr = typeof props.dictData === "string" ? props.dictData : JSON.stringify(props.dictData);
|
||||||
|
jsonStr = jsonStr.replace(/\s+/g, " ").replace(/[\n\t]/g, "");
|
||||||
|
let jsonData = JSON.parse(jsonStr);
|
||||||
|
if (!Array.isArray(jsonData)) jsonData = [jsonData];
|
||||||
|
dictOptions.value = jsonData.map(item => ({
|
||||||
|
label: item.label || item.zdmc || item.name || "",
|
||||||
|
value: item.value || item.zddh || item.code || ""
|
||||||
|
})).filter(item => item.label && item.value);
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error(`下拉框数据解析失败:${error.message}`);
|
||||||
|
console.error("JSON解析失败:", { raw: props.dictData, error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载字典API(type=2/3):zddh→value,zdmc→label
|
||||||
|
async function loadApiDict() {
|
||||||
|
const dictType = props.dictData;
|
||||||
|
if (!dictType) return;
|
||||||
|
if (dictCache.value[dictType]) {
|
||||||
|
dictOptions.value = dictCache.value[dictType];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
dictLoading.value = true;
|
||||||
|
const res = await getoptionselect({ zdlb: dictType });
|
||||||
|
if (res.code === 200 && Array.isArray(res.data)) {
|
||||||
|
dictOptions.value = res.data.map(item => ({
|
||||||
|
label: item.zdmc || item.label || "",
|
||||||
|
value: item.zddh || item.value || ""
|
||||||
|
})).filter(item => item.label && item.value);
|
||||||
|
dictCache.value[dictType] = dictOptions.value;
|
||||||
|
} else {
|
||||||
|
ElMessage.warning(`字典${dictType}无有效数据`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error("字典请求失败");
|
||||||
|
console.error("字典API异常:", { dictType, error });
|
||||||
|
} finally {
|
||||||
|
dictLoading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 开关组件专属变更处理(直接返回数字1/0) ==========
|
||||||
|
function handleSwitchChange(val) {
|
||||||
|
// val是字符串1/0,转为数字提交给后端
|
||||||
|
const finalVal = Number(val);
|
||||||
|
emit("update:modelValue", finalVal);
|
||||||
|
emit("change", finalVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 普通值变更处理(除开关/多选外) ==========
|
||||||
|
function handleValueChange(val) {
|
||||||
|
let finalVal = val;
|
||||||
|
emit("update:modelValue", finalVal);
|
||||||
|
emit("change", finalVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 多选值变更处理 ==========
|
||||||
|
function handleMultipleChange(val) {
|
||||||
|
const strVal = val?.join(",") || "";
|
||||||
|
innerValue.value = strVal;
|
||||||
|
multipleValue.value = val;
|
||||||
|
emit("update:modelValue", strVal);
|
||||||
|
emit("change", strVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 多选值同步监听 ==========
|
||||||
|
watch(multipleValue, (newVal) => {
|
||||||
|
if (props.type === "3") {
|
||||||
|
const strVal = newVal?.join(",") || "";
|
||||||
|
innerValue.value = strVal;
|
||||||
|
emit("update:modelValue", strVal);
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
// ========== 初始化兜底 ==========
|
||||||
|
onMounted(() => {
|
||||||
|
// 开关组件初始值兜底
|
||||||
|
if (props.type === "0" && !innerValue.value) {
|
||||||
|
innerValue.value = "否"; // 默认关闭
|
||||||
|
emit("update:modelValue", 0); // 后端默认值:0
|
||||||
|
}
|
||||||
|
// 多选值初始化
|
||||||
|
if (props.type === "3" && !multipleValue.value.length && innerValue.value) {
|
||||||
|
multipleValue.value = innerValue.value.split(",").map(item => String(item));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dynamic-input-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center; /* 开关组件垂直居中 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 开关组件样式优化 */
|
||||||
|
:deep(.el-switch) {
|
||||||
|
margin: 0 auto; /* 开关水平居中 */
|
||||||
|
}
|
||||||
|
/* 深度选择器强制覆盖激活颜色 */
|
||||||
|
:deep(.custom-switch .el-switch__core) {
|
||||||
|
/* 开启状态背景色 */
|
||||||
|
--el-switch-on-color: #13ce66 !important;
|
||||||
|
/* 关闭状态背景色(可选) */
|
||||||
|
--el-switch-off-color: #ff4949 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 兼容旧版Element Plus(可选) */
|
||||||
|
:deep(.custom-switch .el-switch__core.is-checked) {
|
||||||
|
background-color: #13ce66 !important;
|
||||||
|
border-color: #13ce66 !important;
|
||||||
|
}
|
||||||
|
:deep(.el-radio-group) {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select--small),
|
||||||
|
:deep(.el-input--small),
|
||||||
|
:deep(.el-input-number--small),
|
||||||
|
:deep(.el-date-picker--small),
|
||||||
|
:deep(.el-time-picker--small) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
255
src/views/liswork/xtwh/localconfig/index.vue
Normal file
255
src/views/liswork/xtwh/localconfig/index.vue
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 操作按钮栏:改为保存/取消/还原默认 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
icon="Plus"
|
||||||
|
@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="Download"
|
||||||
|
@click="handleRestoreDefault"
|
||||||
|
>还原默认</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="5" class="table-container">
|
||||||
|
<el-table
|
||||||
|
v-loading="loading"
|
||||||
|
:data="regdictList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
class="config-table"
|
||||||
|
height="100%"
|
||||||
|
>
|
||||||
|
<el-table-column label="序号" align="center" prop="configSort" />
|
||||||
|
<el-table-column :label="`${menuname}编码`" align="center" prop="configCode" show-overflow-tooltip />
|
||||||
|
<el-table-column :label="`${menuname}名称`" align="left" prop="configName" show-overflow-tooltip />
|
||||||
|
<!-- 核心:默认值列改为持久化可编辑输入框 -->
|
||||||
|
<el-table-column label="参数值" align="center" prop="configDefvalue" show-overflow-tooltip>
|
||||||
|
<template #default="scope">
|
||||||
|
<DynamicInput
|
||||||
|
:type="scope.row.configOptiontype"
|
||||||
|
v-model="scope.row.configDefvalue"
|
||||||
|
:dict-data="scope.row.remark"
|
||||||
|
:placeholder="`请输入${scope.row.configName}值`"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="值码" align="center" prop="configDefvalue" show-overflow-tooltip />
|
||||||
|
</el-table>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="localconfig">
|
||||||
|
// 导入核心依赖
|
||||||
|
import { ref, reactive, toRefs, getCurrentInstance } from "vue";
|
||||||
|
import { ElMessage, ElMessageBox } from "element-plus";
|
||||||
|
import DynamicInput from "./components/DynamicInput.vue";
|
||||||
|
import {
|
||||||
|
listlocalconfig, savelocalconfig, getLocalConfigDefault // 新增还原默认接口
|
||||||
|
} from "@/api/liswork/xtwh/localconfigApi.ts";
|
||||||
|
|
||||||
|
const { proxy } = getCurrentInstance();
|
||||||
|
const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
|
||||||
|
|
||||||
|
// 表格数据(原始数据缓存,用于取消修改)
|
||||||
|
const regdictList = ref([]);
|
||||||
|
const originRegdictList = ref([]); // 缓存原始数据,用于取消修改
|
||||||
|
const loading = ref(true);
|
||||||
|
const showSearch = ref(true);
|
||||||
|
const ids = ref([]);
|
||||||
|
const single = ref(true);
|
||||||
|
const multiple = ref(true);
|
||||||
|
const total = ref(0);
|
||||||
|
const menuname = ref("本地选项");
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
queryParams: {
|
||||||
|
configCode: undefined,
|
||||||
|
configName: undefined,
|
||||||
|
configType: undefined,
|
||||||
|
status: undefined
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const { queryParams } = toRefs(data);
|
||||||
|
|
||||||
|
/** 查询字典列表(缓存原始数据) */
|
||||||
|
function getList() {
|
||||||
|
loading.value = true;
|
||||||
|
listlocalconfig(queryParams.value).then(response => {
|
||||||
|
// 存储表格展示数据
|
||||||
|
regdictList.value = response.data.map(item => ({ ...item }));
|
||||||
|
// 缓存原始数据(深拷贝,避免引用修改)
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(response.data));
|
||||||
|
total.value = response.data.length;
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
function handleQuery() {
|
||||||
|
getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
function resetQuery() {
|
||||||
|
proxy.resetForm("queryRef");
|
||||||
|
handleQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表格行选中事件 */
|
||||||
|
function handleSelectionChange(val) {
|
||||||
|
ids.value = val.map(item => item.configId);
|
||||||
|
single.value = val.length === 1;
|
||||||
|
multiple.value = val.length > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 核心:保存整个表格数据(批量提交) */
|
||||||
|
async function handleSave() {
|
||||||
|
// 空值校验:检查所有行的默认值是否为空
|
||||||
|
//const emptyRows = regdictList.value.filter(item => !item.configDefvalue?.trim());
|
||||||
|
//if (emptyRows.length > 0) {
|
||||||
|
// ElMessage.warning(`有${emptyRows.length}行默认值为空,请补充后再保存!`);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 调用批量保存接口,传入整个列表
|
||||||
|
const res = await savelocalconfig(regdictList.value);
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success("批量保存成功!");
|
||||||
|
// 保存后更新原始数据缓存
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(regdictList.value));
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || "批量保存失败,请重试!");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error("保存失败,网络异常!");
|
||||||
|
console.error("保存失败:", error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 取消修改:恢复原始数据 */
|
||||||
|
function handleCancelEdit() {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
"是否确认取消所有修改,恢复到原始数据?",
|
||||||
|
"提示",
|
||||||
|
{
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}
|
||||||
|
).then(() => {
|
||||||
|
// 恢复原始数据
|
||||||
|
regdictList.value = JSON.parse(JSON.stringify(originRegdictList.value));
|
||||||
|
ElMessage.success("已取消所有修改,恢复原始数据!");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 还原默认值:调用接口获取默认值并刷新 */
|
||||||
|
async function handleRestoreDefault() {
|
||||||
|
ElMessageBox.confirm(
|
||||||
|
"是否确认还原所有默认值?此操作会覆盖当前修改!",
|
||||||
|
"警告",
|
||||||
|
{
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "danger"
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 调用还原默认接口
|
||||||
|
const res = await getLocalConfigDefault(queryParams.value);
|
||||||
|
if (res.code === 200) {
|
||||||
|
// 更新表格数据和原始缓存
|
||||||
|
regdictList.value = res.data.map(item => ({ ...item }));
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(res.data));
|
||||||
|
ElMessage.success("已成功还原默认值!");
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || "还原默认值失败,请重试!");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error("还原失败,网络异常!");
|
||||||
|
console.error("还原默认值失败:", error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化加载数据
|
||||||
|
getList();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 90vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb8 {
|
||||||
|
height: 30px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格样式优化 */
|
||||||
|
:deep(.config-table .el-table__row) {
|
||||||
|
height: 30px !important;
|
||||||
|
line-height: 30px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.config-table .el-table__cell) {
|
||||||
|
padding: 2px 4px !important;
|
||||||
|
height: 30px !important;
|
||||||
|
line-height: 1.2 !important;
|
||||||
|
vertical-align: middle !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 编辑输入框样式适配 */
|
||||||
|
:deep(.config-table .edit-input) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
:deep(.config-table .edit-input .el-input__inner) {
|
||||||
|
padding: 0 5px;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
}
|
||||||
|
:deep(.config-table .edit-input .el-input__inner:focus) {
|
||||||
|
border-color: #409eff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user