You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
4.4 KiB

  1. <template>
  2. <el-dialog
  3. v-model="dialogVisible"
  4. title="语言切换"
  5. width="300px"
  6. :close-on-click-modal="false"
  7. append-to-body
  8. class="lang-switch-dialog"
  9. >
  10. <el-form label-width="80px">
  11. <el-form-item label="切换语言">
  12. <el-select
  13. v-model="tempLang"
  14. placeholder="请选择语言"
  15. style="width: 100%"
  16. >
  17. <el-option
  18. v-for="item in langOptions"
  19. :key="item.value"
  20. :label="item.label"
  21. :value="item.value"
  22. />
  23. </el-select>
  24. </el-form-item>
  25. </el-form>
  26. <template #footer>
  27. <div class="dialog-footer">
  28. <el-button @click="dialogVisible = false"> </el-button>
  29. <el-button type="primary" @click="handleConfirm"> </el-button>
  30. </div>
  31. </template>
  32. </el-dialog>
  33. </template>
  34. <script setup>
  35. import {computed, ref} from 'vue'
  36. import {useI18n} from 'vue-i18n'
  37. // === 显式引入所有用到的 Element Plus 组件 ===
  38. import {ElButton, ElDialog, ElForm, ElFormItem, ElMessage, ElOption, ElSelect} from 'element-plus'
  39. import request from "@/util/http.js";
  40. import {useAdminStore} from '@/store/index.js';
  41. import {storeToRefs} from "pinia";
  42. const {locale} = useI18n()
  43. // 控制弹窗显示
  44. const dialogVisible = ref(false)
  45. // 真正的当前语言
  46. const currentLang = computed(() => locale.value)
  47. // 临时选择的语言
  48. const tempLang = ref('')
  49. // 语言选项
  50. const langOptions = [
  51. {label: '中文(简体)', value: 'zh-CN'},
  52. // {label: '中文(繁體)', value: 'zh-TW'},
  53. {label: 'English', value: 'en'},
  54. // {label: 'ภาษาไทย', value: 'th'},
  55. // {label: 'Tiếng Việt', value: 'vi'}
  56. ]
  57. // 获取语言显示名称
  58. const getLangLabel = (langCode) => {
  59. const find = langOptions.find(item => item.value === langCode)
  60. return find ? find.label : langCode
  61. }
  62. // 打开弹窗
  63. const open = () => {
  64. tempLang.value = currentLang.value
  65. dialogVisible.value = true
  66. }
  67. // 确认修改
  68. const handleConfirm = async () => {
  69. locale.value = tempLang.value
  70. localStorage.setItem('lang', tempLang.value)
  71. await getMenuTree()
  72. await selectMarket()
  73. ElMessage.success(`语言已切换为:${getLangLabel(tempLang.value)}`)
  74. dialogVisible.value = false
  75. // 触发页面刷新以重新加载数据
  76. setTimeout(() => {
  77. window.location.reload()
  78. }, 500)
  79. }
  80. defineExpose({
  81. open
  82. })
  83. const adminStore = useAdminStore();
  84. const {adminData} = storeToRefs(adminStore);
  85. // 切换多语言 菜单改变
  86. const getMenuTree = async function () {
  87. // 获取菜单树
  88. try {
  89. const result = await request({
  90. url: '/menu/tree',
  91. data: {
  92. id: adminData.value.roleId,
  93. }
  94. })
  95. if (result.code === 200){
  96. adminStore.setMenuTree(result.data)
  97. }
  98. return result.data // 直接返回接口响应数据
  99. } catch (error) {
  100. console.error('菜单数据请求失败:', error)
  101. // return { code: 500, msg: '获取菜单失败' }
  102. ElMessage.error('网络异常')
  103. adminStore.clearState()
  104. }
  105. }
  106. // 获取地区列表 用于映射
  107. const selectMarket = async function () {
  108. try {
  109. const selectMarketResult = await request({ url: '/market/selectMarket' });
  110. const marketList = {};
  111. // 递归遍历树形结构(从子节点开始)
  112. const traverseTree = (nodes) => {
  113. nodes.forEach(node => {
  114. // 存储当前节点的 id 和 name
  115. marketList[node.id] = node.name;
  116. // 递归处理子节点
  117. if (node.children && node.children.length > 0) {
  118. traverseTree(node.children);
  119. }
  120. });
  121. };
  122. // 关键:跳过第一级节点,直接遍历第一级的子节点
  123. // 假设 selectMarketResult.data 是根节点数组(第一级)
  124. selectMarketResult.data.forEach(rootNode => {
  125. // 只处理第一级节点的子节点(从第二级开始遍历)
  126. if (rootNode.children && rootNode.children.length > 0) {
  127. traverseTree(rootNode.children);
  128. }
  129. });
  130. console.log('排除第一级后的地区列表 语言:', marketList);
  131. adminStore.setMarketList(marketList);
  132. // return marketList;
  133. } catch (error) {
  134. console.error('获取地区树失败:', error);
  135. return {};
  136. }
  137. };
  138. </script>
  139. <style scoped>
  140. .dialog-footer {
  141. display: flex;
  142. justify-content: center;
  143. gap: 20px;
  144. }
  145. /* :deep(.el-dialog__body) {
  146. height: 220px !important;
  147. overflow-y: auto !important;
  148. } */
  149. </style>