From 10dd46fc785b6f3a9f28aed6500b4b19af5651f4 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 28 Sep 2026 11:44:36 +0800 Subject: [PATCH] =?utf8?q?=E9=A2=86=E5=9F=9F=E9=85=8D=E7=BD=AE=EF=BC=9A?= =?utf8?q?=E6=96=B0=E5=A2=9E=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE+=E9=BB=98?= =?utf8?q?=E8=AE=A4=E9=A2=9C=E8=89=B2=E9=85=8D=E7=BD=AE=EF=BC=8C=E4=BF=AE?= =?utf8?q?=E5=A4=8D=E9=80=8F=E6=98=8E=E5=BC=B9=E7=AA=97=EF=BC=9B=E9=A2=86?= =?utf8?q?=E5=9F=9F=E6=96=B9=E6=A1=88=E7=AD=9B=E9=80=89=E6=A0=8F=E5=A2=9E?= =?utf8?q?=E5=8A=A0=E6=9F=A5=E8=AF=A2=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- src-vue/Home.vue | 5 +- src-vue/pages/DomainSettings.vue | 82 ++++++++++++++++++- src-vue/pages/domain/CompanyDomainLibrary.vue | 5 ++ src-vue/styles/ui-system.css | 11 ++- 4 files changed, 96 insertions(+), 7 deletions(-) diff --git a/src-vue/Home.vue b/src-vue/Home.vue index 9ad4273..ca42329 100644 --- a/src-vue/Home.vue +++ b/src-vue/Home.vue @@ -236,11 +236,12 @@ onMounted(() => { const reloadDomains = async () => { try { const d = await fetchDb("/domains"); const arr = d || []; - domainOptions.value = arr.map((x) => ({ id: x.id, name: x.name })); + domainOptions.value = arr.map((x) => ({ id: x.id, name: x.name, color: x.color })); domains.value = arr.map((x) => x.name); } catch (e) { notify("加载领域失败: " + e.ElMessage); } }; const handleDomainDeleted = async (id) => { await reloadDomains(); if (domainFilter.value === id) domainFilter.value = null; }; +const handleDomainUpdated = async () => { await reloadDomains(); }; const loadSite = async (id) => { const data = await fetchDb(`/sites/${id}`); site.value = data; siteId.value = id; }; const createSite = async () => { @@ -619,7 +620,7 @@ function onMenuOpenChange(keys) { resourceNavOpen.value = keys.includes("resourc - +
diff --git a/src-vue/pages/DomainSettings.vue b/src-vue/pages/DomainSettings.vue index 0b1aba3..53327bd 100644 --- a/src-vue/pages/DomainSettings.vue +++ b/src-vue/pages/DomainSettings.vue @@ -11,7 +11,7 @@ import Panel from "../components/Panel.vue"; import Field from "../components/Field.vue"; import StatusTag from "../components/StatusTag.vue"; import PrimaryButton from "../components/PrimaryButton.vue"; -import { fetchDb, loadRenderer } from "../lib/api.js"; +import { fetchDb, loadRenderer, domainTagColor } from "../lib/api.js"; import { MODELS } from "../lib/meta.js"; import { useConfirm } from "../pages/domain/useConfirm.js"; import { DeviceImageField, DeviceTemplateCard, CP_RANGE_PRESETS, fileToBase64 } from "../components/DeviceTemplateCard.js"; @@ -21,6 +21,20 @@ const ElButton = PrimaryButton; // React `Status` (ElTag with tone class). const Status = StatusTag; +// 领域默认颜色配置:skill(web-ui-builder / antd 设计体系)预设色板, +// 与领域方案首页标签同一套配色;未显式设置颜色时按名称回退到 domainTagColor。 +const DOMAIN_COLORS = [ + { value: "blue", label: "蓝" }, + { value: "cyan", label: "青" }, + { value: "orange", label: "橙" }, + { value: "green", label: "绿" }, + { value: "purple", label: "紫" }, + { value: "red", label: "红" }, +]; +function domainColor(row) { + return row.color || domainTagColor(row.name); +} + const CURRENT_USER_EMAIL = "wang.yu@advantech.com"; function useStreamComplete() { const completing = ref(false); @@ -58,6 +72,7 @@ const props = defineProps({ domains: { type: Array, default: () => [] }, notify: { type: Function, default: () => {} }, onDeleted: { type: Function, default: () => Promise.resolve() }, + onUpdated: { type: Function, default: () => Promise.resolve() }, }); const { confirm, el: confirmEl } = useConfirm(); @@ -73,6 +88,31 @@ async function remove(row) { } } +// ---- 领域编辑:名称 + 默认颜色配置 ---- +const editing = ref(null); +const editName = ref(""); +const editColor = ref(""); +function openEdit(row) { + editing.value = row; + editName.value = row.name; + editColor.value = domainColor(row); +} +async function saveEdit() { + if (!editName.value.trim()) { props.notify("请填写领域名称"); return; } + try { + await fetchDb(`/domains/${editing.value.id}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name: editName.value.trim(), color: editColor.value }), + }); + props.notify("已保存领域"); + editing.value = null; + if (props.onUpdated) await props.onUpdated(); + } catch (e) { + props.notify("保存失败:" + (e && e.ElMessage ? e.ElMessage : e)); + } +} + // ============================================================================ // Co-located port of every component defined in app/page.tsx lines 1543–1928. // (DomainLibrary, CreateTemplate, DeviceImageField, DeviceTemplateCard, @@ -590,12 +630,18 @@ const OpsFlowsViewer = { - {{ row.name }} + + + {{ row.name }} + 领域方案、站点项目 - 不可删除 - 删除 + 系统预置 + @@ -603,5 +649,33 @@ const OpsFlowsViewer = {
暂无领域,请点击右上角“新增领域”创建
+ + +
+

编辑领域

+ + + + 取消 + 保存 + +
+
diff --git a/src-vue/pages/domain/CompanyDomainLibrary.vue b/src-vue/pages/domain/CompanyDomainLibrary.vue index bc45e6c..8c8ba83 100644 --- a/src-vue/pages/domain/CompanyDomainLibrary.vue +++ b/src-vue/pages/domain/CompanyDomainLibrary.vue @@ -5,6 +5,8 @@ import { Search, OfficeBuilding, Close, DocumentCopy, Menu } from "@element-plus import UiButton from "../../ui/UiButton.vue"; import UiInput from "../../ui/UiInput.vue"; import UiSelect from "../../ui/UiSelect.vue"; +import UiActions from "../../ui/UiActions.vue"; +import PrimaryButton from "../../components/PrimaryButton.vue"; import { fetchDb, domainTagColor } from "../../lib/api.js"; import { friendlyDomainName, domainScene, SOLUTION_PHOTOS, statusTone } from "./domainCommon.js"; @@ -79,6 +81,9 @@ const statusText = (row) => (row.status === "available" ? "可用" : "不可用" + + 查询 +
正在加载领域方案…
diff --git a/src-vue/styles/ui-system.css b/src-vue/styles/ui-system.css index 6ca7fd4..2880de8 100644 --- a/src-vue/styles/ui-system.css +++ b/src-vue/styles/ui-system.css @@ -82,13 +82,22 @@ html,body{font-family:var(--ant-font-family);font-size:var(--ant-font-size);colo .station-inline-actions,.station-modal-actions,.station-drawer-actions,.drawer-actions,.result-actions,.settings-actions{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--ant-padding-xs)} .station-modal-actions{justify-content:flex-end} /* Element Plus Dialog 承载定位、聚焦与外框;旧类名只标识业务内容。 */ -.station-ui-modal.modal,.station-ui-modal.dlg-box{display:block;position:relative;inset:auto;margin-inline:auto;padding:0;max-width:calc(100vw - 32px);max-height:none;height:auto;background:none;border:0;border-radius:0;box-shadow:none;overflow:visible;z-index:auto;color:var(--ant-color-text-base);font-size:var(--ant-font-size)} +.station-ui-modal.modal,.station-ui-modal.dlg-box{display:block;position:relative;inset:auto;margin-inline:auto;padding:0;max-width:calc(100vw - 32px);max-height:none;height:auto;background:var(--ant-color-bg-container);border:1px solid var(--ant-color-border);border-radius:var(--ant-border-radius-lg);box-shadow:0 12px 36px color-mix(in srgb,var(--ant-color-text-base) 20%,transparent);overflow:visible;z-index:auto;color:var(--ant-color-text-base);font-size:var(--ant-font-size)} .station-ui-modal .el-dialog{padding:var(--ant-padding-lg);border-radius:var(--ant-border-radius-lg)} .station-ui-modal .el-dialog__title{font-size:var(--ant-font-size-heading-4);font-weight:600} .station-ui-modal .el-dialog__body{font-size:var(--ant-font-size);color:var(--ant-color-text-base)} .station-ui-modal .modal-body{padding:0;max-height:70vh;overflow:auto} .station-ui-modal .el-dialog__footer{margin-top:var(--ant-padding-lg)} .station-ui-modal .station-modal-actions .el-button{margin:0} +/* 领域配置:默认颜色配置(swatch / dot),复用 antd 预设色板(web-ui-builder 设计体系) */ +.domain-color-dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-right:8px;vertical-align:middle;border:1px solid color-mix(in srgb,var(--ant-color-text-base) 10%,transparent)} +.domain-color-dot.tag-blue{background:#1677ff}.domain-color-dot.tag-cyan{background:#13c2c2}.domain-color-dot.tag-orange{background:#fa8c16}.domain-color-dot.tag-green{background:#52c41a}.domain-color-dot.tag-purple{background:#722ed1}.domain-color-dot.tag-red{background:#f5222d}.domain-color-dot.tag-default{background:#8c8c8c} +.domain-edit-dialog .field{display:block;margin-bottom:16px} +.domain-edit-dialog .field-label{display:block;font-size:var(--ant-font-size-sm);color:var(--ant-color-text-secondary);margin-bottom:6px} +.domain-color-picker{display:flex;gap:10px;flex-wrap:wrap} +.domain-color-swatch{width:28px;height:28px;border-radius:var(--ant-border-radius);border:1px solid var(--ant-color-border);cursor:pointer;padding:0;transition:box-shadow .15s} +.domain-color-swatch.tag-blue{background:#1677ff}.domain-color-swatch.tag-cyan{background:#13c2c2}.domain-color-swatch.tag-orange{background:#fa8c16}.domain-color-swatch.tag-green{background:#52c41a}.domain-color-swatch.tag-purple{background:#722ed1}.domain-color-swatch.tag-red{background:#f5222d}.domain-color-swatch.tag-default{background:#8c8c8c} +.domain-color-swatch.active{box-shadow:0 0 0 2px var(--ant-color-bg-container),0 0 0 4px var(--ant-color-primary);border-color:transparent} .station-ui-select .el-select__wrapper{font-size:var(--ant-font-size);min-height:var(--ant-control-height)} .filterbar.company-filterbar{height:auto;min-height:48px;flex-wrap:nowrap} .filterbar.company-filterbar .station-ui-select{flex-shrink:0;width:160px;min-width:160px} -- 2.43.0