20260724173425

This commit is contained in:
oneao committed 2026-07-24 17:34:26 +08:00
1 parent 4f40ad9f11
commit b33c743236
27 files changed
+1310 -437

No files matched your search

@@ -0,0 +1,121 @@
<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>