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.
316 lines
30 KiB
316 lines
30 KiB
import { defineComponent, ref, reactive, computed, useSSRContext } from 'vue';
|
|
import { ssrRenderAttrs, ssrRenderStyle, ssrRenderList, ssrRenderClass, ssrRenderAttr, ssrInterpolate, ssrIncludeBooleanAttr, ssrLooseContain, ssrRenderDynamicModel, ssrLooseEqual } from 'vue/server-renderer';
|
|
import { u as useToast } from './useToast-CS21XT61.mjs';
|
|
import { u as useApi } from './useApi-DMQewX5_.mjs';
|
|
import { _ as _export_sfc } from './server.mjs';
|
|
import './useLoading-D4zrSa2m.mjs';
|
|
import './auth-QFkCoU1C.mjs';
|
|
import 'pinia';
|
|
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: "systemconfig",
|
|
__ssrInlineRender: true,
|
|
setup(__props) {
|
|
useToast();
|
|
useApi();
|
|
const categories = [
|
|
{ id: "storage", label: "对象存储", desc: "固件 / 头像 / 文件", color: "#6366f1", icon: "M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8" },
|
|
{ id: "mail", label: "邮件服务", desc: "生产通知 / 厂家发信", color: "#f59e0b", icon: "M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" },
|
|
{ id: "translate", label: "翻译服务", desc: "后台文案多语言同步", color: "#14b8a6", icon: "M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129" }
|
|
];
|
|
const curCat = ref("storage");
|
|
const mail = reactive({
|
|
enable: true,
|
|
host: "smtp.exmail.qq.com",
|
|
port: "465",
|
|
secure: "SSL",
|
|
user: "noreply@yunyan.com",
|
|
pass: "",
|
|
_showPass: false,
|
|
fromName: "云岩科技",
|
|
cc: "ops@yunyan.com",
|
|
testTo: ""
|
|
});
|
|
const secureOptions = ["SSL", "STARTTLS", "不加密"];
|
|
function svcEnabled(id) {
|
|
if (id === "storage") return true;
|
|
if (id === "mail") return mail.enable;
|
|
if (id === "translate") return tActiveProvider.value?.enable ?? false;
|
|
return false;
|
|
}
|
|
const tProviders = reactive([
|
|
{
|
|
id: "volc",
|
|
name: "火山引擎翻译",
|
|
short: "火山",
|
|
tag: "Volcengine MT",
|
|
color: "#1664ff",
|
|
enable: true,
|
|
fields: [
|
|
{ key: "region", label: "Region", value: "cn-beijing", mono: true, required: true },
|
|
{ key: "accessKey", label: "AccessKey", value: "AKLTZjJmODdk****", mono: true, encrypted: true, required: true },
|
|
{ key: "secretKey", label: "SecretKey", value: "", mono: true, encrypted: true, required: true, hint: "留空保留原密文" }
|
|
]
|
|
},
|
|
{
|
|
id: "aliyun",
|
|
name: "阿里云翻译",
|
|
short: "阿里",
|
|
tag: "Aliyun MT",
|
|
color: "#ff6a00",
|
|
enable: true,
|
|
fields: [
|
|
{ key: "region", label: "Region", value: "cn-hangzhou", mono: true, required: true },
|
|
{ key: "accessKeyId", label: "AccessKey ID", value: "LTAI5txxxxxxxx", mono: true, encrypted: true, required: true },
|
|
{ key: "accessKeySecret", label: "AccessKey Secret", value: "", mono: true, encrypted: true, required: true, hint: "留空保留原密文" },
|
|
{ key: "scene", label: "翻译场景", value: "general", mono: true, hint: "general / social / ecommerce / tech" }
|
|
]
|
|
},
|
|
{
|
|
id: "google",
|
|
name: "Google 翻译",
|
|
short: "G",
|
|
tag: "Cloud Translation",
|
|
color: "#ea4335",
|
|
enable: false,
|
|
fields: [
|
|
{ key: "project", label: "Project ID", value: "", mono: true, required: true },
|
|
{ key: "apiKey", label: "API Key", value: "", mono: true, encrypted: true, required: true }
|
|
]
|
|
},
|
|
{
|
|
id: "deepl",
|
|
name: "DeepL",
|
|
short: "DL",
|
|
tag: "DeepL API",
|
|
color: "#0f2b46",
|
|
enable: false,
|
|
fields: [
|
|
{ key: "authKey", label: "Auth Key", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "plan", label: "套餐", value: "free", mono: true, hint: "free / pro" }
|
|
]
|
|
}
|
|
]);
|
|
const tActiveId = ref("volc");
|
|
const tCurProvider = ref("volc");
|
|
const tEditProvider = computed(() => tProviders.find((p) => p.id === tCurProvider.value));
|
|
const tActiveProvider = computed(() => tProviders.find((p) => p.id === tActiveId.value));
|
|
const providers = reactive([
|
|
{
|
|
id: "aliyun",
|
|
name: "阿里云 OSS",
|
|
short: "OSS",
|
|
tag: "Aliyun",
|
|
color: "#ff6a00",
|
|
enable: false,
|
|
fields: [
|
|
{ key: "endpoint", label: "Endpoint", value: "", placeholder: "oss-cn-shanghai.aliyuncs.com", mono: true, required: true },
|
|
{ key: "bucket", label: "Bucket", value: "", placeholder: "yunyan-firmware", mono: true, required: true },
|
|
{ key: "access_key_id", label: "AccessKey ID", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "access_key_secret", label: "AccessKey Secret", value: "", mono: true, encrypted: true, required: true, hint: "留空保留原密文" },
|
|
{ key: "domain", label: "自定义域名 (CDN)", value: "", placeholder: "cdn.yunyan.com", wide: true, hint: "可选,配置后文件下载 URL 走该域名" }
|
|
]
|
|
},
|
|
{
|
|
id: "tencent",
|
|
name: "腾讯云 COS",
|
|
short: "COS",
|
|
tag: "Tencent",
|
|
color: "#00a4ff",
|
|
enable: true,
|
|
fields: [
|
|
{ key: "region", label: "Region", value: "ap-guangzhou", mono: true, required: true },
|
|
{ key: "appid", label: "AppId", value: "1253517901", mono: true, required: true },
|
|
{ key: "bucket", label: "Bucket", value: "yunyan-1253517901", mono: true, required: true },
|
|
{ key: "secretId", label: "SecretId", value: "AKIDxxxxxxxx", mono: true, encrypted: true, required: true },
|
|
{ key: "secretKey", label: "SecretKey", value: "", mono: true, encrypted: true, required: true, hint: "留空保留原密文" },
|
|
{ key: "domain", label: "自定义域名 (CDN)", value: "", wide: true, hint: "可选" }
|
|
]
|
|
},
|
|
{
|
|
id: "qiniu",
|
|
name: "七牛云 Kodo",
|
|
short: "KODO",
|
|
tag: "Qiniu",
|
|
color: "#00aaff",
|
|
enable: false,
|
|
fields: [
|
|
{ key: "zone", label: "存储区域", value: "", mono: true, required: true },
|
|
{ key: "bucket", label: "Bucket", value: "", mono: true, required: true },
|
|
{ key: "accessKey", label: "AccessKey", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "secretKey", label: "SecretKey", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "domain", label: "加速域名", value: "", wide: true }
|
|
]
|
|
},
|
|
{
|
|
id: "minio",
|
|
name: "MinIO",
|
|
short: "S3",
|
|
tag: "S3 兼容",
|
|
color: "#c72e49",
|
|
enable: false,
|
|
fields: [
|
|
{ key: "endpoint", label: "Endpoint", value: "", mono: true, required: true, placeholder: "minio.内网:9000" },
|
|
{ key: "bucket", label: "Bucket", value: "", mono: true, required: true },
|
|
{ key: "accessKey", label: "AccessKey", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "secretKey", label: "SecretKey", value: "", mono: true, encrypted: true, required: true },
|
|
{ key: "useSSL", label: "使用 HTTPS", value: "false", mono: true }
|
|
]
|
|
}
|
|
]);
|
|
const activeId = ref("aliyun");
|
|
const curProvider = ref("aliyun");
|
|
const editProvider = computed(() => providers.find((p) => p.id === curProvider.value));
|
|
const activeProvider = computed(() => providers.find((p) => p.id === activeId.value));
|
|
const STORAGE_SVC = {
|
|
aliyun: { svcId: "storage_aliyun_oss", provider: "aliyun_oss" },
|
|
tencent: { svcId: "storage_tencent_cos", provider: "tencent_cos" },
|
|
qiniu: { svcId: "storage_qiniu_kodo", provider: "qiniu_kodo" },
|
|
minio: { svcId: "storage_minio", provider: "minio" }
|
|
};
|
|
const svcProviderToCard = {};
|
|
for (const [card, m] of Object.entries(STORAGE_SVC)) {
|
|
svcProviderToCard[m.provider] = card;
|
|
m.svcId;
|
|
}
|
|
ref(/* @__PURE__ */ new Set());
|
|
return (_ctx, _push, _parent, _attrs) => {
|
|
_push(`<div${ssrRenderAttrs(_attrs)} data-v-af95cc3b><div class="mb-4 rounded-lg px-4 py-2.5 text-xs flex items-center gap-2" style="${ssrRenderStyle({ "background": "#ecfdf5", "border": "1px solid #a7f3d0", "color": "#047857" })}" data-v-af95cc3b><span class="font-semibold" data-v-af95cc3b>对象存储已接后端</span><span class="text-emerald-400" data-v-af95cc3b>·</span><span data-v-af95cc3b>对象存储配置已落库(存 svc_config,与「第三方服务配置 → 存储」共用同一份),启用的「阿里云 OSS」即固件 / 头像上传所用存储。邮件 / 翻译两项仍为演示。</span></div><div class="flex items-center justify-between mb-5" data-v-af95cc3b><div data-v-af95cc3b><h2 class="text-lg font-semibold text-slate-800" data-v-af95cc3b>系统配置</h2><p class="text-xs text-slate-400 mt-1" data-v-af95cc3b>平台级服务配置:① 对象存储(固件 / 头像等文件,默认阿里云 OSS);② 邮件服务(生产环节给厂家发通知邮件);③ 翻译服务(后台配置多语言同步)。</p></div></div><div class="flex gap-4" style="${ssrRenderStyle({ "align-items": "flex-start" })}" data-v-af95cc3b><div style="${ssrRenderStyle({ "width": "208px", "flex-shrink": "0" })}" data-v-af95cc3b><div class="flex flex-col gap-1.5" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(categories, (c) => {
|
|
_push(`<div class="${ssrRenderClass([{ active: curCat.value === c.id }, "cat-item"])}" data-v-af95cc3b><div class="cat-icon" style="${ssrRenderStyle({ background: c.color })}" data-v-af95cc3b><svg width="17" height="17" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-af95cc3b><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"${ssrRenderAttr("d", c.icon)} data-v-af95cc3b></path></svg></div><div class="flex-1 min-w-0" data-v-af95cc3b><div class="text-sm font-medium text-slate-700" data-v-af95cc3b>${ssrInterpolate(c.label)}</div><div class="text-[11px] text-slate-400 truncate" data-v-af95cc3b>${ssrInterpolate(c.desc)}</div></div>`);
|
|
if (svcEnabled(c.id)) {
|
|
_push(`<span class="dot-on" title="已启用" data-v-af95cc3b></span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
});
|
|
_push(`<!--]--></div></div><div class="flex-1 min-w-0" data-v-af95cc3b>`);
|
|
if (curCat.value === "storage") {
|
|
_push(`<div data-v-af95cc3b><div class="rounded-xl px-4 py-3 mb-4 flex items-center gap-3" style="${ssrRenderStyle({ "background": "linear-gradient(135deg,#ecfdf5,#f0fdfa)", "border": "1px solid #a7f3d0" })}" data-v-af95cc3b><div style="${ssrRenderStyle({ "width": "36px", "height": "36px", "border-radius": "10px", "background": "#10b981", "display": "flex", "align-items": "center", "justify-content": "center", "flex-shrink": "0" })}" data-v-af95cc3b><svg style="${ssrRenderStyle({ "width": "19px", "height": "19px", "color": "#fff" })}" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-af95cc3b><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" data-v-af95cc3b></path></svg></div><div class="flex-1" data-v-af95cc3b><div class="text-sm font-semibold text-emerald-800" data-v-af95cc3b>设备固件上传当前指向:${ssrInterpolate(activeProvider.value.name)}</div><div class="text-[11px] text-emerald-600 mt-0.5" data-v-af95cc3b>固件包、用户头像等文件均上传至此存储桶。切换默认存储不影响历史文件 URL。</div></div><span class="badge badge-success badge-sm text-white" data-v-af95cc3b>运行中</span></div><div class="flex items-center justify-between mb-2" data-v-af95cc3b><span class="text-xs font-semibold text-slate-500" data-v-af95cc3b>选择默认对象存储 <span class="text-slate-400 font-normal" data-v-af95cc3b>(固件 / 头像等文件上传指向此服务)</span></span></div><div class="grid grid-cols-4 gap-3 mb-4" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(providers, (p) => {
|
|
_push(`<div class="${ssrRenderClass([{ active: curProvider.value === p.id, "is-default": p.id === activeId.value }, "provider-card"])}" data-v-af95cc3b><div class="flex items-center justify-between" data-v-af95cc3b><div class="provider-logo" style="${ssrRenderStyle({ background: p.color })}" data-v-af95cc3b>${ssrInterpolate(p.short)}</div>`);
|
|
if (p.enable) {
|
|
_push(`<span class="text-[10px] text-emerald-500 font-semibold" data-v-af95cc3b>已配置</span>`);
|
|
} else {
|
|
_push(`<span class="text-[10px] text-slate-300 font-semibold" data-v-af95cc3b>未配置</span>`);
|
|
}
|
|
_push(`</div><div class="text-sm font-semibold text-slate-700 mt-2" data-v-af95cc3b>${ssrInterpolate(p.name)}</div><div class="text-[11px] text-slate-400 mb-2.5" data-v-af95cc3b>${ssrInterpolate(p.tag)}</div><label class="${ssrRenderClass([{ on: p.id === activeId.value }, "default-pick"])}" data-v-af95cc3b><input type="radio" class="radio radio-xs radio-primary"${ssrIncludeBooleanAttr(p.id === activeId.value) ? " checked" : ""} data-v-af95cc3b><span data-v-af95cc3b>${ssrInterpolate(p.id === activeId.value ? "默认使用" : "设为默认")}</span></label></div>`);
|
|
});
|
|
_push(`<!--]--></div><div class="bg-white rounded-2xl border border-slate-100 shadow-sm p-6" data-v-af95cc3b><div class="flex items-center justify-between mb-5" data-v-af95cc3b><div class="flex items-center gap-3" data-v-af95cc3b><div class="provider-logo" style="${ssrRenderStyle({ background: editProvider.value.color, width: "44px", height: "44px", fontSize: "15px" })}" data-v-af95cc3b>${ssrInterpolate(editProvider.value.short)}</div><div data-v-af95cc3b><h3 class="text-base font-semibold text-slate-800" data-v-af95cc3b>${ssrInterpolate(editProvider.value.name)}</h3><p class="text-xs text-slate-400 mt-0.5" data-v-af95cc3b>${ssrInterpolate(editProvider.value.tag)} · 对象存储</p></div></div><div class="flex items-center gap-2" data-v-af95cc3b><label class="flex items-center gap-2 mr-1" data-v-af95cc3b><span class="text-xs text-slate-500" data-v-af95cc3b>启用</span><input${ssrIncludeBooleanAttr(Array.isArray(editProvider.value.enable) ? ssrLooseContain(editProvider.value.enable, null) : editProvider.value.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary toggle-sm" data-v-af95cc3b></label><button class="btn btn-outline btn-sm" data-v-af95cc3b>测试连接</button>`);
|
|
if (curProvider.value !== activeId.value) {
|
|
_push(`<button class="btn btn-ghost btn-sm text-indigo-600" data-v-af95cc3b>设为默认存储</button>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<button class="btn btn-primary btn-sm text-white" data-v-af95cc3b>保存</button></div></div><div class="divider text-xs text-slate-400 my-3" data-v-af95cc3b>连接配置</div><div class="grid grid-cols-2 gap-x-5 gap-y-4" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(editProvider.value.fields, (f) => {
|
|
_push(`<div class="${ssrRenderClass([{ "col-span-2": f.wide }, "form-control"])}" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>${ssrInterpolate(f.label)}`);
|
|
if (f.required) {
|
|
_push(`<span class="text-rose-500 ml-0.5" data-v-af95cc3b>*</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
if (f.encrypted) {
|
|
_push(`<span class="lock-tag ml-1.5" data-v-af95cc3b>🔒 加密存储</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</span></label><div class="relative" data-v-af95cc3b><input${ssrRenderDynamicModel(f.encrypted && !f._show ? "password" : "text", f.value, null)}${ssrRenderAttr("type", f.encrypted && !f._show ? "password" : "text")} class="${ssrRenderClass([{ "font-mono": f.mono, "pr-14": f.encrypted }, "input input-bordered input-sm w-full"])}"${ssrRenderAttr("placeholder", f.placeholder)} data-v-af95cc3b>`);
|
|
if (f.encrypted) {
|
|
_push(`<button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-af95cc3b>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
if (f.hint) {
|
|
_push(`<span class="text-[11px] text-slate-400 mt-1" data-v-af95cc3b>${ssrInterpolate(f.hint)}</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
});
|
|
_push(`<!--]--></div><div class="divider text-xs text-slate-400 my-4" data-v-af95cc3b>上传规则</div><div class="grid grid-cols-3 gap-4" data-v-af95cc3b><div class="rule-box" data-v-af95cc3b><div class="text-[11px] text-slate-400" data-v-af95cc3b>固件包路径前缀</div><div class="font-mono text-sm text-slate-700 mt-1" data-v-af95cc3b>/firmware/</div></div><div class="rule-box" data-v-af95cc3b><div class="text-[11px] text-slate-400" data-v-af95cc3b>头像路径前缀</div><div class="font-mono text-sm text-slate-700 mt-1" data-v-af95cc3b>/userAvatar/</div></div><div class="rule-box" data-v-af95cc3b><div class="text-[11px] text-slate-400" data-v-af95cc3b>签名 URL 有效期</div><div class="font-mono text-sm text-slate-700 mt-1" data-v-af95cc3b>3600 s</div></div></div></div></div>`);
|
|
} else if (curCat.value === "mail") {
|
|
_push(`<div data-v-af95cc3b><div class="rounded-xl px-4 py-3 mb-4 flex items-center gap-3" style="${ssrRenderStyle({ "background": "#fffbeb", "border": "1px solid #fde68a" })}" data-v-af95cc3b><div style="${ssrRenderStyle({ "width": "36px", "height": "36px", "border-radius": "10px", "background": "#f59e0b", "display": "flex", "align-items": "center", "justify-content": "center", "flex-shrink": "0" })}" data-v-af95cc3b><svg style="${ssrRenderStyle({ "width": "19px", "height": "19px", "color": "#fff" })}" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-af95cc3b><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" data-v-af95cc3b></path></svg></div><div class="flex-1" data-v-af95cc3b><div class="text-sm font-semibold text-amber-800" data-v-af95cc3b>生产环节邮件通知</div><div class="text-[11px] text-amber-600 mt-0.5" data-v-af95cc3b>用于给目标厂家发送授权信息、公码批次、设备出货等通知邮件;账号告警也走此通道。</div></div></div><div class="bg-white rounded-2xl border border-slate-100 shadow-sm p-6" data-v-af95cc3b><div class="flex items-center justify-between mb-5" data-v-af95cc3b><div class="flex items-center gap-3" data-v-af95cc3b><div class="provider-logo" style="${ssrRenderStyle({ background: "#f59e0b", width: "44px", height: "44px", fontSize: "13px" })}" data-v-af95cc3b>SMTP</div><div data-v-af95cc3b><h3 class="text-base font-semibold text-slate-800" data-v-af95cc3b>邮件服务</h3><p class="text-xs text-slate-400 mt-0.5" data-v-af95cc3b>SMTP 发信</p></div></div><div class="flex items-center gap-2" data-v-af95cc3b><label class="flex items-center gap-2 mr-1" data-v-af95cc3b><span class="text-xs text-slate-500" data-v-af95cc3b>启用</span><input${ssrIncludeBooleanAttr(Array.isArray(mail.enable) ? ssrLooseContain(mail.enable, null) : mail.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary toggle-sm" data-v-af95cc3b></label><button class="btn btn-primary btn-sm text-white" data-v-af95cc3b>保存</button></div></div><div class="divider text-xs text-slate-400 my-3" data-v-af95cc3b>发信配置</div><div class="grid grid-cols-2 gap-x-5 gap-y-4" data-v-af95cc3b><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>SMTP 主机 <span class="text-rose-500" data-v-af95cc3b>*</span></span></label><input${ssrRenderAttr("value", mail.host)} class="input input-bordered input-sm font-mono" placeholder="smtp.exmail.qq.com" data-v-af95cc3b></div><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>端口 <span class="text-rose-500" data-v-af95cc3b>*</span></span></label><input${ssrRenderAttr("value", mail.port)} class="input input-bordered input-sm font-mono" placeholder="465" data-v-af95cc3b></div><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>加密方式</span></label><select class="select select-bordered select-sm" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(secureOptions, (o) => {
|
|
_push(`<option${ssrRenderAttr("value", o)} data-v-af95cc3b${ssrIncludeBooleanAttr(Array.isArray(mail.secure) ? ssrLooseContain(mail.secure, o) : ssrLooseEqual(mail.secure, o)) ? " selected" : ""}>${ssrInterpolate(o)}</option>`);
|
|
});
|
|
_push(`<!--]--></select></div><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>发件人显示名</span></label><input${ssrRenderAttr("value", mail.fromName)} class="input input-bordered input-sm" placeholder="云岩科技" data-v-af95cc3b></div><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>发信账号 <span class="text-rose-500" data-v-af95cc3b>*</span></span></label><input${ssrRenderAttr("value", mail.user)} class="input input-bordered input-sm font-mono" placeholder="noreply@yunyan.com" data-v-af95cc3b></div><div class="form-control" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>授权码 / 密码 <span class="lock-tag ml-1.5" data-v-af95cc3b>🔒 加密存储</span></span></label><div class="relative" data-v-af95cc3b><input${ssrRenderDynamicModel(mail._showPass ? "text" : "password", mail.pass, null)}${ssrRenderAttr("type", mail._showPass ? "text" : "password")} class="input input-bordered input-sm w-full font-mono pr-14" placeholder="留空保留原密文" data-v-af95cc3b><button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-af95cc3b>${ssrInterpolate(mail._showPass ? "隐藏" : "显示")}</button></div></div><div class="form-control col-span-2" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>默认抄送 (CC)</span></label><input${ssrRenderAttr("value", mail.cc)} class="input input-bordered input-sm font-mono" placeholder="多个邮箱用逗号分隔,可留空" data-v-af95cc3b></div></div><div class="divider text-xs text-slate-400 my-4" data-v-af95cc3b>测试发信</div><div class="flex items-end gap-3" data-v-af95cc3b><div class="form-control flex-1" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>测试收件邮箱</span></label><input${ssrRenderAttr("value", mail.testTo)} class="input input-bordered input-sm font-mono" placeholder="填一个邮箱,发送一封测试邮件验证配置" data-v-af95cc3b></div><button class="btn btn-outline btn-sm" data-v-af95cc3b>发送测试</button></div></div></div>`);
|
|
} else if (curCat.value === "translate") {
|
|
_push(`<div data-v-af95cc3b><div class="rounded-xl px-4 py-3 mb-4 flex items-center gap-3" style="${ssrRenderStyle({ "background": "#f0fdfa", "border": "1px solid #99f6e4" })}" data-v-af95cc3b><div style="${ssrRenderStyle({ "width": "36px", "height": "36px", "border-radius": "10px", "background": "#14b8a6", "display": "flex", "align-items": "center", "justify-content": "center", "flex-shrink": "0" })}" data-v-af95cc3b><svg style="${ssrRenderStyle({ "width": "19px", "height": "19px", "color": "#fff" })}" fill="none" viewBox="0 0 24 24" stroke="currentColor" data-v-af95cc3b><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129" data-v-af95cc3b></path></svg></div><div class="flex-1" data-v-af95cc3b><div class="text-sm font-semibold text-teal-800" data-v-af95cc3b>后台配置多语言同步</div><div class="text-[11px] text-teal-600 mt-0.5" data-v-af95cc3b>应用文案、通知 / 邮件模板、公告等后台配置内容,按目标语种自动翻译,保证多语言版本一致。</div></div><span class="badge badge-sm text-white" style="${ssrRenderStyle({ "background": "#14b8a6", "border": "none" })}" data-v-af95cc3b>默认 ${ssrInterpolate(tActiveProvider.value.name)}</span></div><div class="flex items-center justify-between mb-2" data-v-af95cc3b><span class="text-xs font-semibold text-slate-500" data-v-af95cc3b>选择默认翻译服务 <span class="text-slate-400 font-normal" data-v-af95cc3b>(后台多语言同步走此服务)</span></span></div><div class="grid grid-cols-4 gap-3 mb-4" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(tProviders, (p) => {
|
|
_push(`<div class="${ssrRenderClass([{ active: tCurProvider.value === p.id, "is-default": p.id === tActiveId.value }, "provider-card"])}" data-v-af95cc3b><div class="flex items-center justify-between" data-v-af95cc3b><div class="provider-logo" style="${ssrRenderStyle({ background: p.color })}" data-v-af95cc3b>${ssrInterpolate(p.short)}</div>`);
|
|
if (p.enable) {
|
|
_push(`<span class="text-[10px] text-emerald-500 font-semibold" data-v-af95cc3b>已配置</span>`);
|
|
} else {
|
|
_push(`<span class="text-[10px] text-slate-300 font-semibold" data-v-af95cc3b>未配置</span>`);
|
|
}
|
|
_push(`</div><div class="text-sm font-semibold text-slate-700 mt-2" data-v-af95cc3b>${ssrInterpolate(p.name)}</div><div class="text-[11px] text-slate-400 mb-2.5" data-v-af95cc3b>${ssrInterpolate(p.tag)}</div><label class="${ssrRenderClass([{ on: p.id === tActiveId.value }, "default-pick"])}" data-v-af95cc3b><input type="radio" class="radio radio-xs radio-primary"${ssrIncludeBooleanAttr(p.id === tActiveId.value) ? " checked" : ""} data-v-af95cc3b><span data-v-af95cc3b>${ssrInterpolate(p.id === tActiveId.value ? "默认使用" : "设为默认")}</span></label></div>`);
|
|
});
|
|
_push(`<!--]--></div><div class="bg-white rounded-2xl border border-slate-100 shadow-sm p-6" data-v-af95cc3b><div class="flex items-center justify-between mb-5" data-v-af95cc3b><div class="flex items-center gap-3" data-v-af95cc3b><div class="provider-logo" style="${ssrRenderStyle({ background: tEditProvider.value.color, width: "44px", height: "44px", fontSize: "13px" })}" data-v-af95cc3b>${ssrInterpolate(tEditProvider.value.short)}</div><div data-v-af95cc3b><h3 class="text-base font-semibold text-slate-800" data-v-af95cc3b>${ssrInterpolate(tEditProvider.value.name)}</h3><p class="text-xs text-slate-400 mt-0.5" data-v-af95cc3b>${ssrInterpolate(tEditProvider.value.tag)} · 机器翻译</p></div></div><div class="flex items-center gap-2" data-v-af95cc3b><label class="flex items-center gap-2 mr-1" data-v-af95cc3b><span class="text-xs text-slate-500" data-v-af95cc3b>启用</span><input${ssrIncludeBooleanAttr(Array.isArray(tEditProvider.value.enable) ? ssrLooseContain(tEditProvider.value.enable, null) : tEditProvider.value.enable) ? " checked" : ""} type="checkbox" class="toggle toggle-primary toggle-sm" data-v-af95cc3b></label><button class="btn btn-outline btn-sm" data-v-af95cc3b>测试连接</button>`);
|
|
if (tCurProvider.value !== tActiveId.value) {
|
|
_push(`<button class="btn btn-ghost btn-sm text-indigo-600" data-v-af95cc3b>设为默认</button>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`<button class="btn btn-primary btn-sm text-white" data-v-af95cc3b>保存</button></div></div><div class="divider text-xs text-slate-400 my-3" data-v-af95cc3b>连接配置</div><div class="grid grid-cols-2 gap-x-5 gap-y-4" data-v-af95cc3b><!--[-->`);
|
|
ssrRenderList(tEditProvider.value.fields, (f) => {
|
|
_push(`<div class="${ssrRenderClass([{ "col-span-2": f.wide }, "form-control"])}" data-v-af95cc3b><label class="label py-1" data-v-af95cc3b><span class="label-text text-sm" data-v-af95cc3b>${ssrInterpolate(f.label)}`);
|
|
if (f.required) {
|
|
_push(`<span class="text-rose-500 ml-0.5" data-v-af95cc3b>*</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
if (f.encrypted) {
|
|
_push(`<span class="lock-tag ml-1.5" data-v-af95cc3b>🔒 加密存储</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</span></label><div class="relative" data-v-af95cc3b><input${ssrRenderDynamicModel(f.encrypted && !f._show ? "password" : "text", f.value, null)}${ssrRenderAttr("type", f.encrypted && !f._show ? "password" : "text")} class="${ssrRenderClass([{ "font-mono": f.mono, "pr-14": f.encrypted }, "input input-bordered input-sm w-full"])}"${ssrRenderAttr("placeholder", f.placeholder)} data-v-af95cc3b>`);
|
|
if (f.encrypted) {
|
|
_push(`<button type="button" class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-400 hover:text-slate-700" data-v-af95cc3b>${ssrInterpolate(f._show ? "隐藏" : "显示")}</button>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
if (f.hint) {
|
|
_push(`<span class="text-[11px] text-slate-400 mt-1" data-v-af95cc3b>${ssrInterpolate(f.hint)}</span>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</div>`);
|
|
});
|
|
_push(`<!--]--></div></div></div>`);
|
|
} else {
|
|
_push(`<!---->`);
|
|
}
|
|
_push(`</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/systemconfig.vue");
|
|
return _sfc_setup ? _sfc_setup(props, ctx) : void 0;
|
|
};
|
|
const systemconfig = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-af95cc3b"]]);
|
|
|
|
export { systemconfig as default };
|
|
//# sourceMappingURL=systemconfig-BxuoO47G.mjs.map
|
|
|