From: root Date: Mon, 14 Sep 2026 02:38:41 +0000 (+0800) Subject: 领域方案列表新增从模板创建列,点击后按模板配置创建新站点 X-Git-Url: http://acesimba.cloud/gitweb/?a=commitdiff_plain;h=27c6a2348a6f5cd9c20dc1f3a836f6e98147dc61;p=StationBuilder.git 领域方案列表新增从模板创建列,点击后按模板配置创建新站点 --- diff --git a/app/page.tsx b/app/page.tsx index 7d3eda6..44bfdc7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2636,7 +2636,7 @@ function CompanyDomainLibrary({go,notify,onOpen,domainFilter,domainOptions}:{go:
- {loading?
加载中…
:<>{filtered.slice((pageIndex-1)*pageSize,pageIndex*pageSize).map(row=>setPreview(row)}>)}
方案名称所属领域版本设备页面文档状态创建人操作
{row.domain_name||"—"}{row.version||"—"}{row.device_count||0}{row.page_count||0}{row.doc_count||0}{row.status==="available"?"可用":"不可用"}{row.creator||"—"}e.stopPropagation()}>},{key:"delete",label:"删除",danger:true,icon:}],onClick:({key})=>key==="edit"?onOpen(row.id):remove(row)}}>}/>
{filtered.length===0&&
暂无符合条件的领域方案
}
{filtered.length} / 总数
} + {loading?
加载中…
:<>{filtered.slice((pageIndex-1)*pageSize,pageIndex*pageSize).map(row=>setPreview(row)}>)}
方案名称所属领域版本设备页面文档状态创建人从模板创建操作
{row.domain_name||"—"}{row.version||"—"}{row.device_count||0}{row.page_count||0}{row.doc_count||0}{row.status==="available"?"可用":"不可用"}{row.creator||"—"}e.stopPropagation()}>e.stopPropagation()}>},{key:"delete",label:"删除",danger:true,icon:}],onClick:({key})=>key==="edit"?onOpen(row.id):remove(row)}}>}/>
{filtered.length===0&&
暂无符合条件的领域方案
}
{filtered.length} / 总数
} setPreview(null)} extra={preview&&}> {preview&&
{preview.status==="available"?"可用":"不可用"}

基础信息

所属领域
{preview.domain_name||"—"}
版本
{preview.version||"—"}
创建人
{preview.creator||"—"}

方案内容

设备模板
{preview.device_count||0}
页面
{preview.page_count||0}
知识文档
{preview.doc_count||0}
{preview.description&&<>

方案说明

{preview.description}

}
} diff --git a/db-sidecar.mjs b/db-sidecar.mjs index 0889bdb..f8732e2 100644 --- a/db-sidecar.mjs +++ b/db-sidecar.mjs @@ -1968,6 +1968,36 @@ async function handleDomainTemplateDelete(res, id) { respondJson(res, 200, { ok: true }); } +async function handleCreateSiteFromTemplate(req, res, tmplId) { + const dt = db.prepare("SELECT dt.*, d.name AS domain_name FROM domain_templates dt JOIN domains d ON d.id=dt.domain_id WHERE dt.id=?").get(tmplId); + if (!dt) return respondError(res, 404, "领域方案不存在"); + // 创建站点 + const info = db.prepare("INSERT INTO sites (name, domain, description, supplement, status) VALUES (?,?,?,?,?)").run( + (dt.name || "") + " - 站点", dt.domain_name || "", dt.description || "", dt.supplement || "", "draft" + ); + const siteId = info.lastInsertRowid; + // 复制模板资产到站点 + const tmplAssets = db.prepare("SELECT device_template_id, count, rule, sort_order FROM domain_template_assets WHERE domain_template_id=? ORDER BY sort_order,id").all(tmplId); + const insertAsset = db.prepare("INSERT INTO assets (site_id, type, count, rule, sort_order) VALUES (?,?,?,?,?)"); + for (const a of tmplAssets) { + insertAsset.run(siteId, String(a.device_template_id), a.count || 0, a.rule || "", a.sort_order ?? 0); + } + if (tmplAssets.length === 0) { + for (let i = 0; i < 4; i++) insertAsset.run(siteId, "", 0, "", i); + } + // 复制模板 MU 页面选择 + const muKeys = db.prepare("SELECT page_key FROM domain_template_mu WHERE domain_template_id=?").all(tmplId).map(r => r.page_key); + if (muKeys.length > 0) { + db.prepare("UPDATE sites SET mu=? WHERE id=?").run(JSON.stringify(muKeys), siteId); + } + // 复制 style_id + if (dt.style_id != null) { + db.prepare("UPDATE sites SET style_id=? WHERE id=?").run(dt.style_id, siteId); + } + const site = hydrateSite(siteId); + respondJson(res, 200, site); +} + // ===== 领域方案 AI 补全 / Cube 生成(复用站点侧提示词构造与生成逻辑)===== async function hydrateDomainTemplateCtx(tmplId) { const dt = db.prepare("SELECT dt.*, d.name AS domain_name FROM domain_templates dt JOIN domains d ON d.id=dt.domain_id WHERE dt.id=?").get(tmplId); @@ -2542,6 +2572,7 @@ async function route(req, res) { const mDtCompleteCubesPrompt = path.match(/^\/api\/domain-templates\/(\d+)\/complete-cubes-prompt$/); const mDtPageGen = path.match(/^\/api\/domain-templates\/(\d+)\/pages\/(\d+)\/generate$/); const mDtPageRefine = path.match(/^\/api\/domain-templates\/(\d+)\/pages\/(\d+)\/refine$/); + const mDtCreateSite = path.match(/^\/api\/domain-templates\/(\d+)\/create-site$/); const mDevList = path === "/api/device-templates"; const mDevCp = path.match(/^\/api\/device-templates\/(\d+)\/collection-points$/); const mDevAttr = path.match(/^\/api\/device-templates\/(\d+)\/attributes$/); @@ -2827,6 +2858,7 @@ async function route(req, res) { if (req.method === "PUT") return handleDomainTemplateUpdate(req, res, Number(mDt[1])); if (req.method === "DELETE") return handleDomainTemplateDelete(res, Number(mDt[1])); } + if (mDtCreateSite && req.method === "POST") return handleCreateSiteFromTemplate(req, res, Number(mDtCreateSite[1])); if (mDevList) { if (req.method === "GET") return handleDeviceTemplatesList(res); if (req.method === "POST") return handleDeviceTemplateCreate(req, res);