]> acesimba.cloud Git - StationBuilder-vue.git/commitdiff
新增领域弹窗:增加默认颜色编辑;修复输入框双重边框(去除 el-input__inner 多余边框)
authorroot <root@localhost.localdomain>
Mon, 28 Sep 2026 05:55:36 +0000 (13:55 +0800)
committerroot <root@localhost.localdomain>
Mon, 28 Sep 2026 05:55:36 +0000 (13:55 +0800)
src-vue/Home.vue
src-vue/styles/ui-system.css

index ca42329497137d78e8b46df9fe2d0f16dff3664e..e733d7d7562284e4bc55b0dea2788fc2937ef1c0 100644 (file)
@@ -105,6 +105,17 @@ const deviceTemplateDomain = ref((() => { try { return new URLSearchParams(windo
 const domainOptions = ref([]);
 const addingDomain = ref(false);
 const newDomainName = ref("");
+const newDomainColor = ref("");
+
+// 领域默认颜色配置:与领域方案首页标签、编辑弹窗同一套色板(web-ui-builder / antd 设计体系)
+const DOMAIN_COLORS = [
+  { value: "blue", label: "蓝" },
+  { value: "cyan", label: "青" },
+  { value: "orange", label: "橙" },
+  { value: "green", label: "绿" },
+  { value: "purple", label: "紫" },
+  { value: "red", label: "红" },
+];
 
 const view = ref("table");
 const siteEditSection = ref("basic");
@@ -374,14 +385,14 @@ const saveMu = async (selected) => {
   try { const saved = await fetchDb(`/sites/${site.value.id}/mu`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ selected }) }); site.value = saved; }
   catch (e) { notify("MU 选择保存失败: " + e.ElMessage); throw e; }
 };
-const addDomain = async (name) => {
+const addDomain = async (name, color) => {
   const n = (name || "").trim();
   if (!n) return;
   if (n.length > 6) { notify("领域名称不超过 6 个字"); return; }
-  try { await fetchDb("/domains", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: n }) }); await reloadDomains(); }
+  try { await fetchDb("/domains", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: n, color: color || "" }) }); await reloadDomains(); }
   catch (e) { notify("添加领域失败: " + e.ElMessage); }
 };
-const doAddDomain = async () => { if (!newDomainName.value.trim()) return; await addDomain(newDomainName.value); addingDomain.value = false; newDomainName.value = ""; };
+const doAddDomain = async () => { if (!newDomainName.value.trim()) return; await addDomain(newDomainName.value, newDomainColor.value); addingDomain.value = false; newDomainName.value = ""; newDomainColor.value = ""; };
 const uploadFile = async (file) => {
   if (!site.value) return;
   const reader = new FileReader(); reader.readAsDataURL(file);
@@ -596,7 +607,7 @@ function onMenuOpenChange(keys) { resourceNavOpen.value = keys.includes("resourc
             <PrimaryButton v-if="page === 'domains' && openDomainTemplateId == null" @click="openDomainTemplateId = 'create'"><Upload /> 导入领域方案</PrimaryButton>
             <PrimaryButton v-if="page === 'domains' && openDomainTemplateId != null" secondary @click="openDomainTemplateId = null">← 返回方案列表</PrimaryButton>
             <PrimaryButton v-if="domainFilter != null && page === 'domains' && openDomainTemplateId == null" secondary @click="domainFilter = null">清除领域筛选:{{ domainOptions.find((d) => d.id === domainFilter)?.name || '' }}</PrimaryButton>
-            <PrimaryButton v-if="page === 'domainSettings'" @click="() => { newDomainName = ''; addingDomain = true; }">+ 新增领域</PrimaryButton>
+            <PrimaryButton v-if="page === 'domainSettings'" @click="() => { newDomainName = ''; newDomainColor = ''; addingDomain = true; }">+ 新增领域</PrimaryButton>
           </div>
         </div>
         <SiteEditTabs v-if="page === 'siteEdit'" :section="siteEditSection" :onChange="(s) => changeConfigurationStep(s)" />
@@ -643,13 +654,30 @@ function onMenuOpenChange(keys) { resourceNavOpen.value = keys.includes("resourc
         </div>
       </main>
     </div>
-    <UiOverlay v-if="addingDomain && page === 'domainSettings'" className="dlg-backdrop" :onMouseDown="() => { addingDomain = false; newDomainName = ''; }">
+    <UiOverlay v-if="addingDomain && page === 'domainSettings'" className="dlg-backdrop" :onMouseDown="() => { addingDomain = false; newDomainName = ''; newDomainColor = ''; }">
       <div class="dlg-box domain-create-dialog" @mousedown.stop>
         <h2>新增领域</h2>
         <p>创建后可在领域方案和站点基本信息中直接选择。</p>
-        <UiInput autoFocus :value="newDomainName" maxLength="6" placeholder="请输入领域名称(最多 6 个字)" @change="(e) => (newDomainName = e.target.value)" @keydown="async (e) => { if (e.key === 'Enter') await doAddDomain(); if (e.key === 'Escape') { addingDomain = false; newDomainName = ''; } }" />
+        <label class="field">
+          <span class="field-label">领域名称</span>
+          <UiInput autoFocus :value="newDomainName" maxLength="6" placeholder="请输入领域名称(最多 6 个字)" @change="(e) => (newDomainName = e.target.value)" @keydown="async (e) => { if (e.key === 'Enter') await doAddDomain(); if (e.key === 'Escape') { addingDomain = false; newDomainName = ''; newDomainColor = ''; } }" />
+        </label>
+        <label class="field">
+          <span class="field-label">默认颜色(可选,不选则按名称自动匹配)</span>
+          <div class="domain-color-picker">
+            <button
+              v-for="c in DOMAIN_COLORS"
+              :key="c.value"
+              type="button"
+              class="domain-color-swatch"
+              :class="['tag-' + c.value, { active: newDomainColor === c.value }]"
+              :title="c.label"
+              @click="() => (newDomainColor = c.value)"
+            ></button>
+          </div>
+        </label>
         <UiActions className="dlg-actions">
-          <PrimaryButton secondary @click="() => { addingDomain = false; newDomainName = ''; }">取消</PrimaryButton>
+          <PrimaryButton secondary @click="() => { addingDomain = false; newDomainName = ''; newDomainColor = ''; }">取消</PrimaryButton>
           <PrimaryButton :disabled="!newDomainName.trim()" @click="doAddDomain">创建</PrimaryButton>
         </UiActions>
       </div>
index 57af44a2c6065fa6f4d5db447f252f99ff25f1a1..d9ae096d6873847fd0b8cf03c1880d1152267d50 100644 (file)
@@ -88,15 +88,15 @@ html,body{font-family:var(--ant-font-family);font-size:var(--ant-font-size);colo
 .station-ui-modal .el-dialog__headerbtn .el-dialog__close{font-size:16px;color:color-mix(in srgb,var(--ant-color-text-base) 45%,transparent)}
 .station-ui-modal .el-dialog__title{font-size:22px;font-weight:600;line-height:1.4454;color:color-mix(in srgb,var(--ant-color-text-base) 88%,transparent)}
 .station-ui-modal .el-dialog__body{padding:0;font-size:var(--ant-font-size);color:var(--ant-color-text-base)}
-.station-ui-modal.dlg-box .el-input__inner{font-size:var(--ant-font-size)}
+.station-ui-modal.dlg-box .el-input__inner{font-size:var(--ant-font-size);border:0}
 .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-edit-dialog .field,.domain-create-dialog .field{display:block;margin-bottom:16px}
+.domain-edit-dialog .field-label,.domain-create-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}