Files
workspace/code/fms/fms-vue/src/views/module-management/components/I18nQuickSetModal.vue
T
2026-07-24 17:34:26 +08:00

122 lines
3.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { ref } from "vue";
import { message } from "antdv-next";
import { loadDataApi, saveObjectApi } from "@/services/api";
// 快速设置多语言弹窗:按 key 加载 b_i18n 各语言值,保存后 emit("saved", key)。
// 调用方通过 ref 调用 open(key, defaultValue),defaultValue 用于默认语言的初始值。
const emit = defineEmits(["saved"]);
const visible = ref(false);
const saving = ref(false);
const i18nKey = ref("");
const entries = ref([]);
const langTypes = ref([]);
async function loadLangTypes() {
try {
const res = await loadDataApi("b_i18n_type", "b_canuse = 1", "b_xh ASC, b_id ASC");
langTypes.value = res.data || [];
} catch (e) {
message.error("加载语言类型失败:" + (e.message || e));
}
}
async function open(key, defaultValue = "") {
if (!key) {
message.warning("多语言键为空");
return;
}
i18nKey.value = key;
const escaped = key.replace(/'/g, "''");
try {
const [i18nRes] = await Promise.all([
loadDataApi("b_i18n", `b_key = '${escaped}'`, "b_locale ASC"),
loadLangTypes(),
]);
const rows = i18nRes.data || [];
const byLocale = Object.fromEntries(rows.map((r) => [r.b_locale, r]));
entries.value = langTypes.value.map((t) => {
const ex = byLocale[t.b_code];
const isDefault = t.b_default === 1 || t.b_code === "zh-CN";
return {
b_id: ex ? ex.b_id : null,
b_locale: t.b_code,
b_name: t.b_name,
b_value: ex ? ex.b_value : isDefault ? defaultValue : "",
};
});
} catch {
entries.value = [];
}
visible.value = true;
}
async function save() {
if (!i18nKey.value) {
message.warning("请填写多语言键");
return;
}
saving.value = true;
try {
const req = { table: "b_i18n", key_field: "b_id", inserts: [], updates: [] };
for (const e of entries.value) {
const value = e.b_value ?? "";
if (!e.b_id && !value) continue;
const row = { b_key: i18nKey.value, b_locale: e.b_locale, b_value: value };
if (e.b_id) req.updates.push({ ...row, b_id: e.b_id });
else req.inserts.push(row);
}
if (req.inserts.length || req.updates.length) {
await saveObjectApi([req]);
}
message.success("多语言已保存");
visible.value = false;
emit("saved", i18nKey.value);
} catch (err) {
message.error("保存失败:" + (err?.message || err));
} finally {
saving.value = false;
}
}
defineExpose({ open });
</script>
<template>
<a-modal v-model:open="visible" title="快速设置多语言" :confirm-loading="saving" @ok="save">
<a-form layout="vertical">
<a-form-item label="多语言键">
<a-input v-model:value="i18nKey" disabled />
</a-form-item>
<a-form-item label="多语言值">
<div v-for="(item, idx) in entries" :key="idx" class="i18n-entry-row">
<span class="i18n-locale-label">{{ item.b_name }} ({{ item.b_locale }})</span>
<a-input v-model:value="item.b_value" class="i18n-value" />
</div>
</a-form-item>
</a-form>
</a-modal>
</template>
<style scoped lang="scss">
.i18n-entry-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
.i18n-locale-label {
flex: none;
width: 140px;
color: #646a73;
font-size: 13px;
}
.i18n-value {
flex: 1;
}
}
</style>