You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

139 lines
10 KiB

import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderStyle, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual, ssrRenderList, ssrRenderAttr, ssrInterpolate } from 'vue/server-renderer';
import { u as useApi } from './useApi-B-E5eLsI.mjs';
import { u as useToast } from './useToast-CS21XT61.mjs';
import './server.mjs';
import '../nitro/nitro.mjs';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'node:fs';
import 'node:path';
import 'node:crypto';
import 'node:url';
import '../routes/renderer.mjs';
import 'vue-bundle-renderer/runtime';
import 'unhead/server';
import 'devalue';
import 'unhead/utils';
import 'pinia';
import 'perfect-debounce';
import './useLoading-D4zrSa2m.mjs';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "meettemplates",
__ssrInlineRender: true,
setup(__props) {
useApi();
useToast();
const view = ref("list");
const rows = ref([]);
const loading = ref(false);
const submitting = ref(false);
const isEditing = ref(false);
const langFilter = ref("zh");
const tidFilter = ref("");
const kwFilter = ref("");
const form = reactive({
id: 0,
title: "",
tid: "",
language: "",
ttype: "",
tags: "",
icon: "",
description: "",
outline: "",
template: ""
});
function tagList(s) {
return (s || "").split(",").map((x) => x.trim()).filter(Boolean);
}
function baseLang(s) {
return (s || "").split("-")[0].trim().toLowerCase();
}
const langOptions = computed(() => {
const set = /* @__PURE__ */ new Set();
rows.value.forEach((t) => {
if (t.language) set.add(t.language);
});
return Array.from(set).sort();
});
const tidOptions = computed(() => {
const set = /* @__PURE__ */ new Set();
rows.value.forEach((t) => {
if (t.tid) set.add(t.tid);
});
return Array.from(set).sort();
});
const filteredRows = computed(() => {
const kw = kwFilter.value.trim().toLowerCase();
return rows.value.filter((t) => {
if (langFilter.value && baseLang(t.language) !== baseLang(langFilter.value)) return false;
if (tidFilter.value && (t.tid || "") !== tidFilter.value) return false;
if (kw && (t.title || "").toLowerCase().indexOf(kw) < 0) return false;
return true;
});
});
const groupedRows = computed(() => {
const groups = {};
filteredRows.value.forEach((t) => {
const g = t.tid || "";
(groups[g] = groups[g] || []).push(t);
});
const names = Object.keys(groups).sort((a, b) => {
if (a === "") return -1;
if (b === "") return 1;
return a < b ? -1 : 1;
});
return names.map((g) => ({ key: g, label: g || "无 tid", items: groups[g] }));
});
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)}><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}"><div class="flex items-center justify-between mb-5"><div><h2 class="text-lg font-semibold text-slate-800">会议模板</h2><p class="text-xs text-slate-400 mt-1">会议纪要公共模板(source=public),所有应用共享。修改后各服务约 10 分钟内自动同步。</p></div><button class="btn btn-primary btn-sm text-white">+ 新增模板</button></div><div class="flex items-center gap-3 mb-4 flex-wrap"><span class="text-sm text-slate-500">语言</span><select class="select select-bordered select-sm"><option value=""${ssrIncludeBooleanAttr(Array.isArray(langFilter.value) ? ssrLooseContain(langFilter.value, "") : ssrLooseEqual(langFilter.value, "")) ? " selected" : ""}>全部语言</option><!--[-->`);
ssrRenderList(langOptions.value, (l) => {
_push(`<option${ssrRenderAttr("value", l)}${ssrIncludeBooleanAttr(Array.isArray(langFilter.value) ? ssrLooseContain(langFilter.value, l) : ssrLooseEqual(langFilter.value, l)) ? " selected" : ""}>${ssrInterpolate(l)}</option>`);
});
_push(`<!--]--></select><span class="text-sm text-slate-500">分组(tid)</span><select class="select select-bordered select-sm"><option value=""${ssrIncludeBooleanAttr(Array.isArray(tidFilter.value) ? ssrLooseContain(tidFilter.value, "") : ssrLooseEqual(tidFilter.value, "")) ? " selected" : ""}>全部分组</option><!--[-->`);
ssrRenderList(tidOptions.value, (t) => {
_push(`<option${ssrRenderAttr("value", t)}${ssrIncludeBooleanAttr(Array.isArray(tidFilter.value) ? ssrLooseContain(tidFilter.value, t) : ssrLooseEqual(tidFilter.value, t)) ? " selected" : ""}>${ssrInterpolate(t)}</option>`);
});
_push(`<!--]--></select><input${ssrRenderAttr("value", kwFilter.value)} class="input input-bordered input-sm w-48" placeholder="按标题搜索"></div><div class="bg-white rounded-xl shadow-sm border border-slate-100"><div class="overflow-x-auto"><table class="table table-zebra"><thead><tr><th>ID</th><th>标题</th><th>模板标识(tid)</th><th>语言</th><th>类型</th><th>标签</th><th class="text-right">操作</th></tr></thead><tbody>`);
if (loading.value) {
_push(`<tr><td colspan="7" class="text-center py-8"><span class="loading loading-spinner loading-sm"></span></td></tr>`);
} else if (!filteredRows.value.length) {
_push(`<tr><td colspan="7" class="text-center text-slate-400 py-8">暂无模板</td></tr>`);
} else {
_push(`<!--[-->`);
ssrRenderList(groupedRows.value, (g) => {
_push(`<!--[--><tr class="bg-slate-100/80"><td colspan="7" class="py-2"><span class="font-semibold text-slate-600 text-sm">▸ ${ssrInterpolate(g.label)}</span><span class="text-xs text-slate-400 ml-2">${ssrInterpolate(g.items.length)} 个版本</span></td></tr><!--[-->`);
ssrRenderList(g.items, (t) => {
_push(`<tr class="hover"><td class="font-mono text-sm text-slate-400">${ssrInterpolate(t.id || "")}</td><td class="font-medium">${ssrInterpolate(t.title || "")}</td><td class="font-mono text-sm">${ssrInterpolate(t.tid || "")}</td><td><span class="badge badge-outline badge-sm">${ssrInterpolate(t.language || "-")}</span></td><td class="text-sm">${ssrInterpolate(t.ttype || "")}</td><td class="text-sm">`);
if (tagList(t.tags).length) {
_push(`<!--[-->`);
ssrRenderList(tagList(t.tags), (tag, i) => {
_push(`<span class="badge badge-ghost badge-sm mr-1">${ssrInterpolate(tag)}</span>`);
});
_push(`<!--]-->`);
} else {
_push(`<span class="text-slate-300">-</span>`);
}
_push(`</td><td class="text-right"><div class="inline-flex gap-1"><button class="btn btn-ghost btn-xs">编辑</button><button class="btn btn-ghost btn-xs text-red-500">删除</button></div></td></tr>`);
});
_push(`<!--]--><!--]-->`);
});
_push(`<!--]-->`);
}
_push(`</tbody></table></div></div></div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}"><div class="flex items-center gap-3 mb-5"><button class="btn btn-ghost btn-sm">← 返回列表</button><h2 class="text-lg font-semibold text-slate-800">${ssrInterpolate(isEditing.value ? "编辑模板" : "新增模板")}</h2></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-3xl"><form><div class="grid grid-cols-2 gap-4"><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">标题 *</span></label><input${ssrRenderAttr("value", form.title)} type="text" class="input input-bordered w-full" required></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">模板标识 (tid)</span></label><input${ssrRenderAttr("value", form.tid)} type="text" class="input input-bordered w-full" placeholder="同一 tid 可有多语言版本"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">语言</span></label><input${ssrRenderAttr("value", form.language)} type="text" class="input input-bordered w-full" placeholder="如 zh / en" list="langlist"><datalist id="langlist"><option value="zh"></option><option value="en"></option><option value="ja"></option><option value="ko"></option></datalist></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">类型 (ttype)</span></label><input${ssrRenderAttr("value", form.ttype)} type="text" class="input input-bordered w-full" placeholder="如 meeting / interview"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">标签 (tags)</span></label><input${ssrRenderAttr("value", form.tags)} type="text" class="input input-bordered w-full" placeholder="逗号分隔"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">图标 (icon)</span></label><input${ssrRenderAttr("value", form.icon)} type="text" class="input input-bordered w-full" placeholder="图标 URL 或名称"></div></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">描述</span></label><input${ssrRenderAttr("value", form.description)} type="text" class="input input-bordered w-full"></div><div class="form-control mb-4"><label class="label"><span class="label-text font-medium">大纲 (outline)</span></label><textarea class="textarea textarea-bordered w-full font-mono text-sm" rows="4">${ssrInterpolate(form.outline)}</textarea></div><div class="form-control mb-6"><label class="label"><span class="label-text font-medium">模板内容 (template)</span></label><textarea class="textarea textarea-bordered w-full font-mono text-sm" rows="10">${ssrInterpolate(form.template)}</textarea></div><div class="flex gap-3"><button type="button" class="btn btn-ghost">取消</button><button type="submit" class="btn btn-primary text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""}>保存</button></div></form></div></div></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/meettemplates.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
export { _sfc_main as default };
//# sourceMappingURL=meettemplates-3onnOzNE.mjs.map