ai_scheduler/web/assets/js/project_list.js

129 lines
7.3 KiB
JavaScript

/* ==================== 视图一:项目管理 ==================== */
function renderProjects() {
var st = state.projects;
$("#view-projects").innerHTML =
'<div class="card">' +
'<div class="card-title"><span class="bar"></span>项目列表<span class="spacer"></span>' +
'<div class="search-box" style="max-width:220px"><input id="pj-search" class="input sm" placeholder="按名称搜索" value="' + Core.esc(st.kw) + '"></div>' +
'<button class="btn primary sm" id="pj-add">+ 新增项目</button></div>' +
'<div class="card-sub">新建项目时可选择行业模板自动复制维度内容,进入项目后可继续编辑与 AI 分析。</div>' +
'<div id="pj-table"></div>' +
'<div id="pj-pager"></div>' +
"</div>";
$("#pj-add").onclick = projectCreateDialog;
var doSearch = Core.debounce(function () { st.kw = $("#pj-search").value.trim(); loadProjects(1); }, 350);
$("#pj-search").oninput = doSearch;
loadProjects(st.page);
}
function loadProjects(page) {
page = page || 1;
var st = state.projects;
$("#pj-table").innerHTML = '<div class="empty"><span class="spin"></span></div>';
Core.api("project/list", { name: st.kw, page: page, page_size: 10 })
.then(function (data) {
st.list = (data && data.list) || [];
st.total = (data && data.total) || 0;
st.page = page;
renderProjectsTable();
})
.catch(function (e) {
$("#pj-table").innerHTML = '<div class="empty"><div class="big">⚠</div>' + Core.esc(e.message) + "</div>";
});
}
function renderProjectsTable() {
var st = state.projects;
if (!st.list.length) {
$("#pj-table").innerHTML = '<div class="empty"><div class="big">▤</div>' + (st.kw ? "无匹配项目" : '暂无项目,点击「+ 新增项目」开始<br><span class="fs-12">提示:先在管理后台配置行业模板与模型配置效果更佳</span>') + "</div>";
$("#pj-pager").innerHTML = "";
return;
}
var activeId = state.project && state.project.projectId;
var rows = st.list.map(function (p) {
var isActive = String(p.project_id) === String(activeId);
var dims = ["client_dimension", "project_dimension", "advicer_dimension", "talk_skill_dimension"].filter(function (k) {
return p[k] && String(p[k]).trim();
}).length;
return "<tr>" +
'<td class="mono">' + p.project_id + "</td>" +
'<td><span class="name pj-enter-link" data-id="' + p.project_id + '" style="cursor:pointer" title="点击进入项目">' + Core.esc(p.name) + "</span>" + (isActive ? ' <span class="badge green">当前</span>' : "") + "</td>" +
'<td>' + (p.model_sup_id ? '<span class="badge blue">#' + p.model_sup_id + "</span>" : '<span class="badge gray">未配置</span>') + "</td>" +
'<td>' + (p.industry_id ? '<span class="badge purple">#' + p.industry_id + "</span>" : '<span class="badge gray">未关联</span>') + "</td>" +
'<td><span class="badge ' + (dims >= 4 ? "green" : dims > 0 ? "yellow" : "gray") + '">' + dims + "/4 维度</span></td>" +
'<td class="fs-12">' + Core.fmtTime(p.create_at) + "</td>" +
'<td class="ops">' +
'<button class="btn primary sm pj-enter" data-id="' + p.project_id + '">进入</button>' +
'<button class="btn ghost sm pj-set" data-id="' + p.project_id + '">设置</button>' +
"</td></tr>";
}).join("");
$("#pj-table").innerHTML =
'<div class="table-wrap"><table class="table"><thead><tr>' +
"<th>ID</th><th>项目名称</th><th>模型配置</th><th>行业模板</th><th>维度</th><th>创建时间</th><th>操作</th>" +
"</tr></thead><tbody>" + rows + "</tbody></table></div>";
var pages = Math.max(1, Math.ceil(st.total / 10));
$("#pj-pager").innerHTML =
'<div class="row mt-2"><span class="fs-12 c-dim">共 ' + st.total + " 条 · 第 " + st.page + "/" + pages + ' 页</span><span class="spacer"></span>' +
'<button class="btn ghost sm pg-prev" ' + (st.page <= 1 ? "disabled" : "") + ">上一页</button>" +
'<button class="btn ghost sm pg-next" ' + (st.page >= pages ? "disabled" : "") + ">下一页</button></div>";
$(".pg-prev").onclick = function () { loadProjects(st.page - 1); };
$(".pg-next").onclick = function () { loadProjects(st.page + 1); };
function enterProject(id) {
console.log("[enterProject] id=", id, "list len=", st.list.length);
var p = st.list.filter(function (x) { return String(x.project_id) === String(id); })[0];
if (!p) { Core.toast("未找到项目", "err"); return; }
console.log("[enterProject] found project:", p.project_id, p.name);
setActiveProject(p);
Core.toast("已进入项目:" + p.name, "ok");
setTimeout(function () { switchView("data"); }, 50);
}
$$("#pj-table .pj-enter").forEach(function (b) {
b.onclick = function (e) { e.stopPropagation(); enterProject(b.dataset.id); };
});
$$("#pj-table .pj-enter-link").forEach(function (b) {
b.onclick = function () { enterProject(b.dataset.id); };
});
$$("#pj-table .pj-set").forEach(function (b) {
b.onclick = function (e) { e.stopPropagation();
var p = st.list.filter(function (x) { return String(x.project_id) === b.dataset.id; })[0];
if (!p) return;
setActiveProject(p);
setTimeout(function () { switchView("projectDetail"); }, 50);
};
});
}
function projectCreateDialog() {
var m = Core.modal({
title: "新增项目",
body:
'<div class="field"><label class="label">项目名称<span class="req">*</span></label><input id="pc-name" class="input" placeholder="如:槐树店项目"></div>' +
'<div class="field"><label class="label">模型配置<span class="req">*</span></label><select id="pc-model" class="select"><option>加载中…</option></select><div class="hint">项目内所有 AI 能力(分析/对话)将使用该模型配置</div></div>' +
'<div class="field"><label class="label">行业模板(复制维度模板)</label><select id="pc-industry" class="select"><option>加载中…</option></select><div class="hint">选择后自动把行业模板的维度内容复制到项目,可在项目设置中继续编辑</div></div>',
footer: '<button class="btn ghost mf-cancel">取消</button><button class="btn primary mf-save">创建并进入</button>'
});
loadModelsupOptions($("#pc-model", m.root), null).catch(function (e) { Core.toast(e.message, "err"); });
loadIndustryOptions($("#pc-industry", m.root), null).catch(function (e) { Core.toast(e.message, "err"); });
$(".mf-cancel", m.root).onclick = m.close;
$(".mf-save", m.root).onclick = function () {
var name = $("#pc-name", m.root).value.trim();
var modelSupId = Number($("#pc-model", m.root).value);
var industryId = Number($("#pc-industry", m.root).value) || 0;
if (!name) { Core.toast("请填写项目名称", "err"); return; }
if (!modelSupId) { Core.toast("请选择模型配置", "err"); return; }
Core.loading(true, "创建项目中…");
Core.api("project/base/init", { name: name, modelSupId: modelSupId, industryId: industryId })
.then(function (data) {
Core.loading(false);
m.close();
var pid = data && data.projectId;
Core.toast("项目创建成功 #" + pid + (industryId ? "(已复制行业模板)" : ""), "ok");
setActiveProject({ projectId: pid, name: name });
loadProjects(1);
switchView("projectDetail");
})
.catch(function (e) { Core.loading(false); Core.toast(e.message, "err"); });
};
}