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.
 
 
 
 
 
 

165 lines
16 KiB

import { defineComponent, ref, reactive, useSSRContext } from 'vue';
import { ssrRenderAttrs, ssrRenderStyle, ssrRenderList, ssrInterpolate, ssrRenderClass, ssrRenderAttr, ssrIncludeBooleanAttr, ssrLooseContain, ssrLooseEqual } from 'vue/server-renderer';
import { u as useApi } from './useApi-D_CttG2t.mjs';
import { u as useToast } from './useToast-CS21XT61.mjs';
import { _ as _export_sfc } from './server.mjs';
import './auth-QFkCoU1C.mjs';
import 'pinia';
import './useLoading-D4zrSa2m.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 'perfect-debounce';
const _sfc_main = /* @__PURE__ */ defineComponent({
__name: "accounts",
__ssrInlineRender: true,
setup(__props) {
useApi();
useToast();
const ROLE = { 1: "超管", 2: "管理员", 3: "代理", 4: "运营" };
const ROLE_CLS = { 1: "badge-error", 2: "badge-primary", 3: "badge-warning", 4: "badge-info" };
const ACCESS_PAGES = [["dashboard", "仪表盘"], ["provider", "方案商"], ["factory", "品牌商"], ["product", "产品管理"], ["device", "生产管理"], ["code", "公码管理"], ["user", "用户查询"], ["apps", "应用注册"]];
const REGIONS = [["cn", "中国"], ["us", "美国"], ["ea", "东亚"], ["sea", "东南亚"], ["sa", "南亚"], ["me", "中东"], ["eu", "欧洲"], ["ru", "俄罗斯"], ["af", "非洲"], ["sam", "南美"], ["nam", "北美"], ["oc", "大洋洲"], ["br", "巴西"], ["in", "印度"]];
const view = ref("list");
const rows = ref([]);
const apps = ref([]);
const loading = ref(false);
const submitting = ref(false);
const editId = ref(0);
const form = reactive({
username: "",
password: "",
identity: 2,
enabled: "1",
remark: ""
});
const sel = reactive({
access: [],
apps: [],
regions: [],
products: []
});
const productGroups = ref([]);
const prodLoading = ref(false);
function fromCsv(s) {
return (s || "").split(",").map((x) => x.trim()).filter((x) => x);
}
function scopeParts(a) {
const parts = [];
if (a.apps) parts.push("应用:" + fromCsv(a.apps).length);
if (a.regions) parts.push("区域:" + fromCsv(a.regions).length);
if (a.products) parts.push("产品:" + fromCsv(a.products).length);
if (a.access) parts.push("页面:" + fromCsv(a.access).length);
return parts;
}
ref(null);
ref(0);
const topup = reactive({
name: "",
cur: "",
vipday: 0,
trademin: 0,
meetmin: 0
});
return (_ctx, _push, _parent, _attrs) => {
_push(`<div${ssrRenderAttrs(_attrs)} data-v-f682efe9><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}" data-v-f682efe9><div class="flex items-center justify-between mb-4" data-v-f682efe9><div data-v-f682efe9><h2 class="text-lg font-bold text-slate-700" data-v-f682efe9>后台账号</h2><p class="text-xs text-slate-400 mt-0.5" data-v-f682efe9>超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。</p></div><button class="btn btn-primary btn-sm text-white" data-v-f682efe9>+ 新建账号</button></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden" data-v-f682efe9><table class="table table-sm" data-v-f682efe9><thead data-v-f682efe9><tr class="text-slate-500" data-v-f682efe9><th data-v-f682efe9>ID</th><th data-v-f682efe9>用户名</th><th data-v-f682efe9>角色</th><th data-v-f682efe9>状态</th><th data-v-f682efe9>绑定作用域</th><th data-v-f682efe9>备注</th><th class="text-right" data-v-f682efe9>操作</th></tr></thead><tbody data-v-f682efe9>`);
if (loading.value) {
_push(`<tr data-v-f682efe9><td colspan="7" class="text-center text-slate-400 py-8" data-v-f682efe9>加载中...</td></tr>`);
} else if (!rows.value.length) {
_push(`<tr data-v-f682efe9><td colspan="7" class="text-center text-slate-400 py-8" data-v-f682efe9>暂无账号(引导超管不在此列)</td></tr>`);
} else {
_push(`<!---->`);
}
_push(`<!--[-->`);
ssrRenderList(rows.value, (a) => {
_push(`<tr data-v-f682efe9><td class="font-mono" data-v-f682efe9>${ssrInterpolate(a.id)}</td><td class="font-medium" data-v-f682efe9>${ssrInterpolate(a.username || "")}</td><td data-v-f682efe9><span class="${ssrRenderClass([ROLE_CLS[a.identity] || "", "badge badge-sm"])}" data-v-f682efe9>${ssrInterpolate(ROLE[a.identity] || a.identity)}</span></td><td data-v-f682efe9>`);
if (a.enabled) {
_push(`<span class="text-green-600 text-xs" data-v-f682efe9>启用</span>`);
} else {
_push(`<span class="text-slate-400 text-xs" data-v-f682efe9>停用</span>`);
}
_push(`</td><td data-v-f682efe9>`);
if (a.identity === 3 || a.identity === 4) {
_push(`<!--[-->`);
if (scopeParts(a).length) {
_push(`<span class="text-xs text-slate-500" data-v-f682efe9>${ssrInterpolate(scopeParts(a).join(" · "))}</span>`);
} else {
_push(`<span class="text-xs text-slate-300" data-v-f682efe9>未绑定(不限)</span>`);
}
_push(`<!--]-->`);
} else {
_push(`<span class="text-xs text-slate-300" data-v-f682efe9>全部权限</span>`);
}
if (a.identity === 3) {
_push(`<div class="text-[11px] text-emerald-600 mt-0.5" data-v-f682efe9> 余额 VIP${ssrInterpolate(a.balance_vipday || 0)}天 · 翻译${ssrInterpolate(a.balance_trademin || 0)}分 · 会议${ssrInterpolate(a.balance_meetmin || 0)}分 </div>`);
} else {
_push(`<!---->`);
}
_push(`</td><td class="text-xs text-slate-500" data-v-f682efe9>${ssrInterpolate(a.remark || "")}</td><td data-v-f682efe9><div class="flex gap-1 justify-end" data-v-f682efe9>`);
if (a.identity === 3) {
_push(`<button class="btn btn-ghost btn-xs text-emerald-600" data-v-f682efe9>充值</button>`);
} else {
_push(`<!---->`);
}
_push(`<button class="btn btn-ghost btn-xs" data-v-f682efe9>编辑</button><button class="btn btn-ghost btn-xs text-amber-600" data-v-f682efe9>改密</button><button class="btn btn-ghost btn-xs text-red-500" data-v-f682efe9>删除</button></div></td></tr>`);
});
_push(`<!--]--></tbody></table></div></div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}" data-v-f682efe9><div class="flex items-center gap-3 mb-5" data-v-f682efe9><button class="btn btn-ghost btn-sm" data-v-f682efe9>← 返回列表</button><h2 class="text-lg font-semibold text-slate-800" data-v-f682efe9>${ssrInterpolate(editId.value ? "编辑账号 #" + editId.value : "新建账号")}</h2></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 p-6 max-w-2xl" data-v-f682efe9><div class="grid grid-cols-2 gap-3" data-v-f682efe9><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>用户名</label><input${ssrRenderAttr("value", form.username)}${ssrIncludeBooleanAttr(!!editId.value) ? " disabled" : ""} class="input input-bordered input-sm w-full" placeholder="登录用户名" data-v-f682efe9></div><div style="${ssrRenderStyle(!editId.value ? null : { display: "none" })}" data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>密码</label><input${ssrRenderAttr("value", form.password)} type="password" class="input input-bordered input-sm w-full" placeholder="登录密码" data-v-f682efe9></div><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>角色</label><select class="select select-bordered select-sm w-full" data-v-f682efe9><option${ssrRenderAttr("value", 2)} data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 2) : ssrLooseEqual(form.identity, 2)) ? " selected" : ""}>管理员(除账号管理外全部)</option><option${ssrRenderAttr("value", 3)} data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 3) : ssrLooseEqual(form.identity, 3)) ? " selected" : ""}>代理(外部,按绑定限制)</option><option${ssrRenderAttr("value", 4)} data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 4) : ssrLooseEqual(form.identity, 4)) ? " selected" : ""}>运营(内部,按绑定限制)</option><option${ssrRenderAttr("value", 1)} data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 1) : ssrLooseEqual(form.identity, 1)) ? " selected" : ""}>超管(全部权限)</option></select></div><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>状态</label><select class="select select-bordered select-sm w-full" data-v-f682efe9><option value="1" data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "1") : ssrLooseEqual(form.enabled, "1")) ? " selected" : ""}>启用</option><option value="0" data-v-f682efe9${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "0") : ssrLooseEqual(form.enabled, "0")) ? " selected" : ""}>停用</option></select></div><div class="col-span-2" data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>备注</label><input${ssrRenderAttr("value", form.remark)} class="input input-bordered input-sm w-full" placeholder="可选" data-v-f682efe9></div></div><div class="mt-4 border-t border-slate-100 pt-4" style="${ssrRenderStyle(form.identity === 3 || form.identity === 4 ? null : { display: "none" })}" data-v-f682efe9><div class="text-sm font-semibold text-slate-600 mb-2" data-v-f682efe9>作用域绑定 <span class="text-xs text-slate-400 font-normal" data-v-f682efe9>(代理/运营生效;勾选可访问页面,并限制仪表盘数据范围)</span></div><div class="mb-3" data-v-f682efe9><div class="text-xs text-slate-500 mb-1.5" data-v-f682efe9>可访问页面</div><div class="flex flex-wrap gap-2" data-v-f682efe9><!--[-->`);
ssrRenderList(ACCESS_PAGES, (p) => {
_push(`<label class="chk" data-v-f682efe9><input${ssrIncludeBooleanAttr(Array.isArray(sel.access) ? ssrLooseContain(sel.access, p[0]) : sel.access) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", p[0])} data-v-f682efe9>${ssrInterpolate(p[1])}</label>`);
});
_push(`<!--]--></div></div><div class="mb-3" data-v-f682efe9><div class="text-xs text-slate-500 mb-1.5" data-v-f682efe9>绑定应用 <span class="text-slate-300" data-v-f682efe9>(仪表盘只显示这些应用数据;不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-f682efe9>`);
if (apps.value.length) {
_push(`<!--[-->`);
ssrRenderList(apps.value, (a) => {
_push(`<label class="chk" data-v-f682efe9><input${ssrIncludeBooleanAttr(Array.isArray(sel.apps) ? ssrLooseContain(sel.apps, a.name) : sel.apps) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", a.name)} data-v-f682efe9>${ssrInterpolate(a.name || "应用#" + a.id)}</label>`);
});
_push(`<!--]-->`);
} else {
_push(`<span class="text-xs text-slate-300" data-v-f682efe9>无注册应用</span>`);
}
_push(`</div></div><div class="mb-3" data-v-f682efe9><div class="text-xs text-slate-500 mb-1.5" data-v-f682efe9>绑定区域 <span class="text-slate-300" data-v-f682efe9>(不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-f682efe9><!--[-->`);
ssrRenderList(REGIONS, (r) => {
_push(`<label class="chk" data-v-f682efe9><input${ssrIncludeBooleanAttr(Array.isArray(sel.regions) ? ssrLooseContain(sel.regions, r[0]) : sel.regions) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", r[0])} data-v-f682efe9>${ssrInterpolate(r[1])}</label>`);
});
_push(`<!--]--></div></div><div data-v-f682efe9><div class="text-xs text-slate-500 mb-1.5" data-v-f682efe9>绑定产品 <span class="text-slate-300" data-v-f682efe9>(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)</span></div><div class="max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2" data-v-f682efe9>`);
if (prodLoading.value) {
_push(`<span class="text-xs text-slate-300" data-v-f682efe9>加载产品中...</span>`);
} else if (!productGroups.value.length) {
_push(`<span class="text-xs text-slate-300" data-v-f682efe9>无产品</span>`);
} else {
_push(`<!--[-->`);
ssrRenderList(productGroups.value, (g) => {
_push(`<div class="mb-2 last:mb-0" data-v-f682efe9><div class="text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5" data-v-f682efe9>🏭 ${ssrInterpolate(g.label)}</div><div class="flex flex-wrap gap-2" data-v-f682efe9><!--[-->`);
ssrRenderList(g.products, (p) => {
_push(`<label class="chk" data-v-f682efe9><input${ssrIncludeBooleanAttr(Array.isArray(sel.products) ? ssrLooseContain(sel.products, String(p.id)) : sel.products) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", String(p.id))} data-v-f682efe9>${ssrInterpolate((p.devicename || "产品") + " #" + p.id)}</label>`);
});
_push(`<!--]--></div></div>`);
});
_push(`<!--]-->`);
}
_push(`</div></div></div><div class="flex gap-3 justify-end mt-6" data-v-f682efe9><button class="btn btn-ghost btn-sm" data-v-f682efe9>取消</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""} data-v-f682efe9>保存</button></div></div></div><dialog class="modal" data-v-f682efe9><div class="modal-box max-w-md" data-v-f682efe9><h3 class="font-bold text-lg mb-1" data-v-f682efe9>充值 / 调整资源点</h3><p class="text-xs text-slate-400 mb-3" data-v-f682efe9>代理:<span class="font-medium text-slate-600" data-v-f682efe9>${ssrInterpolate(topup.name)}</span>。填增量(可填负数下调),当前余额:<span class="text-emerald-600" data-v-f682efe9>${ssrInterpolate(topup.cur)}</span></p><div class="grid grid-cols-3 gap-3" data-v-f682efe9><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>VIP天数</label><input${ssrRenderAttr("value", topup.vipday)} type="number" class="input input-bordered input-sm w-full" data-v-f682efe9></div><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>翻译分钟</label><input${ssrRenderAttr("value", topup.trademin)} type="number" class="input input-bordered input-sm w-full" data-v-f682efe9></div><div data-v-f682efe9><label class="text-xs text-slate-500" data-v-f682efe9>会议分钟</label><input${ssrRenderAttr("value", topup.meetmin)} type="number" class="input input-bordered input-sm w-full" data-v-f682efe9></div></div><div class="modal-action" data-v-f682efe9><button class="btn btn-ghost btn-sm" data-v-f682efe9>取消</button><button class="btn btn-primary btn-sm text-white" data-v-f682efe9>确认</button></div></div><form method="dialog" class="modal-backdrop" data-v-f682efe9><button data-v-f682efe9>close</button></form></dialog></div>`);
};
}
});
const _sfc_setup = _sfc_main.setup;
_sfc_main.setup = (props, ctx) => {
const ssrContext = useSSRContext();
(ssrContext.modules || (ssrContext.modules = /* @__PURE__ */ new Set())).add("pages/accounts.vue");
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
};
const accounts = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f682efe9"]]);
export { accounts as default };
//# sourceMappingURL=accounts-D3gizV-b.mjs.map