Browse Source

feat:组件和home文件调整

milestone-20251209-多语言二期^2
zhangrenyuan 1 month ago
parent
commit
811b70f005
  1. 31
      src/components/dialogs/LanguageSwitch.vue
  2. 49
      src/components/dialogs/changePassword.vue
  3. 1717
      src/components/locales/lang/en.js
  4. 65
      src/components/locales/lang/zh-CN.js
  5. 67
      src/views/home.vue

31
src/components/dialogs/LanguageSwitch.vue

@ -1,7 +1,7 @@
<template>
<el-dialog
v-model="dialogVisible"
title="语言切换"
:title="t('home.languageSwitch')"
width="300px"
:close-on-click-modal="false"
append-to-body
@ -9,10 +9,10 @@
style="background-color: rgb(243,250,254);"
>
<el-form label-width="80px">
<el-form-item label="切换语言">
<el-form-item :label="t('home.languageSwitch')">
<el-select
v-model="tempLang"
placeholder="请选择语言"
:placeholder="t('home.languageDialog.placeholder')"
style="width: 100%"
>
<el-option
@ -27,8 +27,8 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleConfirm"> </el-button>
<el-button @click="dialogVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" @click="handleConfirm">{{ t('common.confirm') }}</el-button>
</div>
</template>
</el-dialog>
@ -43,7 +43,7 @@ import request from "@/util/http.js";
import {useAdminStore} from '@/store/index.js';
import {storeToRefs} from "pinia";
const {locale} = useI18n()
const { locale, t } = useI18n()
//
const dialogVisible = ref(false)
@ -55,17 +55,14 @@ const currentLang = computed(() => locale.value)
const tempLang = ref('')
//
const langOptions = [
{label: '中文(简体)', value: 'zh-CN'},
// {label: '()', value: 'zh-TW'},
{label: 'English', value: 'en'},
// {label: '', value: 'th'},
// {label: 'Tiếng Vit', value: 'vi'}
]
const langOptions = computed(() => ([
{ label: t('home.languageDialog.options.zhCN'), value: 'zh-CN' },
{ label: t('home.languageDialog.options.en'), value: 'en' },
]))
//
const getLangLabel = (langCode) => {
const find = langOptions.find(item => item.value === langCode)
const find = langOptions.value.find(item => item.value === langCode)
return find ? find.label : langCode
}
@ -84,7 +81,7 @@ const handleConfirm = async () => {
await getMenuTree()
await selectMarket()
ElMessage.success(`语言已切换为:${getLangLabel(tempLang.value)}`)
ElMessage.success(t('elmessage.languageChangedSuccess', { lang: getLangLabel(tempLang.value) }))
dialogVisible.value = false
//
setTimeout(() => {
@ -118,7 +115,7 @@ const getMenuTree = async function () {
} catch (error) {
console.error('菜单数据请求失败:', error)
// return { code: 500, msg: '' }
ElMessage.error('网络异常')
ElMessage.error(t('elmessage.inNetworkError'))
adminStore.clearState()
}
}
@ -176,4 +173,4 @@ const selectMarket = async function () {
height: 220px !important;
overflow-y: auto !important;
} */
</style>
</style>

49
src/components/dialogs/changePassword.vue

@ -7,10 +7,13 @@ import {ElMessage} from "element-plus";
import API from '@/util/http.js'
import PasswordSuccess from '../PasswordSuccess.vue';
import router from "@/router/index.js";
import { useI18n } from 'vue-i18n'
//
const emit = defineEmits(['confirm'])
const { t } = useI18n()
const passwdFormRef = ref(null)
const passwd = reactive({
account: '',
@ -43,7 +46,7 @@ const isComplexValid = computed(() => {
watch(() => passwd.newPassword, (val) => {
if (val && val === passwd.oldPassword) {
errorMsg.value = '新密码不能与旧密码一致'
errorMsg.value = t('home.password.rules.notSameAsOld')
} else {
errorMsg.value = ''
}
@ -52,22 +55,22 @@ watch(() => passwd.newPassword, (val) => {
const loading = ref(false)
//
const rules = reactive({
oldPassword: [{required: true, message: '请输入原密码', trigger: 'blur'}],
oldPassword: [{required: true, message: t('home.password.oldPasswordPlaceholder'), trigger: 'blur'}],
newPassword: [
{required: true, message: '新密码不能为空', trigger: 'blur'},
{required: true, message: t('home.password.rules.newPasswordRequired'), trigger: 'blur'},
{
validator: (rule, value, callback) => {
if (!/^[a-zA-Z0-9!@#$%^&*()-_+={}[\]|\\:;"'<>,.?/~\`]+$/.test(value)) {
callback(new Error('密码只能包含数字、字母或符号'));
callback(new Error(t('home.password.rules.allowedChars')));
} else if (value === passwd.oldPassword) {
callback(new Error('新密码不能与旧密码一致'))
callback(new Error(t('home.password.rules.notSameAsOld')))
} else if (value.length < 8 || value.length > 16) {
callback(new Error('长度应在 8 到 16 个字符'))
callback(new Error(t('home.password.rules.length')))
} else {
const types = [/\d/, /[a-z]/, /[A-Z]/, /[!@#$%^&*()\-_+={}[\]|\\:;"'<>,.?/~`]/];
const matchCount = types.filter((r) => r.test(value)).length
if (matchCount < 2) {
callback(new Error('密码至少包含两种类型(数字、字母或符号)'))
callback(new Error(t('home.password.rules.complexity')))
} else {
callback()
}
@ -77,11 +80,11 @@ const rules = reactive({
}
],
againPassword: [
{required: true, message: '请再次输入新密码', trigger: 'blur'},
{required: true, message: t('home.password.rules.againPasswordRequired'), trigger: 'blur'},
{
validator: (rule, value, callback) => {
if (value !== passwd.newPassword) {
callback(new Error('两次输入密码不一致'))
callback(new Error(t('home.password.rules.notMatch')))
} else {
callback()
}
@ -107,7 +110,7 @@ const changePassword = async function () {
if (result.code === 200) {
// 使
//await router.push({ name: 'PasswordSuccess' });
ElMessage.success('修改密码成功');
ElMessage.success(t('elmessage.resetPasswordSuccess'));
// 使
//await router.push('/PasswordSuccess');
emit('confirm')
@ -117,20 +120,20 @@ const changePassword = async function () {
router.push('/PasswordSuccess'); // pushreplace
}, 1000);
}else if (result.code === 0){
ElMessage.error('原密码错误,请重新输入')
ElMessage.error(t('elmessage.oldPasswordError'))
passwd.oldPassword = '';
}else if(result.code === 400){
//
console.log('修改密码失败')
ElMessage.error('修改密码失败')
ElMessage.error(t('elmessage.resetPasswordFailed'))
//todo
}
} catch (error) {
console.error('修改密码失败', error)
ElMessage.error('操作失败')
ElMessage.error(t('elmessage.operationFailed'))
// finally
throw error
}
@ -186,34 +189,34 @@ onMounted(() => {
label-width="100px"
class="password-form"
>
<h3 class="form-title">修改密码</h3>
<h3 class="form-title">{{ t('home.password.title') }}</h3>
<!-- 原密码 -->
<el-form-item prop="oldPassword" label="原密码">
<el-form-item prop="oldPassword" :label="t('home.password.oldPassword')">
<el-input
v-model.trim="passwd.oldPassword"
type="password"
placeholder="请输入原密码"
:placeholder="t('home.password.oldPasswordPlaceholder')"
show-password
/>
</el-form-item>
<!-- 新密码 -->
<el-form-item prop="newPassword" label="新密码">
<el-form-item prop="newPassword" :label="t('home.password.newPassword')">
<el-input
v-model.trim="passwd.newPassword"
type="password"
placeholder="请输入新密码"
:placeholder="t('home.password.newPasswordPlaceholder')"
show-password
/>
</el-form-item>
<!-- 重复密码 -->
<el-form-item prop="againPassword" label="重复密码">
<el-form-item prop="againPassword" :label="t('home.password.againPassword')">
<el-input
v-model.trim="passwd.againPassword"
type="password"
placeholder="请再次输入新密码"
:placeholder="t('home.password.againPasswordPlaceholder')"
show-password
/>
</el-form-item>
@ -225,13 +228,13 @@ onMounted(() => {
<!-- 动态组件 -->
<component :is="isLengthValid ? SuccessFilled : CircleCloseFilled"/>
</el-icon>
密码由8-16位数字字母或符号组成
{{ t('home.password.tips.lengthAndChars') }}
</div>
<div :class="isComplexValid ? 'tip pass' : 'tip neutral'">
<el-icon>
<component :is="isComplexValid ? SuccessFilled : CircleCloseFilled"/>
</el-icon>
至少含2种以上字符
{{ t('home.password.tips.complexity') }}
</div>
<div v-if="errorMsg" class="tip fail">
<el-icon>
@ -250,7 +253,7 @@ onMounted(() => {
:loading="loading"
:disabled="!isLengthValid || !isComplexValid"
>
{{ loading ? '修改中...' : '确定' }}
{{ loading ? t('home.password.submitting') : t('common.confirm') }}
</el-button>
</div>

1717
src/components/locales/lang/en.js
File diff suppressed because it is too large
View File

65
src/components/locales/lang/zh-CN.js

@ -176,6 +176,18 @@ export default {
// 提示信息组
elmessage: {
// 通用
languageChangedSuccess: "语言已切换到{lang}",
refreshLoading: "数据刷新中,请稍候...",
refreshSuccess: "数据刷新成功",
refreshFailed: "数据刷新失败:{msg}",
unknownError: "未知错误",
refreshError: "数据刷新异常,请重试",
logoutSuccess: "退出成功",
staffHidden: "员工数据已隐藏",
staffShown: "员工数据已显示",
jumpSuccess: "跳转成功",
jumpFailed: "跳转失败",
oldPasswordError: "原密码错误,请重新输入",
addSuccess: "添加成功", // 大写是添加成功,小写是新增
addsuccess: "新增成功",
prompt: "提示",
@ -941,6 +953,59 @@ export default {
prompt1: "提示:当前规则每",
prompt2: "可兑换 1 新币",
},
// 设置中心(Home)
home: {
settingsCenter: "设置中心",
languageSwitch: "语言切换",
languageDialog: {
placeholder: "请选择语言",
options: {
zhCN: "中文(简体)",
en: "English"
}
},
showStaffData: "显示员工数据",
hideStaffData: "隐藏员工数据",
viewProfile: "查看个人信息",
changePassword: "修改密码",
logout: "退出登录",
messageCenter: "消息中心",
noMessage: "暂无未办消息,快去处理工作吧~",
goToView: "前往查看",
viewAll: "查看全部",
collapse: "收起",
backToTop: "返回顶部",
dialog: {
userName: "用户姓名",
jwcode: "精网号",
market: "地区",
registerTime: "注册时间",
},
orderNeedsReview: "用户有条收款订单需审核",
password: {
title: "修改密码",
oldPassword: "原密码",
newPassword: "新密码",
againPassword: "重复密码",
oldPasswordPlaceholder: "请输入原密码",
newPasswordPlaceholder: "请输入新密码",
againPasswordPlaceholder: "请再次输入新密码",
tips: {
lengthAndChars: "密码由8-16位数字、字母或符号组成",
complexity: "至少含2种以上字符"
},
rules: {
allowedChars: "密码只能包含数字、字母或符号",
notSameAsOld: "新密码不能与旧密码一致",
length: "长度应在 8 到 16 个字符",
complexity: "密码至少包含两种类型(数字、字母或符号)",
notMatch: "两次输入密码不一致",
newPasswordRequired: "新密码不能为空",
againPasswordRequired: "请再次输入新密码"
},
submitting: "修改中..."
},
},
// 现金管理
cash: {

67
src/views/home.vue

@ -17,6 +17,9 @@ import {getOrderPage} from '@/utils/goToCheck.js'
import {groupMessages} from "@/utils/getMessage.js"
import {findMenuById,permissionMapping} from "@/utils/menuTreePermission.js"
import {useMessageStore} from '@/store/index.js'
//
import { useI18n } from 'vue-i18n'
const {t} = useI18n();
// ------------------ ICONS ------------------
const icons = import.meta.glob('@/assets/SvgIcons/*.svg', {eager: true})
@ -56,26 +59,26 @@ const openLanguageSwitch = () => {
}
const handleLanguageChanged = (lang) => {
ElMessage.success(`语言已切换到${lang}`)
ElMessage.success(t('elmessage.languageChangedSuccess', { lang }))
}
// ------------------ ------------------
const refreshData = async () => {
try {
ElMessage({message: '数据刷新中,请稍候...', type: 'info'});
ElMessage({ message: t('elmessage.refreshLoading'), type: 'info' })
const response = await API({url: '/Mysql', method: 'POST', data: {}});
if (response && response.code === 200) {
const currentRoute = route.fullPath;
router.replace('/blank');
setTimeout(() => router.replace(currentRoute), 10);
ElMessage.success('数据刷新成功');
ElMessage.success(t('elmessage.refreshSuccess'))
} else {
ElMessage.error('数据刷新失败:' + (response?.msg || '未知错误'));
ElMessage.error(t('elmessage.refreshFailed', { msg: response?.msg || t('elmessage.unknownError') }))
}
} catch (error) {
console.error(error)
ElMessage.error('数据刷新异常,请重试');
ElMessage.error(t('elmessage.refreshError'))
}
}
@ -126,14 +129,14 @@ function logout() {
localStorage.removeItem('token')
adminStore.clearState()
router.push('/login?machineId=' + machineId)
ElMessage.success('退出成功')
ElMessage.success(t('elmessage.logoutSuccess'))
}
// ------------------ ------------------
const toggleFlag = () => {
const newFlag = flag.value === 1 ? 0 : 1
adminStore.setFlag(newFlag)
ElMessage.success(newFlag === 1 ? '员工数据已隐藏' : '员工数据已显示')
ElMessage.success(newFlag === 1 ? t('elmessage.staffHidden') : t('elmessage.staffShown'))
}
// ------------------ ------------------
@ -290,9 +293,9 @@ const handleMessageClick = async (item) => {
closeMessageDialog()
await router.push(getOrderPage(item.status))
await getMessage()
ElMessage.success('跳转成功')
ElMessage.success(t('elmessage.jumpSuccess'))
} else {
ElMessage.error('跳转失败')
ElMessage.error(t('elmessage.jumpFailed'))
}
}
@ -374,8 +377,8 @@ onMounted(() => getMessage())
<el-dropdown placement="top-start">
<span class="el-dropdown-link">
<!-- 暂时使用静态路径确保设置图标正常显示 -->
<img src="@/assets/SvgIcons/setting.svg" alt="设置" style="width: 4vh; height: 4vh"/>
<span>设置中心</span>
<img src="@/assets/SvgIcons/setting.svg" :alt="t('home.settingsCenter')" style="width: 4vh; height: 4vh"/>
<span>{{ t('home.settingsCenter') }}</span>
<el-icon class="arrow-icon">
<ArrowUp/>
</el-icon>
@ -383,13 +386,13 @@ onMounted(() => getMessage())
<template #dropdown>
<el-dropdown-menu>
<!-- <el-dropdown-item @click="refreshData()">数据刷新</el-dropdown-item>-->
<el-dropdown-item @click="openLanguageSwitch">语言切换</el-dropdown-item>
<el-dropdown-item @click="openLanguageSwitch">{{ t('home.languageSwitch') }}</el-dropdown-item>
<el-dropdown-item @click="toggleFlag()">
{{ flag === 1 ? '显示员工数据' : '隐藏员工数据' }}
{{ flag === 1 ? t('home.showStaffData') : t('home.hideStaffData') }}
</el-dropdown-item>
<el-dropdown-item @click="message()">查看个人信息</el-dropdown-item>
<el-dropdown-item @click="openChangePassword">修改密码</el-dropdown-item>
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
<el-dropdown-item @click="message()">{{ t('home.viewProfile') }}</el-dropdown-item>
<el-dropdown-item @click="openChangePassword">{{ t('home.changePassword') }}</el-dropdown-item>
<el-dropdown-item @click="logout">{{ t('home.logout') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@ -424,24 +427,24 @@ onMounted(() => getMessage())
</div>
<!-- 查看个人信息 -->
<el-dialog v-model="messageVisible" title="查看个人信息" width="500px">
<el-dialog v-model="messageVisible" :title="t('home.viewProfile')" width="500px">
<el-form :model="adminData">
<el-form-item label="用户姓名" label-width="100px" label-position="left">
<el-form-item :label="t('home.dialog.userName')" label-width="100px" label-position="left">
<span class="message-font">{{ adminData.adminName }}</span>
</el-form-item>
<el-form-item label="精网号" label-width="100px" label-position="left">
<el-form-item :label="t('home.dialog.jwcode')" label-width="100px" label-position="left">
<span class="message-font">{{ adminData.account }}</span>
</el-form-item>
<el-form-item label="地区" label-width="100px" label-position="left">
<el-form-item :label="t('home.dialog.market')" label-width="100px" label-position="left">
<span class="message-font">{{ adminData.markets }}</span>
</el-form-item>
<el-form-item label="注册时间" label-width="100px" label-position="left">
<el-form-item :label="t('home.dialog.registerTime')" label-width="100px" label-position="left">
<span class="message-font">{{ adminData.createTime }}</span>
</el-form-item>
</el-form>
<template #footer>
<div>
<el-button text @click="closeMessage()">关闭</el-button>
<el-button text @click="closeMessage()">{{ t('common_export.close') }}</el-button>
</div>
</template>
</el-dialog>
@ -458,13 +461,13 @@ onMounted(() => getMessage())
class="divider"
direction="vertical"
></el-divider>
消息中心 ({{ messageNum }})
{{ t('home.messageCenter') }} ({{ messageNum }})
</div>
<!-- todo 这是为了样式显示 一定要改逻辑-->
<div v-if="messageNum === 0">
<div class="no-message">
<el-image :src="noMessage"></el-image>
<p class="no-message-text">暂无未办消息快去处理工作吧</p>
<p class="no-message-text">{{ t('home.noMessage') }}</p>
</div>
</div>
<div v-else
@ -498,16 +501,16 @@ onMounted(() => getMessage())
</div>
</div>
<div class="message-desc">
<div v-if="findMenuById(menuTree, permissionMapping.refund_headquarters_finance)">[{{ item.marketName }}] </div>
<div>[{{item.name}}{{ item.jwcode }}]用户有条收款订单需审核</div>
</div>
<div class="message-desc">
<div v-if="findMenuById(menuTree, permissionMapping.refund_headquarters_finance)">[{{ item.marketName }}] </div>
<div>[{{item.name}}{{ item.jwcode }}]{{ t('home.orderNeedsReview') }}</div>
</div>
<el-button
type="primary"
style="margin: 0 auto; display: block;"
@click="handleMessageClick(item)"
>
前往查看
{{ t('home.goToView') }}
</el-button>
</div>
<el-divider
@ -523,7 +526,7 @@ onMounted(() => getMessage())
class="view-all"
@click="toggleShowAll"
>
{{ showAll ? '收起' : '查看全部' }}
{{ showAll ? t('home.collapse') : t('home.viewAll') }}
</el-button>
<div v-if="showAll" @click="scrollToTop" class="go-top">
@ -532,7 +535,7 @@ onMounted(() => getMessage())
style="width: 20px; height: 20px;"
fit="contain"
/>
<span>返回顶部</span>
<span>{{ t('home.backToTop') }}</span>
</div>
</div>
</div>
@ -850,4 +853,4 @@ display: flex;
padding: 8px;
}
</style>
</style>
Loading…
Cancel
Save