| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <template>
- <div class="multi-lang-input">
- <el-input v-model="inputModelValue" :placeholder="`请输入 ${currentLangLabel}`" clearable @update:model-value="(val: string) => { emit('update:modelValue', val); }">
- <template #append>
- <el-button @click="openDialog" circle>
- <template #icon>
- <i class="iconfont icon-diqiu1"></i>
- </template>
- </el-button>
- </template>
- </el-input>
- <el-dialog v-model="dialogVisible" title="多语言设置" draggable :close-on-click-modal="false" width="600px">
- <el-form ref="ruleFormRef" label-width="auto">
- <el-row :gutter="35">
- <el-col v-for="lang in languages" :key="lang.code" :span="24" class="mb10">
- <el-form-item :label="lang.label">
- <el-input v-model="multiLangValue[lang.code]" :placeholder="`请输入: ${lang.label}`" clearable />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- <template #footer>
- <el-button @click="aiTranslation">AI翻译</el-button>
- <el-button @click="closeDialog">关闭</el-button>
- <el-button type="primary" @click="confirmDialog">确认修改</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, computed, onMounted } from 'vue';
- import { useLangStore } from '/@/stores/useLangStore';
- import { Local } from '/@/utils/storage';
- import { getAPI } from '/@/utils/axios-utils';
- import { SysLangTextApi } from '/@/api-services/api';
- import { ElMessage } from 'element-plus';
- const emit = defineEmits<{ (e: 'update:modelValue', value: string): void; }>();
- const ruleFormRef = ref();
- const fetchMultiLang = async () => {
- const result = await getAPI(SysLangTextApi).apiSysLangTextListPost({ entityName: props.entityName, entityId: props.entityId, fieldName: props.fieldName, pageSize: 200 }).then(res => res.data.result)
- return result ?? [];
- };
- const inputModelValue = computed({
- get: () => props.modelValue,
- set: (val) => emit('update:modelValue', val),
- });
- const props = defineProps<{
- modelValue: string;
- entityName: string;
- entityId: number;
- fieldName: string;
- }>();
- // 全局语言
- const langStore = useLangStore();
- const languages = ref<any>([] as any);
- // 当前语言(可根据用户设置或浏览器设置)
- const currentLang = ref('zh-CN');
- const activeLang = ref('zh-CN');
- // 是否弹框
- const dialogVisible = ref(false);
- // 多语言对象
- const multiLangValue = ref<Record<string, string>>({});
- // 当前语言显示 Label
- const currentLangLabel = computed(() => {
- return (
- languages.value.find((l: { code: string; }) => l.code === currentLang.value)?.Label || currentLang.value
- );
- });
- // 初始化语言
- onMounted(async () => {
- if (langStore.languages.length === 0) {
- await langStore.loadLanguages();
- }
- const themeConfig = Local.get('themeConfig');
- const globalI18n = themeConfig?.globalI18n;
- if (globalI18n) {
- const matched = langStore.languages.find(l => l.code === globalI18n);
- const langCode = matched?.code || 'zh-CN';
- currentLang.value = langCode;
- activeLang.value = langCode;
- }
- languages.value = langStore.languages;
- if (languages.value.length > 0) {
- currentLang.value = languages.value[0].code;
- activeLang.value = languages.value[0].code;
- }
- });
- const aiTranslation = async () => {
- languages.value.forEach(async (element: { code: string; value: string | null; }) => {
- if (element.code == currentLang.value) {
- return;
- }
- multiLangValue.value[element.code] = '正在翻译...';
- try {
- const text = await getAPI(SysLangTextApi).apiSysLangTextAiTranslateTextPost({ originalText: props.modelValue, targetLang: element.value }).then(res => res.data.result);
- if (text) {
- multiLangValue.value[element.code] = text;
- } else {
- multiLangValue.value[element.code] = '';
- }
- } catch (e: any) {
- multiLangValue.value[element.code] = '';
- ElMessage.warning(e.message);
- }
- });
- }
- // 打开对话框(点击按钮)
- const openDialog = async () => {
- if (!props.entityId) {
- ElMessage.warning('请先保存数据!');
- return;
- }
- multiLangValue.value = {};
- const res = await fetchMultiLang();
- multiLangValue.value[currentLang.value] = props.modelValue;
- res.forEach((element: { langCode?: string | null; content?: string | null; }) => {
- multiLangValue.value[element.langCode ?? 0] = element.content ?? '';
- });
- dialogVisible.value = true;
- ruleFormRef.value?.resetFields();
- };
- // 关闭对话框(只是关闭)
- const closeDialog = () => {
- dialogVisible.value = false;
- multiLangValue.value = {};
- ruleFormRef.value?.resetFields();
- };
- // 确认按钮(更新 + 关闭)
- const confirmDialog = async () => {
- const langItems = Object.entries(multiLangValue.value)
- .filter(([_, content]) => content && content.trim() !== '')
- .map(([code, content]) => ({
- entityName: props.entityName,
- entityId: props.entityId,
- fieldName: props.fieldName,
- langCode: code,
- content: content,
- }));
- if (langItems.length === 0) {
- ElMessage.warning('请输入至少一条多语言内容!');
- return;
- }
- try {
- await getAPI(SysLangTextApi).apiSysLangTextBatchSavePost(langItems);
- ElMessage.success('保存成功!');
- // 同步当前语言内容到父组件 input
- emit('update:modelValue', multiLangValue.value[currentLang.value]);
- dialogVisible.value = false;
- } catch (err) {
- console.error(err);
- ElMessage.error('保存失败!');
- }
- dialogVisible.value = false;
- ruleFormRef.value?.resetFields();
- };
- </script>
- <style lang="scss" scoped>
- .multi-lang-input {
- width: 100%;
- }
- .mb10:last-child { margin-bottom: 0 !important; }
- </style>
|