docs: annotate remaining routes layouts and view boundaries
This commit is contained in:
1 parent
408f8e5c98
commit
ab22d406c0
56 files changed
+403
No files matched your search
@@ -1,4 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
/**
|
||||||
|
* 公共认证布局:登录、注册、找回及第三方绑定共享站点标识和主题入口。认证页链接保留处理后的 redirect,发布版 data-v 作用域用于继续匹配已有共享样式。
|
||||||
|
*/
|
||||||
import "~/assets/styles/blank.DOa3C9wi.css";
|
import "~/assets/styles/blank.DOa3C9wi.css";
|
||||||
import { onMounted } from "vue";
|
import { onMounted } from "vue";
|
||||||
import { useRoute } from "#app";
|
import { useRoute } from "#app";
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 会员中心主布局:组合静态导航与服务端导航权限、面包屑、消息邮箱、账户菜单及移动侧栏。后端导航具有权威性时,不自行补回被关闭入口。
|
||||||
|
*/
|
||||||
import "~/assets/styles/ConsoleLegalFooter.DAYWmXIB.css";
|
import "~/assets/styles/ConsoleLegalFooter.DAYWmXIB.css";
|
||||||
import "~/assets/styles/BackendNavigation.CEj4LnzI.css";
|
import "~/assets/styles/BackendNavigation.CEj4LnzI.css";
|
||||||
import "~/assets/styles/BackendNavEntry.Bx6IPica.css";
|
import "~/assets/styles/BackendNavEntry.Bx6IPica.css";
|
||||||
@@ -308,6 +311,7 @@ var Ce = {
|
|||||||
.filter((e) => e.items.length),
|
.filter((e) => e.items.length),
|
||||||
),
|
),
|
||||||
Je = computed(() => backend_menu_a(j, qe.value, P.value));
|
Je = computed(() => backend_menu_a(j, qe.value, P.value));
|
||||||
|
// 规范化后端菜单并记录其覆盖路径,为静态菜单合成和当前导航判断提供同一数据。
|
||||||
function Ye(e, t) {
|
function Ye(e, t) {
|
||||||
((e = backend_menu_l(e)), (P.value = e), (F.value = t));
|
((e = backend_menu_l(e)), (P.value = e), (F.value = t));
|
||||||
let n = [],
|
let n = [],
|
||||||
@@ -332,17 +336,21 @@ var Ce = {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
let I = ref({});
|
let I = ref({});
|
||||||
|
// 根据当前路由判断父菜单初始展开,实例详情归入服务器菜单。
|
||||||
function L(e) {
|
function L(e) {
|
||||||
return O.path === `/servers/server` && e.label === `服务器`
|
return O.path === `/servers/server` && e.label === `服务器`
|
||||||
? !0
|
? !0
|
||||||
: (e.children?.some((t) => R(t.to, e.children)) ?? !1);
|
: (e.children?.some((t) => R(t.to, e.children)) ?? !1);
|
||||||
}
|
}
|
||||||
|
// 菜单匹配交给公共路径/查询匹配工具,避免仅前缀判断导致高亮错误。
|
||||||
function R(e, t = []) {
|
function R(e, t = []) {
|
||||||
return backend_menu_c(e, O, t);
|
return backend_menu_c(e, O, t);
|
||||||
}
|
}
|
||||||
|
// 用户显式切换父菜单展开状态,覆盖当前路由推导的初始值。
|
||||||
function Xe(e) {
|
function Xe(e) {
|
||||||
I.value[e.label] = !z(e);
|
I.value[e.label] = !z(e);
|
||||||
}
|
}
|
||||||
|
// 先读取用户手动展开选择,未选择时再使用路由推导值。
|
||||||
function z(e) {
|
function z(e) {
|
||||||
return I.value[e.label] ?? L(e);
|
return I.value[e.label] ?? L(e);
|
||||||
}
|
}
|
||||||
@@ -388,9 +396,11 @@ var Ce = {
|
|||||||
]),
|
]),
|
||||||
{ count: V, recent: H, refresh: U } = useMailbox_t(),
|
{ count: V, recent: H, refresh: U } = useMailbox_t(),
|
||||||
W = ref(!1);
|
W = ref(!1);
|
||||||
|
// 打开消息面板时刷新公共邮箱数据,不用旧未读计数代替最新消息。
|
||||||
async function Qe(e) {
|
async function Qe(e) {
|
||||||
((W.value = !0), await U());
|
((W.value = !0), await U());
|
||||||
}
|
}
|
||||||
|
// 选中最近消息后关闭浮层,并通过消息页查询 ID 打开详情。
|
||||||
function $e(e) {
|
function $e(e) {
|
||||||
((W.value = !1),
|
((W.value = !1),
|
||||||
D.push({
|
D.push({
|
||||||
@@ -400,6 +410,7 @@ var Ce = {
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
// 进入完整消息列表时关闭当前消息浮层。
|
||||||
function et() {
|
function et() {
|
||||||
((W.value = !1), D.push(`/messages`));
|
((W.value = !1), D.push(`/messages`));
|
||||||
}
|
}
|
||||||
@@ -435,6 +446,7 @@ var Ce = {
|
|||||||
await nextTick(),
|
await nextTick(),
|
||||||
J.value && q.value?.focus());
|
J.value && q.value?.focus());
|
||||||
}));
|
}));
|
||||||
|
// 移动侧栏打开时处理 Escape 和 Tab 焦点循环,防止键盘焦点移到被遮住的页面。
|
||||||
function tt(e) {
|
function tt(e) {
|
||||||
if (!J.value || !G.value) return;
|
if (!J.value || !G.value) return;
|
||||||
if (e.key === `Escape`) {
|
if (e.key === `Escape`) {
|
||||||
@@ -537,6 +549,7 @@ var Ce = {
|
|||||||
useHead(() => ({
|
useHead(() => ({
|
||||||
title: `${$.value.at(-1) || `会员中心`} - ${A.siteName.value}`,
|
title: `${$.value.at(-1) || `会员中心`} - ${A.siteName.value}`,
|
||||||
})),
|
})),
|
||||||
|
// 导航、面包屑和账户/消息浮层来自同一布局状态;移动侧栏需保留焦点约束与滚动锁清理。
|
||||||
(e, r) => {
|
(e, r) => {
|
||||||
let a = BackendNavEntry,
|
let a = BackendNavEntry,
|
||||||
s = Icon,
|
s = Icon,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 官网布局:从内容模型派生导航、页脚链接、品牌图与主题色;过滤隐藏项,页面正文通过默认插槽提供,移动导航状态仅在当前布局内维护。
|
||||||
|
*/
|
||||||
import "~/assets/styles/official-site.pBD-PXD7.css";
|
import "~/assets/styles/official-site.pBD-PXD7.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
import { renderList } from "vue";
|
import { renderList } from "vue";
|
||||||
@@ -123,6 +126,7 @@ var S = {
|
|||||||
}));
|
}));
|
||||||
return (
|
return (
|
||||||
onMounted(() => X()),
|
onMounted(() => X()),
|
||||||
|
// 公共头尾使用同一内容模型,导航/品牌/页脚 URL 逐项经过内容工具处理,正文通过插槽注入。
|
||||||
(n, i) => {
|
(n, i) => {
|
||||||
let s = NuxtLink;
|
let s = NuxtLink;
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 公开订购布局:为未登录商品流程提供站点配置、主题与登录入口。配置器通过 provide 注册带镜像选择的续接地址,路由变化或旧注销回调不会清除新续接信息。
|
||||||
|
*/
|
||||||
import "~/assets/styles/ConsoleLegalFooter.DAYWmXIB.css";
|
import "~/assets/styles/ConsoleLegalFooter.DAYWmXIB.css";
|
||||||
import "~/assets/styles/public-order.0RThfr7m.css";
|
import "~/assets/styles/public-order.0RThfr7m.css";
|
||||||
import { provide } from "vue";
|
import { provide } from "vue";
|
||||||
@@ -90,6 +93,7 @@ var D = {
|
|||||||
useHead(() => ({
|
useHead(() => ({
|
||||||
title: `产品选购 - ${L.siteName.value}`,
|
title: `产品选购 - ${L.siteName.value}`,
|
||||||
})),
|
})),
|
||||||
|
// 公开订购页保留跳转主内容链接及登录入口,登录地址优先使用配置器登记的完整续接地址。
|
||||||
(e, n) => {
|
(e, n) => {
|
||||||
let a = NuxtLink,
|
let a = NuxtLink,
|
||||||
o = ConsoleLegalFooter;
|
o = ConsoleLegalFooter;
|
||||||
|
|||||||
@@ -310,6 +310,7 @@ var O = {
|
|||||||
`私钥仅显示一次,请确认已保存后离开。离开后将无法再次查看。`,
|
`私钥仅显示一次,请确认已保存后离开。离开后将无法再次查看。`,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 视图分别呈现权限/列表状态、白名单编辑与一次性私钥弹窗;关闭私钥必须调用 Z 清空敏感状态。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
s = button,
|
s = button,
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ var D = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(Y),
|
onMounted(Y),
|
||||||
|
// 列表、绑定入口与解绑确认共用上方互斥状态;外部授权流程由公共 OAuth 控制器处理。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let a = NuxtLink,
|
let a = NuxtLink,
|
||||||
c = button,
|
c = button,
|
||||||
|
|||||||
@@ -920,6 +920,7 @@ var Ce = {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
(Jt().catch(() => {}), en(), await Qt(), (Gt.value = !1));
|
(Jt().catch(() => {}), en(), await Qt(), (Gt.value = !1));
|
||||||
}),
|
}),
|
||||||
|
// 按当前标签展示独立表单,锁定字段与安全验证弹窗共用账户配置;不要把某个标签的忙碌态误用于其他字段。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let te = NuxtLink,
|
let te = NuxtLink,
|
||||||
ne = skeleton,
|
ne = skeleton,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import index from "~/pages/account/realname/index.vue";
|
|||||||
var i = defineComponent({
|
var i = defineComponent({
|
||||||
__name: `company`,
|
__name: `company`,
|
||||||
setup(t) {
|
setup(t) {
|
||||||
|
// 此渲染只传入企业初始类型,避免复制认证主页面的业务状态。
|
||||||
return (t, i) => (
|
return (t, i) => (
|
||||||
openBlock(),
|
openBlock(),
|
||||||
createBlock(index, {
|
createBlock(index, {
|
||||||
|
|||||||
@@ -914,6 +914,7 @@ var xe = {
|
|||||||
Ft());
|
Ft());
|
||||||
}),
|
}),
|
||||||
onMounted(Pt),
|
onMounted(Pt),
|
||||||
|
// 视图区分申请资料、渠道动态字段、费用支付和二维码核验弹窗;状态来自上方独立流程,未支付不等于已提交认证。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let ee = NuxtLink,
|
let ee = NuxtLink,
|
||||||
o = skeleton,
|
o = skeleton,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import index from "~/pages/account/realname/index.vue";
|
|||||||
var i = defineComponent({
|
var i = defineComponent({
|
||||||
__name: `personal`,
|
__name: `personal`,
|
||||||
setup(t) {
|
setup(t) {
|
||||||
|
// 此渲染只传入个人初始类型,认证结果始终由共用主页面加载。
|
||||||
return (t, i) => (
|
return (t, i) => (
|
||||||
openBlock(),
|
openBlock(),
|
||||||
createBlock(index, {
|
createBlock(index, {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ var a = defineComponent({
|
|||||||
composables_t({
|
composables_t({
|
||||||
key: (e) => e.fullPath,
|
key: (e) => e.fullPath,
|
||||||
}),
|
}),
|
||||||
|
// 账单地址只复用订单详情视图,金额与付款状态仍由该详情读取。
|
||||||
(t, r) => (openBlock(), createBlock(_id_))
|
(t, r) => (openBlock(), createBlock(_id_))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ var i = defineComponent({
|
|||||||
hash: e.hash,
|
hash: e.hash,
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
// 保留空壳渲染以兼容旧入口,实际列表由路由重定向进入财务中心。
|
||||||
(t, r) => (openBlock(), createElementBlock(`div`))
|
(t, r) => (openBlock(), createElementBlock(`div`))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -738,6 +738,7 @@ var me = {
|
|||||||
Z()
|
Z()
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
// 渲染当前购物车行与逐项报价,合计不可用时禁用结算;删除确认和订单支付各自保留独立目标。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let i = button,
|
let i = button,
|
||||||
o = message,
|
o = message,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ var m = defineComponent({
|
|||||||
? Number(m.query.m)
|
? Number(m.query.m)
|
||||||
: void 0,
|
: void 0,
|
||||||
);
|
);
|
||||||
|
// m 参数非法时只呈现错误;有效时复用 HostList,menu-id 变化通过 key 重建列表状态。
|
||||||
return (n, a) => {
|
return (n, a) => {
|
||||||
let c = message,
|
let c = message,
|
||||||
g = button,
|
g = button,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ var m = defineComponent({
|
|||||||
? Number(m.query.m)
|
? Number(m.query.m)
|
||||||
: void 0,
|
: void 0,
|
||||||
);
|
);
|
||||||
|
// 物理模块组交给 HostList;无效菜单参数不会回退为另一个有效分组。
|
||||||
return (n, a) => {
|
return (n, a) => {
|
||||||
let c = message,
|
let c = message,
|
||||||
g = button,
|
g = button,
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ var je = {
|
|||||||
Q(),
|
Q(),
|
||||||
At());
|
At());
|
||||||
}),
|
}),
|
||||||
|
// 各财务标签使用各自列表/错误;充值、提现和冻结记录弹窗不能以页面当前余额替代实时接口结果。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
s = button,
|
s = button,
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ var D = {
|
|||||||
G.value = !1;
|
G.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 手机号/邮箱输入、验证码和密码表单共享提交锁;成功导航由 pe 负责,渲染层不直接建立会话。
|
||||||
return (r, o) => {
|
return (r, o) => {
|
||||||
let f = PhoneCodeField,
|
let f = PhoneCodeField,
|
||||||
h = inputtext,
|
h = inputtext,
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ var me = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((X = !0), J++, Y++);
|
((X = !0), J++, Y++);
|
||||||
}),
|
}),
|
||||||
|
// 目录与文章分别显示加载/错误,正文与附件使用公共清理/解析工具;嵌入模式不改变业务请求。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let i = button,
|
let i = button,
|
||||||
o = inputicon,
|
o = inputicon,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
/**
|
||||||
|
* 旧平台单点登录入口:路由守卫负责从 URL 提取并清理凭据;本页只发起服务端验证,支持失败后重试并在离页时取消待处理凭据。
|
||||||
|
*/
|
||||||
import { onBeforeUnmount, onMounted, ref } from "vue";
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
||||||
import { useHead, useRouter } from "#app";
|
import { useHead, useRouter } from "#app";
|
||||||
import { NuxtLink } from "#components";
|
import { NuxtLink } from "#components";
|
||||||
@@ -18,6 +21,7 @@ const isVerifying = ref(false);
|
|||||||
const verificationError = ref("");
|
const verificationError = ref("");
|
||||||
let disposed = false;
|
let disposed = false;
|
||||||
|
|
||||||
|
// 通过会话核心验证已提取的旧平台登录,不再次读取 URL 中的敏感参数;只有组件仍存活时才进入首页。
|
||||||
async function verifyAndEnterConsole() {
|
async function verifyAndEnterConsole() {
|
||||||
if (isVerifying.value) return;
|
if (isVerifying.value) return;
|
||||||
isVerifying.value = true;
|
isVerifying.value = true;
|
||||||
|
|||||||
@@ -316,6 +316,7 @@ var w = {
|
|||||||
t
|
t
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
// 首页将账户提示和业务面板组合展示;各面板自行加载数据,不能把缺省空态当作已确认无资源。
|
||||||
return (n, i) => {
|
return (n, i) => {
|
||||||
let o = Icon,
|
let o = Icon,
|
||||||
c = skeleton,
|
c = skeleton,
|
||||||
|
|||||||
@@ -751,6 +751,7 @@ var Ce = {
|
|||||||
watch(q, () => {
|
watch(q, () => {
|
||||||
O.value && Q();
|
O.value && Q();
|
||||||
}),
|
}),
|
||||||
|
// 列表状态、开票选项、实时报价和费用支付分区展示;提交按钮只接受匹配当前表单的有效报价。
|
||||||
(n, i) => {
|
(n, i) => {
|
||||||
let o = NuxtLink,
|
let o = NuxtLink,
|
||||||
l = PageInfoNotice,
|
l = PageInfoNotice,
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ var T = {
|
|||||||
let Z = computed(() => q(z.value?.invoice_url));
|
let Z = computed(() => q(z.value?.invoice_url));
|
||||||
return (
|
return (
|
||||||
onMounted(X),
|
onMounted(X),
|
||||||
|
// 历史开票登记与正式文件下载分开展示,仅使用经过 q 校验的 URL 作为下载入口。
|
||||||
(t, i) => {
|
(t, i) => {
|
||||||
let s = message,
|
let s = message,
|
||||||
f = skeleton,
|
f = skeleton,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import index from "~/pages/invoices/index.vue";
|
|||||||
var i = defineComponent({
|
var i = defineComponent({
|
||||||
__name: `request`,
|
__name: `request`,
|
||||||
setup(t) {
|
setup(t) {
|
||||||
|
// 申请入口仍挂载同一个发票页面,避免两份申请逻辑产生不同校验。
|
||||||
return (t, i) => (openBlock(), createBlock(index));
|
return (t, i) => (openBlock(), createBlock(index));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ var ue = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(F),
|
onMounted(F),
|
||||||
|
// 抬头与地址编辑分别锁定提交,删除统一二次确认;电子/纸质字段按当前地址类型呈现。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
s = message,
|
s = message,
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ var k = {
|
|||||||
(z.value = `desc`),
|
(z.value = `desc`),
|
||||||
q());
|
q());
|
||||||
}
|
}
|
||||||
|
// 表格使用公共分页工具返回的列表和错误,搜索草稿与已生效关键词保持分离。
|
||||||
return (t, r) => {
|
return (t, r) => {
|
||||||
let o = select,
|
let o = select,
|
||||||
f = inputtext,
|
f = inputtext,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
/**
|
||||||
|
* 会员登录:站点配置决定手机/邮箱密码与短信入口;验证码、安全挑战及第三方登录共用会话核心。attemptVersion 隔离取消、离页和重新提交后的旧响应。
|
||||||
|
*/
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
@@ -140,6 +143,7 @@ watch([() => form.account, loginMode], () => {
|
|||||||
errorMessage.value = "";
|
errorMessage.value = "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 仅允许切换到站点已开放的登录方式;提交、发送短信或安全验证期间保持表单锁定。
|
||||||
function setLoginMode(mode) {
|
function setLoginMode(mode) {
|
||||||
if (
|
if (
|
||||||
fieldsDisabled.value ||
|
fieldsDisabled.value ||
|
||||||
@@ -149,6 +153,7 @@ function setLoginMode(mode) {
|
|||||||
loginMode.value = mode;
|
loginMode.value = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 短信登录只接受手机号,发送前再次确认站点配置;倒计时和验证码挑战交给公共发送器。
|
||||||
function sendLoginCode() {
|
function sendLoginCode() {
|
||||||
if (loginMode.value !== "code" || fieldsDisabled.value) return;
|
if (loginMode.value !== "code" || fieldsDisabled.value) return;
|
||||||
if (!config.value) {
|
if (!config.value) {
|
||||||
@@ -167,6 +172,7 @@ function sendLoginCode() {
|
|||||||
return sendCode("phone", account, "请输入手机号");
|
return sendCode("phone", account, "请输入手机号");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 取消当前尝试时增加版本号并清空暂存凭据;页面卸载也调用,旧异步结果不再导航或更新反馈。
|
||||||
function cancelLogin() {
|
function cancelLogin() {
|
||||||
attemptVersion += 1;
|
attemptVersion += 1;
|
||||||
securityDialogVisible.value = false;
|
securityDialogVisible.value = false;
|
||||||
@@ -177,6 +183,7 @@ function cancelLogin() {
|
|||||||
}
|
}
|
||||||
onBeforeUnmount(cancelLogin);
|
onBeforeUnmount(cancelLogin);
|
||||||
|
|
||||||
|
// 使用同一份凭据快照请求登录;安全挑战保存快照等待续接,其他失败显示脱敏错误并按需刷新验证码。
|
||||||
async function attemptLogin(credentials, verification) {
|
async function attemptLogin(credentials, verification) {
|
||||||
const methodEnabled =
|
const methodEnabled =
|
||||||
credentials.type === "code"
|
credentials.type === "code"
|
||||||
@@ -238,6 +245,7 @@ async function attemptLogin(credentials, verification) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 实名认证安全挑战可能要求回到原表单完成新验证码,再携带同一凭据和验证结果续交。
|
||||||
async function confirmSecurityVerification(verification) {
|
async function confirmSecurityVerification(verification) {
|
||||||
const credentials = pendingCredentials.value;
|
const credentials = pendingCredentials.value;
|
||||||
if (!credentials || submitting.value || pendingVerification.value) return;
|
if (!credentials || submitting.value || pendingVerification.value) return;
|
||||||
@@ -257,6 +265,7 @@ async function confirmSecurityVerification(verification) {
|
|||||||
await attemptLogin(credentials, verification);
|
await attemptLogin(credentials, verification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 区分全新登录与挑战后的续交;校验账号、登录方式、区号、口令及验证码后才创建新的登录尝试。
|
||||||
async function submitLogin() {
|
async function submitLogin() {
|
||||||
if (submitting.value || sendingCode.value || securityDialogVisible.value)
|
if (submitting.value || sendingCode.value || securityDialogVisible.value)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -291,6 +291,7 @@ var ge = {
|
|||||||
let e = Number(T.query.id);
|
let e = Number(T.query.id);
|
||||||
e && Q(e);
|
e && Q(e);
|
||||||
}),
|
}),
|
||||||
|
// 批量操作基于当前选择集,详情正文经公共清理后展示;详情 ID 与加载代次防止快速切换串信。
|
||||||
(t, i) => {
|
(t, i) => {
|
||||||
let s = button,
|
let s = button,
|
||||||
p = NotificationPreferences,
|
p = NotificationPreferences,
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ var fe = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((X = !0), Y++);
|
((X = !0), Y++);
|
||||||
}),
|
}),
|
||||||
|
// 列表摘要为纯文本,详情 HTML 经公共清理工具处理后展示;正文失败不覆盖列表查询状态。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let i = ListSegments,
|
let i = ListSegments,
|
||||||
o = inputtext,
|
o = inputtext,
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ var ue = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((H = !0), (X += 1), V++);
|
((H = !0), (X += 1), V++);
|
||||||
}),
|
}),
|
||||||
|
// 公告列表与正文弹窗使用不同错误/加载状态,详情内容经公共清理工具处理后渲染。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let i = inputtext,
|
let i = inputtext,
|
||||||
o = select,
|
o = select,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 第三方首次登录绑定:微信扫码和通用 OAuth 使用各自的待绑定会话;先验证授权状态,再以手机/邮箱验证码绑定并校验服务端 JWT。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PhoneCodeField.CwyHXfML.css";
|
import "~/assets/styles/PhoneCodeField.CwyHXfML.css";
|
||||||
import "~/assets/styles/GeetestField.DiieTibK.css";
|
import "~/assets/styles/GeetestField.DiieTibK.css";
|
||||||
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
||||||
@@ -120,6 +123,7 @@ var ve = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
G = !1;
|
G = !1;
|
||||||
});
|
});
|
||||||
|
// 先确认授权仍有效;微信支持已完成登录或 WaitBind,通用 OAuth 解析登录/绑定结果,失效状态不开放绑定。
|
||||||
async function K() {
|
async function K() {
|
||||||
if (!W.value && G) {
|
if (!W.value && G) {
|
||||||
((W.value = !0), (U.value = !1), (H.value = ``));
|
((W.value = !0), (U.value = !1), (H.value = ``));
|
||||||
@@ -204,6 +208,7 @@ var ve = {
|
|||||||
watch(I, () => {
|
watch(I, () => {
|
||||||
((L.value = ``), (z.value = ``), (H.value = ``));
|
((L.value = ``), (z.value = ``), (H.value = ``));
|
||||||
});
|
});
|
||||||
|
// 必须先验证授权会话并同意协议;提交验证码绑定,微信额外携带扫码 ticket/token,成功响应的 JWT 合法后才建立会话。
|
||||||
async function Le() {
|
async function Le() {
|
||||||
if (!V.value && G) {
|
if (!V.value && G) {
|
||||||
if (((H.value = ``), !U.value)) {
|
if (((H.value = ``), !U.value)) {
|
||||||
@@ -264,6 +269,7 @@ var ve = {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
(j.load(), K());
|
(j.load(), K());
|
||||||
}),
|
}),
|
||||||
|
// 授权状态未验证时锁定绑定流程;协议勾选、验证码和当前渠道共同决定是否可以提交。
|
||||||
(e, n) => {
|
(e, n) => {
|
||||||
let i = message,
|
let i = message,
|
||||||
a = button,
|
a = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* OAuth 回调恢复页:从服务端恢复授权会话,不从 URL 直接接纳登录令牌;结果只能进入登录或继续绑定流程。
|
||||||
|
*/
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: `blank`,
|
layout: `blank`,
|
||||||
});
|
});
|
||||||
@@ -46,6 +49,7 @@ var w = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
k = !1;
|
k = !1;
|
||||||
});
|
});
|
||||||
|
// 防止并发恢复;解析 OAuth 返回地址的允许来源,拒绝回调自循环,组件卸载后不再处理结果。
|
||||||
async function A() {
|
async function A() {
|
||||||
if (k && !D.value) {
|
if (k && !D.value) {
|
||||||
((D.value = !0), (O.value = ``));
|
((D.value = !0), (O.value = ``));
|
||||||
@@ -82,6 +86,7 @@ var w = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(A),
|
onMounted(A),
|
||||||
|
// 恢复状态、重试按钮与返回登录入口共用 A;展示页不从查询参数直接接纳 JWT。
|
||||||
(e, n) => {
|
(e, n) => {
|
||||||
let r = message,
|
let r = message,
|
||||||
a = button,
|
a = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 官网内容页:从公共站点内容模型读取主题、版块顺序、产品及卖点;使用 official-site 布局,主题值与外链展示通过公共工具约束。
|
||||||
|
*/
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: `official-site`,
|
layout: `official-site`,
|
||||||
});
|
});
|
||||||
@@ -213,6 +216,7 @@ var x = {
|
|||||||
],
|
],
|
||||||
})),
|
})),
|
||||||
onMounted(() => Se()),
|
onMounted(() => Se()),
|
||||||
|
// 按配置中的 sectionOrder 渲染官网版块,隐藏条目不显示,富文本/外链使用公共内容工具处理。
|
||||||
(n, o) => {
|
(n, o) => {
|
||||||
let f = NuxtLink,
|
let f = NuxtLink,
|
||||||
g = Icon;
|
g = Icon;
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 订单/账单详情与旧支付路由共用页:展示订单、流水、转账凭证和支付入口;取消前重读订单,支付完成后从服务端刷新状态。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||||
import "~/assets/styles/_id_.gjoJy9S8.css";
|
import "~/assets/styles/_id_.gjoJy9S8.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
@@ -38,6 +41,7 @@ import PaymentDialog from "~/components/PaymentDialog.vue";
|
|||||||
import tag from "primevue/tag";
|
import tag from "primevue/tag";
|
||||||
import skeleton from "primevue/skeleton";
|
import skeleton from "primevue/skeleton";
|
||||||
import { t as bandwidth_display_t } from "~/lib/bandwidth-display.js";
|
import { t as bandwidth_display_t } from "~/lib/bandwidth-display.js";
|
||||||
|
// 仅从符合续费周期格式的描述中提取商品名,避免把日期区间重复显示成产品标题。
|
||||||
function D(e) {
|
function D(e) {
|
||||||
let t = e.description?.trim() || ``,
|
let t = e.description?.trim() || ``,
|
||||||
n = e.product_name?.trim() || ``,
|
n = e.product_name?.trim() || ``,
|
||||||
@@ -192,6 +196,7 @@ var ue = {
|
|||||||
credit: `余额支付`,
|
credit: `余额支付`,
|
||||||
credit_limit: `信用额支付`,
|
credit_limit: `信用额支付`,
|
||||||
};
|
};
|
||||||
|
// 在实际支付渠道列表中按标识查找显示名称。
|
||||||
function L(e) {
|
function L(e) {
|
||||||
let t = e?.trim().toLowerCase();
|
let t = e?.trim().toLowerCase();
|
||||||
return (
|
return (
|
||||||
@@ -202,6 +207,7 @@ var ue = {
|
|||||||
``
|
``
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 渠道名称先使用服务端配置,再回落到已知余额/信用额类型或原始名称。
|
||||||
function Ze(e) {
|
function Ze(e) {
|
||||||
let t = e?.trim() || ``;
|
let t = e?.trim() || ``;
|
||||||
return L(t) || Xe[t.toLowerCase()] || t || `—`;
|
return L(t) || Xe[t.toLowerCase()] || t || `—`;
|
||||||
@@ -211,6 +217,7 @@ var ue = {
|
|||||||
t = j.value?.gateway?.trim() || ``;
|
t = j.value?.gateway?.trim() || ``;
|
||||||
return L(e) || L(t) || Ze(t || e);
|
return L(e) || L(t) || Ze(t || e);
|
||||||
});
|
});
|
||||||
|
// 支付渠道元信息单独加载,失败不阻止订单详情展示。
|
||||||
async function $e() {
|
async function $e() {
|
||||||
try {
|
try {
|
||||||
let e = await O.get(`/gateway`);
|
let e = await O.get(`/gateway`);
|
||||||
@@ -220,15 +227,18 @@ var ue = {
|
|||||||
onMounted($e);
|
onMounted($e);
|
||||||
let R = ref(!1),
|
let R = ref(!1),
|
||||||
z = ref(!0);
|
z = ref(!0);
|
||||||
|
// 轻量刷新当前订单,用于支付、凭证或取消后的状态同步。
|
||||||
async function B() {
|
async function B() {
|
||||||
try {
|
try {
|
||||||
let e = await O.get(`/order/${k}`);
|
let e = await O.get(`/order/${k}`);
|
||||||
e.order && (j.value = e.order);
|
e.order && (j.value = e.order);
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
// 只接收与当前 ID 匹配的订单更新,避免支付组件更新其他订单。
|
||||||
function et(e) {
|
function et(e) {
|
||||||
String(e.id) === k && (j.value = e);
|
String(e.id) === k && (j.value = e);
|
||||||
}
|
}
|
||||||
|
// 交易流水有独立错误与加载状态;失败不把未加载的金额显示成已支付零元。
|
||||||
async function V() {
|
async function V() {
|
||||||
((P.value = !0), (F.value = !1), (I.value = ``));
|
((P.value = !0), (F.value = !1), (I.value = ``));
|
||||||
try {
|
try {
|
||||||
@@ -240,6 +250,7 @@ var ue = {
|
|||||||
P.value = !1;
|
P.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 旧 pay 路由支付完成进入 paid 路由;普通详情则刷新订单及流水。
|
||||||
function tt() {
|
function tt() {
|
||||||
if (((R.value = !1), A.value)) {
|
if (((R.value = !1), A.value)) {
|
||||||
qe.push(`/orders/order/paid?id=${k}`);
|
qe.push(`/orders/order/paid?id=${k}`);
|
||||||
@@ -262,6 +273,7 @@ var ue = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
let nt = computed(() => j.value?.items?.some((e) => !!D(e)) ?? !1);
|
let nt = computed(() => j.value?.items?.some((e) => !!D(e)) ?? !1);
|
||||||
|
// 订单项标题优先使用已清理的产品名,缺失时回落到描述。
|
||||||
function rt(e) {
|
function rt(e) {
|
||||||
return (
|
return (
|
||||||
product_name_n(D(e) || e.product_name) ||
|
product_name_n(D(e) || e.product_name) ||
|
||||||
@@ -285,6 +297,7 @@ var ue = {
|
|||||||
ot = computed(() =>
|
ot = computed(() =>
|
||||||
(j.value?.items ?? []).map((e) => e.product_name),
|
(j.value?.items ?? []).map((e) => e.product_name),
|
||||||
);
|
);
|
||||||
|
// 订单项说明统一通过产品与带宽展示工具整理,保留真实配置含义。
|
||||||
function st(e) {
|
function st(e) {
|
||||||
return bandwidth_display_t(product_name_r(e.description, ot.value));
|
return bandwidth_display_t(product_name_r(e.description, ot.value));
|
||||||
}
|
}
|
||||||
@@ -316,6 +329,7 @@ var ue = {
|
|||||||
!q.value &&
|
!q.value &&
|
||||||
!J.value,
|
!J.value,
|
||||||
);
|
);
|
||||||
|
// 上传凭证后仅保存服务端 save_name 标识;附件上传期间阻止重复选择处理。
|
||||||
async function dt(e) {
|
async function dt(e) {
|
||||||
let t = e.target,
|
let t = e.target,
|
||||||
n = Array.from(t.files ?? []);
|
n = Array.from(t.files ?? []);
|
||||||
@@ -334,9 +348,11 @@ var ue = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 尚未提交审核时允许移除本地待提交附件,不代表删除服务端历史凭证。
|
||||||
function ft(e) {
|
function ft(e) {
|
||||||
J.value || (K.value = K.value.filter((t, n) => n !== e));
|
J.value || (K.value = K.value.filter((t, n) => n !== e));
|
||||||
}
|
}
|
||||||
|
// 只有允许上传凭证的订单且附件已就绪才提交;提交后进入 WaitReview 并再次读取订单。
|
||||||
async function pt() {
|
async function pt() {
|
||||||
if (j.value && Q.value && !J.value) {
|
if (j.value && Q.value && !J.value) {
|
||||||
((J.value = !0), (Y.value = ``));
|
((J.value = !0), (Y.value = ``));
|
||||||
@@ -358,6 +374,7 @@ var ue = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 从人工转账凭证流程切换到其他支付方式,实际可用渠道由重新加载的订单决定。
|
||||||
async function mt() {
|
async function mt() {
|
||||||
if (j.value && !X.value && ut.value) {
|
if (j.value && !X.value && ut.value) {
|
||||||
((X.value = !0), (Y.value = ``));
|
((X.value = !0), (Y.value = ``));
|
||||||
@@ -381,9 +398,11 @@ var ue = {
|
|||||||
j.value.status,
|
j.value.status,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
// 仅对可取消状态打开确认框,按需订单不走此取消入口。
|
||||||
function ht() {
|
function ht() {
|
||||||
$.value && !U.value && ((W.value = ``), (H.value = !0));
|
$.value && !U.value && ((W.value = ``), (H.value = !0));
|
||||||
}
|
}
|
||||||
|
// 确认取消时再次读取订单并重新检查状态,再执行删除,减少使用过期详情误操作。
|
||||||
async function gt() {
|
async function gt() {
|
||||||
if (H.value && $.value && !U.value && j.value) {
|
if (H.value && $.value && !U.value && j.value) {
|
||||||
((U.value = !0), (W.value = ``));
|
((U.value = !0), (W.value = ``));
|
||||||
@@ -407,9 +426,11 @@ var ue = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 调用浏览器打印当前订单视图,不另行生成服务端发票。
|
||||||
function _t() {
|
function _t() {
|
||||||
window.print();
|
window.print();
|
||||||
}
|
}
|
||||||
|
// 订单项、交易流水、凭证审核与支付分开显示;取消确认读取最新状态,打印仅针对当前详情视图。
|
||||||
return (n, a) => {
|
return (n, a) => {
|
||||||
let l = skeleton,
|
let l = skeleton,
|
||||||
g = message,
|
g = message,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 订单列表:支持账单嵌入/路由模式、筛选、取消、导出与按需订单合并;选择集在筛选或账户变化时同步清空。
|
||||||
|
*/
|
||||||
import "~/assets/styles/orders.BflDlvVz.css";
|
import "~/assets/styles/orders.BflDlvVz.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
import { normalizeClass } from "vue";
|
import { normalizeClass } from "vue";
|
||||||
@@ -51,9 +54,11 @@ var x = new Set([
|
|||||||
`WaitReview`,
|
`WaitReview`,
|
||||||
`ReviewFail`,
|
`ReviewFail`,
|
||||||
]);
|
]);
|
||||||
|
// 状态筛选只接受已知枚举;all 显式转换为空筛选值。
|
||||||
function S(e, t = ``) {
|
function S(e, t = ``) {
|
||||||
return e === `all` ? `` : typeof e == `string` && x.has(e) ? e : t;
|
return e === `all` ? `` : typeof e == `string` && x.has(e) ? e : t;
|
||||||
}
|
}
|
||||||
|
// 订单/账单地址只使用正的安全整数 ID,不把任意服务端字符串拼入路由。
|
||||||
function C(e, t = !1) {
|
function C(e, t = !1) {
|
||||||
if (typeof e != `string` && typeof e != `number`) return null;
|
if (typeof e != `string` && typeof e != `number`) return null;
|
||||||
let n = String(e);
|
let n = String(e);
|
||||||
@@ -208,6 +213,7 @@ var Se = {
|
|||||||
t !== O.value && ((O.value = t), J());
|
t !== O.value && ((O.value = t), J());
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// 根据当前账单模式生成详情链接,无效 ID 使用安全回落地址。
|
||||||
function Y(e) {
|
function Y(e) {
|
||||||
return C(e, w.value) || `/bills`;
|
return C(e, w.value) || `/bills`;
|
||||||
}
|
}
|
||||||
@@ -258,12 +264,14 @@ var Se = {
|
|||||||
flush: `sync`,
|
flush: `sync`,
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
// 合并前冻结当前选中的按需订单 ID,等待确认时不再依赖可变选择数组。
|
||||||
function Re() {
|
function Re() {
|
||||||
Ie.value &&
|
Ie.value &&
|
||||||
((B.value = [...new Set(N.value.map((e) => Number(e.id)))]),
|
((B.value = [...new Set(N.value.map((e) => Number(e.id)))]),
|
||||||
(z.value = ``),
|
(z.value = ``),
|
||||||
(L.value = !0));
|
(L.value = !0));
|
||||||
}
|
}
|
||||||
|
// 逐单核实仍是未付款按需订单,且账户未切换才合并;返回结果不完整时提示刷新核实,避免重复合并。
|
||||||
async function ze() {
|
async function ze() {
|
||||||
if (R.value || !L.value || B.value.length < 2 || V) return;
|
if (R.value || !L.value || B.value.length < 2 || V) return;
|
||||||
let e = E.token,
|
let e = E.token,
|
||||||
@@ -304,9 +312,11 @@ var Se = {
|
|||||||
R.value = !1;
|
R.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 判断普通未付款状态;具体批量取消集合还会排除按需订单。
|
||||||
function Be(e) {
|
function Be(e) {
|
||||||
return String(e.status) === `Unpaid`;
|
return String(e.status) === `Unpaid`;
|
||||||
}
|
}
|
||||||
|
// 只允许对已选可取消订单打开确认,无法取消的选择项单独计数提示。
|
||||||
function Ve() {
|
function Ve() {
|
||||||
if (((I.value = ``), !X.value.length)) {
|
if (((I.value = ``), !X.value.length)) {
|
||||||
I.value = Z.value
|
I.value = Z.value
|
||||||
@@ -316,6 +326,7 @@ var Se = {
|
|||||||
}
|
}
|
||||||
P.value = !0;
|
P.value = !0;
|
||||||
}
|
}
|
||||||
|
// 批量取消仅发送允许取消的 ID,成功后清空选择并刷新列表。
|
||||||
async function He() {
|
async function He() {
|
||||||
if (!F.value && X.value.length) {
|
if (!F.value && X.value.length) {
|
||||||
((F.value = !0), (I.value = ``));
|
((F.value = !0), (I.value = ``));
|
||||||
@@ -335,6 +346,7 @@ var Se = {
|
|||||||
}
|
}
|
||||||
let Ue = ref(!1),
|
let Ue = ref(!1),
|
||||||
$ = ref(``);
|
$ = ref(``);
|
||||||
|
// 按当前类型、状态和关键词导出服务端表格,下载超时与错误由公共 API 层处理。
|
||||||
async function We() {
|
async function We() {
|
||||||
((Ue.value = !0), ($.value = ``));
|
((Ue.value = !0), ($.value = ``));
|
||||||
try {
|
try {
|
||||||
@@ -353,6 +365,7 @@ var Se = {
|
|||||||
Ue.value = !1;
|
Ue.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 恢复默认筛选、排序及 URL 状态值,同时清除选择后刷新。
|
||||||
function Ge() {
|
function Ge() {
|
||||||
((D.value = ``),
|
((D.value = ``),
|
||||||
(O.value = ``),
|
(O.value = ``),
|
||||||
@@ -376,6 +389,7 @@ var Se = {
|
|||||||
J());
|
J());
|
||||||
}
|
}
|
||||||
let Ke = computed(() => !!D.value || !!O.value || !!A.value);
|
let Ke = computed(() => !!D.value || !!O.value || !!A.value);
|
||||||
|
// 合并仅适用于已选未付按需订单,批量取消使用另一允许集合;导出参数与当前已应用筛选一致。
|
||||||
return (n, r) => {
|
return (n, r) => {
|
||||||
let a = button,
|
let a = button,
|
||||||
c = ListSegments,
|
c = ListSegments,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 旧订单详情路由适配层:复用 /orders/[id] 的详情实现,并以完整地址为组件键以响应查询 ID 变化。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||||
import "~/assets/styles/_id_.gjoJy9S8.css";
|
import "~/assets/styles/_id_.gjoJy9S8.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -16,6 +19,7 @@ var a = defineComponent({
|
|||||||
composables_t({
|
composables_t({
|
||||||
key: (e) => e.fullPath,
|
key: (e) => e.fullPath,
|
||||||
}),
|
}),
|
||||||
|
// 兼容路径直接挂载订单详情,不复制详情请求。
|
||||||
(t, r) => (openBlock(), createBlock(_id_))
|
(t, r) => (openBlock(), createBlock(_id_))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 旧支付结果路由适配层:复用订单详情及服务端订单查询,不能仅凭跳入此路径认定付款成功。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||||
import "~/assets/styles/_id_.gjoJy9S8.css";
|
import "~/assets/styles/_id_.gjoJy9S8.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -16,6 +19,7 @@ var a = defineComponent({
|
|||||||
composables_t({
|
composables_t({
|
||||||
key: (e) => e.fullPath,
|
key: (e) => e.fullPath,
|
||||||
}),
|
}),
|
||||||
|
// 此路径展示订单查询结果,不把 paid 路由名称当作服务端付款凭据。
|
||||||
(t, r) => (openBlock(), createBlock(_id_))
|
(t, r) => (openBlock(), createBlock(_id_))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 旧订单支付路由适配层:复用订单详情,详情页根据 /pay 后缀展示支付流程;本文件不自行确认支付结果。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
import "~/assets/styles/PaymentDialog.BNFKQF1U.css";
|
||||||
import "~/assets/styles/_id_.gjoJy9S8.css";
|
import "~/assets/styles/_id_.gjoJy9S8.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -16,6 +19,7 @@ var a = defineComponent({
|
|||||||
composables_t({
|
composables_t({
|
||||||
key: (e) => e.fullPath,
|
key: (e) => e.fullPath,
|
||||||
}),
|
}),
|
||||||
|
// 此路径只复用详情的支付模式,不自行产生支付成功状态。
|
||||||
(t, r) => (openBlock(), createBlock(_id_))
|
(t, r) => (openBlock(), createBlock(_id_))
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 商品详情/购物车编辑入口:校验商品与编辑位置,按服务端模块选择配置器;下单结果交给公共支付弹窗处理。
|
||||||
|
*/
|
||||||
import "~/assets/styles/MfDcimConfig.BhC_eZ0V.css";
|
import "~/assets/styles/MfDcimConfig.BhC_eZ0V.css";
|
||||||
import "~/assets/styles/MfCloudConfig.DbgUu8qr.css";
|
import "~/assets/styles/MfCloudConfig.DbgUu8qr.css";
|
||||||
import "~/assets/styles/KkyEcsConfig.BFaAwQPZ.css";
|
import "~/assets/styles/KkyEcsConfig.BFaAwQPZ.css";
|
||||||
@@ -86,6 +89,7 @@ var j = {
|
|||||||
composables_t({
|
composables_t({
|
||||||
key: (e) => e.fullPath,
|
key: (e) => e.fullPath,
|
||||||
});
|
});
|
||||||
|
// 返回商品目录时仅保留有效的一、二级分类 ID,避免携带任意查询值。
|
||||||
function V() {
|
function V() {
|
||||||
let e = {},
|
let e = {},
|
||||||
t = b.query.g ?? b.query.first_group_id,
|
t = b.query.g ?? b.query.first_group_id,
|
||||||
@@ -123,6 +127,7 @@ var j = {
|
|||||||
onScopeDispose(() => {
|
onScopeDispose(() => {
|
||||||
Z++;
|
Z++;
|
||||||
});
|
});
|
||||||
|
// 依次确认商品可售、购物车位置仍匹配、模块可用;请求序号防止旧详情或描述覆盖新页面。
|
||||||
async function Q() {
|
async function Q() {
|
||||||
let e = ++Z;
|
let e = ++Z;
|
||||||
((W.value = !0), (G.value = ``), (H.value = null), (U.value = null));
|
((W.value = !0), (G.value = ``), (H.value = null), (U.value = null));
|
||||||
@@ -164,14 +169,17 @@ var j = {
|
|||||||
e === Z && (W.value = !1);
|
e === Z && (W.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 接收配置器返回的订单 ID 与金额,打开支付而不在此页重新创建订单。
|
||||||
function $(e) {
|
function $(e) {
|
||||||
((Y.value = e.order_id), (X.value = e.amount), (J.value = !0));
|
((Y.value = e.order_id), (X.value = e.amount), (J.value = !0));
|
||||||
}
|
}
|
||||||
|
// 支付完成后进入订单列表,后续状态由订单页确认。
|
||||||
function se() {
|
function se() {
|
||||||
I.push(`/orders`);
|
I.push(`/orders`);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(Q),
|
onMounted(Q),
|
||||||
|
// 商品模块决定实际配置组件;加载、不可售和模块错误先显示提示,配置器返回订单后才打开支付。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
o = ConfigLoadingShell,
|
o = ConfigLoadingShell,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 云服务器订购:先筛出云服务分类,再按分页商品选择对应模块配置器;分类和商品详情各用独立代次处理快速切换。
|
||||||
|
*/
|
||||||
import "~/assets/styles/MfCloudConfig.DbgUu8qr.css";
|
import "~/assets/styles/MfCloudConfig.DbgUu8qr.css";
|
||||||
import "~/assets/styles/KkyEcsConfig.BFaAwQPZ.css";
|
import "~/assets/styles/KkyEcsConfig.BFaAwQPZ.css";
|
||||||
import "~/assets/styles/ConfigResourceOption.Dj4VopnA.css";
|
import "~/assets/styles/ConfigResourceOption.Dj4VopnA.css";
|
||||||
@@ -135,6 +138,7 @@ var ge = {
|
|||||||
Number(e.hidden ?? 0) !== 1 &&
|
Number(e.hidden ?? 0) !== 1 &&
|
||||||
(e.product_group_id_second == null ||
|
(e.product_group_id_second == null ||
|
||||||
Number(e.product_group_id_second) === T.value);
|
Number(e.product_group_id_second) === T.value);
|
||||||
|
// 只选择当前分组内且有库存的商品;读取详情后再次核验分组/库存并解析可用模块,再挂载配置器。
|
||||||
async function K(e) {
|
async function K(e) {
|
||||||
let t = E.value.find((t) => t.id === e);
|
let t = E.value.find((t) => t.id === e);
|
||||||
if (
|
if (
|
||||||
@@ -180,6 +184,7 @@ var ge = {
|
|||||||
n === z && (j.value = !1);
|
n === z && (j.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 切换分组或分页时清空旧配置,加载商品后优先选择查询指定或首个可售商品。
|
||||||
async function q() {
|
async function q() {
|
||||||
let e = ++R;
|
let e = ++R;
|
||||||
(z++,
|
(z++,
|
||||||
@@ -215,6 +220,7 @@ var ge = {
|
|||||||
e === R && (A.value = !1);
|
e === R && (A.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 重新读取两级分类,并按标准化的云产品分类名筛选可用线路。
|
||||||
async function J() {
|
async function J() {
|
||||||
let e = ++R;
|
let e = ++R;
|
||||||
(z++,
|
(z++,
|
||||||
@@ -255,20 +261,24 @@ var ge = {
|
|||||||
e === R && (k.value = !1);
|
e === R && (k.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 仅允许选择当前分类列表中存在的分组,并从第一页重新加载。
|
||||||
function xe(e) {
|
function xe(e) {
|
||||||
T.value !== e &&
|
T.value !== e &&
|
||||||
w.value.some((t) => t.id === e) &&
|
w.value.some((t) => t.id === e) &&
|
||||||
((T.value = e), (L.value = 1), q());
|
((T.value = e), (L.value = 1), q());
|
||||||
}
|
}
|
||||||
|
// 商品分页变化时重载列表,旧配置器随之失效。
|
||||||
function Se(e) {
|
function Se(e) {
|
||||||
((L.value = e.page + 1), q());
|
((L.value = e.page + 1), q());
|
||||||
}
|
}
|
||||||
let Y = ref(!1),
|
let Y = ref(!1),
|
||||||
X = ref(null),
|
X = ref(null),
|
||||||
Z = ref(``);
|
Z = ref(``);
|
||||||
|
// 配置器下单后记录返回订单并打开支付。
|
||||||
function Ce(e) {
|
function Ce(e) {
|
||||||
((X.value = e.order_id), (Z.value = e.amount), (Y.value = !0));
|
((X.value = e.order_id), (Z.value = e.amount), (Y.value = !0));
|
||||||
}
|
}
|
||||||
|
// 支付完成进入该订单的结果页,真实付款状态仍由服务端返回。
|
||||||
function we() {
|
function we() {
|
||||||
((Y.value = !1),
|
((Y.value = !1),
|
||||||
X.value && ve.push(`/orders/order/paid?id=${X.value}`));
|
X.value && ve.push(`/orders/order/paid?id=${X.value}`));
|
||||||
@@ -296,6 +306,7 @@ var ge = {
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
onMounted(J),
|
onMounted(J),
|
||||||
|
// 选择器与模块配置器使用同一商品快照;快速切换时由版本和组件 key 阻止旧配置继续提交。
|
||||||
(t, r) => {
|
(t, r) => {
|
||||||
let a = CloudProductPicker,
|
let a = CloudProductPicker,
|
||||||
l = button,
|
l = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 物理服务器定制入口:只接受有效商品 ID 且模块为 mf_dcim/remf_dcim,避免把其他类型商品交给物理服务器配置器。
|
||||||
|
*/
|
||||||
import "~/assets/styles/dedicated-server.CiJfMYtk.css";
|
import "~/assets/styles/dedicated-server.CiJfMYtk.css";
|
||||||
import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css";
|
import "~/assets/styles/ConfigDiskCard.Dx9IqqQ_.css";
|
||||||
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
import "~/assets/styles/PromoCodeField.qFEkB6Hm.css";
|
||||||
@@ -76,6 +79,7 @@ var A = {
|
|||||||
onScopeDispose(() => {
|
onScopeDispose(() => {
|
||||||
U++;
|
U++;
|
||||||
});
|
});
|
||||||
|
// 重新读取商品并解析实际模块;页面离开时提升序号,描述异步补全也必须匹配当前请求。
|
||||||
async function W() {
|
async function W() {
|
||||||
let e = ++U,
|
let e = ++U,
|
||||||
t = I.value;
|
t = I.value;
|
||||||
@@ -105,6 +109,7 @@ var A = {
|
|||||||
e === U && (R.value = !1);
|
e === U && (R.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 使用配置器返回的订单信息打开支付,不重复下单。
|
||||||
function G(e) {
|
function G(e) {
|
||||||
((V.value = e.order_id), (H.value = e.amount), (B.value = !0));
|
((V.value = e.order_id), (H.value = e.amount), (B.value = !0));
|
||||||
}
|
}
|
||||||
@@ -112,6 +117,7 @@ var A = {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
I.value ? W() : (R.value = !1);
|
I.value ? W() : (R.value = !1);
|
||||||
}),
|
}),
|
||||||
|
// 只有已验证的物理商品挂载 MfDcimConfig,付款使用配置器返回订单而非再次下单。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
s = skeleton,
|
s = skeleton,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 物理服务器选型:汇总可售物理商品、机型与地区线路,支持规格/价格筛选,选择线路后进入独立定制页。
|
||||||
|
*/
|
||||||
import "~/assets/styles/dedicated-server.CiJfMYtk.css";
|
import "~/assets/styles/dedicated-server.CiJfMYtk.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
import { renderList } from "vue";
|
import { renderList } from "vue";
|
||||||
@@ -29,6 +32,7 @@ import { n as product_name_n } from "~/lib/product-name.js";
|
|||||||
import inputnumber from "primevue/inputnumber";
|
import inputnumber from "primevue/inputnumber";
|
||||||
import tag from "primevue/tag";
|
import tag from "primevue/tag";
|
||||||
import skeleton from "primevue/skeleton";
|
import skeleton from "primevue/skeleton";
|
||||||
|
// 只识别本地或资源模块映射到 mf_dcim 的物理商品;未知模块不强行套用配置器。
|
||||||
function O(e) {
|
function O(e) {
|
||||||
let t = e.module?.trim() || ``;
|
let t = e.module?.trim() || ``;
|
||||||
return t === `mf_dcim` || t === `remf_dcim`
|
return t === `mf_dcim` || t === `remf_dcim`
|
||||||
@@ -37,6 +41,7 @@ function O(e) {
|
|||||||
? `remf_dcim`
|
? `remf_dcim`
|
||||||
: void 0;
|
: void 0;
|
||||||
}
|
}
|
||||||
|
// 封装选型数据、筛选和线路详情,列表请求与选中线路请求使用独立序号。
|
||||||
function k() {
|
function k() {
|
||||||
let e = useApi(),
|
let e = useApi(),
|
||||||
t = ref(!0),
|
t = ref(!0),
|
||||||
@@ -103,6 +108,7 @@ function k() {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((S = !0), y++, b++);
|
((S = !0), y++, b++);
|
||||||
});
|
});
|
||||||
|
// 只清除筛选草稿,不修改服务端商品。
|
||||||
function C() {
|
function C() {
|
||||||
Object.assign(p, {
|
Object.assign(p, {
|
||||||
minPrice: null,
|
minPrice: null,
|
||||||
@@ -114,6 +120,7 @@ function k() {
|
|||||||
disk: ``,
|
disk: ``,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// 商品库存与自动同步的机型库存都满足时才允许选购。
|
||||||
function w(e) {
|
function w(e) {
|
||||||
return (
|
return (
|
||||||
!(e.product.stock_control === 1 && Number(e.product.qty) <= 0) &&
|
!(e.product.stock_control === 1 && Number(e.product.qty) <= 0) &&
|
||||||
@@ -124,6 +131,7 @@ function k() {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 分页收集商品后并行加载物理模块配置;单个商品失败保留其余可用项并提示部分加载失败。
|
||||||
async function T() {
|
async function T() {
|
||||||
let a = ++y;
|
let a = ++y;
|
||||||
(b++,
|
(b++,
|
||||||
@@ -200,6 +208,7 @@ function k() {
|
|||||||
!S && a === y && (t.value = !1);
|
!S && a === y && (t.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 按当前机型读取各线路详情,快速改选时只接纳最新选择的结果。
|
||||||
async function E(t) {
|
async function E(t) {
|
||||||
o.value = m(t);
|
o.value = m(t);
|
||||||
let n = ++b;
|
let n = ++b;
|
||||||
@@ -219,6 +228,7 @@ function k() {
|
|||||||
(l.value = !1));
|
(l.value = !1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 关闭机型选择并使尚未完成的线路请求失效。
|
||||||
function D() {
|
function D() {
|
||||||
(b++, (o.value = ``), (c.value = {}), (l.value = !1), (f.value = ``));
|
(b++, (o.value = ``), (c.value = {}), (l.value = !1), (f.value = ``));
|
||||||
}
|
}
|
||||||
@@ -382,16 +392,19 @@ var te = {
|
|||||||
label: `硬盘`,
|
label: `硬盘`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
// 只有明确有效的商品价格才显示金额,缺失时提示配置后确认。
|
||||||
function xe(e) {
|
function xe(e) {
|
||||||
return e !== void 0 && e.trim() !== `` && Number.isFinite(Number(e))
|
return e !== void 0 && e.trim() !== `` && Number.isFinite(Number(e))
|
||||||
? `¥ ${Number(e).toFixed(2)}`
|
? `¥ ${Number(e).toFixed(2)}`
|
||||||
: `价格待配置`;
|
: `价格待配置`;
|
||||||
}
|
}
|
||||||
|
// 定制链接携带当前商品、机型及所选线路 ID,最终仍由配置页加载并验证商品。
|
||||||
function Se(e) {
|
function Se(e) {
|
||||||
return `/products/dedicated-server/customize?id=${C.value?.product.id}&model_id=${C.value?.model.id}&line_id=${e}`;
|
return `/products/dedicated-server/customize?id=${C.value?.product.id}&model_id=${C.value?.model.id}&line_id=${e}`;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(s.load),
|
onMounted(s.load),
|
||||||
|
// 机型筛选卡、线路详情和定制入口共享当前选择;部分配置读取失败有单独反馈,不伪装成无库存。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let a = NuxtLink,
|
let a = NuxtLink,
|
||||||
k = inputnumber,
|
k = inputnumber,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 商品目录:两级分类、搜索、分页和配置摘要;摘要缓存按账户令牌与 API origin 分区,切换会话后清理,不能跨账号复用。
|
||||||
|
*/
|
||||||
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
|
import "~/assets/styles/ProductGroupLabel.B1kWpFA-.css";
|
||||||
import "~/assets/styles/ProductDescription.Ctb7jDuO.css";
|
import "~/assets/styles/ProductDescription.Ctb7jDuO.css";
|
||||||
import "~/assets/styles/ProductConfigurationSummary.BqZns1LB.css";
|
import "~/assets/styles/ProductConfigurationSummary.BqZns1LB.css";
|
||||||
@@ -53,6 +56,7 @@ var j = rolldown_runtime_i(getCrypto(), 1),
|
|||||||
N = 100,
|
N = 100,
|
||||||
P = 512e3,
|
P = 512e3,
|
||||||
F = 3;
|
F = 3;
|
||||||
|
// 校验本地摘要缓存键的结构、字段长度和规范序列化,拒绝不符合当前格式的存储条目。
|
||||||
function I(e) {
|
function I(e) {
|
||||||
if (typeof e != `string` || e.length > 4096) return !1;
|
if (typeof e != `string` || e.length > 4096) return !1;
|
||||||
try {
|
try {
|
||||||
@@ -73,6 +77,7 @@ function I(e) {
|
|||||||
return !1;
|
return !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 摘要仅接受有界、非空的字符串数组,不从本地存储信任任意结构。
|
||||||
function L(e) {
|
function L(e) {
|
||||||
return (
|
return (
|
||||||
Array.isArray(e) &&
|
Array.isArray(e) &&
|
||||||
@@ -83,6 +88,7 @@ function L(e) {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 管理摘要缓存、过期清理和同键在途请求复用;持久化容量有界,清空操作会使旧异步任务失效。
|
||||||
function R(e, t = Date.now, n) {
|
function R(e, t = Date.now, n) {
|
||||||
let r = new Map(),
|
let r = new Map(),
|
||||||
i = new Map(),
|
i = new Map(),
|
||||||
@@ -226,6 +232,7 @@ function R(e, t = Date.now, n) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var z = new WeakMap();
|
var z = new WeakMap();
|
||||||
|
// 为当前 Pinia 会话建立缓存管理;每次读取确认 localStorage 令牌一致,并按后端 origin 隔离数据。
|
||||||
function pe() {
|
function pe() {
|
||||||
let e = useAuth(),
|
let e = useAuth(),
|
||||||
n = useRuntimeConfig(),
|
n = useRuntimeConfig(),
|
||||||
@@ -291,6 +298,7 @@ function pe() {
|
|||||||
clear: () => B(a),
|
clear: () => B(a),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 提升缓存版本并清除各分区及持久化内容,使旧账号的在途摘要结果不能写回。
|
||||||
function B(e) {
|
function B(e) {
|
||||||
e.version++;
|
e.version++;
|
||||||
for (let t of e.caches.values()) t.clear();
|
for (let t of e.caches.values()) t.clear();
|
||||||
@@ -405,6 +413,7 @@ var me = {
|
|||||||
onScopeDispose(() => {
|
onScopeDispose(() => {
|
||||||
(W++, G++);
|
(W++, G++);
|
||||||
});
|
});
|
||||||
|
// 部分物理模块列表无可靠起价,需要后续从套餐配置补充,不直接把无效零价当报价。
|
||||||
function q(e) {
|
function q(e) {
|
||||||
let t = Number(e.price);
|
let t = Number(e.price);
|
||||||
return (
|
return (
|
||||||
@@ -413,6 +422,7 @@ var me = {
|
|||||||
(!Number.isFinite(t) || t <= 0)
|
(!Number.isFinite(t) || t <= 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 列出有效父分类与子分类配对,供未指定分类时逐一寻找可展示商品。
|
||||||
function Re() {
|
function Re() {
|
||||||
return I.value.flatMap((e) =>
|
return I.value.flatMap((e) =>
|
||||||
L.value
|
L.value
|
||||||
@@ -423,11 +433,13 @@ var me = {
|
|||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 分类查询参数只接受正的安全整数,避免错误编号进入目录状态。
|
||||||
function J(e) {
|
function J(e) {
|
||||||
if (typeof e != `string` || !/^[1-9]\d*$/.test(e)) return null;
|
if (typeof e != `string` || !/^[1-9]\d*$/.test(e)) return null;
|
||||||
let t = Number(e);
|
let t = Number(e);
|
||||||
return Number.isSafeInteger(t) ? t : null;
|
return Number.isSafeInteger(t) ? t : null;
|
||||||
}
|
}
|
||||||
|
// 依据实际分类树恢复查询选择,子分类必须属于有效父分类;无效组合不直接套用。
|
||||||
function ze() {
|
function ze() {
|
||||||
let e = J(o.query.g) ?? J(o.query.first_group_id),
|
let e = J(o.query.g) ?? J(o.query.first_group_id),
|
||||||
t = J(o.query.sg) ?? J(o.query.second_group_id),
|
t = J(o.query.sg) ?? J(o.query.second_group_id),
|
||||||
@@ -456,6 +468,7 @@ var me = {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// 把分类选择规范为 g/sg 查询参数,去掉旧参数别名并保留其他查询。
|
||||||
function Y(e, t) {
|
function Y(e, t) {
|
||||||
let n = {
|
let n = {
|
||||||
...o.query,
|
...o.query,
|
||||||
@@ -473,6 +486,7 @@ var me = {
|
|||||||
query: n,
|
query: n,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
// 未指定有效分类时依次查找非空分类;全部为空则回到首个分类展示真实空态。
|
||||||
async function Be(e) {
|
async function Be(e) {
|
||||||
let t = Re(),
|
let t = Re(),
|
||||||
n = t[0];
|
n = t[0];
|
||||||
@@ -502,6 +516,7 @@ var me = {
|
|||||||
(j.value = ``),
|
(j.value = ``),
|
||||||
(D.value = !1));
|
(D.value = !1));
|
||||||
}
|
}
|
||||||
|
// 重新加载两级分类后恢复有效选择与页码;分类已变更时重新选择,不沿用过期商品列表。
|
||||||
async function X() {
|
async function X() {
|
||||||
let e = ++G;
|
let e = ++G;
|
||||||
(W++, (B.value = !0), (D.value = !0), (V.value = ``), (j.value = ``));
|
(W++, (B.value = !0), (D.value = !0), (V.value = ``), (j.value = ``));
|
||||||
@@ -547,6 +562,7 @@ var me = {
|
|||||||
e === G && (B.value = !1);
|
e === G && (B.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 切换一级分类时选择其首个子分类,重置分页并同步 URL。
|
||||||
function Ve(e) {
|
function Ve(e) {
|
||||||
if (
|
if (
|
||||||
!B.value &&
|
!B.value &&
|
||||||
@@ -561,6 +577,7 @@ var me = {
|
|||||||
Z()
|
Z()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 只允许切换当前一级分类下存在的二级分类。
|
||||||
function He(e) {
|
function He(e) {
|
||||||
if (
|
if (
|
||||||
!B.value &&
|
!B.value &&
|
||||||
@@ -569,6 +586,7 @@ var me = {
|
|||||||
)
|
)
|
||||||
return ((z.value = e), (M.value = 1), Y(R.value, z.value), Z());
|
return ((z.value = e), (M.value = 1), Y(R.value, z.value), Z());
|
||||||
}
|
}
|
||||||
|
// 按当前分类/页码/搜索请求列表;仅同一查询复用现有摘要与起价,异步补全仍需匹配列表代次。
|
||||||
async function Z(e = !1) {
|
async function Z(e = !1) {
|
||||||
if (B.value || V.value) return;
|
if (B.value || V.value) return;
|
||||||
let n = ++W;
|
let n = ++W;
|
||||||
@@ -644,16 +662,20 @@ var me = {
|
|||||||
n === W && (D.value = !1);
|
n === W && (D.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 搜索确认后应用关键词并回到第一页。
|
||||||
function Ue() {
|
function Ue() {
|
||||||
return ((F.value = P.value.trim()), (M.value = 1), Z());
|
return ((F.value = P.value.trim()), (M.value = 1), Z());
|
||||||
}
|
}
|
||||||
|
// 清空草稿关键词,再复用统一搜索提交逻辑。
|
||||||
function We() {
|
function We() {
|
||||||
return ((P.value = ``), Ue());
|
return ((P.value = ``), Ue());
|
||||||
}
|
}
|
||||||
|
// 加载中或当前查询有错误时不接受分页,防止叠加新的列表状态。
|
||||||
function Ge(e) {
|
function Ge(e) {
|
||||||
if (!(D.value || B.value || j.value || V.value))
|
if (!(D.value || B.value || j.value || V.value))
|
||||||
return ((M.value = e.page + 1), (N.value = e.rows), Z());
|
return ((M.value = e.page + 1), (N.value = e.rows), Z());
|
||||||
}
|
}
|
||||||
|
// 把已知计费周期转换为中文单位,未知英文枚举不直接作为用户文案。
|
||||||
function Ke(e) {
|
function Ke(e) {
|
||||||
return e
|
return e
|
||||||
? {
|
? {
|
||||||
@@ -667,11 +689,13 @@ var me = {
|
|||||||
}[e] || (/[\u4e00-\u9fff]/.test(e) ? e : ``)
|
}[e] || (/[\u4e00-\u9fff]/.test(e) ? e : ``)
|
||||||
: ``;
|
: ``;
|
||||||
}
|
}
|
||||||
|
// 仅在库存控制已开启且数量明确不大于零时判定售罄。
|
||||||
function Q(e) {
|
function Q(e) {
|
||||||
return (
|
return (
|
||||||
Number(e.stock_control) === 1 && e.qty != null && Number(e.qty) <= 0
|
Number(e.stock_control) === 1 && e.qty != null && Number(e.qty) <= 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 不允许订购标记或未知模块会阻止进入配置流程,不能单靠列表有价格就开放下单。
|
||||||
function $(e) {
|
function $(e) {
|
||||||
let t = e.module?.trim();
|
let t = e.module?.trim();
|
||||||
return (
|
return (
|
||||||
@@ -692,6 +716,7 @@ var me = {
|
|||||||
].includes(t))
|
].includes(t))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 区别免费、有效起价、补价中、缺货及配置后报价,不把未知金额显示成零元。
|
||||||
function qe(e) {
|
function qe(e) {
|
||||||
if (e.pay_type === `free`) return `免费`;
|
if (e.pay_type === `free`) return `免费`;
|
||||||
let t = Number(e.price);
|
let t = Number(e.price);
|
||||||
@@ -705,6 +730,7 @@ var me = {
|
|||||||
? `暂无价格`
|
? `暂无价格`
|
||||||
: `配置后报价`;
|
: `配置后报价`;
|
||||||
}
|
}
|
||||||
|
// 详情链接保留当前有效分类选择,返回目录时可恢复上下文。
|
||||||
function Je(e) {
|
function Je(e) {
|
||||||
return {
|
return {
|
||||||
path: `/products/${e}`,
|
path: `/products/${e}`,
|
||||||
@@ -724,6 +750,7 @@ var me = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(X),
|
onMounted(X),
|
||||||
|
// 分类、商品列表、起价/摘要及库存状态分别呈现;配置摘要是辅助信息,最终报价仍在配置器中确认。
|
||||||
(e, t) => {
|
(e, t) => {
|
||||||
let i = NuxtLink,
|
let i = NuxtLink,
|
||||||
o = skeleton,
|
o = skeleton,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 推介计划:开通推广身份、推广链接、奖励记录、提现与受邀用户;永久关系模式才显示受邀用户,提现能力由服务端配置控制。
|
||||||
|
*/
|
||||||
import "~/assets/styles/WithdrawDialog.ks0wdKEK.css";
|
import "~/assets/styles/WithdrawDialog.ks0wdKEK.css";
|
||||||
import "~/assets/styles/recommend.C1KCHBPJ.css";
|
import "~/assets/styles/recommend.C1KCHBPJ.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
@@ -46,6 +49,7 @@ import tabpanels from "primevue/tabpanels";
|
|||||||
import tabpanel from "primevue/tabpanel";
|
import tabpanel from "primevue/tabpanel";
|
||||||
import tablist from "primevue/tablist";
|
import tablist from "primevue/tablist";
|
||||||
import tab from "primevue/tab";
|
import tab from "primevue/tab";
|
||||||
|
// 把本地日期范围转换为秒级查询边界;严格复核年月日并覆盖结束日全天,拒绝无效日期或反向区间。
|
||||||
function C(e, t) {
|
function C(e, t) {
|
||||||
function n(e, t) {
|
function n(e, t) {
|
||||||
if (!e) return ``;
|
if (!e) return ``;
|
||||||
@@ -251,6 +255,7 @@ var Se = {
|
|||||||
Ct = ref(`links`),
|
Ct = ref(`links`),
|
||||||
O = ref(!1),
|
O = ref(!1),
|
||||||
k = ref(``);
|
k = ref(``);
|
||||||
|
// 仅在有开通权限且尚无推广地址时创建推广身份,完成后重新加载资料。
|
||||||
async function wt() {
|
async function wt() {
|
||||||
if (!(O.value || !xt.value || bt.value)) {
|
if (!(O.value || !xt.value || bt.value)) {
|
||||||
((O.value = !0), (k.value = ``));
|
((O.value = !0), (k.value = ``));
|
||||||
@@ -263,6 +268,7 @@ var Se = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 推广资料为核心查询,说明内容可独立缺失;已开通时再读取链接配置与当前标签数据。
|
||||||
async function A() {
|
async function A() {
|
||||||
((vt.value = !0), (T.value = ``));
|
((vt.value = !0), (T.value = ``));
|
||||||
try {
|
try {
|
||||||
@@ -304,6 +310,7 @@ var Se = {
|
|||||||
onScopeDispose(() => {
|
onScopeDispose(() => {
|
||||||
q !== void 0 && clearTimeout(q);
|
q !== void 0 && clearTimeout(q);
|
||||||
});
|
});
|
||||||
|
// 奖励规则、推荐商品、系统链接和自定义链接分别处理成功/失败,单项失败不抹去其余成功内容。
|
||||||
async function J() {
|
async function J() {
|
||||||
if (!N.value) {
|
if (!N.value) {
|
||||||
((N.value = !0),
|
((N.value = !0),
|
||||||
@@ -353,6 +360,7 @@ var Se = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 刷新自定义链接列表,与其他推广配置保持独立加载状态。
|
||||||
async function Et() {
|
async function Et() {
|
||||||
((Tt.value = !0), (z.value = ``));
|
((Tt.value = !0), (z.value = ``));
|
||||||
try {
|
try {
|
||||||
@@ -365,6 +373,7 @@ var Se = {
|
|||||||
Tt.value = !1;
|
Tt.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 系统页面必须来自当前允许列表,自定义标识非空后才创建链接;成功后重读链接。
|
||||||
async function Dt() {
|
async function Dt() {
|
||||||
if (B.value || V.value !== null || N.value) return;
|
if (B.value || V.value !== null || N.value) return;
|
||||||
let e = H.system_url.trim(),
|
let e = H.system_url.trim(),
|
||||||
@@ -392,6 +401,7 @@ var Se = {
|
|||||||
B.value = !1;
|
B.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 确认后按编码 ID 删除自定义链接,删除与生成操作相互锁定。
|
||||||
async function Ot(e) {
|
async function Ot(e) {
|
||||||
if (
|
if (
|
||||||
!(V.value !== null || B.value) &&
|
!(V.value !== null || B.value) &&
|
||||||
@@ -412,9 +422,11 @@ var Se = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 选取服务端提供的完整链接或自定义链接,不自行拼接未知推广参数。
|
||||||
function kt(e) {
|
function kt(e) {
|
||||||
return e.url || e.custom_url || ``;
|
return e.url || e.custom_url || ``;
|
||||||
}
|
}
|
||||||
|
// 复制推广链接并短暂显示反馈;失败提供可手动复制的原链接,计时器在离页时清除。
|
||||||
async function At(e, t) {
|
async function At(e, t) {
|
||||||
if (e) {
|
if (e) {
|
||||||
(clearTimeout(q), (U.value = ``), (W.value = ``), (G.value = ``));
|
(clearTimeout(q), (U.value = ``), (W.value = ``), (G.value = ``));
|
||||||
@@ -428,6 +440,7 @@ var Se = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 先验证商品 ID,再向服务端获取带推广归属的链接,不直接用商品详情地址替代。
|
||||||
async function jt(e) {
|
async function jt(e) {
|
||||||
if (K.value !== null) return;
|
if (K.value !== null) return;
|
||||||
let t = Number(e.product_id);
|
let t = Number(e.product_id);
|
||||||
@@ -569,6 +582,7 @@ var Se = {
|
|||||||
value: `renew`,
|
value: `renew`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
// 提交搜索关键词后由公共列表工具应用完整筛选与日期范围。
|
||||||
function Yt() {
|
function Yt() {
|
||||||
((It.value = Ft.value.trim()), Q());
|
((It.value = Ft.value.trim()), Q());
|
||||||
}
|
}
|
||||||
@@ -637,11 +651,13 @@ var Se = {
|
|||||||
value: 0,
|
value: 0,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
// 仅在相应标签激活时加载奖励、提现或受邀用户列表,避免全部标签一起请求。
|
||||||
function $(e) {
|
function $(e) {
|
||||||
(e === `records` && Q(),
|
(e === `records` && Q(),
|
||||||
e === `withdraws` && rn(),
|
e === `withdraws` && rn(),
|
||||||
e === `invitees` && mn());
|
e === `invitees` && mn());
|
||||||
}
|
}
|
||||||
|
// 保存当前标签并触发对应数据加载。
|
||||||
function gn(e) {
|
function gn(e) {
|
||||||
((Ct.value = e), $(e));
|
((Ct.value = e), $(e));
|
||||||
}
|
}
|
||||||
@@ -657,6 +673,7 @@ var Se = {
|
|||||||
invitees: `受邀用户`,
|
invitees: `受邀用户`,
|
||||||
},
|
},
|
||||||
yn = ref(!1);
|
yn = ref(!1);
|
||||||
|
// 提现完成后刷新推广余额资料与提现记录,金额以服务端结果为准。
|
||||||
async function bn() {
|
async function bn() {
|
||||||
(await A(), rn());
|
(await A(), rn());
|
||||||
}
|
}
|
||||||
@@ -664,6 +681,7 @@ var Se = {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
(A(), w());
|
(A(), w());
|
||||||
}),
|
}),
|
||||||
|
// 先区分未开通与已开通状态,再按标签显示链接/奖励/提现/受邀用户;各查询失败保持独立反馈。
|
||||||
(n, i) => {
|
(n, i) => {
|
||||||
let o = skeleton,
|
let o = skeleton,
|
||||||
l = message,
|
l = message,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 账号注册:站点配置控制手机/邮箱入口、验证码要求和动态资料;提交成功跳回登录,不在本页假定已取得登录会话。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PhoneCodeField.CwyHXfML.css";
|
import "~/assets/styles/PhoneCodeField.CwyHXfML.css";
|
||||||
import "~/assets/styles/GeetestField.DiieTibK.css";
|
import "~/assets/styles/GeetestField.DiieTibK.css";
|
||||||
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
||||||
@@ -49,6 +52,7 @@ import { t as composables_t } from "~/lib/composables-2.js";
|
|||||||
import { t as useVerifyCode_t } from "~/lib/useVerifyCode.js";
|
import { t as useVerifyCode_t } from "~/lib/useVerifyCode.js";
|
||||||
var w = (e) => e === !0 || e === 1 || e === `1`,
|
var w = (e) => e === !0 || e === 1 || e === `1`,
|
||||||
T = (e) => (typeof e == `string` || typeof e == `number` ? String(e) : ``);
|
T = (e) => (typeof e == `string` || typeof e == `number` ? String(e) : ``);
|
||||||
|
// 归一化服务端注册字段,限制支持的控件类型、拒绝原型敏感键与重复字段;不支持的配置明确提示而非静默丢弃。
|
||||||
function _e(e) {
|
function _e(e) {
|
||||||
if (e == null)
|
if (e == null)
|
||||||
return {
|
return {
|
||||||
@@ -247,6 +251,7 @@ var ve = {
|
|||||||
q = computed(() => _e(V.value?.custom_fields)),
|
q = computed(() => _e(V.value?.custom_fields)),
|
||||||
J = computed(() => q.value.fields),
|
J = computed(() => q.value.fields),
|
||||||
Y = computed(() => !!V.value && (G.value.phone || G.value.email));
|
Y = computed(() => !!V.value && (G.value.phone || G.value.email));
|
||||||
|
// 先加载注册配置;手机关闭且邮箱开放时自动选择可用方式。
|
||||||
async function X() {
|
async function X() {
|
||||||
(await U(), !G.value.phone && G.value.email && (P.value = `email`));
|
(await U(), !G.value.phone && G.value.email && (P.value = `email`));
|
||||||
}
|
}
|
||||||
@@ -261,6 +266,7 @@ var ve = {
|
|||||||
error: I,
|
error: I,
|
||||||
phoneCode: () => F.phone_code,
|
phoneCode: () => F.phone_code,
|
||||||
});
|
});
|
||||||
|
// 仅对已开放且需要验证码的注册方式发送验证码,倒计时与验证码挑战由公共发送器管理。
|
||||||
function ze() {
|
function ze() {
|
||||||
if (!Y.value || !G.value[P.value] || !K.value || L.value) return;
|
if (!Y.value || !G.value[P.value] || !K.value || L.value) return;
|
||||||
let e = F.account.trim();
|
let e = F.account.trim();
|
||||||
@@ -270,9 +276,11 @@ var ve = {
|
|||||||
P.value === `email` ? `请输入邮箱` : `请输入手机号`,
|
P.value === `email` ? `请输入邮箱` : `请输入手机号`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 允许切换注册方式时清空旧验证码,避免将另一种渠道验证码一并提交。
|
||||||
function $(e) {
|
function $(e) {
|
||||||
!G.value[e] || L.value || Z.value || ((P.value = e), (F.code = ``));
|
!G.value[e] || L.value || Z.value || ((P.value = e), (F.code = ``));
|
||||||
}
|
}
|
||||||
|
// 检查站点配置与动态必填资料,再按当前渠道组装注册请求;成功后保留安全处理的站内跳转目标。
|
||||||
async function Be() {
|
async function Be() {
|
||||||
if (L.value || Z.value) return;
|
if (L.value || Z.value) return;
|
||||||
if (((I.value = ``), !V.value))
|
if (((I.value = ``), !V.value))
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 独立远控窗口:校验 hostId 与受支持模块后挂载 RemoteConsole;mf_dcim 先收集操作密码,页面只管理连接界面,不在前端保存长期远控凭据。
|
||||||
|
*/
|
||||||
import "~/assets/styles/RemoteConsole.DLmX5UZu.css";
|
import "~/assets/styles/RemoteConsole.DLmX5UZu.css";
|
||||||
import "~/assets/styles/remote-console.zcxaOxxS.css";
|
import "~/assets/styles/remote-console.zcxaOxxS.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -101,9 +104,11 @@ var O = {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
V = computed(() => z.value === `mf_dcim` && !I.value);
|
V = computed(() => z.value === `mf_dcim` && !I.value);
|
||||||
|
// 用户确认操作密码后开放远控组件挂载,实际鉴权由远控请求和网关完成。
|
||||||
function H() {
|
function H() {
|
||||||
((I.value = !0), (P.value = !0));
|
((I.value = !0), (P.value = !0));
|
||||||
}
|
}
|
||||||
|
// 重新连接时清空密码与确认状态,必要时重新显示密码门禁。
|
||||||
function U() {
|
function U() {
|
||||||
((F.value = ``), (I.value = !1), (P.value = !0));
|
((F.value = ``), (I.value = !1), (P.value = !0));
|
||||||
}
|
}
|
||||||
@@ -117,6 +122,7 @@ var O = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
F.value = ``;
|
F.value = ``;
|
||||||
}),
|
}),
|
||||||
|
// 仅在编号与模块有效且密码门禁已通过时挂载远控组件;无效/已关闭状态显示返回入口与重连操作。
|
||||||
(t, n) => {
|
(t, n) => {
|
||||||
let i = RemoteConsole,
|
let i = RemoteConsole,
|
||||||
s = NuxtLink,
|
s = NuxtLink,
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ var j = {
|
|||||||
W(V[n].value),
|
W(V[n].value),
|
||||||
document.getElementById(`resource-tab-${V[n].value}`)?.focus());
|
document.getElementById(`resource-tab-${V[n].value}`)?.focus());
|
||||||
}
|
}
|
||||||
|
// 标签使用稳定 ID 关联 tab/panel,解析分类后才挂载对应页面,避免非法参数触发错误内容入口。
|
||||||
return (n, i) => {
|
return (n, i) => {
|
||||||
let a = button,
|
let a = button,
|
||||||
s = skeleton,
|
s = skeleton,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 域名白名单:按主机及审核状态查询记录;提交前必须加载可用主机、实名认证状态和当前主机对应的动态表单。
|
||||||
|
*/
|
||||||
import "~/assets/styles/domains.GiD6NSti.css";
|
import "~/assets/styles/domains.GiD6NSti.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
alias: [`/security/domain-whitelist`],
|
alias: [`/security/domain-whitelist`],
|
||||||
@@ -128,6 +131,7 @@ var ve = {
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
k = computed(() => x.value !== null || S.value !== null);
|
k = computed(() => x.value !== null || S.value !== null);
|
||||||
|
// 清除主机和状态筛选后重新查询记录。
|
||||||
function Re() {
|
function Re() {
|
||||||
((x.value = null), (S.value = null), O());
|
((x.value = null), (S.value = null), O());
|
||||||
}
|
}
|
||||||
@@ -171,6 +175,7 @@ var ve = {
|
|||||||
value: -1,
|
value: -1,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
// 独立加载可申请白名单的主机列表,并校验响应为数组;旧请求或离页响应不回写。
|
||||||
async function Ve() {
|
async function Ve() {
|
||||||
let e = ++L;
|
let e = ++L;
|
||||||
((P.value = !0), (M.value = ``));
|
((P.value = !0), (M.value = ``));
|
||||||
@@ -187,6 +192,7 @@ var ve = {
|
|||||||
!I && e === L && (P.value = !1);
|
!I && e === L && (P.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 明确验证服务端实名标记的允许格式,不能把未知响应默认为已实名。
|
||||||
async function He() {
|
async function He() {
|
||||||
let e = ++R;
|
let e = ++R;
|
||||||
((F.value = !0), (N.value = ``));
|
((F.value = !0), (N.value = ``));
|
||||||
@@ -204,6 +210,7 @@ var ve = {
|
|||||||
!I && e === R && (F.value = !1);
|
!I && e === R && (F.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 用户文案区分已通过、已驳回、人工审核与自动处理中。
|
||||||
function Ue(e) {
|
function Ue(e) {
|
||||||
return e.status === 1
|
return e.status === 1
|
||||||
? `已通过`
|
? `已通过`
|
||||||
@@ -213,6 +220,7 @@ var ve = {
|
|||||||
? `等待人工审核`
|
? `等待人工审核`
|
||||||
: `处理中`;
|
: `处理中`;
|
||||||
}
|
}
|
||||||
|
// 状态颜色与审核结果保持对应,不以有记录就表示已生效。
|
||||||
function We(e) {
|
function We(e) {
|
||||||
return e.status === 1
|
return e.status === 1
|
||||||
? `success`
|
? `success`
|
||||||
@@ -224,6 +232,7 @@ var ve = {
|
|||||||
}
|
}
|
||||||
let z = ref(``),
|
let z = ref(``),
|
||||||
Ge = ref(`success`);
|
Ge = ref(`success`);
|
||||||
|
// 统一设置操作反馈与级别,避免撤销失败仍显示成功样式。
|
||||||
function B(e, t = `success`) {
|
function B(e, t = `success`) {
|
||||||
((z.value = e), (Ge.value = t));
|
((z.value = e), (Ge.value = t));
|
||||||
}
|
}
|
||||||
@@ -236,6 +245,7 @@ var ve = {
|
|||||||
q = ref(!1),
|
q = ref(!1),
|
||||||
J = ref(null),
|
J = ref(null),
|
||||||
Y = 0;
|
Y = 0;
|
||||||
|
// 打开申请并选定主机,表单字段必须重新按该主机加载。
|
||||||
function X(e) {
|
function X(e) {
|
||||||
if (!q.value)
|
if (!q.value)
|
||||||
return (
|
return (
|
||||||
@@ -245,6 +255,7 @@ var ve = {
|
|||||||
Ke()
|
Ke()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 每次切换主机先清空旧字段,响应必须同时匹配请求序号与主机 ID 才可提交。
|
||||||
async function Ke() {
|
async function Ke() {
|
||||||
let e = ++Y,
|
let e = ++Y,
|
||||||
t = H.value;
|
t = H.value;
|
||||||
@@ -273,6 +284,7 @@ var ve = {
|
|||||||
e === Y && (W.value = !1);
|
e === Y && (W.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 只提交当前已加载主机表单,且实名/主机前置查询无错误;校验动态必填项后创建记录。
|
||||||
async function qe() {
|
async function qe() {
|
||||||
if (!(
|
if (!(
|
||||||
q.value ||
|
q.value ||
|
||||||
@@ -311,9 +323,11 @@ var ve = {
|
|||||||
let Z = ref(!1),
|
let Z = ref(!1),
|
||||||
Q = ref(null),
|
Q = ref(null),
|
||||||
$ = ref(!1);
|
$ = ref(!1);
|
||||||
|
// 打开撤销确认并保存目标,不立即删除。
|
||||||
function Je(e) {
|
function Je(e) {
|
||||||
((Q.value = e), (Z.value = !0));
|
((Q.value = e), (Z.value = !0));
|
||||||
}
|
}
|
||||||
|
// 仅对服务端允许撤销的记录发送删除,完成后刷新列表。
|
||||||
async function Ye() {
|
async function Ye() {
|
||||||
if (!Q.value || $.value || !Q.value.can_remove) return;
|
if (!Q.value || $.value || !Q.value.can_remove) return;
|
||||||
let e = Q.value;
|
let e = Q.value;
|
||||||
@@ -334,6 +348,7 @@ var ve = {
|
|||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
(He(), await Ve(), x.value && X(x.value));
|
(He(), await Ve(), x.value && X(x.value));
|
||||||
}),
|
}),
|
||||||
|
// 记录列表、主机实名前置状态和申请动态字段分别展示;申请字段必须属于当前选择主机。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let a = NuxtLink,
|
let a = NuxtLink,
|
||||||
c = message,
|
c = message,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 安全组:组列表、出入站规则与实例关联共用页面;主列表、规则、已关联和可关联主机分别用请求代次隔离,批量关联保留失败目标供重试。
|
||||||
|
*/
|
||||||
import "~/assets/styles/PageInfoNotice._16xRFrB.css";
|
import "~/assets/styles/PageInfoNotice._16xRFrB.css";
|
||||||
import "~/assets/styles/groups.Buw8nwl1.css";
|
import "~/assets/styles/groups.Buw8nwl1.css";
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
@@ -244,6 +247,7 @@ var Te = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
k = ref([]);
|
k = ref([]);
|
||||||
|
// 常用端口快捷选择仅生成待确认的文本规则;默认 IP 为全网范围,生成并不立即下发。
|
||||||
function dt() {
|
function dt() {
|
||||||
$.value = ut
|
$.value = ut
|
||||||
.filter((e) => k.value.includes(e.port))
|
.filter((e) => k.value.includes(e.port))
|
||||||
@@ -253,9 +257,11 @@ var Te = {
|
|||||||
).join(`
|
).join(`
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
// 打开新增规则弹窗,方向取当前入站/出站标签。
|
||||||
function ft() {
|
function ft() {
|
||||||
((R.value = null), (L.direction = D.value), (O.value = !0));
|
((R.value = null), (L.direction = D.value), (O.value = !0));
|
||||||
}
|
}
|
||||||
|
// 把已选规则复制到草稿后编辑,避免未保存时改动列表。
|
||||||
function pt(e) {
|
function pt(e) {
|
||||||
((R.value = e),
|
((R.value = e),
|
||||||
Object.assign(L, {
|
Object.assign(L, {
|
||||||
@@ -293,6 +299,7 @@ var Te = {
|
|||||||
}),
|
}),
|
||||||
R = ref(null),
|
R = ref(null),
|
||||||
bt = computed(() => ht.value.filter((e) => e.direction === D.value));
|
bt = computed(() => ht.value.filter((e) => e.direction === D.value));
|
||||||
|
// 按关键词分页查询安全组,组件离开或新请求发起后废弃旧响应。
|
||||||
async function z() {
|
async function z() {
|
||||||
let e = ++x;
|
let e = ++x;
|
||||||
((st.value = !0), (T.value = ``));
|
((st.value = !0), (T.value = ``));
|
||||||
@@ -313,6 +320,7 @@ var Te = {
|
|||||||
e === x && !b && (st.value = !1);
|
e === x && !b && (st.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 新建组前清空上一次编辑目标和名称描述。
|
||||||
function xt() {
|
function xt() {
|
||||||
((j.value = null),
|
((j.value = null),
|
||||||
(M.name = ``),
|
(M.name = ``),
|
||||||
@@ -320,6 +328,7 @@ var Te = {
|
|||||||
(T.value = ``),
|
(T.value = ``),
|
||||||
(A.value = !0));
|
(A.value = !0));
|
||||||
}
|
}
|
||||||
|
// 编辑组时回填现有名称描述,保留原对象用于更新 ID。
|
||||||
function St(e) {
|
function St(e) {
|
||||||
((j.value = e),
|
((j.value = e),
|
||||||
(M.name = e.name),
|
(M.name = e.name),
|
||||||
@@ -327,6 +336,7 @@ var Te = {
|
|||||||
(T.value = ``),
|
(T.value = ``),
|
||||||
(A.value = !0));
|
(A.value = !0));
|
||||||
}
|
}
|
||||||
|
// 名称必填且同一时间只提交一次;新增/更新后重新读取组列表。
|
||||||
async function Ct() {
|
async function Ct() {
|
||||||
if (!mt.value) {
|
if (!mt.value) {
|
||||||
if (((T.value = ``), !M.name.trim())) {
|
if (((T.value = ``), !M.name.trim())) {
|
||||||
@@ -352,6 +362,7 @@ var Te = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 删除组后刷新列表,失败保留页面错误。
|
||||||
async function wt(e) {
|
async function wt(e) {
|
||||||
try {
|
try {
|
||||||
(await y.del(`/security_group/${e.id}`), await z());
|
(await y.del(`/security_group/${e.id}`), await z());
|
||||||
@@ -359,6 +370,7 @@ var Te = {
|
|||||||
T.value = e instanceof Error ? e.message : `删除失败`;
|
T.value = e instanceof Error ? e.message : `删除失败`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 进入组详情时重置规则页码、草稿与当前标签,再加载该组规则。
|
||||||
async function Tt(e) {
|
async function Tt(e) {
|
||||||
((P.value = e),
|
((P.value = e),
|
||||||
(N.value = !0),
|
(N.value = !0),
|
||||||
@@ -375,6 +387,7 @@ var Te = {
|
|||||||
}),
|
}),
|
||||||
await B());
|
await B());
|
||||||
}
|
}
|
||||||
|
// 规则响应必须匹配组 ID 与请求代次,避免切组后展示上一组规则。
|
||||||
async function B() {
|
async function B() {
|
||||||
if (!P.value) return;
|
if (!P.value) return;
|
||||||
let e = ++tt,
|
let e = ++tt,
|
||||||
@@ -429,6 +442,7 @@ var Te = {
|
|||||||
G.value ||
|
G.value ||
|
||||||
Ot.value,
|
Ot.value,
|
||||||
);
|
);
|
||||||
|
// 读取当前组全部关联主机用于搜索与去重,而不是只拿关联列表第一页。
|
||||||
async function Z() {
|
async function Z() {
|
||||||
if (!P.value) return;
|
if (!P.value) return;
|
||||||
let e = P.value.id,
|
let e = P.value.id,
|
||||||
@@ -453,6 +467,7 @@ var Te = {
|
|||||||
n() && (H.value = !1);
|
n() && (H.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 分页收集可用主机,失败时清空旧候选,避免沿用已失效的关联资格。
|
||||||
async function jt() {
|
async function jt() {
|
||||||
let e = ++rt,
|
let e = ++rt,
|
||||||
t = () => !b && e === rt;
|
t = () => !b && e === rt;
|
||||||
@@ -492,6 +507,7 @@ var Te = {
|
|||||||
value: e.id,
|
value: e.id,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
// 批量提交前核对所有选择仍可关联;解析部分成功结果后保留失败 ID,刷新已关联列表及组计数。
|
||||||
async function Pt() {
|
async function Pt() {
|
||||||
if (!P.value || !W.value.length || X.value) return;
|
if (!P.value || !W.value.length || X.value) return;
|
||||||
let e = P.value.id,
|
let e = P.value.id,
|
||||||
@@ -524,6 +540,7 @@ var Te = {
|
|||||||
Ot.value = !1;
|
Ot.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 单主机关联仅接受当前候选项,提交后刷新关联及组列表。
|
||||||
async function Ft() {
|
async function Ft() {
|
||||||
if (
|
if (
|
||||||
P.value &&
|
P.value &&
|
||||||
@@ -544,6 +561,7 @@ var Te = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 解除实例与组的关联后刷新状态,不在本地假定服务端已删除关系。
|
||||||
async function It(e) {
|
async function It(e) {
|
||||||
if (P.value && !X.value) {
|
if (P.value && !X.value) {
|
||||||
((G.value = !0), (T.value = ``));
|
((G.value = !0), (T.value = ``));
|
||||||
@@ -561,6 +579,7 @@ var Te = {
|
|||||||
let Q = ref(!1),
|
let Q = ref(!1),
|
||||||
$ = ref(``),
|
$ = ref(``),
|
||||||
Lt = ref(!1);
|
Lt = ref(!1);
|
||||||
|
// 每行按方向、协议、端口、IP 和可选描述解析;空行忽略,不足四列明确报格式错误。
|
||||||
function Rt(e) {
|
function Rt(e) {
|
||||||
let t = [];
|
let t = [];
|
||||||
for (let n of e.split(`
|
for (let n of e.split(`
|
||||||
@@ -580,6 +599,7 @@ var Te = {
|
|||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
// 批量规则先完整解析再提交,至少需要一条;成功后清空文本并刷新规则和组计数。
|
||||||
async function zt() {
|
async function zt() {
|
||||||
if (!P.value || Lt.value) return;
|
if (!P.value || Lt.value) return;
|
||||||
T.value = ``;
|
T.value = ``;
|
||||||
@@ -617,6 +637,7 @@ var Te = {
|
|||||||
watch(V, (e) => {
|
watch(V, (e) => {
|
||||||
e === `host` && (Z(), jt());
|
e === `host` && (Z(), jt());
|
||||||
});
|
});
|
||||||
|
// 单条规则按是否有编辑目标选择 PUT/POST;端口必填,成功后重置编辑器并刷新。
|
||||||
async function Vt() {
|
async function Vt() {
|
||||||
if (!yt.value) {
|
if (!yt.value) {
|
||||||
if (((T.value = ``), !P.value)) {
|
if (((T.value = ``), !P.value)) {
|
||||||
@@ -654,6 +675,7 @@ var Te = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 删除规则后同步规则列表与安全组统计。
|
||||||
async function Ht(e) {
|
async function Ht(e) {
|
||||||
try {
|
try {
|
||||||
(await y.del(`/security_group/rule/${e.id}`), await B(), await z());
|
(await y.del(`/security_group/rule/${e.id}`), await B(), await z());
|
||||||
@@ -661,6 +683,7 @@ var Te = {
|
|||||||
T.value = e instanceof Error ? e.message : `删除规则失败`;
|
T.value = e instanceof Error ? e.message : `删除规则失败`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 把已知协议枚举转换为可读名称,未知协议保留大写标识。
|
||||||
function Ut(e) {
|
function Ut(e) {
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
@@ -678,12 +701,15 @@ var Te = {
|
|||||||
function Wt(e) {
|
function Wt(e) {
|
||||||
((C.value = e.page + 1), (w.value = e.rows), z());
|
((C.value = e.page + 1), (w.value = e.rows), z());
|
||||||
}
|
}
|
||||||
|
// 确认搜索词后回到第一页查询组列表。
|
||||||
function Gt() {
|
function Gt() {
|
||||||
((ct.value = E.value.trim()), (C.value = 1), z());
|
((ct.value = E.value.trim()), (C.value = 1), z());
|
||||||
}
|
}
|
||||||
|
// 清空搜索草稿及已应用词,并恢复第一页。
|
||||||
function Kt() {
|
function Kt() {
|
||||||
((E.value = ``), (ct.value = ``), (C.value = 1), z());
|
((E.value = ``), (ct.value = ``), (C.value = 1), z());
|
||||||
}
|
}
|
||||||
|
// 切换规则方向时恢复规则第一页,再按服务端方向筛选读取。
|
||||||
function qt(e) {
|
function qt(e) {
|
||||||
((V.value = `rule`), (D.value = e), (F.value = 1), B());
|
((V.value = `rule`), (D.value = e), (F.value = 1), B());
|
||||||
}
|
}
|
||||||
@@ -704,6 +730,7 @@ var Te = {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
}),
|
}),
|
||||||
|
// 组列表、规则详情、主机关联和批量规则各自使用独立草稿与提交锁,避免一个弹窗改变另一操作目标。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let i = button,
|
let i = button,
|
||||||
te = PageInfoNotice,
|
te = PageInfoNotice,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
/**
|
||||||
|
* SSH 公钥管理:普通列表使用服务端分页,搜索先读取完整列表再在本地过滤/分页;requestGeneration 与 disposed 共同阻止旧请求回写。只管理公钥,不接收私钥。
|
||||||
|
*/
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
@@ -48,10 +51,12 @@ const visibleRows = computed(() =>
|
|||||||
: rows.value,
|
: rows.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 仅允许当前加载代次且组件尚未卸载时修改列表反馈。
|
||||||
function isCurrentLoad(generation) {
|
function isCurrentLoad(generation) {
|
||||||
return !disposed && generation === requestGeneration;
|
return !disposed && generation === requestGeneration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除或搜索后夹紧页码;返回是否变化,供服务端分页决定是否重读修正后的页。
|
||||||
function clampPage() {
|
function clampPage() {
|
||||||
const lastPage = Math.max(1, Math.ceil(totalRows.value / pageSize.value));
|
const lastPage = Math.max(1, Math.ceil(totalRows.value / pageSize.value));
|
||||||
const nextPage = Math.max(1, Math.min(currentPage.value, lastPage));
|
const nextPage = Math.max(1, Math.min(currentPage.value, lastPage));
|
||||||
@@ -60,6 +65,7 @@ function clampPage() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 非搜索模式请求当前服务端页,删除末页最后一条时先修正页码再重读。
|
||||||
async function loadKeys() {
|
async function loadKeys() {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
if (appliedSearch.value) return loadSearchResults();
|
if (appliedSearch.value) return loadSearchResults();
|
||||||
@@ -90,6 +96,7 @@ async function loadKeys() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 搜索拥有全量过滤结果,visibleRows 才做本地分页;不能只在服务端某一页上搜索全部密钥。
|
||||||
async function loadSearchResults() {
|
async function loadSearchResults() {
|
||||||
const query = appliedSearch.value;
|
const query = appliedSearch.value;
|
||||||
const generation = ++requestGeneration;
|
const generation = ++requestGeneration;
|
||||||
@@ -124,12 +131,14 @@ async function loadSearchResults() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关键词确认后才应用,并从第一页重新查询。
|
||||||
async function submitSearch() {
|
async function submitSearch() {
|
||||||
appliedSearch.value = draftSearch.value.trim().toLowerCase();
|
appliedSearch.value = draftSearch.value.trim().toLowerCase();
|
||||||
currentPage.value = 1;
|
currentPage.value = 1;
|
||||||
await loadKeys();
|
await loadKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清除草稿与已应用关键词,恢复服务端分页。
|
||||||
async function clearSearch() {
|
async function clearSearch() {
|
||||||
draftSearch.value = "";
|
draftSearch.value = "";
|
||||||
appliedSearch.value = "";
|
appliedSearch.value = "";
|
||||||
@@ -137,6 +146,7 @@ async function clearSearch() {
|
|||||||
await loadKeys();
|
await loadKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 每页条数变化回到第一页;搜索只调整本地页,普通模式重新读接口。
|
||||||
function changePage(event) {
|
function changePage(event) {
|
||||||
currentPage.value = event.rows === pageSize.value ? event.page + 1 : 1;
|
currentPage.value = event.rows === pageSize.value ? event.page + 1 : 1;
|
||||||
pageSize.value = event.rows;
|
pageSize.value = event.rows;
|
||||||
@@ -144,6 +154,7 @@ function changePage(event) {
|
|||||||
else void loadKeys();
|
else void loadKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新建前清空上次编辑对象和表单,避免把旧 ID 带入创建。
|
||||||
function openCreateDialog() {
|
function openCreateDialog() {
|
||||||
editingKey.value = null;
|
editingKey.value = null;
|
||||||
keyForm.name = "";
|
keyForm.name = "";
|
||||||
@@ -152,6 +163,7 @@ function openCreateDialog() {
|
|||||||
editorVisible.value = true;
|
editorVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 复制行中的名称与公钥到草稿,不直接改表格对象。
|
||||||
function openEditDialog(key) {
|
function openEditDialog(key) {
|
||||||
editingKey.value = key;
|
editingKey.value = key;
|
||||||
keyForm.name = key.name;
|
keyForm.name = key.name;
|
||||||
@@ -160,6 +172,7 @@ function openEditDialog(key) {
|
|||||||
editorVisible.value = true;
|
editorVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 校验名称非空、字符数上限和公钥非空;按编辑对象选择创建/更新,成功后刷新当前模式列表。
|
||||||
async function saveKey() {
|
async function saveKey() {
|
||||||
if (saving.value || disposed) return;
|
if (saving.value || disposed) return;
|
||||||
actionError.value = "";
|
actionError.value = "";
|
||||||
@@ -196,6 +209,7 @@ async function saveKey() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 删除后复用加载逻辑;末页恢复由 loadKeys/clampPage 统一处理。
|
||||||
async function deleteKey(key) {
|
async function deleteKey(key) {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
try {
|
try {
|
||||||
@@ -207,6 +221,7 @@ async function deleteKey(key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 剪贴板成功后短暂标记当前行;离页时清除反馈计时器,复制失败仍可手工选择公钥。
|
||||||
async function copyPublicKey(key) {
|
async function copyPublicKey(key) {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(key.public_key);
|
await navigator.clipboard.writeText(key.public_key);
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 实例详情调度页:先确认主机与商品,再解析实际管理模块;统一展示数据与能力开关,云/物理/通用旧模块分别委派管理组件。权限展示不替代后端鉴权。
|
||||||
|
*/
|
||||||
import "~/assets/styles/InstanceLoadingShell.CwfiUwdU.css";
|
import "~/assets/styles/InstanceLoadingShell.CwfiUwdU.css";
|
||||||
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
|
import "~/assets/styles/FlowPacketPanel.-RJSx13z.css";
|
||||||
import "~/assets/styles/InstanceServiceInfo.BftSVIeW.css";
|
import "~/assets/styles/InstanceServiceInfo.BftSVIeW.css";
|
||||||
@@ -151,6 +154,7 @@ var M = {
|
|||||||
remoteConsole: !0,
|
remoteConsole: !0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
// 统一云实例数据、状态和磁盘访问;模块变化或作用域销毁时递增请求代次,使旧模块在途响应失效。
|
||||||
function Ee(e, t, n) {
|
function Ee(e, t, n) {
|
||||||
let r = useApi(),
|
let r = useApi(),
|
||||||
i = ref(null),
|
i = ref(null),
|
||||||
@@ -197,11 +201,13 @@ function Ee(e, t, n) {
|
|||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
S = () => t.value;
|
S = () => t.value;
|
||||||
|
// 镜像图标名经过 URL 编码后仅拼入本地固定图标目录。
|
||||||
function ee(e) {
|
function ee(e) {
|
||||||
return e
|
return e
|
||||||
? `/plugins/server/mf_cloud/view/assets/default_icons/${encodeURIComponent(e)}.svg`
|
? `/plugins/server/mf_cloud/view/assets/default_icons/${encodeURIComponent(e)}.svg`
|
||||||
: ``;
|
: ``;
|
||||||
}
|
}
|
||||||
|
// 把 mf_cloud/remf_cloud 详情转换为统一展示结构,同时保留 raw 供专用管理组件读取。
|
||||||
function te(e) {
|
function te(e) {
|
||||||
let t = e.image ?? {},
|
let t = e.image ?? {},
|
||||||
n = String(t.icon ?? ``);
|
n = String(t.icon ?? ``);
|
||||||
@@ -231,6 +237,7 @@ function Ee(e, t, n) {
|
|||||||
raw: e,
|
raw: e,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 从财务模块 host_data 与配置项提取实例规格;IP 去重,连接端口交给公共解析器处理。
|
||||||
function C(e) {
|
function C(e) {
|
||||||
let t = instance_data_l(e.host_data),
|
let t = instance_data_l(e.host_data),
|
||||||
n = instance_data_i(e.config_options),
|
n = instance_data_i(e.config_options),
|
||||||
@@ -272,6 +279,7 @@ function Ee(e, t, n) {
|
|||||||
raw: e,
|
raw: e,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 整理弹性云的镜像、带宽计费和安全组字段,不改变原始接口数据。
|
||||||
function ne(e) {
|
function ne(e) {
|
||||||
let t = instance_data_a(e),
|
let t = instance_data_a(e),
|
||||||
n = String(t.icon ?? ``);
|
n = String(t.icon ?? ``);
|
||||||
@@ -304,6 +312,7 @@ function Ee(e, t, n) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 整理 jy 系列的多种字段来源;仅选有效数值作为统一规格,保留原始详情。
|
||||||
function w(e) {
|
function w(e) {
|
||||||
let t = instance_data_l(e.host_data),
|
let t = instance_data_l(e.host_data),
|
||||||
n = instance_data_a(e),
|
n = instance_data_a(e),
|
||||||
@@ -352,6 +361,7 @@ function Ee(e, t, n) {
|
|||||||
raw: e,
|
raw: e,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 按模块读取并规范化磁盘列表;财务模块从快照/备份信息提取,明确空数组才作为无磁盘。
|
||||||
async function ie(t) {
|
async function ie(t) {
|
||||||
if (t === `remf_finance`) {
|
if (t === `remf_finance`) {
|
||||||
let t = !1,
|
let t = !1,
|
||||||
@@ -433,6 +443,7 @@ function Ee(e, t, n) {
|
|||||||
raw: e,
|
raw: e,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
// 磁盘异步结果同时绑定模块、详情代次和磁盘请求代次,失败只更新磁盘区域。
|
||||||
async function ae() {
|
async function ae() {
|
||||||
let e = t.value;
|
let e = t.value;
|
||||||
if (!e || !i.value || M[e].disk === !1) return;
|
if (!e || !i.value || M[e].disk === !1) return;
|
||||||
@@ -450,6 +461,7 @@ function Ee(e, t, n) {
|
|||||||
a() && (h.value = !1);
|
a() && (h.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 状态查询有独立 12 秒截止时间;结果缺少有效 rescue 标记时保留详情已有标记,不用未知状态冒充关机。
|
||||||
async function T() {
|
async function T() {
|
||||||
let n = S();
|
let n = S();
|
||||||
if (!n) return;
|
if (!n) return;
|
||||||
@@ -483,6 +495,7 @@ function Ee(e, t, n) {
|
|||||||
u() && (l.value = !1);
|
u() && (l.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 并行发起状态与详情查询,按模块归一化详情后再加载磁盘;缺失连接端口时单独读取 remote_info。
|
||||||
async function oe(n) {
|
async function oe(n) {
|
||||||
let a = t.value;
|
let a = t.value;
|
||||||
if (!a) return;
|
if (!a) return;
|
||||||
@@ -527,6 +540,7 @@ function Ee(e, t, n) {
|
|||||||
c() && (f.value = !1);
|
c() && (f.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 先核对模块电源能力及强制操作能力,再携带可选操作密码请求,完成后重新读取状态。
|
||||||
async function se(t, n = ``) {
|
async function se(t, n = ``) {
|
||||||
if (!M[S()]?.power) throw Error(`当前模块暂未开放电源管理操作`);
|
if (!M[S()]?.power) throw Error(`当前模块暂未开放电源管理操作`);
|
||||||
if (t.startsWith(`hard_`) && !M[S()]?.hardPower)
|
if (t.startsWith(`hard_`) && !M[S()]?.hardPower)
|
||||||
@@ -538,6 +552,7 @@ function Ee(e, t, n) {
|
|||||||
: void 0;
|
: void 0;
|
||||||
(await r.post(`/${S()}/${e}/${t}`, i), await T());
|
(await r.post(`/${S()}/${e}/${t}`, i), await T());
|
||||||
}
|
}
|
||||||
|
// 密码重置按模块组装既有字段契约,不能把 kky 与其他模块的参数形状直接互换。
|
||||||
async function ce(t, n = ``, i = ``) {
|
async function ce(t, n = ``, i = ``) {
|
||||||
if (!M[S()]?.passwordReset) throw Error(`当前模块暂未开放密码重置操作`);
|
if (!M[S()]?.passwordReset) throw Error(`当前模块暂未开放密码重置操作`);
|
||||||
S() === `kky_ecs`
|
S() === `kky_ecs`
|
||||||
@@ -587,6 +602,7 @@ var N = new Set([
|
|||||||
F = (e) => e === `idcsmart_common` || e === `reidcsmart_common`,
|
F = (e) => e === `idcsmart_common` || e === `reidcsmart_common`,
|
||||||
I = (e) => e === !0 || e === 1 || e === `1` || e === `on` || e === `true`,
|
I = (e) => e === !0 || e === 1 || e === `1` || e === `on` || e === `true`,
|
||||||
L = (e) => e === !1 || e === 0 || e === `0` || e === `off` || e === `false`;
|
L = (e) => e === !1 || e === 0 || e === `0` || e === `off` || e === `false`;
|
||||||
|
// 从后端按钮元数据提取允许与禁止电源动作;显式禁用优先于允许,同名动作不能被另一条配置重新放开。
|
||||||
function R(e) {
|
function R(e) {
|
||||||
let t = new Set(),
|
let t = new Set(),
|
||||||
n = new Set(),
|
n = new Set(),
|
||||||
@@ -614,6 +630,7 @@ function R(e) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
var z = (e) => R(e).allowed;
|
var z = (e) => R(e).allowed;
|
||||||
|
// 按旧模块的实际权限形状计算动作集合,兼顾 dcim 授权与手工资源控制模式;未知模块不开放电源操作。
|
||||||
function Oe(e, t) {
|
function Oe(e, t) {
|
||||||
if (F(e)) return z(t.client_button);
|
if (F(e)) return z(t.client_button);
|
||||||
if (e === `remf_finance_common`) return z(t.module_button);
|
if (e === `remf_finance_common`) return z(t.module_button);
|
||||||
@@ -641,6 +658,7 @@ function Oe(e, t) {
|
|||||||
}
|
}
|
||||||
return new Set();
|
return new Set();
|
||||||
}
|
}
|
||||||
|
// 旧/通用实例电源权限与状态控制器:权限元数据必须属于当前模块才能开放动作,提交期间互斥。
|
||||||
function ke(e, t) {
|
function ke(e, t) {
|
||||||
let n = useApi(),
|
let n = useApi(),
|
||||||
r = ref(!1),
|
r = ref(!1),
|
||||||
@@ -655,6 +673,7 @@ function ke(e, t) {
|
|||||||
h = 0,
|
h = 0,
|
||||||
g = !1,
|
g = !1,
|
||||||
_ = !1;
|
_ = !1;
|
||||||
|
// 模块重载、切换或销毁时清空权限和状态,并让已有异步结果失效。
|
||||||
function v() {
|
function v() {
|
||||||
(h++,
|
(h++,
|
||||||
f++,
|
f++,
|
||||||
@@ -667,9 +686,11 @@ function ke(e, t) {
|
|||||||
(i.value = ``),
|
(i.value = ``),
|
||||||
(r.value = !1));
|
(r.value = !1));
|
||||||
}
|
}
|
||||||
|
// 只有当前模块元数据已成功加载、没有错误且动作被允许时才可提交。
|
||||||
function y(e) {
|
function y(e) {
|
||||||
return !g && !r.value && !i.value && m === t.value && p.value.has(e);
|
return !g && !r.value && !i.value && m === t.value && p.value.has(e);
|
||||||
}
|
}
|
||||||
|
// 刷新旧模块电源状态;状态错误独立于权限错误,不把查询失败转为已关机。
|
||||||
async function b() {
|
async function b() {
|
||||||
let r = t.value;
|
let r = t.value;
|
||||||
if (g || m !== r || !N.has(r)) return;
|
if (g || m !== r || !N.has(r)) return;
|
||||||
@@ -687,6 +708,7 @@ function ke(e, t) {
|
|||||||
o() && (l.value = !1);
|
o() && (l.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 先重置旧权限,再读取当前模块配置;已有初始详情可复用,空响应不授予任何操作。
|
||||||
async function x(a) {
|
async function x(a) {
|
||||||
v();
|
v();
|
||||||
let s = t.value;
|
let s = t.value;
|
||||||
@@ -708,6 +730,7 @@ function ke(e, t) {
|
|||||||
l() && (r.value = !1);
|
l() && (r.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 请求前再次检查当前权限与互斥标记,响应后复查模块/代次;切换实例后要求核实操作结果。
|
||||||
async function S(r, i = ``) {
|
async function S(r, i = ``) {
|
||||||
if (!y(r)) throw Error(`当前实例不支持此电源操作或权限尚未加载`);
|
if (!y(r)) throw Error(`当前实例不支持此电源操作或权限尚未加载`);
|
||||||
if (_) throw Error(`电源操作正在提交,请稍候`);
|
if (_) throw Error(`电源操作正在提交,请稍候`);
|
||||||
@@ -1067,6 +1090,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
label: `返回产品列表`,
|
label: `返回产品列表`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// 非统一云详情模块独立读取主机 IP,使用请求序号避免旧响应覆盖。
|
||||||
async function Et() {
|
async function Et() {
|
||||||
if (V.value) return;
|
if (V.value) return;
|
||||||
let e = ++F;
|
let e = ++F;
|
||||||
@@ -1081,6 +1105,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
e === F && (De.value = !1);
|
e === F && (De.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 读取通用主机配置并把同一份响应交给权限控制器,避免两次查询得到不同权限快照。
|
||||||
async function Dt(e = O) {
|
async function Dt(e = O) {
|
||||||
let t = () => !k && e === O;
|
let t = () => !k && e === O;
|
||||||
K.reset();
|
K.reset();
|
||||||
@@ -1100,6 +1125,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
(ye.value = e instanceof Error ? e.message : `主机配置加载失败`);
|
(ye.value = e instanceof Error ? e.message : `主机配置加载失败`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 主机或商品不匹配时清空所有展示与模块信息,废弃旧 IP 请求,防止混合显示不同实例。
|
||||||
function Ot() {
|
function Ot() {
|
||||||
((w.value = null),
|
((w.value = null),
|
||||||
(B.value = ``),
|
(B.value = ``),
|
||||||
@@ -1113,6 +1139,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
(P.value = ``),
|
(P.value = ``),
|
||||||
(De.value = !1));
|
(De.value = !1));
|
||||||
}
|
}
|
||||||
|
// 先严格核对 /host 响应 ID 与商品,再补取实际模块;按模块组合加载详情、IP、配置和电源权限。
|
||||||
async function q() {
|
async function q() {
|
||||||
if (k) return;
|
if (k) return;
|
||||||
let e = ++O,
|
let e = ++O,
|
||||||
@@ -1188,6 +1215,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
t() && ((T.value = !1), (D.value = !1));
|
t() && ((T.value = !1), (D.value = !1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 保存备注时绑定主机对象与加载代次;离页/切换后不把旧备注回填到新实例。
|
||||||
async function kt() {
|
async function kt() {
|
||||||
let e = w.value;
|
let e = w.value;
|
||||||
if (R.value || !e || k) return;
|
if (R.value || !e || k) return;
|
||||||
@@ -1212,27 +1240,32 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
R.value = !1;
|
R.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 打开备注编辑时从最新主机对象复制草稿,提交中不重新打开。
|
||||||
function At() {
|
function At() {
|
||||||
w.value &&
|
w.value &&
|
||||||
!R.value &&
|
!R.value &&
|
||||||
((z.value = ``), (I.value = w.value.notes || ``), (L.value = !0));
|
((z.value = ``), (I.value = w.value.notes || ``), (L.value = !0));
|
||||||
}
|
}
|
||||||
|
// 为当前实例尚未完成的原订单打开支付,使用已有订单而非再次创建。
|
||||||
function jt() {
|
function jt() {
|
||||||
w.value?.order_id &&
|
w.value?.order_id &&
|
||||||
((vt.value = w.value.order_id),
|
((vt.value = w.value.order_id),
|
||||||
(yt.value = String(w.value.first_payment_amount ?? ``)),
|
(yt.value = String(w.value.first_payment_amount ?? ``)),
|
||||||
(Oe.value = !0));
|
(Oe.value = !0));
|
||||||
}
|
}
|
||||||
|
// 续费/升级等子组件返回订单后统一打开支付弹窗。
|
||||||
function Mt(e) {
|
function Mt(e) {
|
||||||
((vt.value = e.order_id),
|
((vt.value = e.order_id),
|
||||||
(yt.value = String(e.amount ?? ``)),
|
(yt.value = String(e.amount ?? ``)),
|
||||||
(Oe.value = !0));
|
(Oe.value = !0));
|
||||||
}
|
}
|
||||||
let Nt = ref(0);
|
let Nt = ref(0);
|
||||||
|
// 操作完成后重载实例并递增刷新键,让需要重新挂载的管理区域同步更新。
|
||||||
async function Pt() {
|
async function Pt() {
|
||||||
(await q(), k || Nt.value++);
|
(await q(), k || Nt.value++);
|
||||||
}
|
}
|
||||||
let J = ref(``);
|
let J = ref(``);
|
||||||
|
// 复制非空字段并短暂标识具体复制项,不在日志中输出连接资料。
|
||||||
async function Ft(e, t) {
|
async function Ft(e, t) {
|
||||||
if (e)
|
if (e)
|
||||||
try {
|
try {
|
||||||
@@ -1294,6 +1327,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
Vt;
|
Vt;
|
||||||
|
// 仅在页面可见、实例 Active、无弹窗且无其他动作时刷新电源状态,避免状态查询与操作冲突。
|
||||||
function Ht() {
|
function Ht() {
|
||||||
k ||
|
k ||
|
||||||
D.value ||
|
D.value ||
|
||||||
@@ -1314,19 +1348,23 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
Gt = !1,
|
Gt = !1,
|
||||||
Kt = ref(``),
|
Kt = ref(``),
|
||||||
qt = ref(``);
|
qt = ref(``);
|
||||||
|
// 成功反馈清除之前的错误;仅提示指令已下发,不保证实例已经进入最终电源状态。
|
||||||
function Jt(e) {
|
function Jt(e) {
|
||||||
((qt.value = ``),
|
((qt.value = ``),
|
||||||
(Kt.value = e),
|
(Kt.value = e),
|
||||||
setTimeout(() => (Kt.value = ``), 4e3));
|
setTimeout(() => (Kt.value = ``), 4e3));
|
||||||
}
|
}
|
||||||
|
// 统一提取操作异常消息,失败与成功提示互斥。
|
||||||
function Yt(e, t) {
|
function Yt(e, t) {
|
||||||
((Kt.value = ``), (qt.value = e instanceof Error ? e.message : t));
|
((Kt.value = ``), (qt.value = e instanceof Error ? e.message : t));
|
||||||
}
|
}
|
||||||
|
// 识别后端 operate_password 标记,决定是否保留确认框要求再次输入操作密码。
|
||||||
function Xt(e) {
|
function Xt(e) {
|
||||||
if (!e || typeof e != `object`) return !1;
|
if (!e || typeof e != `object`) return !1;
|
||||||
let t = e.data;
|
let t = e.data;
|
||||||
return !!t && typeof t == `object` && t.operate_password === 1;
|
return !!t && typeof t == `object` && t.operate_password === 1;
|
||||||
}
|
}
|
||||||
|
// 确认电源动作快照仍匹配当前路由、主机、模块、状态和权限,防止确认期间切换目标。
|
||||||
function Zt(e) {
|
function Zt(e) {
|
||||||
return (
|
return (
|
||||||
!Gt &&
|
!Gt &&
|
||||||
@@ -1340,6 +1378,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
(!G.value || K.can(e.action))
|
(!G.value || K.can(e.action))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 按云/物理/旧模块分流电源动作;创建确认快照时冻结目标实例与动作,最终提交仍再校验。
|
||||||
function Q(e) {
|
function Q(e) {
|
||||||
if (U.value) {
|
if (U.value) {
|
||||||
!T.value &&
|
!T.value &&
|
||||||
@@ -1375,9 +1414,11 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
};
|
};
|
||||||
Zt(t) && ((Z.value = ``), (Ut.value = ``), (X.value = t));
|
Zt(t) && ((Z.value = ``), (Ut.value = ``), (X.value = t));
|
||||||
}
|
}
|
||||||
|
// 无动作执行时关闭确认并清空操作密码。
|
||||||
function Qt() {
|
function Qt() {
|
||||||
Y.value || ((X.value = null), (Z.value = ``), (Ut.value = ``));
|
Y.value || ((X.value = null), (Z.value = ``), (Ut.value = ``));
|
||||||
}
|
}
|
||||||
|
// 路由/实例/模块/状态变化时废弃待确认动作和旧反馈,密码不跨目标复用。
|
||||||
function $t() {
|
function $t() {
|
||||||
((Wt += 1),
|
((Wt += 1),
|
||||||
(X.value = null),
|
(X.value = null),
|
||||||
@@ -1392,6 +1433,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
flush: `sync`,
|
flush: `sync`,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
// 确认提交前后都验证动作快照;后端要求操作密码时留在确认框重试,其他结果关闭并刷新实例。
|
||||||
async function en() {
|
async function en() {
|
||||||
let e = X.value;
|
let e = X.value;
|
||||||
if (!e || Y.value || j.value) return;
|
if (!e || Y.value || j.value) return;
|
||||||
@@ -1427,6 +1469,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
t === Wt && ((Y.value = ``), (Z.value = ``));
|
t === Wt && ((Y.value = ``), (Z.value = ``));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 只有当前模块支持远控且实例 Active 才打开独立远控入口。
|
||||||
function tn() {
|
function tn() {
|
||||||
!D.value &&
|
!D.value &&
|
||||||
H.caps.value.remoteConsole &&
|
H.caps.value.remoteConsole &&
|
||||||
@@ -1435,6 +1478,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
((qt.value = ``), remote_console_t(C, V.value));
|
((qt.value = ``), remote_console_t(C, V.value));
|
||||||
}
|
}
|
||||||
let nn = ref(!1);
|
let nn = ref(!1);
|
||||||
|
// 打开续费弹窗,具体报价和可用周期交给续费组件处理。
|
||||||
function rn() {
|
function rn() {
|
||||||
((qt.value = ``), (nn.value = !0));
|
((qt.value = ``), (nn.value = !0));
|
||||||
}
|
}
|
||||||
@@ -1537,6 +1581,7 @@ var Ae = publicAssetsURL(`/images/reference/cloud-server.png`),
|
|||||||
(Gt = !0),
|
(Gt = !0),
|
||||||
$t());
|
$t());
|
||||||
}),
|
}),
|
||||||
|
// 初始骨架、加载错误与主机详情互斥展示;按实际管理模块挂载专用面板,电源确认/续费/支付弹窗使用冻结目标。
|
||||||
(n, r) => {
|
(n, r) => {
|
||||||
let a = skeleton,
|
let a = skeleton,
|
||||||
s = InstanceLoadingShell,
|
s = InstanceLoadingShell,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 工单详情:把首帖与回复按时间组成对话,支持引用、附件上传、回复、催单与关闭;附件使用服务端保存标识提交。
|
||||||
|
*/
|
||||||
import "~/assets/styles/TicketAttachments.DtbJGLkE.css";
|
import "~/assets/styles/TicketAttachments.DtbJGLkE.css";
|
||||||
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
||||||
import "~/assets/styles/_id_.C-0--Lx-.css";
|
import "~/assets/styles/_id_.C-0--Lx-.css";
|
||||||
@@ -138,6 +141,7 @@ var le = {
|
|||||||
q = ref([]),
|
q = ref([]),
|
||||||
J = ref(!1),
|
J = ref(!1),
|
||||||
Y = ref(0);
|
Y = ref(0);
|
||||||
|
// 读取工单并确认实际存在;后续回复/催单/关闭完成也复用此入口同步服务端状态。
|
||||||
async function X() {
|
async function X() {
|
||||||
try {
|
try {
|
||||||
let e = await z.get(`/ticket/${B}`);
|
let e = await z.get(`/ticket/${B}`);
|
||||||
@@ -177,12 +181,14 @@ var le = {
|
|||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
});
|
});
|
||||||
|
// 按回复发送方显示客服或客户名称,不依赖消息顺序推断身份。
|
||||||
function Q(e) {
|
function Q(e) {
|
||||||
return e.type === `Admin`
|
return e.type === `Admin`
|
||||||
? e.admin_name || `客服`
|
? e.admin_name || `客服`
|
||||||
: e.client_name || `我`;
|
: e.client_name || `我`;
|
||||||
}
|
}
|
||||||
let $ = computed(() => Z.value.find((e) => e.id === Y.value));
|
let $ = computed(() => Z.value.find((e) => e.id === Y.value));
|
||||||
|
// 关闭工单不允许上传;逐个上传并检查 save_name,成功部分保留在当前附件草稿。
|
||||||
async function xe(e) {
|
async function xe(e) {
|
||||||
if (J.value || G.value || V.value?.status === `已关闭`) return;
|
if (J.value || G.value || V.value?.status === `已关闭`) return;
|
||||||
let t = e.target,
|
let t = e.target,
|
||||||
@@ -206,12 +212,15 @@ var le = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 尚未提交回复时可移除本地附件项,不直接删除历史工单附件。
|
||||||
function Se(e) {
|
function Se(e) {
|
||||||
G.value || q.value.splice(e, 1);
|
G.value || q.value.splice(e, 1);
|
||||||
}
|
}
|
||||||
|
// 仅允许引用真实回复 ID;首帖 ID 为 0 不设置为引用目标。
|
||||||
function Ce(e) {
|
function Ce(e) {
|
||||||
e.id > 0 && V.value?.status !== `已关闭` && (Y.value = e.id);
|
e.id > 0 && V.value?.status !== `已关闭` && (Y.value = e.id);
|
||||||
}
|
}
|
||||||
|
// 引用已删除时明确提示;否则优先用服务端引用快照,再从当前对话寻找原文。
|
||||||
function we(e) {
|
function we(e) {
|
||||||
return Number(e.quote_info?.is_deleted) === 1
|
return Number(e.quote_info?.is_deleted) === 1
|
||||||
? `该回复已删除`
|
? `该回复已删除`
|
||||||
@@ -219,6 +228,7 @@ var le = {
|
|||||||
Z.value.find((t) => t.id === e.quote_reply_id)?.content ||
|
Z.value.find((t) => t.id === e.quote_reply_id)?.content ||
|
||||||
`原回复 #${e.quote_reply_id}(内容暂不可用)`;
|
`原回复 #${e.quote_reply_id}(内容暂不可用)`;
|
||||||
}
|
}
|
||||||
|
// 引用发送者优先来自引用快照,缺失时回查当前对话。
|
||||||
function Te(e) {
|
function Te(e) {
|
||||||
let t = e.quote_info,
|
let t = e.quote_info,
|
||||||
n = Z.value.find((t) => t.id === e.quote_reply_id);
|
n = Z.value.find((t) => t.id === e.quote_reply_id);
|
||||||
@@ -229,6 +239,7 @@ var le = {
|
|||||||
(n ? Q(n) : `回复 #${e.quote_reply_id}`)
|
(n ? Q(n) : `回复 #${e.quote_reply_id}`)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 已删除引用不再显示附件;其他引用统一交给附件解析工具处理链接。
|
||||||
function Ee(e) {
|
function Ee(e) {
|
||||||
return Number(e.quote_info?.is_deleted) === 1
|
return Number(e.quote_info?.is_deleted) === 1
|
||||||
? []
|
? []
|
||||||
@@ -238,6 +249,7 @@ var le = {
|
|||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 回复要求内容非空、附件已上传且工单未关闭;成功后清空草稿与引用并重读工单。
|
||||||
async function De() {
|
async function De() {
|
||||||
if (!(
|
if (!(
|
||||||
G.value ||
|
G.value ||
|
||||||
@@ -263,6 +275,7 @@ var le = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 催单后重新读取工单,结果与可继续操作状态以服务端为准。
|
||||||
async function Oe() {
|
async function Oe() {
|
||||||
K.value = !0;
|
K.value = !0;
|
||||||
try {
|
try {
|
||||||
@@ -273,6 +286,7 @@ var le = {
|
|||||||
K.value = !1;
|
K.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 关闭工单完成后重读详情,由新状态控制回复与上传入口。
|
||||||
async function ke() {
|
async function ke() {
|
||||||
K.value = !0;
|
K.value = !0;
|
||||||
try {
|
try {
|
||||||
@@ -285,6 +299,7 @@ var le = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(X),
|
onMounted(X),
|
||||||
|
// 对话按时间展示并使用公共 HTML 清理与附件解析;引用删除有独立文案,关闭工单不再开放回复编辑。
|
||||||
(n, a) => {
|
(n, a) => {
|
||||||
let c = TicketNotice,
|
let c = TicketNotice,
|
||||||
m = NuxtLink,
|
m = NuxtLink,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 创建工单:加载类型/部门及可选实例,上传附件后提交标题、富文本内容和关联实例;选项未就绪或附件仍上传时不提交。
|
||||||
|
*/
|
||||||
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
||||||
import "~/assets/styles/create.gX6gpD00.css";
|
import "~/assets/styles/create.gX6gpD00.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
@@ -113,13 +116,16 @@ var le = {
|
|||||||
G = ref(``),
|
G = ref(``),
|
||||||
K = ref(!1),
|
K = ref(!1),
|
||||||
q = ref(!1);
|
q = ref(!1);
|
||||||
|
// 选择器优先显示主 IP,缺失时显示分配 IP。
|
||||||
function J(e) {
|
function J(e) {
|
||||||
return e.dedicate_ip || e.assign_ip || ``;
|
return e.dedicate_ip || e.assign_ip || ``;
|
||||||
}
|
}
|
||||||
|
// 实例候选文案组合 ID、名称与 IP,方便同名实例区分。
|
||||||
function pe(e) {
|
function pe(e) {
|
||||||
return [`#${e.id}`, e.name, J(e)].filter(Boolean).join(` / `);
|
return [`#${e.id}`, e.name, J(e)].filter(Boolean).join(` / `);
|
||||||
}
|
}
|
||||||
let Y = computed(() => new Map(H.value.map((e) => [e.id, e])));
|
let Y = computed(() => new Map(H.value.map((e) => [e.id, e])));
|
||||||
|
// 已选实例展示产品名与 ID,列表缺失时仍保留其编号。
|
||||||
function me(e) {
|
function me(e) {
|
||||||
let t = Y.value.get(e);
|
let t = Y.value.get(e);
|
||||||
return t
|
return t
|
||||||
@@ -128,6 +134,7 @@ var le = {
|
|||||||
}
|
}
|
||||||
let X = ref([]),
|
let X = ref([]),
|
||||||
Z = ref(!1);
|
Z = ref(!1);
|
||||||
|
// 逐个上传并要求 save_name,上传部分成功的附件仍保留,失败显示具体文件问题。
|
||||||
async function he(e) {
|
async function he(e) {
|
||||||
if (Z.value || W.value) return;
|
if (Z.value || W.value) return;
|
||||||
let t = e.target,
|
let t = e.target,
|
||||||
@@ -151,9 +158,11 @@ var le = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 提交期间锁定附件列表,其余时间可移除本地待提交项。
|
||||||
function ge(e) {
|
function ge(e) {
|
||||||
W.value || X.value.splice(e, 1);
|
W.value || X.value.splice(e, 1);
|
||||||
}
|
}
|
||||||
|
// 类型/部门加载成功后再开放提交;实例可选列表分页读取,最多 100 页,实例查询失败不阻止无关联工单创建。
|
||||||
async function Q() {
|
async function Q() {
|
||||||
if (!K.value) {
|
if (!K.value) {
|
||||||
((K.value = !0), (q.value = !1), (G.value = ``));
|
((K.value = !0), (q.value = !1), (G.value = ``));
|
||||||
@@ -191,6 +200,7 @@ var le = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 标题和内容非空且选项就绪后创建工单,只提交附件保存标识,成功进入返回 ID 的详情。
|
||||||
async function $() {
|
async function $() {
|
||||||
if (!(W.value || Z.value || K.value || !q.value)) {
|
if (!(W.value || Z.value || K.value || !q.value)) {
|
||||||
if (((G.value = ``), !U.title.trim())) {
|
if (((G.value = ``), !U.title.trim())) {
|
||||||
@@ -221,6 +231,7 @@ var le = {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
onMounted(Q),
|
onMounted(Q),
|
||||||
|
// 类型/部门选项就绪且附件上传完成后才可创建;富文本编辑器与本地附件草稿共同组成提交内容。
|
||||||
(n, i) => {
|
(n, i) => {
|
||||||
let s = TicketNotice,
|
let s = TicketNotice,
|
||||||
c = button,
|
c = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 工单列表:状态/类型/关键词分页查询;筛选字典和统计独立请求,部分失败不会把已成功的选项全部丢弃。
|
||||||
|
*/
|
||||||
import "~/assets/styles/tickets.Dz8JrDhQ.css";
|
import "~/assets/styles/tickets.Dz8JrDhQ.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
import { onMounted } from "vue";
|
import { onMounted } from "vue";
|
||||||
@@ -88,6 +91,7 @@ var ie = {
|
|||||||
ticket_type_id: U.value ?? ``,
|
ticket_type_id: U.value ?? ``,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
// 状态和类型使用 allSettled 分别处理,失败项单独汇总提示。
|
||||||
async function Z() {
|
async function Z() {
|
||||||
if (!I.value) {
|
if (!I.value) {
|
||||||
((I.value = !0), (F.value = ``));
|
((I.value = !0), (F.value = ``));
|
||||||
@@ -111,6 +115,7 @@ var ie = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 工单统计独立加载,异常不清空工单主列表。
|
||||||
async function Q() {
|
async function Q() {
|
||||||
if (!R.value) {
|
if (!R.value) {
|
||||||
((R.value = !0), (L.value = ``));
|
((R.value = !0), (L.value = ``));
|
||||||
@@ -152,9 +157,11 @@ var ie = {
|
|||||||
})),
|
})),
|
||||||
]),
|
]),
|
||||||
$ = computed(() => !!B.value || !!H.value || !!U.value);
|
$ = computed(() => !!B.value || !!H.value || !!U.value);
|
||||||
|
// 确认搜索后应用关键词并交由公共分页工具重载。
|
||||||
function ue() {
|
function ue() {
|
||||||
((B.value = z.value.trim()), X());
|
((B.value = z.value.trim()), X());
|
||||||
}
|
}
|
||||||
|
// 清除关键词、状态与工单类型,恢复全部工单。
|
||||||
function de() {
|
function de() {
|
||||||
((z.value = ``),
|
((z.value = ``),
|
||||||
(B.value = ``),
|
(B.value = ``),
|
||||||
@@ -166,6 +173,7 @@ var ie = {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
(Z(), Q());
|
(Z(), Q());
|
||||||
}),
|
}),
|
||||||
|
// 筛选字典、统计提示与工单主列表分开展示,失败选项提供重试,不用空列表掩盖请求错误。
|
||||||
(t, r) => {
|
(t, r) => {
|
||||||
let o = message,
|
let o = message,
|
||||||
f = button,
|
f = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 旧工单详情路由适配层:复用动态工单详情页,详情 ID 由被复用页从路由参数/查询中读取。
|
||||||
|
*/
|
||||||
import "~/assets/styles/TicketAttachments.DtbJGLkE.css";
|
import "~/assets/styles/TicketAttachments.DtbJGLkE.css";
|
||||||
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
import "~/assets/styles/RichTextEditor.NkmgPT5m.css";
|
||||||
import "~/assets/styles/_id_.C-0--Lx-.css";
|
import "~/assets/styles/_id_.C-0--Lx-.css";
|
||||||
@@ -9,6 +12,7 @@ import _id_ from "~/pages/tickets/[id].vue";
|
|||||||
var i = defineComponent({
|
var i = defineComponent({
|
||||||
__name: `ticket`,
|
__name: `ticket`,
|
||||||
setup(t) {
|
setup(t) {
|
||||||
|
// 旧路径只挂载动态详情页,不维护额外工单状态。
|
||||||
return (t, i) => (openBlock(), createBlock(_id_));
|
return (t, i) => (openBlock(), createBlock(_id_));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 实例转移:可转移、待接收和记录各自走服务端列表;发起前验证接收人转移码,敏感请求可由安全挑战续接,手续费订单独立支付。
|
||||||
|
*/
|
||||||
import "~/assets/styles/GeetestField.DiieTibK.css";
|
import "~/assets/styles/GeetestField.DiieTibK.css";
|
||||||
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
import "~/assets/styles/CaptchaField.BSN3ZbsD.css";
|
||||||
import "~/assets/styles/SecurityVerificationDialog.skYFo4v7.css";
|
import "~/assets/styles/SecurityVerificationDialog.skYFo4v7.css";
|
||||||
@@ -215,6 +218,7 @@ var xe = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((I = !0), F++, Y(), (q.value = null));
|
((I = !0), F++, Y(), (q.value = null));
|
||||||
});
|
});
|
||||||
|
// 并行读取转移规则与本账户转移码;失败时不继续假定规则已就绪。
|
||||||
async function it() {
|
async function it() {
|
||||||
N.value = ``;
|
N.value = ``;
|
||||||
try {
|
try {
|
||||||
@@ -229,6 +233,7 @@ var xe = {
|
|||||||
(N.value = e instanceof Error ? e.message : `加载转移设置失败`);
|
(N.value = e instanceof Error ? e.message : `加载转移设置失败`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 按当前标签、分页和关键词读取列表,类型筛选只用于历史记录;旧代次不回写。
|
||||||
async function L() {
|
async function L() {
|
||||||
let e = ++F,
|
let e = ++F,
|
||||||
t = x.value,
|
t = x.value,
|
||||||
@@ -258,6 +263,7 @@ var xe = {
|
|||||||
e === F && (E.value = !1);
|
e === F && (E.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 切换标签时重置页码与筛选,避免将记录条件带入可转移列表。
|
||||||
function at(e) {
|
function at(e) {
|
||||||
e !== void 0 &&
|
e !== void 0 &&
|
||||||
((x.value = e),
|
((x.value = e),
|
||||||
@@ -266,12 +272,15 @@ var xe = {
|
|||||||
(C.value = null),
|
(C.value = null),
|
||||||
L());
|
L());
|
||||||
}
|
}
|
||||||
|
// 筛选变化时回到第一页再加载。
|
||||||
function R() {
|
function R() {
|
||||||
((D.value = 1), L());
|
((D.value = 1), L());
|
||||||
}
|
}
|
||||||
|
// 将分页器零基页码转换为服务端一基页码。
|
||||||
function ot(e) {
|
function ot(e) {
|
||||||
((D.value = e.page + 1), (O.value = e.rows), L());
|
((D.value = e.page + 1), (O.value = e.rows), L());
|
||||||
}
|
}
|
||||||
|
// 复制本账户接收转移码,反馈仅用于界面,不改变转移状态。
|
||||||
async function st() {
|
async function st() {
|
||||||
try {
|
try {
|
||||||
(await navigator.clipboard.writeText(A.value),
|
(await navigator.clipboard.writeText(A.value),
|
||||||
@@ -279,6 +288,7 @@ var xe = {
|
|||||||
setTimeout(() => (j.value = !1), 2e3));
|
setTimeout(() => (j.value = !1), 2e3));
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
// 把秒级限制时长转换为小时或天,不把它当作绝对到期时间。
|
||||||
function ct(e) {
|
function ct(e) {
|
||||||
if (!e || e <= 0) return `—`;
|
if (!e || e <= 0) return `—`;
|
||||||
let t = 86400;
|
let t = 86400;
|
||||||
@@ -301,6 +311,7 @@ var xe = {
|
|||||||
lt = ref({}),
|
lt = ref({}),
|
||||||
q = ref(null),
|
q = ref(null),
|
||||||
J = 0;
|
J = 0;
|
||||||
|
// 转移码或确认码变化时立即废弃旧的接收人验证;非提交期间同时清除待续交安全请求。
|
||||||
function Y() {
|
function Y() {
|
||||||
(J++,
|
(J++,
|
||||||
(U.value = null),
|
(U.value = null),
|
||||||
@@ -332,6 +343,7 @@ var xe = {
|
|||||||
!W.value &&
|
!W.value &&
|
||||||
!G.value),
|
!G.value),
|
||||||
);
|
);
|
||||||
|
// 新发起转移前清空上一次接收码、免责声明与校验结果。
|
||||||
function dt(e) {
|
function dt(e) {
|
||||||
G.value ||
|
G.value ||
|
||||||
K.value ||
|
K.value ||
|
||||||
@@ -345,9 +357,11 @@ var xe = {
|
|||||||
(M.value = ``),
|
(M.value = ``),
|
||||||
(z.value = !0));
|
(z.value = !0));
|
||||||
}
|
}
|
||||||
|
// 打开待接收记录的处理模式,与发起转移草稿区分。
|
||||||
function ft(e) {
|
function ft(e) {
|
||||||
((V.value = e), (B.value = `handle`), (M.value = ``), (z.value = !0));
|
((V.value = e), (B.value = `handle`), (M.value = ``), (z.value = !0));
|
||||||
}
|
}
|
||||||
|
// 只有两次转移码一致才查找用户;结果绑定提交时的码及请求代次,修改后不能复用。
|
||||||
async function pt() {
|
async function pt() {
|
||||||
if (
|
if (
|
||||||
W.value ||
|
W.value ||
|
||||||
@@ -389,6 +403,7 @@ var xe = {
|
|||||||
let X = ref(!1),
|
let X = ref(!1),
|
||||||
mt = ref(null),
|
mt = ref(null),
|
||||||
Z = ref(``);
|
Z = ref(``);
|
||||||
|
// 通过规则、免责声明与接收人校验后冻结 host_id/transfer_code,再提交敏感操作。
|
||||||
async function ht() {
|
async function ht() {
|
||||||
V.value &&
|
V.value &&
|
||||||
B.value === `start` &&
|
B.value === `start` &&
|
||||||
@@ -401,6 +416,7 @@ var xe = {
|
|||||||
}),
|
}),
|
||||||
await gt());
|
await gt());
|
||||||
}
|
}
|
||||||
|
// 携带冻结的转移请求和安全验证结果续交;确认安全流程完成后刷新列表,返回手续费订单时打开支付。
|
||||||
async function gt(e) {
|
async function gt(e) {
|
||||||
if (!q.value || G.value || I) return;
|
if (!q.value || G.value || I) return;
|
||||||
let t = {
|
let t = {
|
||||||
@@ -435,6 +451,7 @@ var xe = {
|
|||||||
G.value = !1;
|
G.value = !1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 对待接收记录执行接受或退回,成功后关闭弹窗并从服务端刷新。
|
||||||
async function _t(e) {
|
async function _t(e) {
|
||||||
if (V.value && !G.value) {
|
if (V.value && !G.value) {
|
||||||
((G.value = !0), (M.value = ``));
|
((G.value = !0), (M.value = ``));
|
||||||
@@ -453,9 +470,11 @@ var xe = {
|
|||||||
}
|
}
|
||||||
let Q = ref(!1),
|
let Q = ref(!1),
|
||||||
$ = ref(null);
|
$ = ref(null);
|
||||||
|
// 取消前保存目标记录并打开确认,尚未发起取消请求。
|
||||||
function vt(e) {
|
function vt(e) {
|
||||||
(($.value = e), (M.value = ``), (Q.value = !0));
|
(($.value = e), (M.value = ``), (Q.value = !0));
|
||||||
}
|
}
|
||||||
|
// 确认取消当前记录,成功后刷新列表,不直接在本地改成完成状态。
|
||||||
async function yt() {
|
async function yt() {
|
||||||
if ($.value && !G.value) {
|
if ($.value && !G.value) {
|
||||||
G.value = !0;
|
G.value = !0;
|
||||||
@@ -472,6 +491,7 @@ var xe = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 只有有效正整数手续费订单 ID 才能继续支付,缺少订单时提示刷新核实。
|
||||||
function bt(e) {
|
function bt(e) {
|
||||||
if (
|
if (
|
||||||
!Number.isSafeInteger(Number(e.order_id)) ||
|
!Number.isSafeInteger(Number(e.order_id)) ||
|
||||||
@@ -488,6 +508,7 @@ var xe = {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
(it(), L());
|
(it(), L());
|
||||||
}),
|
}),
|
||||||
|
// 三类列表共用分页但操作目标分开保存;转移码校验、安全验证与手续费支付为不同阶段。
|
||||||
(t, r) => {
|
(t, r) => {
|
||||||
let i = ListSegments,
|
let i = ListSegments,
|
||||||
o = button,
|
o = button,
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* 代金券:领券中心与我的券分别分页、缓存加载状态及错误;当前时间用于有效期展示,领取后刷新两侧列表,最终订单可用性由后端确认。
|
||||||
|
*/
|
||||||
import "~/assets/styles/vouchers.5FV4ozrh.css";
|
import "~/assets/styles/vouchers.5FV4ozrh.css";
|
||||||
import { toDisplayString } from "vue";
|
import { toDisplayString } from "vue";
|
||||||
import { renderList } from "vue";
|
import { renderList } from "vue";
|
||||||
@@ -147,6 +150,7 @@ var he = {
|
|||||||
K = computed(() => (x.value === `mine` ? N.value : D.value)),
|
K = computed(() => (x.value === `mine` ? N.value : D.value)),
|
||||||
ze = computed(() => (x.value === `mine` ? A.value : w.value)),
|
ze = computed(() => (x.value === `mine` ? A.value : w.value)),
|
||||||
Be = computed(() => (x.value === `mine` ? j.value : T.value));
|
Be = computed(() => (x.value === `mine` ? j.value : T.value));
|
||||||
|
// 加载领券中心当前页,用已领取 ID 集合补齐界面标记;旧响应或离页结果不写回。
|
||||||
async function q() {
|
async function q() {
|
||||||
let e = ++B;
|
let e = ++B;
|
||||||
((E.value = !0), (D.value = ``));
|
((E.value = !0), (D.value = ``));
|
||||||
@@ -174,6 +178,7 @@ var he = {
|
|||||||
!H && e === B && (E.value = !1);
|
!H && e === B && (E.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 我的代金券使用独立请求序号,不能被领券中心响应覆盖。
|
||||||
async function J() {
|
async function J() {
|
||||||
let e = ++V;
|
let e = ++V;
|
||||||
((M.value = !0), (N.value = ``));
|
((M.value = !0), (N.value = ``));
|
||||||
@@ -194,24 +199,30 @@ var he = {
|
|||||||
!H && e === V && (M.value = !1);
|
!H && e === V && (M.value = !1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 归一化布尔/数字/字符串的开关标记。
|
||||||
function Y(e) {
|
function Y(e) {
|
||||||
return e === !0 || e === 1 || e === `1`;
|
return e === !0 || e === 1 || e === `1`;
|
||||||
}
|
}
|
||||||
|
// 领取状态同时参考服务端标记与本页成功领取记录,避免刷新间隙允许重复领取。
|
||||||
function X(e) {
|
function X(e) {
|
||||||
return Y(e.is_get) || R.value.includes(e.id);
|
return Y(e.is_get) || R.value.includes(e.id);
|
||||||
}
|
}
|
||||||
|
// 显式 expired 状态或已到结束时间都视为过期。
|
||||||
function Z(e) {
|
function Z(e) {
|
||||||
return (
|
return (
|
||||||
e.status === `expired` ||
|
e.status === `expired` ||
|
||||||
(Number(e.end_time) > 0 && Number(e.end_time) <= z.value)
|
(Number(e.end_time) > 0 && Number(e.end_time) <= z.value)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 判断是否尚未到使用开始时间,不与领取资格混为一谈。
|
||||||
function Ve(e) {
|
function Ve(e) {
|
||||||
return Number(e.start_time) > z.value;
|
return Number(e.start_time) > z.value;
|
||||||
}
|
}
|
||||||
|
// 领取入口只排除已领取和过期;是否满足额外业务资格仍由服务端决定。
|
||||||
function Q(e) {
|
function Q(e) {
|
||||||
return !X(e) && !Z(e);
|
return !X(e) && !Z(e);
|
||||||
}
|
}
|
||||||
|
// 展示状态区分领券中心与我的券,已使用/过期/未开始各有独立文案。
|
||||||
function $(e) {
|
function $(e) {
|
||||||
return x.value === `available`
|
return x.value === `available`
|
||||||
? X(e)
|
? X(e)
|
||||||
@@ -253,9 +264,11 @@ var he = {
|
|||||||
severity: `secondary`,
|
severity: `secondary`,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// 本页只在 normal 状态且处于有效期内展示可使用入口,订单仍需重新校验券资格。
|
||||||
function He(e) {
|
function He(e) {
|
||||||
return e.status === `normal` && !Z(e) && !Ve(e);
|
return e.status === `normal` && !Z(e) && !Ve(e);
|
||||||
}
|
}
|
||||||
|
// 金额只有在非空、有限且非负时才格式化,无效值显示占位而不是零元。
|
||||||
function Ue(e) {
|
function Ue(e) {
|
||||||
let t = Number(e);
|
let t = Number(e);
|
||||||
return e != null &&
|
return e != null &&
|
||||||
@@ -267,6 +280,7 @@ var he = {
|
|||||||
})
|
})
|
||||||
: `—`;
|
: `—`;
|
||||||
}
|
}
|
||||||
|
// 缺失使用门槛时明确以订单为准,不把未知条件显示成无门槛。
|
||||||
function We(e) {
|
function We(e) {
|
||||||
let t = Number(e.min_price);
|
let t = Number(e.min_price);
|
||||||
return !Number.isFinite(t) ||
|
return !Number.isFinite(t) ||
|
||||||
@@ -278,6 +292,7 @@ var he = {
|
|||||||
? `满 ¥${Ue(t)} 可用`
|
? `满 ¥${Ue(t)} 可用`
|
||||||
: `无金额门槛`;
|
: `无金额门槛`;
|
||||||
}
|
}
|
||||||
|
// 根据存在的起止时间组成有效期文字,零值表示没有该边界。
|
||||||
function Ge(e) {
|
function Ge(e) {
|
||||||
let t = Number(e.start_time) > 0 ? dict_r(e.start_time) : ``,
|
let t = Number(e.start_time) > 0 ? dict_r(e.start_time) : ``,
|
||||||
n = Number(e.end_time) > 0 ? dict_r(e.end_time) : ``;
|
n = Number(e.end_time) > 0 ? dict_r(e.end_time) : ``;
|
||||||
@@ -289,6 +304,7 @@ var he = {
|
|||||||
? `${t} 起,长期有效`
|
? `${t} 起,长期有效`
|
||||||
: `长期有效`;
|
: `长期有效`;
|
||||||
}
|
}
|
||||||
|
// 能解析产品名称时逐一显示,否则只展示限制数量,不把内部商品 ID 当商品名。
|
||||||
function Ke(e) {
|
function Ke(e) {
|
||||||
if (!e.product?.length) return `全场产品通用`;
|
if (!e.product?.length) return `全场产品通用`;
|
||||||
let t = e.product.flatMap((e) =>
|
let t = e.product.flatMap((e) =>
|
||||||
@@ -302,6 +318,7 @@ var he = {
|
|||||||
? t.join(`、`)
|
? t.join(`、`)
|
||||||
: `限指定 ${e.product.length} 款产品,以付款时可用代金券为准`;
|
: `限指定 ${e.product.length} 款产品,以付款时可用代金券为准`;
|
||||||
}
|
}
|
||||||
|
// 列出新购、续费和升降级的允许标记,保留既有新购缺省允许契约。
|
||||||
function qe(e) {
|
function qe(e) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -318,6 +335,7 @@ var he = {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
// 领取成功先记录本地防重标记,再从第一页刷新我的券与领券中心;不在本页自动抵扣订单。
|
||||||
async function Je(e) {
|
async function Je(e) {
|
||||||
if (!(H || F.value || !Q(e))) {
|
if (!(H || F.value || !Q(e))) {
|
||||||
((F.value = e.id), (I.value = ``), (L.value = ``));
|
((F.value = e.id), (I.value = ``), (L.value = ``));
|
||||||
@@ -351,6 +369,7 @@ var he = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 切换标签刷新当前时间,尚未加载过的列表才惰性加载,保留各自分页。
|
||||||
function Ye(e) {
|
function Ye(e) {
|
||||||
((x.value = e === `available` ? `available` : `mine`),
|
((x.value = e === `available` ? `available` : `mine`),
|
||||||
(z.value = Math.floor(Date.now() / 1e3)),
|
(z.value = Math.floor(Date.now() / 1e3)),
|
||||||
@@ -358,12 +377,14 @@ var he = {
|
|||||||
? !P.value && !M.value && J()
|
? !P.value && !M.value && J()
|
||||||
: !O.value && !E.value && q());
|
: !O.value && !E.value && q());
|
||||||
}
|
}
|
||||||
|
// 手动刷新当前标签列表前同步时间,避免沿用旧的有效期展示。
|
||||||
function Xe() {
|
function Xe() {
|
||||||
return (
|
return (
|
||||||
(z.value = Math.floor(Date.now() / 1e3)),
|
(z.value = Math.floor(Date.now() / 1e3)),
|
||||||
x.value === `mine` ? J() : q()
|
x.value === `mine` ? J() : q()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// 分页事件只更新当前标签对应的页码和每页条数。
|
||||||
function Ze(e) {
|
function Ze(e) {
|
||||||
x.value === `mine`
|
x.value === `mine`
|
||||||
? ((A.value = e.page + 1), (j.value = e.rows), J())
|
? ((A.value = e.page + 1), (j.value = e.rows), J())
|
||||||
@@ -379,6 +400,7 @@ var he = {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
((H = !0), (B += 1), (V += 1), U && clearInterval(U));
|
((H = !0), (B += 1), (V += 1), U && clearInterval(U));
|
||||||
}),
|
}),
|
||||||
|
// 根据当前标签选择列表、分页与错误,状态文案区分未开始/过期/已用,实际抵扣留待订单支付校验。
|
||||||
(n, i) => {
|
(n, i) => {
|
||||||
let o = button,
|
let o = button,
|
||||||
l = message,
|
l = message,
|
||||||
|
|||||||
Reference in new issue
Block a user