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");
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);
<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)" />
</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>
.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}