修复:将页面异步副作用绑定到当前归属

This commit is contained in:
cieanyau committed 2026-11-07 04:00:10 +08:00
1 parent b3a66d97c8
commit eca3aa8fe5
6 files changed
+623 -90

No files matched your search

+45 -24
View File
@@ -12,6 +12,7 @@ definePageMeta({
import { toDisplayString } from "vue";
import { renderList } from "vue";
import { onMounted } from "vue";
import { onScopeDispose } from "vue";
import { normalizeClass } from "vue";
import { createBlock } from "vue";
import { ref } from "vue";
@@ -30,7 +31,7 @@ import { openBlock } from "vue";
import { normalizeStyle } from "vue";
import { useRoute } from "#app";
import { NuxtLink } from "#components";
import { useApi } from "~/lib/auth.js";
import { useApi, useAuth } from "~/lib/auth.js";
import button from "openvue/button";
import { t as _plugin_vue_export_helper_t } from "~/lib/_plugin-vue_export-helper.js";
import message from "openvue/message";
@@ -124,6 +125,12 @@ var le = {
defineComponent({
__name: `[id]`,
setup(m) {
const session = useAuth().prepareLogin();
let disposed = false;
const isCurrent = () => !disposed && session.isCurrent();
onScopeDispose(() => {
disposed = true;
});
let y = useRoute(),
z = useApi(),
B = String(y.params.id ?? y.query.id ?? ``);
@@ -143,17 +150,20 @@ var le = {
const canOperate = computed(() => V.value?.can_operate === 1);
// 读取工单并确认实际存在;后续回复/催单/关闭完成也复用此入口同步服务端状态。
async function X() {
if (!isCurrent()) return;
try {
let e = await z.get(`/ticket/${B}`);
if (!isCurrent()) return;
if (!e.ticket || !e.ticket.id) {
U.value = `工单不存在或已删除`;
return;
}
V.value = e.ticket;
} catch (e) {
U.value = e instanceof Error ? e.message : `加载失败`;
if (isCurrent())
U.value = e instanceof Error ? e.message : `加载失败`;
} finally {
H.value = !1;
if (isCurrent()) H.value = !1;
}
}
let Z = computed(() => {
@@ -192,15 +202,16 @@ var le = {
);
// 工单允许操作时逐个上传并检查 save_name,成功部分保留在当前附件草稿。
async function xe(e) {
if (J.value || G.value || !canOperate.value) return;
if (!isCurrent() || J.value || G.value || !canOperate.value) return;
let t = e.target,
n = Array.from(t.files ?? []);
if (n.length) {
((J.value = !0), (U.value = ``));
try {
for (let e of n) {
if (!isCurrent() || !canOperate.value) return;
let t = await z.upload(e);
if (!canOperate.value) return;
if (!isCurrent() || !canOperate.value) return;
if (!t?.save_name)
throw Error(`附件「${e.name}」上传失败,请重新选择文件`);
q.value.push({
@@ -209,9 +220,10 @@ var le = {
});
}
} catch (e) {
U.value = e instanceof Error ? e.message : `附件上传失败`;
if (isCurrent())
U.value = e instanceof Error ? e.message : `附件上传失败`;
} finally {
((J.value = !1), (t.value = ``));
if (isCurrent()) ((J.value = !1), (t.value = ``));
}
}
}
@@ -254,47 +266,56 @@ var le = {
}
// 回复要求内容非空、附件已上传且服务端允许操作;成功后清空草稿与引用并重读工单。
async function De() {
if (!(G.value || !W.value.trim() || J.value || !canOperate.value)) {
if (
isCurrent() &&
!(G.value || !W.value.trim() || J.value || !canOperate.value)
) {
G.value = !0;
try {
(await z.post(`/ticket/${B}/reply`, {
await z.post(`/ticket/${B}/reply`, {
content: W.value.trim(),
attachment: q.value.map((e) => e.save_name),
quote_reply_id: Y.value,
}),
(W.value = ``),
(q.value = []),
(Y.value = 0),
await X());
});
if (!isCurrent()) return;
W.value = ``;
q.value = [];
Y.value = 0;
await X();
} catch (e) {
U.value = e instanceof Error ? e.message : `回复失败`;
if (isCurrent())
U.value = e instanceof Error ? e.message : `回复失败`;
} finally {
G.value = !1;
if (isCurrent()) G.value = !1;
}
}
}
// 催单后重新读取工单,结果与可继续操作状态以服务端为准。
async function Oe() {
if (!canOperate.value) return;
if (!isCurrent() || !canOperate.value) return;
K.value = !0;
try {
(await z.put(`/ticket/${B}/urge`), await X());
await z.put(`/ticket/${B}/urge`);
if (isCurrent()) await X();
} catch (e) {
U.value = e instanceof Error ? e.message : `催单失败`;
if (isCurrent())
U.value = e instanceof Error ? e.message : `催单失败`;
} finally {
K.value = !1;
if (isCurrent()) K.value = !1;
}
}
// 关闭工单完成后重读详情,由服务端权限控制回复与上传入口。
async function ke() {
if (!canOperate.value) return;
if (!isCurrent() || !canOperate.value) return;
K.value = !0;
try {
(await z.put(`/ticket/${B}/close`), await X());
await z.put(`/ticket/${B}/close`);
if (isCurrent()) await X();
} catch (e) {
U.value = e instanceof Error ? e.message : `关闭失败`;
if (isCurrent())
U.value = e instanceof Error ? e.message : `关闭失败`;
} finally {
K.value = !1;
if (isCurrent()) K.value = !1;
}
}
return (