系统全局设置界面
This commit is contained in:
parent
8d98e4c8c3
commit
ea9d79144a
53
src/api/liswork/xtwh/ComOpt.ts
Normal file
53
src/api/liswork/xtwh/ComOpt.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//@ts-ignore js语法检查忽略
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
|
||||||
|
// 查询参数列表
|
||||||
|
export function paramList(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/param/query',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 获取默认值
|
||||||
|
export function getdef(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/param/getdef',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 修改参数列表
|
||||||
|
export function updateParam(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/param/update',
|
||||||
|
method: 'put',
|
||||||
|
data: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 删除参数列表
|
||||||
|
export function delParam(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/param/del',
|
||||||
|
method: 'delete',
|
||||||
|
params: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 查询参数列表树状结构
|
||||||
|
export function paramTree(query?: Object) {
|
||||||
|
return request({
|
||||||
|
url: '/param/queryTree',
|
||||||
|
method: 'get',
|
||||||
|
params: query,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询某个参数
|
||||||
|
export function queryOneService(yq: string,xxdh: string) {
|
||||||
|
return request({
|
||||||
|
url: '/param/queryOne',
|
||||||
|
method: 'get',
|
||||||
|
params: {yq,xxdh}
|
||||||
|
});
|
||||||
|
}
|
||||||
653
src/views/liswork/xtwh/comopt/index.vue
Normal file
653
src/views/liswork/xtwh/comopt/index.vue
Normal file
@ -0,0 +1,653 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20" class="main-row">
|
||||||
|
<!-- 左侧树区域 -->
|
||||||
|
<el-col :span="4" :xs="24" class="tree-col">
|
||||||
|
<el-input
|
||||||
|
v-model="deptName"
|
||||||
|
placeholder="请输入仪器名称"
|
||||||
|
clearable
|
||||||
|
prefix-icon="Search"
|
||||||
|
class="tree-search-input"
|
||||||
|
/>
|
||||||
|
<div class="tree-container">
|
||||||
|
<el-tree
|
||||||
|
:data="deptOptions"
|
||||||
|
:props="treeProps"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
ref="deptTreeRef"
|
||||||
|
node-key="id"
|
||||||
|
highlight-current
|
||||||
|
:expanded-keys="expandedKeys"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
@expand-change="handleForceExpand"
|
||||||
|
:default-expanded-keys="[]"
|
||||||
|
>
|
||||||
|
<!-- 自定义树节点模板:新增newflag徽章 -->
|
||||||
|
<template #default="{ node, data }">
|
||||||
|
<span class="tree-node-content">
|
||||||
|
{{ node.label }}
|
||||||
|
<!-- 新节点徽章:newflag=1时显示黄色"新"标 -->
|
||||||
|
<el-badge
|
||||||
|
v-if="data.newflag === '1'"
|
||||||
|
value="新"
|
||||||
|
class="new-node-badge"
|
||||||
|
type="warning"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<!-- 右侧列表区域(三列表格) -->
|
||||||
|
<el-col :span="20" :xs="24" class="table-col">
|
||||||
|
<el-row :gutter="10" class="yq-title-row">
|
||||||
|
<h1 class="yq-title">仪器:{{ yqmc }}</h1>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="10" class="table-toolbar">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- 三列表格容器 -->
|
||||||
|
<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="center" prop="configCode" v-if="false" show-overflow-tooltip min-width="120" />
|
||||||
|
<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="center" prop="configCode" v-if="false" show-overflow-tooltip min-width="120" />
|
||||||
|
<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="center" prop="configCode" v-if="false" show-overflow-tooltip min-width="120" />
|
||||||
|
<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>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup name="ComOpt" lang="ts">
|
||||||
|
import { ref, watch, nextTick, computed } from 'vue'
|
||||||
|
import { ElMessage, ElTree, ElTreeNode, ElMessageBox, ElBadge } from 'element-plus'
|
||||||
|
import { paramList, paramTree, getdef, updateParam } from '@/api/liswork/xtwh/ComOpt'
|
||||||
|
import { getFirstLetter } from '@/utils/pinyin.js'
|
||||||
|
import DynamicInput from "@/views/liswork/xtwh/localconfig/components/DynamicInput.vue"
|
||||||
|
|
||||||
|
// ========== TypeScript 类型定义 ==========
|
||||||
|
interface InstrTreeNode {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
lx: string
|
||||||
|
newflag:string // 新增newflag字段
|
||||||
|
children?: InstrTreeNode[]
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ParamTreeResponse {
|
||||||
|
code: string
|
||||||
|
msg: string
|
||||||
|
data: InstrTreeNode[]
|
||||||
|
url: null | string
|
||||||
|
method: null | string
|
||||||
|
params: null | any
|
||||||
|
problemId: null | string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QueryParams {
|
||||||
|
yq?: string | undefined
|
||||||
|
xxdh?: string | undefined
|
||||||
|
xxqz?: string | undefined
|
||||||
|
groupId?: string | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RegDictItem {
|
||||||
|
configId: string | number
|
||||||
|
configSort: number
|
||||||
|
configCode: string
|
||||||
|
configName: string
|
||||||
|
configDefvalue: string | number
|
||||||
|
configOptiontype: string
|
||||||
|
remark: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 响应式变量 ==========
|
||||||
|
// 树相关
|
||||||
|
const deptTreeRef = ref<InstanceType<typeof ElTree>>()
|
||||||
|
const deptOptions = ref<InstrTreeNode[]>([])
|
||||||
|
const deptName = ref<string>("")
|
||||||
|
const yqmc = ref<string>("")
|
||||||
|
const expandedKeys = ref<string[]>([])
|
||||||
|
const isFiltering = ref<boolean>(false)
|
||||||
|
const treeProps = ref({
|
||||||
|
label: 'label',
|
||||||
|
children: 'children',
|
||||||
|
isLeaf: (data: InstrTreeNode) => !data.children || data.children.length === 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查询参数
|
||||||
|
const queryParams = ref<QueryParams>({
|
||||||
|
yq: undefined,
|
||||||
|
xxdh: undefined,
|
||||||
|
xxqz: undefined,
|
||||||
|
groupId: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
// 列表相关
|
||||||
|
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 forceExpandSingleNode = (nodeId: string): void => {
|
||||||
|
expandedKeys.value = []
|
||||||
|
nextTick(() => {
|
||||||
|
expandedKeys.value = [nodeId]
|
||||||
|
deptTreeRef.value?.expand(nodeId, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleNodeClick = (data: InstrTreeNode): void => {
|
||||||
|
if (isFiltering.value) {
|
||||||
|
queryParams.value.groupId = data.id === "-1" ? undefined : data.id
|
||||||
|
handleQuery()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.children && data.children.length > 0) {
|
||||||
|
const isExpanded = expandedKeys.value.includes(data.id)
|
||||||
|
expandedKeys.value = isExpanded ? [] : [data.id]
|
||||||
|
!isExpanded && forceExpandSingleNode(data.id)
|
||||||
|
} else {
|
||||||
|
queryParams.value.yq = data.id
|
||||||
|
yqmc.value=data.label
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleForceExpand = (_: string[], node: ElTreeNode): void => {
|
||||||
|
if (isFiltering.value) return
|
||||||
|
|
||||||
|
const nodeData = node.data as InstrTreeNode
|
||||||
|
if (nodeData.children && nodeData.children.length > 0) {
|
||||||
|
if (node.expanded) {
|
||||||
|
forceExpandSingleNode(node.key as string)
|
||||||
|
} else {
|
||||||
|
expandedKeys.value = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 检索过滤逻辑 ==========
|
||||||
|
const filterNode = (value: string, data: InstrTreeNode, _node: ElTreeNode): boolean => {
|
||||||
|
if (!value) return true
|
||||||
|
|
||||||
|
const keyword = value.trim().toUpperCase()
|
||||||
|
const nodeLabel = data.label?.toLowerCase() || ''
|
||||||
|
const nodePinyinFirst = data.label ? getFirstLetter(data.label).toUpperCase() : ''
|
||||||
|
|
||||||
|
const currentMatch = nodeLabel.includes(keyword.toLowerCase()) || nodePinyinFirst.includes(keyword)
|
||||||
|
const childrenMatch = (data.children || []).some(child => filterNode(value, child, _node))
|
||||||
|
return currentMatch || childrenMatch
|
||||||
|
}
|
||||||
|
|
||||||
|
const debounceFilter = (() => {
|
||||||
|
let timer: number | undefined
|
||||||
|
return (val: string): void => {
|
||||||
|
clearTimeout(timer)
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
isFiltering.value = true
|
||||||
|
deptTreeRef.value?.filter(val)
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
expandedKeys.value = []
|
||||||
|
const expandMatched = (nodes: InstrTreeNode[]) => {
|
||||||
|
nodes.forEach(node => {
|
||||||
|
if (filterNode(val, node, {} as ElTreeNode) && node.children?.length) {
|
||||||
|
expandedKeys.value.push(node.id)
|
||||||
|
}
|
||||||
|
node.children && expandMatched(node.children)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
expandMatched(deptOptions.value)
|
||||||
|
} else {
|
||||||
|
expandedKeys.value = []
|
||||||
|
}
|
||||||
|
isFiltering.value = false
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
watch(deptName, debounceFilter, { immediate: false })
|
||||||
|
|
||||||
|
// ========== 业务逻辑 ==========
|
||||||
|
const getDeptTree = async (): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const response = await paramTree() as ParamTreeResponse
|
||||||
|
if (response.code === "0" && response.data) {
|
||||||
|
deptOptions.value = response.data
|
||||||
|
} else {
|
||||||
|
ElMessage.warning(response.msg || "获取树数据失败")
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error(`获取树数据异常:${(error as Error).message}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleQuery = (): void => {
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getList = async (): Promise<void> => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await paramList({ yq: queryParams.value.yq })
|
||||||
|
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 === 200) {
|
||||||
|
ElMessage.success("批量保存成功!")
|
||||||
|
originRegdictList.value = JSON.parse(JSON.stringify(allData))
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || "保存失败,请重试")
|
||||||
|
}
|
||||||
|
} 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: "danger"
|
||||||
|
}
|
||||||
|
).then(async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getdef({ yq: queryParams.value.yq })
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 初始化 ==========
|
||||||
|
getDeptTree()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 90vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 8px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-row {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-col {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tree-search-input {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-container {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
// 核心:树选中节点样式
|
||||||
|
:deep(.el-tree) {
|
||||||
|
--el-tree-node-transition-duration: 0.2s;
|
||||||
|
|
||||||
|
.el-tree-node__children {
|
||||||
|
transition: all var(--el-tree-node-transition-duration) ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon.is-leaf {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中节点的背景色(蓝色)+ 文字白色
|
||||||
|
.el-tree-node.is-current > .el-tree-node__content {
|
||||||
|
background-color: #409eff !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中节点hover样式(加深蓝色)
|
||||||
|
.el-tree-node.is-current > .el-tree-node__content:hover {
|
||||||
|
background-color: #1e88e5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 树节点内容容器样式
|
||||||
|
.tree-node-content {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px; // 徽章和文字间距
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新节点徽章样式
|
||||||
|
.new-node-badge {
|
||||||
|
--el-badge-font-size: 10px !important;
|
||||||
|
--el-badge-height: 16px !important;
|
||||||
|
--el-badge-padding: 0 4px !important;
|
||||||
|
--el-badge-warning-color: #FFEC24 !important; // 黄色徽章
|
||||||
|
--el-badge-warning-bg-color: #fff7e6 !important; // 浅黄色背景
|
||||||
|
--el-badge-border-radius: 2px !important; // 圆角优化
|
||||||
|
|
||||||
|
// 徽章文字样式
|
||||||
|
.el-badge__content {
|
||||||
|
font-size: 10px !important;
|
||||||
|
line-height: 16px !important;
|
||||||
|
padding: 0 4px !important;
|
||||||
|
height: 16px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-col {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
// 仪器标题行样式
|
||||||
|
.yq-title-row {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
.yq-title {
|
||||||
|
font-size: 16px; // 缩小h1字体(默认24px→16px)
|
||||||
|
color: #409eff; // 蓝色(Element Plus主题色)
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0; // 清除默认margin
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-toolbar {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
height: 36px;
|
||||||
|
line-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 三列表格容器
|
||||||
|
.triple-table-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
height: calc(100% - 36px - 24px); // 减去标题行+工具栏高度
|
||||||
|
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>
|
||||||
@ -2,16 +2,14 @@
|
|||||||
<div class="dynamic-input-container">
|
<div class="dynamic-input-container">
|
||||||
<!-- 1. 开关组件(替代原单选框 type=0:是/否 → 开启/关闭) -->
|
<!-- 1. 开关组件(替代原单选框 type=0:是/否 → 开启/关闭) -->
|
||||||
<el-switch
|
<el-switch
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
class="custom-switch"
|
class="custom-switch"
|
||||||
v-if="type === '0'"
|
v-if="type === '0'"
|
||||||
v-model="innerValue"
|
v-model="innerValue"
|
||||||
active-color="#13ce66"
|
active-color="#13ce66"
|
||||||
inactive-color="#ff4949"
|
inactive-color="#ff4949"
|
||||||
active-value="1"
|
active-value="1"
|
||||||
inactive-value="0"
|
inactive-value="0"
|
||||||
@change="handleSwitchChange"
|
@change="handleSwitchChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 2. 下拉框(1):直接绑定value -->
|
<!-- 2. 下拉框(1):直接绑定value -->
|
||||||
@ -82,15 +80,16 @@
|
|||||||
@change="handleValueChange"
|
@change="handleValueChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 7. 数字框(6) -->
|
<!-- 7. 数字框(6):支持dictData定义小数位数,空值初始化 -->
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-else-if="type === '6'"
|
v-else-if="type === '6'"
|
||||||
v-model="innerValue"
|
v-model="innerValue"
|
||||||
size="small"
|
size="small"
|
||||||
:min="minNum"
|
:min="minNum"
|
||||||
:precision="precisionNum"
|
:precision="finalPrecision"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
@change="handleValueChange"
|
@change="handleValueChange"
|
||||||
|
:placeholder="placeholder || '请输入数字'"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 8. 日期框(7):适配yyyy/mm/dd -->
|
<!-- 8. 日期框(7):适配yyyy/mm/dd -->
|
||||||
@ -129,7 +128,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="DynamicInput">
|
<script setup name="DynamicInput">
|
||||||
import { ref, watch, defineProps, defineEmits, onMounted } from "vue";
|
import { ref, watch, defineProps, defineEmits, onMounted, computed } from "vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { getoptionselect } from "@/api/liswork/xtwh/localconfigApi.ts";
|
import { getoptionselect } from "@/api/liswork/xtwh/localconfigApi.ts";
|
||||||
|
|
||||||
@ -139,82 +138,101 @@ const dictCache = ref({});
|
|||||||
// Props定义
|
// Props定义
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { // Vue3 规范:v-model 绑定 modelValue
|
modelValue: { // Vue3 规范:v-model 绑定 modelValue
|
||||||
type: [String, Number, Boolean],
|
type: [String, Number, Boolean, null, undefined], // 新增null/undefined支持空值
|
||||||
required: true,
|
required: false, // 允许空值
|
||||||
default: "" // 开关默认值:0(关闭)
|
default: ""
|
||||||
},
|
},
|
||||||
type: { type: String, required: true, default: "5" },
|
type: {type: String, required: true, default: "5"},
|
||||||
dictData: { type: [String, Object, Array], default: "" },
|
dictData: {type: [String, Number, Object, Array], default: ""}, // 支持Number类型(小数位数)
|
||||||
placeholder: { type: String, default: "请输入值" },
|
placeholder: {type: String, default: "请输入值"},
|
||||||
minNum: { type: Number, default: 0 },
|
minNum: {type: Number, default: -Infinity}, // 数字框最小值改为无限制(空值场景)
|
||||||
precisionNum: { type: Number, default: 2 }
|
precisionNum: {type: Number, default: 0} // 默认整数
|
||||||
});
|
|
||||||
|
|
||||||
console.log("子组件接收的props:", {
|
|
||||||
type: props.type,
|
|
||||||
value: props.modelValue,
|
|
||||||
dictData: props.dictData,
|
|
||||||
valueType: typeof props.modelValue
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Emits定义(统一触发 update:modelValue)
|
// Emits定义(统一触发 update:modelValue)
|
||||||
const emit = defineEmits(["update:modelValue", "change"]);
|
const emit = defineEmits(["update:modelValue", "change"]);
|
||||||
|
|
||||||
// 内部状态
|
// 内部状态
|
||||||
const innerValue = ref(""); // 单值组件绑定(开关/下拉/文本等)
|
const innerValue = ref(null); // 初始值改为null,适配空值
|
||||||
const multipleValue = ref([]); // 多选值(仅type=3用)
|
const multipleValue = ref([]); // 多选值(仅type=3用)
|
||||||
const dictOptions = ref([]); // 下拉/字典选项列表
|
const dictOptions = ref([]); // 下拉/字典选项列表
|
||||||
const dictLoading = ref(false); // 字典加载状态
|
const dictLoading = ref(false); // 字典加载状态
|
||||||
|
|
||||||
|
// ========== 核心:数字框小数位数计算 ==========
|
||||||
|
const finalPrecision = computed(() => {
|
||||||
|
if (props.type !== "6") return props.precisionNum;
|
||||||
|
|
||||||
|
// dictData为小数保留位数(优先级最高)
|
||||||
|
if (props.dictData !== "" && props.dictData !== null && props.dictData !== undefined) {
|
||||||
|
const precision = Number(props.dictData);
|
||||||
|
return isNaN(precision) ? 0 : Math.max(0, precision); // 确保非负整数
|
||||||
|
}
|
||||||
|
|
||||||
|
// dictData为空,默认整数(precisionNum=0)
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
// ========== 核心:值初始化 + 格式适配 ==========
|
// ========== 核心:值初始化 + 格式适配 ==========
|
||||||
watch(() => props.modelValue, (newVal) => {
|
watch(() => props.modelValue, (newVal) => {
|
||||||
const val = newVal ?? ""; // 开关兜底默认值:0
|
const val = newVal; // 移除兜底空值,保留原始值
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
// 开关组件(替代原单选框):后端1/0 → 前端"是"/"否"
|
// 开关组件(替代原单选框):后端1/0 → 前端"1"/"0"
|
||||||
case "0":
|
case "0":
|
||||||
innerValue.value = (val === 1 || val === "1" || val === true) ? "1" : "0";
|
innerValue.value = (val === 1 || val === "1" || val === true) ? "1" : "0";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 下拉框/字典单选:直接绑定value(zddh)
|
// 下拉框/字典单选:直接绑定value(zddh)
|
||||||
case "1":
|
case "1":
|
||||||
case "2":
|
case "2":
|
||||||
innerValue.value = String(val); // 强制字符串,匹配选项value类型
|
innerValue.value = val === null || val === undefined ? "" : String(val);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 字典多选:后端逗号字符串→前端数组
|
// 字典多选:后端逗号字符串→前端数组
|
||||||
case "3":
|
case "3":
|
||||||
multipleValue.value = typeof val === "string" && val
|
multipleValue.value = typeof val === "string" && val
|
||||||
? val.split(",").map(item => String(item))
|
? val.split(",").map(item => String(item))
|
||||||
: [];
|
: [];
|
||||||
innerValue.value = val;
|
innerValue.value = val || "";
|
||||||
break;
|
break;
|
||||||
// 数字框:确保是数字类型
|
|
||||||
|
// 数字框:空值处理,支持小数位数
|
||||||
case "6":
|
case "6":
|
||||||
innerValue.value = !isNaN(Number(val)) ? Number(val) : 0;
|
// 空值/非数字 → 空(null),否则转为数字
|
||||||
|
if (val === null || val === undefined || val === "" || isNaN(Number(val))) {
|
||||||
|
innerValue.value = null;
|
||||||
|
} else {
|
||||||
|
innerValue.value = Number(val);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 日期框:后端 yyyy/mm/dd → 前端 yyyy-MM-dd
|
// 日期框:后端 yyyy/mm/dd → 前端 yyyy-MM-dd
|
||||||
case "7":
|
case "7":
|
||||||
innerValue.value = typeof val === "string" && val.includes("/")
|
innerValue.value = typeof val === "string" && val.includes("/")
|
||||||
? val.replace(/\//g, "-")
|
? val.replace(/\//g, "-")
|
||||||
: val;
|
: val || null;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 时间框:后端 hh:mm → 前端 hh:mm:ss
|
// 时间框:后端 hh:mm → 前端 hh:mm:ss
|
||||||
case "8":
|
case "8":
|
||||||
innerValue.value = typeof val === "string" && val.includes(":") && val.split(":").length === 2
|
innerValue.value = typeof val === "string" && val.includes(":") && val.split(":").length === 2
|
||||||
? `${val}:00`
|
? `${val}:00`
|
||||||
: val;
|
: val || null;
|
||||||
break;
|
break;
|
||||||
// 其他类型:直接赋值
|
|
||||||
|
// 其他类型:保留原始值(空值则为null)
|
||||||
default:
|
default:
|
||||||
innerValue.value = val;
|
innerValue.value = val === null || val === undefined ? "" : val;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true });
|
}, {immediate: true, deep: true});
|
||||||
|
|
||||||
// ========== 同步子组件值到父组件 ==========
|
// ========== 同步子组件值到父组件 ==========
|
||||||
watch(innerValue, (newVal) => {
|
watch(innerValue, (newVal) => {
|
||||||
let finalVal = newVal;
|
let finalVal = newVal;
|
||||||
// 数字框:确保数字类型
|
|
||||||
|
// 数字框:空值提交空字符串,非空则保留数字类型
|
||||||
if (props.type === "6") {
|
if (props.type === "6") {
|
||||||
finalVal = !isNaN(Number(newVal)) ? Number(newVal) : 0;
|
finalVal = newVal === null || newVal === undefined ? "" : Number(newVal);
|
||||||
}
|
}
|
||||||
// 日期框:前端 yyyy-MM-dd → 后端 yyyy/mm/dd
|
// 日期框:前端 yyyy-MM-dd → 后端 yyyy/mm/dd
|
||||||
else if (props.type === "7" && typeof newVal === "string" && newVal.includes("-")) {
|
else if (props.type === "7" && typeof newVal === "string" && newVal.includes("-")) {
|
||||||
@ -224,19 +242,21 @@ watch(innerValue, (newVal) => {
|
|||||||
else if (props.type === "8" && typeof newVal === "string" && newVal.includes(":")) {
|
else if (props.type === "8" && typeof newVal === "string" && newVal.includes(":")) {
|
||||||
finalVal = newVal.split(":").slice(0, 2).join(":");
|
finalVal = newVal.split(":").slice(0, 2).join(":");
|
||||||
}
|
}
|
||||||
|
|
||||||
emit("update:modelValue", finalVal);
|
emit("update:modelValue", finalVal);
|
||||||
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)不需要加载字典
|
||||||
if (props.type === "1") {
|
if (props.type === "1") {
|
||||||
await parseJsonDict();
|
await parseJsonDict();
|
||||||
} else if (["2", "3"].includes(props.type)) {
|
} else if (["2", "3"].includes(props.type)) {
|
||||||
await loadApiDict();
|
await loadApiDict();
|
||||||
}
|
}
|
||||||
}, { immediate: true, deep: true });
|
}, {immediate: true, deep: true});
|
||||||
|
|
||||||
// 解析下拉框JSON数组(type=1)
|
// 解析下拉框JSON数组(type=1)
|
||||||
async function parseJsonDict() {
|
async function parseJsonDict() {
|
||||||
@ -252,7 +272,7 @@ async function parseJsonDict() {
|
|||||||
})).filter(item => item.label && item.value);
|
})).filter(item => item.label && item.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error(`下拉框数据解析失败:${error.message}`);
|
ElMessage.error(`下拉框数据解析失败:${error.message}`);
|
||||||
console.error("JSON解析失败:", { raw: props.dictData, error });
|
console.error("JSON解析失败:", {raw: props.dictData, error});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +286,7 @@ async function loadApiDict() {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
dictLoading.value = true;
|
dictLoading.value = true;
|
||||||
const res = await getoptionselect({ zdlb: dictType });
|
const res = await getoptionselect({zdlb: dictType});
|
||||||
if (res.code === 200 && Array.isArray(res.data)) {
|
if (res.code === 200 && Array.isArray(res.data)) {
|
||||||
dictOptions.value = res.data.map(item => ({
|
dictOptions.value = res.data.map(item => ({
|
||||||
label: item.zdmc || item.label || "",
|
label: item.zdmc || item.label || "",
|
||||||
@ -278,7 +298,7 @@ async function loadApiDict() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error("字典请求失败");
|
ElMessage.error("字典请求失败");
|
||||||
console.error("字典API异常:", { dictType, error });
|
console.error("字典API异常:", {dictType, error});
|
||||||
} finally {
|
} finally {
|
||||||
dictLoading.value = false;
|
dictLoading.value = false;
|
||||||
}
|
}
|
||||||
@ -315,13 +335,13 @@ watch(multipleValue, (newVal) => {
|
|||||||
innerValue.value = strVal;
|
innerValue.value = strVal;
|
||||||
emit("update:modelValue", strVal);
|
emit("update:modelValue", strVal);
|
||||||
}
|
}
|
||||||
}, { deep: true });
|
}, {deep: true});
|
||||||
|
|
||||||
// ========== 初始化兜底 ==========
|
// ========== 初始化兜底 ==========
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 开关组件初始值兜底
|
// 开关组件初始值兜底
|
||||||
if (props.type === "0" && !innerValue.value) {
|
if (props.type === "0" && innerValue.value === null) {
|
||||||
innerValue.value = "否"; // 默认关闭
|
innerValue.value = "0"; // 默认关闭
|
||||||
emit("update:modelValue", 0); // 后端默认值:0
|
emit("update:modelValue", 0); // 后端默认值:0
|
||||||
}
|
}
|
||||||
// 多选值初始化
|
// 多选值初始化
|
||||||
@ -334,20 +354,24 @@ onMounted(() => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.dynamic-input-container {
|
.dynamic-input-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%; /* 关键:占满表格单元格高度 */
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center; /* 开关组件垂直居中 */
|
align-items: center; /* 垂直居中 */
|
||||||
|
justify-content: center; /* 水平居中 */
|
||||||
|
padding: 0 2px; /* 轻微内边距,避免贴边 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 开关组件样式优化 */
|
/* 开关组件样式优化 */
|
||||||
:deep(.el-switch) {
|
:deep(.el-switch) {
|
||||||
margin: 0 auto; /* 开关水平居中 */
|
margin: 0 auto; /* 开关水平居中 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 深度选择器强制覆盖激活颜色 */
|
/* 深度选择器强制覆盖激活颜色 */
|
||||||
:deep(.custom-switch .el-switch__core) {
|
:deep(.custom-switch .el-switch__core) {
|
||||||
/* 开启状态背景色 */
|
/* 开启状态背景色 */
|
||||||
--el-switch-on-color: #13ce66 !important;
|
--el-switch-on-color: #13ce66 !important;
|
||||||
/* 关闭状态背景色(可选) */
|
/* 关闭状态背景色(可选) */
|
||||||
--el-switch-off-color: #ff4949 !important;
|
--el-switch-off-color: #C3C3C3 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 兼容旧版Element Plus(可选) */
|
/* 兼容旧版Element Plus(可选) */
|
||||||
@ -355,6 +379,7 @@ onMounted(() => {
|
|||||||
background-color: #13ce66 !important;
|
background-color: #13ce66 !important;
|
||||||
border-color: #13ce66 !important;
|
border-color: #13ce66 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-radio-group) {
|
:deep(.el-radio-group) {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@ -368,4 +393,18 @@ onMounted(() => {
|
|||||||
:deep(.el-time-picker--small) {
|
:deep(.el-time-picker--small) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 数字输入框空值样式优化 */
|
||||||
|
:deep(.el-input-number--small) {
|
||||||
|
.el-input__inner {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空值时占位符样式 */
|
||||||
|
|
||||||
|
.el-input__placeholder {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user