全局中文化

This commit is contained in:
Cheng Zhou
2026-01-12 11:14:04 +08:00
parent 9021c7fe2b
commit 1338fa7e2b
103 changed files with 2443 additions and 1533 deletions
+32 -33
View File
@@ -3,44 +3,44 @@
<el-card v-loading="loading">
<div class="content">
<div class="question-header">
<div class="question-label">问题描述</div>
<div class="question-label">{{ TEXT.modules.knowledgeMedicalConsult.questionDesc }}</div>
<div class="question-actions">
<el-button v-if="canEditQuestion" type="primary" size="small" class="edit-btn" @click="openEdit">
编辑问题
{{ TEXT.modules.knowledgeMedicalConsult.editQuestion }}
</el-button>
<el-button v-if="canConfirmResolved" type="success" size="small" @click="confirmResolved">
确认解决
{{ TEXT.modules.knowledgeMedicalConsult.confirmResolved }}
</el-button>
</div>
</div>
<div class="question-meta">
<span class="meta-pill meta-user"
>提问人{{ displayUser(item?.created_by, { members: memberMap, users: userMap }) }}</span
>{{ TEXT.modules.knowledgeMedicalConsult.asker }}{{ displayUser(item?.created_by, { members: memberMap, users: userMap }) }}</span
>
<span class="meta-pill meta-time">提问时间{{ displayDateTime(item?.created_at) }}</span>
<span class="meta-pill meta-category">分类{{ categoryName }}</span>
<span class="meta-pill meta-status">状态{{ statusLabel }}</span>
<span class="meta-pill meta-time">{{ TEXT.modules.knowledgeMedicalConsult.askedAt }}{{ displayDateTime(item?.created_at) }}</span>
<span class="meta-pill meta-category">{{ TEXT.common.labels.category }}{{ categoryName }}</span>
<span class="meta-pill meta-status">{{ TEXT.common.fields.status }}{{ statusLabel }}</span>
</div>
<pre class="question-text">{{ item?.question }}</pre>
</div>
<div v-if="bestReply" class="best-answer">
<div class="best-title">
<span>最佳答案</span>
<el-tag type="success" size="small">已采纳</el-tag>
<span>{{ TEXT.modules.knowledgeMedicalConsult.bestAnswer }}</span>
<el-tag type="success" size="small">{{ TEXT.modules.knowledgeMedicalConsult.adopted }}</el-tag>
</div>
<div class="best-meta">
{{ displayUser(bestReply.created_by, { members: memberMap, users: userMap }) }}
· {{ displayDateTime(bestReply.created_at) }}
</div>
<div class="best-content">{{ bestReply.is_deleted ? "回复已删除" : bestReply.content }}</div>
<div class="best-content">{{ bestReply.is_deleted ? TEXT.modules.knowledgeMedicalConsult.replyDeleted : bestReply.content }}</div>
</div>
</el-card>
<el-card class="mt-12" v-loading="repliesLoading">
<template #header>
<div class="reply-header">
<span>回复</span>
<span class="reply-count"> {{ replies.length }} </span>
<span>{{ TEXT.modules.knowledgeMedicalConsult.replies }}</span>
<span class="reply-count">{{ TEXT.modules.knowledgeMedicalConsult.replyCount.replace("{count}", String(replies.length)) }}</span>
</div>
</template>
<div v-if="canReply" class="reply-form">
@@ -56,7 +56,7 @@
@clear-quote="clearQuote"
/>
</div>
<div v-else class="reply-disabled">当前角色无权限回复</div>
<div v-else class="reply-disabled">{{ TEXT.modules.knowledgeMedicalConsult.noReplyPermission }}</div>
<el-divider v-if="replies.length" />
<ThreadList
v-if="replies.length"
@@ -71,13 +71,13 @@
@delete="removeReply"
>
<template #actions="{ item: r }">
<el-tag v-if="item?.best_reply_id === r.id" type="success" size="small">最佳答案</el-tag>
<el-tag v-if="item?.best_reply_id === r.id" type="success" size="small">{{ TEXT.modules.knowledgeMedicalConsult.bestAnswer }}</el-tag>
<el-button v-if="canSelectBest && !r.is_deleted" type="text" size="small" @click="toggleBest(r)">
{{ item?.best_reply_id === r.id ? "取消最佳" : "设为最佳" }}
{{ item?.best_reply_id === r.id ? TEXT.modules.knowledgeMedicalConsult.cancelBest : TEXT.modules.knowledgeMedicalConsult.setBest }}
</el-button>
</template>
</ThreadList>
<div v-else class="reply-empty">暂无回复</div>
<div v-else class="reply-empty">{{ TEXT.modules.knowledgeMedicalConsult.emptyReplies }}</div>
</el-card>
<FaqItemForm
@@ -111,6 +111,7 @@ import { usePermission } from "../utils/permission";
import FaqItemForm from "../components/FaqItemForm.vue";
import ThreadComposer from "../components/ThreadComposer.vue";
import ThreadList from "../components/ThreadList.vue";
import { TEXT } from "../locales";
const route = useRoute();
const auth = useAuthStore();
@@ -163,9 +164,7 @@ const canConfirmResolved = computed(() => {
});
const statusLabel = computed(() => {
if (item.value?.status === "RESOLVED") return "已解决";
if (item.value?.status === "PROCESSING") return "处理中";
return "待回答";
return TEXT.enums.faqStatus[item.value?.status as keyof typeof TEXT.enums.faqStatus] || TEXT.enums.faqStatus.PENDING;
});
const bestReply = computed(() => {
@@ -227,7 +226,7 @@ const loadReplies = async () => {
replies.value = Array.isArray(data) ? data : data.items || [];
await loadReplyAttachments();
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "回复加载失败");
ElMessage.error(e?.response?.data?.message || TEXT.modules.knowledgeMedicalConsult.replyLoadFailed);
} finally {
repliesLoading.value = false;
}
@@ -247,7 +246,7 @@ const loadData = async () => {
categories.value = catData.items || catData || [];
await Promise.all([loadReplies(), loadMembers(faqData.study_id)]);
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "加载失败");
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.loadFailed);
} finally {
loading.value = false;
}
@@ -263,7 +262,7 @@ const clearQuote = () => {
const submitReply = async () => {
if (!replyContent.value.trim()) {
ElMessage.warning("请输入回复内容");
ElMessage.warning(TEXT.modules.knowledgeMedicalConsult.replyRequired);
return;
}
if (!item.value) return;
@@ -281,16 +280,16 @@ const submitReply = async () => {
await uploadAttachment(item.value.study_id, "faq_replies", created.id, file.raw as File);
}
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "附件上传失败");
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.uploadFailed);
}
}
ElMessage.success("回复已提交");
ElMessage.success(TEXT.modules.knowledgeMedicalConsult.replySubmitted);
replyContent.value = "";
quoteReply.value = null;
replyFiles.value = [];
loadReplies();
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "回复失败");
ElMessage.error(e?.response?.data?.message || TEXT.modules.knowledgeMedicalConsult.replyFailed);
} finally {
submitting.value = false;
}
@@ -298,14 +297,14 @@ const submitReply = async () => {
const removeReply = async (reply: any) => {
if (!item.value) return;
const ok = await ElMessageBox.confirm("确认删除该回复?", "提示").catch(() => null);
const ok = await ElMessageBox.confirm(TEXT.common.confirm.delete, TEXT.common.labels.tips).catch(() => null);
if (!ok) return;
try {
await deleteFaqReply(item.value.id, reply.id);
ElMessage.success("回复已删除");
ElMessage.success(TEXT.common.messages.deleteSuccess);
loadReplies();
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "删除失败");
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.deleteFailed);
}
};
@@ -314,14 +313,14 @@ const toggleBest = async (reply: any) => {
try {
const target = item.value.best_reply_id === reply.id ? null : reply.id;
if (target) {
const ok = await ElMessageBox.confirm("设为最佳答案并确认已解决?", "提示").catch(() => null);
const ok = await ElMessageBox.confirm(TEXT.modules.knowledgeMedicalConsult.confirmBestReply, TEXT.common.labels.tips).catch(() => null);
if (!ok) return;
}
const { data } = await setFaqBestReply(item.value.id, { best_reply_id: target });
item.value = data;
ElMessage.success(target ? "已设为最佳答案" : "已取消最佳答案");
ElMessage.success(target ? TEXT.modules.knowledgeMedicalConsult.bestReplySet : TEXT.modules.knowledgeMedicalConsult.bestReplyCleared);
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "操作失败");
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.actionFailed);
}
};
@@ -330,9 +329,9 @@ const confirmResolved = async () => {
try {
const { data } = await setFaqStatus(item.value.id, { status: "RESOLVED" });
item.value = data;
ElMessage.success("已设置为已解决");
ElMessage.success(TEXT.modules.knowledgeMedicalConsult.resolvedSuccess);
} catch (e: any) {
ElMessage.error(e?.response?.data?.message || "操作失败");
ElMessage.error(e?.response?.data?.message || TEXT.common.messages.actionFailed);
}
};