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.
166 lines
16 KiB
166 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-B6h53Mkt.mjs';
|
|
import { u as useToast } from './useToast-C76a6bSX.mjs';
|
|
import { _ as _export_sfc } from './server.mjs';
|
|
import './auth-QFkCoU1C.mjs';
|
|
import 'pinia';
|
|
import './useLoading-D6mc40Wj.mjs';
|
|
import './state-DQnwRar-.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", "仪表盘"], ["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-eb25cf37><div style="${ssrRenderStyle(view.value === "list" ? null : { display: "none" })}" data-v-eb25cf37><div class="flex items-center justify-between mb-4" data-v-eb25cf37><div data-v-eb25cf37><h2 class="text-lg font-bold text-slate-700" data-v-eb25cf37>后台账号</h2><p class="text-xs text-slate-400 mt-0.5" data-v-eb25cf37>超管 / 管理员 / 代理 / 运营。代理·运营可绑定应用·区域·产品,登录后仪表盘按绑定限制。</p></div><button class="btn btn-primary btn-sm text-white" data-v-eb25cf37>+ 新建账号</button></div><div class="bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden" data-v-eb25cf37><table class="table table-sm" data-v-eb25cf37><thead data-v-eb25cf37><tr class="text-slate-500" data-v-eb25cf37><th data-v-eb25cf37>ID</th><th data-v-eb25cf37>用户名</th><th data-v-eb25cf37>角色</th><th data-v-eb25cf37>状态</th><th data-v-eb25cf37>绑定作用域</th><th data-v-eb25cf37>备注</th><th class="text-right" data-v-eb25cf37>操作</th></tr></thead><tbody data-v-eb25cf37>`);
|
|
if (loading.value) {
|
|
_push(`<tr data-v-eb25cf37><td colspan="7" class="text-center text-slate-400 py-8" data-v-eb25cf37>加载中...</td></tr>`);
|
|
} else if (!rows.value.length) {
|
|
_push(`<tr data-v-eb25cf37><td colspan="7" class="text-center text-slate-400 py-8" data-v-eb25cf37>暂无账号(引导超管不在此列)</td></tr>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(rows.value, (a) => {
|
|
_push(`<tr data-v-eb25cf37><td class="font-mono" data-v-eb25cf37>${ssrInterpolate(a.id)}</td><td class="font-medium" data-v-eb25cf37>${ssrInterpolate(a.username || "")}</td><td data-v-eb25cf37><span class="${ssrRenderClass([ROLE_CLS[a.identity] || "", "badge badge-sm"])}" data-v-eb25cf37>${ssrInterpolate(ROLE[a.identity] || a.identity)}</span></td><td data-v-eb25cf37>`);
|
|
if (a.enabled) {
|
|
_push(`<span class="text-green-600 text-xs" data-v-eb25cf37>启用</span>`);
|
|
} else {
|
|
_push(`<span class="text-slate-400 text-xs" data-v-eb25cf37>停用</span>`);
|
|
}
|
|
_push(`</td><td data-v-eb25cf37>`);
|
|
if (a.identity === 3 || a.identity === 4) {
|
|
_push(`<!--[-->`);
|
|
if (scopeParts(a).length) {
|
|
_push(`<span class="text-xs text-slate-500" data-v-eb25cf37>${ssrInterpolate(scopeParts(a).join(" · "))}</span>`);
|
|
} else {
|
|
_push(`<span class="text-xs text-slate-300" data-v-eb25cf37>未绑定(不限)</span>`);
|
|
}
|
|
_push(`<!--]-->`);
|
|
} else {
|
|
_push(`<span class="text-xs text-slate-300" data-v-eb25cf37>全部权限</span>`);
|
|
}
|
|
if (a.identity === 3) {
|
|
_push(`<div class="text-[11px] text-emerald-600 mt-0.5" data-v-eb25cf37> 余额 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-eb25cf37>${ssrInterpolate(a.remark || "")}</td><td data-v-eb25cf37><div class="flex gap-1 justify-end" data-v-eb25cf37>`);
|
|
if (a.identity === 3) {
|
|
_push(`<button class="btn btn-ghost btn-xs text-emerald-600" data-v-eb25cf37>充值</button>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<button class="btn btn-ghost btn-xs" data-v-eb25cf37>编辑</button><button class="btn btn-ghost btn-xs text-amber-600" data-v-eb25cf37>改密</button><button class="btn btn-ghost btn-xs text-red-500" data-v-eb25cf37>删除</button></div></td></tr>`);
|
|
});
|
|
_push(`<!--]--></tbody></table></div></div><div style="${ssrRenderStyle(view.value === "form" ? null : { display: "none" })}" data-v-eb25cf37><div class="flex items-center gap-3 mb-5" data-v-eb25cf37><button class="btn btn-ghost btn-sm" data-v-eb25cf37>← 返回列表</button><h2 class="text-lg font-semibold text-slate-800" data-v-eb25cf37>${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-eb25cf37><div class="grid grid-cols-2 gap-3" data-v-eb25cf37><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>用户名</label><input${ssrRenderAttr("value", form.username)}${ssrIncludeBooleanAttr(!!editId.value) ? " disabled" : ""} class="input input-bordered input-sm w-full" placeholder="登录用户名" data-v-eb25cf37></div><div style="${ssrRenderStyle(!editId.value ? null : { display: "none" })}" data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>密码</label><input${ssrRenderAttr("value", form.password)} type="password" class="input input-bordered input-sm w-full" placeholder="登录密码" data-v-eb25cf37></div><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>角色</label><select class="select select-bordered select-sm w-full" data-v-eb25cf37><option${ssrRenderAttr("value", 2)} data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 2) : ssrLooseEqual(form.identity, 2)) ? " selected" : ""}>管理员(除账号管理外全部)</option><option${ssrRenderAttr("value", 3)} data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 3) : ssrLooseEqual(form.identity, 3)) ? " selected" : ""}>代理(外部,按绑定限制)</option><option${ssrRenderAttr("value", 4)} data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 4) : ssrLooseEqual(form.identity, 4)) ? " selected" : ""}>运营(内部,按绑定限制)</option><option${ssrRenderAttr("value", 1)} data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.identity) ? ssrLooseContain(form.identity, 1) : ssrLooseEqual(form.identity, 1)) ? " selected" : ""}>超管(全部权限)</option></select></div><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>状态</label><select class="select select-bordered select-sm w-full" data-v-eb25cf37><option value="1" data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "1") : ssrLooseEqual(form.enabled, "1")) ? " selected" : ""}>启用</option><option value="0" data-v-eb25cf37${ssrIncludeBooleanAttr(Array.isArray(form.enabled) ? ssrLooseContain(form.enabled, "0") : ssrLooseEqual(form.enabled, "0")) ? " selected" : ""}>停用</option></select></div><div class="col-span-2" data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>备注</label><input${ssrRenderAttr("value", form.remark)} class="input input-bordered input-sm w-full" placeholder="可选" data-v-eb25cf37></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-eb25cf37><div class="text-sm font-semibold text-slate-600 mb-2" data-v-eb25cf37>作用域绑定 <span class="text-xs text-slate-400 font-normal" data-v-eb25cf37>(代理/运营生效;勾选可访问页面,并限制仪表盘数据范围)</span></div><div class="mb-3" data-v-eb25cf37><div class="text-xs text-slate-500 mb-1.5" data-v-eb25cf37>可访问页面</div><div class="flex flex-wrap gap-2" data-v-eb25cf37><!--[-->`);
|
|
ssrRenderList(ACCESS_PAGES, (p) => {
|
|
_push(`<label class="chk" data-v-eb25cf37><input${ssrIncludeBooleanAttr(Array.isArray(sel.access) ? ssrLooseContain(sel.access, p[0]) : sel.access) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", p[0])} data-v-eb25cf37>${ssrInterpolate(p[1])}</label>`);
|
|
});
|
|
_push(`<!--]--></div></div><div class="mb-3" data-v-eb25cf37><div class="text-xs text-slate-500 mb-1.5" data-v-eb25cf37>绑定应用 <span class="text-slate-300" data-v-eb25cf37>(仪表盘只显示这些应用数据;不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-eb25cf37>`);
|
|
if (apps.value.length) {
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(apps.value, (a) => {
|
|
_push(`<label class="chk" data-v-eb25cf37><input${ssrIncludeBooleanAttr(Array.isArray(sel.apps) ? ssrLooseContain(sel.apps, a.name) : sel.apps) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", a.name)} data-v-eb25cf37>${ssrInterpolate(a.name || "应用#" + a.id)}</label>`);
|
|
});
|
|
_push(`<!--]-->`);
|
|
} else {
|
|
_push(`<span class="text-xs text-slate-300" data-v-eb25cf37>无注册应用</span>`);
|
|
}
|
|
_push(`</div></div><div class="mb-3" data-v-eb25cf37><div class="text-xs text-slate-500 mb-1.5" data-v-eb25cf37>绑定区域 <span class="text-slate-300" data-v-eb25cf37>(不勾=不限)</span></div><div class="flex flex-wrap gap-2" data-v-eb25cf37><!--[-->`);
|
|
ssrRenderList(REGIONS, (r) => {
|
|
_push(`<label class="chk" data-v-eb25cf37><input${ssrIncludeBooleanAttr(Array.isArray(sel.regions) ? ssrLooseContain(sel.regions, r[0]) : sel.regions) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", r[0])} data-v-eb25cf37>${ssrInterpolate(r[1])}</label>`);
|
|
});
|
|
_push(`<!--]--></div></div><div data-v-eb25cf37><div class="text-xs text-slate-500 mb-1.5" data-v-eb25cf37>绑定产品 <span class="text-slate-300" data-v-eb25cf37>(按厂家分组;仪表盘只显示这些产品数据;不勾=不限)</span></div><div class="max-h-56 overflow-y-auto pr-1 border border-slate-100 rounded-lg p-2" data-v-eb25cf37>`);
|
|
if (prodLoading.value) {
|
|
_push(`<span class="text-xs text-slate-300" data-v-eb25cf37>加载产品中...</span>`);
|
|
} else if (!productGroups.value.length) {
|
|
_push(`<span class="text-xs text-slate-300" data-v-eb25cf37>无产品</span>`);
|
|
} else {
|
|
_push(`<!--[-->`);
|
|
ssrRenderList(productGroups.value, (g) => {
|
|
_push(`<div class="mb-2 last:mb-0" data-v-eb25cf37><div class="text-[11px] font-semibold text-slate-500 mb-1 sticky top-0 bg-white py-0.5" data-v-eb25cf37>🏭 ${ssrInterpolate(g.label)}</div><div class="flex flex-wrap gap-2" data-v-eb25cf37><!--[-->`);
|
|
ssrRenderList(g.products, (p) => {
|
|
_push(`<label class="chk" data-v-eb25cf37><input${ssrIncludeBooleanAttr(Array.isArray(sel.products) ? ssrLooseContain(sel.products, String(p.id)) : sel.products) ? " checked" : ""} type="checkbox"${ssrRenderAttr("value", String(p.id))} data-v-eb25cf37>${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-eb25cf37><button class="btn btn-ghost btn-sm" data-v-eb25cf37>取消</button><button class="btn btn-primary btn-sm text-white"${ssrIncludeBooleanAttr(submitting.value) ? " disabled" : ""} data-v-eb25cf37>保存</button></div></div></div><dialog class="modal" data-v-eb25cf37><div class="modal-box max-w-md" data-v-eb25cf37><h3 class="font-bold text-lg mb-1" data-v-eb25cf37>充值 / 调整资源点</h3><p class="text-xs text-slate-400 mb-3" data-v-eb25cf37>代理:<span class="font-medium text-slate-600" data-v-eb25cf37>${ssrInterpolate(topup.name)}</span>。填增量(可填负数下调),当前余额:<span class="text-emerald-600" data-v-eb25cf37>${ssrInterpolate(topup.cur)}</span></p><div class="grid grid-cols-3 gap-3" data-v-eb25cf37><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>VIP天数</label><input${ssrRenderAttr("value", topup.vipday)} type="number" class="input input-bordered input-sm w-full" data-v-eb25cf37></div><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>翻译分钟</label><input${ssrRenderAttr("value", topup.trademin)} type="number" class="input input-bordered input-sm w-full" data-v-eb25cf37></div><div data-v-eb25cf37><label class="text-xs text-slate-500" data-v-eb25cf37>会议分钟</label><input${ssrRenderAttr("value", topup.meetmin)} type="number" class="input input-bordered input-sm w-full" data-v-eb25cf37></div></div><div class="modal-action" data-v-eb25cf37><button class="btn btn-ghost btn-sm" data-v-eb25cf37>取消</button><button class="btn btn-primary btn-sm text-white" data-v-eb25cf37>确认</button></div></div><form method="dialog" class="modal-backdrop" data-v-eb25cf37><button data-v-eb25cf37>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-eb25cf37"]]);
|
|
|
|
export { accounts as default };
|
|
//# sourceMappingURL=accounts-BlBS367g.mjs.map
|
|
|