瀏覽代碼

feat: 登录弹窗、首页、应用管理新增多语言翻译,添加全局样式

lixuan 1 月之前
父節點
當前提交
c572685fa0

二進制
apps/web-velofex/src/assets/image/the-left.png


+ 2 - 2
apps/web-velofex/src/components/login/CaptchaInput.vue

@@ -52,7 +52,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <div class="flex items-center gap-2">
+  <div class="flex w-full items-center gap-2">
     <input
       v-model="captchaValue"
       :placeholder="placeholder"
@@ -60,7 +60,7 @@ onMounted(() => {
       type="text"
     />
     <div
-      class="flex h-[38px] w-[120px] cursor-pointer items-center justify-center overflow-hidden rounded-md border border-gray-300 bg-gray-100"
+      class="flex h-[38px] w-[120px] cursor-pointer items-center justify-center overflow-hidden rounded-[5px]"
       @click="handleRefresh"
     >
       <img

+ 55 - 38
apps/web-velofex/src/components/login/login.vue

@@ -6,6 +6,7 @@ import { computed, reactive, ref, watch } from 'vue';
 import { useVbenForm, useVbenModal, VbenButton, z } from '@vben/common-ui';
 import { useAccessStore, useUserStore } from '@vben/stores';
 
+import { $t } from '@/locales';
 import { message } from 'antdv-next';
 import MD5 from 'crypto-js/md5';
 
@@ -44,8 +45,10 @@ const loginFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'username',
-      label: 'Login Name',
-      rules: z.string().min(1, { message: '请输入用户名' }),
+      label: $t('auth.loginName'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterUsername') }),
       defaultValue: localUsername,
     },
     {
@@ -54,8 +57,10 @@ const loginFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'password',
-      label: 'Password',
-      rules: z.string().min(1, { message: '请输入密码' }),
+      label: $t('auth.password'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterPassword') }),
     },
     {
       component: 'VbenInput',
@@ -63,8 +68,10 @@ const loginFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'captcha',
-      label: 'Verification Code',
-      rules: z.string().min(1, { message: '请输入验证码' }),
+      label: $t('auth.verificationCode'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterVerificationCode') }),
       formItemClass: 'captcha-form-item',
     },
   ];
@@ -78,11 +85,13 @@ const registerFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'mobile',
-      label: 'Mobile Number',
+      label: $t('auth.mobileNumber'),
       rules: z
         .string()
-        .min(1, { message: '请输入手机号' })
-        .regex(/^1[3-9]\d{9}$/, { message: '请输入正确的手机号' }),
+        .min(1, { message: $t('auth.validation.enterMobileNumber') })
+        .regex(/^1[3-9]\d{9}$/, {
+          message: $t('auth.validation.enterCorrectMobileNumber'),
+        }),
     },
     {
       component: 'VbenInput',
@@ -90,8 +99,10 @@ const registerFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'code',
-      label: 'Verification Code',
-      rules: z.string().min(1, { message: '请输入验证码' }),
+      label: $t('auth.verificationCode'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterVerificationCode') }),
       formItemClass: 'verification-form-item',
     },
     {
@@ -100,8 +111,10 @@ const registerFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'accountName',
-      label: 'Account Name',
-      rules: z.string().min(1, { message: '请输入账号名称' }),
+      label: $t('auth.accountName'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterAccountName') }),
     },
     {
       component: 'VbenInputPassword',
@@ -109,8 +122,10 @@ const registerFormSchema = computed((): VbenFormSchema[] => {
         placeholder: '',
       },
       fieldName: 'password',
-      label: 'Password',
-      rules: z.string().min(1, { message: '请输入密码' }),
+      label: $t('auth.password'),
+      rules: z
+        .string()
+        .min(1, { message: $t('auth.validation.enterPassword') }),
     },
     {
       component: 'VbenCheckbox',
@@ -119,9 +134,9 @@ const registerFormSchema = computed((): VbenFormSchema[] => {
       },
       fieldName: 'agreeTerms',
       label: '',
-      rules: z
-        .boolean()
-        .refine((val) => val === true, { message: '请同意用户条款' }),
+      rules: z.boolean().refine((val) => val === true, {
+        message: $t('auth.validation.agreeTerms'),
+      }),
       formItemClass: 'agree-terms-form-item',
     },
   ];
@@ -146,7 +161,7 @@ const [RegisterForm, registerFormApi] = useVbenForm(
     commonConfig: {
       hideLabel: false,
       hideRequiredMark: true,
-      formItemClass: 'pb-[20px]',
+      formItemClass: 'pb-[15px]',
     },
     layout: 'vertical',
     schema: registerFormSchema,
@@ -190,7 +205,7 @@ async function handleLoginSubmit() {
           accessStore.setAccessToken(loginRes.token);
         }
         open.value = false;
-        message.success('登录成功');
+        message.success($t('auth.message.loginSuccess'));
         const userInfoRes = await getUserInfoApi();
         if (userInfoRes && userInfoRes.isSuccess) {
           const userInfo = {
@@ -210,7 +225,7 @@ async function handleLoginSubmit() {
           userStore.setUserInfo(userInfo);
         }
       } else {
-        message.error(loginRes?.error || '登录失败');
+        message.error(loginRes?.error || $t('auth.message.loginFailed'));
       }
     } finally {
       loading.value = false;
@@ -223,13 +238,13 @@ async function handleSendCode() {
   const mobile = values?.mobile;
 
   if (!mobile) {
-    message.error('请先输入手机号');
+    message.error($t('auth.message.enterMobileNumberFirst'));
     return;
   }
 
   const mobileRegex = /^1[3-9]\d{9}$/;
   if (!mobileRegex.test(mobile)) {
-    message.error('请输入正确的手机号');
+    message.error($t('auth.validation.enterCorrectMobileNumber'));
     return;
   }
 
@@ -248,10 +263,10 @@ async function handleSendCode() {
         isSending.value = false;
       }
     }, 1000);
-    message.success('验证码已发送');
+    message.success($t('auth.message.verificationCodeSent'));
   } catch {
     isSending.value = false;
-    message.error('发送验证码失败');
+    message.error($t('auth.message.sendVerificationCodeFailed'));
   }
 }
 
@@ -281,10 +296,10 @@ async function handleRegisterSubmit() {
         },
       });
       if (registerRes && registerRes.isSuccess) {
-        message.success('注册成功,请登录后使用');
+        message.success($t('auth.message.registerSuccess'));
         isRegister.value = false;
       } else {
-        message.error(registerRes?.error || '注册失败');
+        message.error(registerRes?.error || $t('auth.message.registerFailed'));
       }
     } finally {
       loading.value = false;
@@ -330,27 +345,29 @@ defineExpose({
         </div>
         <div class="w-full px-[86px] py-[30px] sm:w-1/2">
           <div v-if="!isRegister" class="mb-6">
-            <h2 class="text-[21px] font-bold">Login</h2>
+            <h2 class="text-[21px] font-bold">{{ $t('auth.login') }}</h2>
             <p class="text-muted-foreground mt-3 text-sm">
-              New user?
+              {{ $t('auth.newUser') }}
               <span
                 class="cursor-pointer text-[#8B0046]"
                 @click="handleGoToRegister"
               >
-                Create an account
+                {{ $t('auth.createAccount') }}
               </span>
             </p>
           </div>
 
           <div v-if="isRegister" class="mb-6">
-            <h2 class="text-[21px] font-bold">Create an account</h2>
+            <h2 class="text-[21px] font-bold">
+              {{ $t('auth.createAccount') }}
+            </h2>
             <p class="text-muted-foreground mt-3 text-sm">
-              Already have an account?
+              {{ $t('auth.alreadyHaveAccount') }}
               <span
                 class="cursor-pointer text-[#8B0046]"
                 @click="handleGoToLogin"
               >
-                Login
+                {{ $t('auth.login') }}
               </span>
             </p>
           </div>
@@ -395,7 +412,7 @@ defineExpose({
                   class="h-[38px] whitespace-nowrap rounded-md bg-gradient-to-b from-[#8B0046] to-[#460023] px-4 text-white"
                   @click="handleSendCode"
                 >
-                  {{ countdown > 0 ? `${countdown}s` : 'Send Code' }}
+                  {{ countdown > 0 ? `${countdown}s` : $t('auth.sendCode') }}
                 </VbenButton>
               </div>
             </template>
@@ -411,7 +428,7 @@ defineExpose({
                     }
                   "
                 />
-                <span class="text-sm">I agree with user's terms</span>
+                <span class="text-sm">{{ $t('auth.agreeTerms') }}</span>
               </label>
             </template>
           </RegisterForm>
@@ -424,7 +441,7 @@ defineExpose({
             class="m-auto mt-[20px] flex h-[50px] w-full cursor-pointer items-center justify-center rounded-[25px] bg-gradient-to-b from-[#8B0046] to-[#460023] text-[16px] text-white"
             @click="handleLoginSubmit"
           >
-            Login
+            {{ $t('auth.loginButton') }}
           </VbenButton>
 
           <VbenButton
@@ -432,10 +449,10 @@ defineExpose({
             :class="{ 'cursor-wait': loading }"
             :loading="loading"
             aria-label="register"
-            class="m-auto flex h-[50px] w-full cursor-pointer items-center justify-center rounded-[25px] bg-gradient-to-b from-[#8B0046] to-[#460023] text-[16px] text-white"
+            class="m-auto mt-[20px] flex h-[50px] w-full cursor-pointer items-center justify-center rounded-[25px] bg-gradient-to-b from-[#8B0046] to-[#460023] text-[16px] text-white"
             @click="handleRegisterSubmit"
           >
-            Create an account
+            {{ $t('auth.createAccountButton') }}
           </VbenButton>
         </div>
         <div class="absolute right-[20px] top-[24px] h-[44px] w-[59.12px]">

+ 3 - 5
apps/web-velofex/src/layouts/header/header.vue

@@ -7,12 +7,12 @@ import useAvatar from '@/assets/image/user.png';
 import { $t } from '@/locales';
 
 import Logo from '#/assets/image/logo.png';
-import { useLoginModalStore } from '#/store';
+// import { useLoginModalStore } from '#/store';
 
 import SelectLang from '../select-lang.vue';
 import Avatar from './avatar.vue';
 
-const loginModalStore = useLoginModalStore();
+// const loginModalStore = useLoginModalStore();
 
 const menus = computed(() => [
   { title: $t('homeMenu.toolDownloads'), path: '/' },
@@ -22,9 +22,7 @@ const menus = computed(() => [
   { title: $t('homeMenu.applicationMarket'), path: '/' },
 ]);
 
-function openLogin() {
-  loginModalStore.open();
-}
+function openLogin() {}
 </script>
 
 <template>

File diff suppressed because it is too large
+ 132 - 2
apps/web-velofex/src/locales/langs/en-US/page.json


File diff suppressed because it is too large
+ 132 - 2
apps/web-velofex/src/locales/langs/zh-CN/page.json


+ 1 - 1
apps/web-velofex/src/router/routes/external/router-a.ts

@@ -40,7 +40,7 @@ const routes: RouteRecordRaw[] = [
           import('#/views/dashboard/application-management/index.vue'),
         meta: {
           icon: 'carbon:application',
-          title: $t('dashboard.applicationManagement'),
+          title: $t('homeModule.applicationManagement'),
         },
       },
     ],

+ 8 - 0
apps/web-velofex/src/styles/global.scss

@@ -52,3 +52,11 @@
   border: 1px solid #8b0046 !important;
   border-color: #8b0046;
 }
+
+.global-color {
+  background-color: #5d1818;
+}
+
+.global-color:hover {
+  background-color: #7a003d;
+}

+ 210 - 83
apps/web-velofex/src/views/dashboard/application-management/application-modal.vue

@@ -1,8 +1,10 @@
 <script setup lang="ts">
+import type { TablePaginationConfig } from 'antdv-next';
 import type { Dayjs } from 'dayjs';
 
 import { computed, ref, watch } from 'vue';
 
+import { $t } from '@/locales';
 import {
   Button,
   DatePicker,
@@ -92,11 +94,23 @@ const userSearchKeyword = ref('');
 const userModalOpen = ref(false);
 const selectedUsers = ref<any[]>([]);
 
-const menuItems = [
-  { key: 'basic', label: '基本' },
-  { key: 'users', label: '关联用户' },
-  { key: 'keys', label: '系统密钥' },
-];
+const menuItems = computed(() => [
+  {
+    key: 'basic',
+    label: $t('applicationManagement.modal.menu.basic'),
+    title: $t('applicationManagement.modal.menu.basic'),
+  },
+  {
+    key: 'users',
+    label: $t('applicationManagement.modal.menu.users'),
+    title: $t('applicationManagement.modal.menu.users'),
+  },
+  {
+    key: 'keys',
+    label: $t('applicationManagement.modal.menu.keys'),
+    title: $t('applicationManagement.modal.menu.keys'),
+  },
+]);
 
 const roleOptions = [
   { value: '普通人员', label: '普通人员' },
@@ -295,7 +309,14 @@ const isOpen = computed({
   set: (val) => emit('update:open', val),
 });
 
-function handleMenuClick({ key }: { key: string }) {
+function handleMenuClick({
+  key,
+}: {
+  domEvent: Event;
+  item: any;
+  key: string;
+  keyPath: string[];
+}) {
   activeMenu.value = key;
 }
 
@@ -348,7 +369,7 @@ async function handleSave() {
     if (result?.isSuccess) {
       emit('save', data);
       isOpen.value = false;
-      message.success('应用保存成功');
+      message.success($t('applicationManagement.saveSuccess'));
     }
   } catch {}
 }
@@ -369,10 +390,12 @@ function handleUserSearch() {
   getAddUsers();
 }
 
-function handleUserPageChange(pagination: any) {
-  userPagination.value.currentPage = pagination.current;
-  userPagination.value.pageSize = pagination.pageSize;
-  getAddUsers();
+function handleUserPageChange(pagination: TablePaginationConfig) {
+  if (pagination.current && pagination.pageSize) {
+    userPagination.value.currentPage = pagination.current;
+    userPagination.value.pageSize = pagination.pageSize;
+    getAddUsers();
+  }
 }
 
 async function handleUserSelect(user: any) {
@@ -382,7 +405,7 @@ async function handleUserSelect(user: any) {
       formData.value.code,
     );
     if (result?.isSuccess) {
-      message.success('用户添加成功');
+      message.success($t('applicationManagement.addUserSuccess'));
       getAssociatedUsers();
       userModalOpen.value = false;
     }
@@ -391,23 +414,24 @@ async function handleUserSelect(user: any) {
 
 async function handleUserDelete(user: any) {
   Modal.confirm({
-    title: 'Are you sure delete this task?',
-    content: 'Some descriptions',
-    okText: 'Yes',
+    title: $t('applicationManagement.deleteConfirm'),
+    content: $t('applicationManagement.deleteDescription'),
+    okText: $t('btn.yes'),
     okType: 'danger',
-    cancelText: 'No',
-    async onOk() {
+    cancelText: $t('btn.no'),
+    type: 'warning',
+    onOk: async () => {
       try {
         const result = await deleteUserFromApplicationApi(user.id, [
           formData.value.id,
         ]);
         if (result?.isSuccess) {
-          message.success('用户删除成功');
+          message.success($t('applicationManagement.deleteSuccess'));
           getAssociatedUsers();
         }
       } catch {}
     },
-    onCancel() {},
+    onCancel: () => {},
   });
 }
 
@@ -420,7 +444,7 @@ async function handleAssociateUser(user: any) {
     };
     const result = await associateUserApi(data);
     if (result?.isSuccess) {
-      message.success('用户保存成功');
+      message.success($t('applicationManagement.associateUserSuccess'));
     }
   } catch {}
 }
@@ -439,7 +463,7 @@ async function handleGenerateKey() {
     };
     const result = await generateSystemSecretApi(data);
     if (result?.result) {
-      message.success('系统密钥生成成功');
+      message.success($t('applicationManagement.generateKeySuccess'));
       fetchSystemSecret();
     }
   } catch {}
@@ -448,7 +472,7 @@ async function handleGenerateKey() {
 function handleCopyKey() {
   if (keyData.value.systemKey) {
     navigator.clipboard.writeText(keyData.value.systemKey);
-    message.success('系统密钥已复制');
+    message.success($t('applicationManagement.copyKeySuccess'));
   }
 }
 
@@ -497,7 +521,11 @@ function resetFormData() {
   <Modal
     v-model:open="isOpen"
     :footer="null"
-    :title="mode === 'add' ? '添加应用' : '编辑应用'"
+    :title="
+      mode === 'add'
+        ? $t('applicationManagement.modal.addTitle')
+        : $t('applicationManagement.modal.editTitle')
+    "
     width="1200px"
   >
     <div class="flex h-[600px]">
@@ -515,7 +543,9 @@ function resetFormData() {
         <div v-show="activeMenu === 'basic'" class="space-y-4">
           <div class="flex items-center gap-4">
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">企业Logo</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.enterpriseLogo')
+              }}</label>
               <Upload
                 v-model:file-list="formData.fileList"
                 :headers="{ Authorization: String(token) }"
@@ -529,7 +559,9 @@ function resetFormData() {
                 >
                   <div class="text-center">
                     <div class="text-4xl">+</div>
-                    <div class="text-sm text-gray-500">上传Logo</div>
+                    <div class="text-sm text-gray-500">
+                      {{ $t('applicationManagement.modal.uploadLogo') }}
+                    </div>
                   </div>
                 </div>
               </Upload>
@@ -538,115 +570,166 @@ function resetFormData() {
 
           <div class="grid grid-cols-2 gap-4">
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">合作伙伴</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.partner')
+              }}</label>
               <Select
                 v-model:value="formData.partner"
                 :disabled="props.mode === 'edit'"
                 :options="applicationMenu"
+                :placeholder="$t('applicationManagement.modal.selectPartner')"
                 class="h-[32px]"
-                placeholder="请选择合作伙伴"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">项目代码</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.projectCode')
+              }}</label>
               <Input
                 v-model:value="formData.projectCode"
                 :disabled="props.mode === 'edit'"
-                placeholder="请输入项目代码"
+                :placeholder="
+                  $t('applicationManagement.modal.enterProjectCode')
+                "
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">克隆项目</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.cloneProject')
+              }}</label>
               <Select
                 v-model:value="formData.cloneProject"
                 :disabled="props.mode === 'edit'"
                 :options="applications"
+                :placeholder="
+                  $t('applicationManagement.modal.selectCloneProject')
+                "
                 class="h-[32px]"
-                placeholder="请选择克隆项目"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">项目名称(中文)</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.projectNameCn')
+              }}</label>
               <Input
                 v-model:value="formData.nameCn"
-                placeholder="请输入项目名称"
+                :placeholder="
+                  $t('applicationManagement.modal.enterProjectName')
+                "
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">项目名称(英文)</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.projectNameEn')
+              }}</label>
               <Input
                 v-model:value="formData.nameEn"
-                placeholder="请输入项目名称"
+                :placeholder="
+                  $t('applicationManagement.modal.enterProjectName')
+                "
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">客户关系</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.customerRelation')
+              }}</label>
               <Select
                 v-model:value="formData.customerRelation"
                 :options="customerRelationsOptions"
+                :placeholder="
+                  $t('applicationManagement.modal.selectCustomerRelation')
+                "
                 class="h-[32px]"
-                placeholder="请选择客户关系"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">联系人</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.contact')
+              }}</label>
               <Input
                 v-model:value="formData.contact"
-                placeholder="请输入联系人"
+                :placeholder="$t('applicationManagement.modal.enterContact')"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">手机号</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.phone')
+              }}</label>
               <Input
                 v-model:value="formData.phone"
-                placeholder="请输入手机号"
+                :placeholder="$t('applicationManagement.modal.enterPhone')"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">邮箱</label>
-              <Input v-model:value="formData.email" placeholder="请输入邮箱" />
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.email')
+              }}</label>
+              <Input
+                v-model:value="formData.email"
+                :placeholder="$t('applicationManagement.modal.enterEmail')"
+              />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">地址</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.address')
+              }}</label>
               <Input
                 v-model:value="formData.address"
-                placeholder="请输入地址"
+                :placeholder="$t('applicationManagement.modal.enterAddress')"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">描述</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.description')
+              }}</label>
               <Input
                 v-model:value="formData.description"
+                :placeholder="
+                  $t('applicationManagement.modal.enterDescription')
+                "
                 :rows="3"
-                placeholder="请输入描述"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">是否启用</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.isEnabled')
+              }}</label>
               <Switch v-model:checked="formData.isEnabled" class="w-[40px]" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">流程数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.processCount')
+              }}</label>
               <Input v-model:value="formData.processCount" type="number" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">页面数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.pageCount')
+              }}</label>
               <Input v-model:value="formData.pageCount" type="number" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">数据表</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.tableCount')
+              }}</label>
               <Input v-model:value="formData.tableCount" type="number" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">设计人员数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.designerCount')
+              }}</label>
               <Input v-model:value="formData.designerCount" type="number" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">业务场景数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.scenarioCount')
+              }}</label>
               <Input v-model:value="formData.scenarioCount" type="number" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">C端用户数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.userCount')
+              }}</label>
               <Input v-model:value="formData.userCount" type="number" />
             </div>
           </div>
@@ -654,14 +737,28 @@ function resetFormData() {
 
         <div v-show="activeMenu === 'users'" class="space-y-4">
           <div class="mb-4 flex items-center justify-between">
-            <Button type="primary" @click="handleAddUser">添加用户</Button>
+            <Button type="primary" @click="handleAddUser">
+              {{ $t('applicationManagement.modal.users.addUser') }}
+            </Button>
           </div>
 
           <Table
             :columns="[
-              { title: '账户', dataIndex: 'account', key: 'account' },
-              { title: '角色', dataIndex: 'roleTypes', key: 'roleTypes' },
-              { title: '操作', key: 'action', width: 200 },
+              {
+                title: $t('applicationManagement.modal.users.account'),
+                dataIndex: 'account',
+                key: 'account',
+              },
+              {
+                title: $t('applicationManagement.modal.users.role'),
+                dataIndex: 'roleTypes',
+                key: 'roleTypes',
+              },
+              {
+                title: $t('applicationManagement.modal.users.action'),
+                key: 'action',
+                width: 200,
+              },
             ]"
             :data-source="relatedUsers"
             :pagination="false"
@@ -682,7 +779,7 @@ function resetFormData() {
                     type="primary"
                     @click="handleAssociateUser(record)"
                   >
-                    保存
+                    {{ $t('applicationManagement.modal.users.save') }}
                   </Button>
                   <Button
                     class="ml-[10px]"
@@ -690,7 +787,7 @@ function resetFormData() {
                     size="small"
                     @click="handleUserDelete(record)"
                   >
-                    删除
+                    {{ $t('applicationManagement.modal.users.delete') }}
                   </Button>
                 </div>
               </template>
@@ -701,7 +798,9 @@ function resetFormData() {
         <div v-show="activeMenu === 'keys'" class="space-y-4">
           <div class="grid grid-cols-2 gap-4">
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">开始时间</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.startTime')
+              }}</label>
               <DatePicker
                 v-model:value="keyData.startTime"
                 format="YYYY-MM-DD"
@@ -709,49 +808,67 @@ function resetFormData() {
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">加密类型</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.encryptionType')
+              }}</label>
               <Input
                 v-model:value="keyData.encryptionType"
+                :placeholder="
+                  $t('applicationManagement.modal.keys.encryptionType')
+                "
                 disabled
-                placeholder="请输入加密类型"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">有效天数</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.validDays')
+              }}</label>
               <Input
                 v-model:value="keyData.validDays"
-                placeholder="请输入有效天数"
+                :placeholder="
+                  $t('applicationManagement.modal.keys.enterValidDays')
+                "
                 type="number"
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">永久有效</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.isPermanent')
+              }}</label>
               <Switch v-model:checked="keyData.isPermanent" class="w-[40px]" />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">错误信息描述</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.errorDescription')
+              }}</label>
               <Input
                 v-model:value="keyData.errorDescription"
-                placeholder="请输入错误信息描述"
+                :placeholder="
+                  $t('applicationManagement.modal.keys.enterErrorDescription')
+                "
               />
             </div>
             <div class="flex flex-col gap-2">
-              <label class="text-sm font-medium">系统密钥</label>
+              <label class="text-sm font-medium">{{
+                $t('applicationManagement.modal.keys.systemKey')
+              }}</label>
               <Input
                 v-model:value="keyData.systemKey"
+                :placeholder="$t('applicationManagement.modal.keys.systemKey')"
                 disabled
-                placeholder="系统密钥"
               />
             </div>
           </div>
           <div class="mt-6 flex justify-end gap-2">
-            <Button type="primary" @click="handleGenerateKey">生成</Button>
+            <Button type="primary" @click="handleGenerateKey">
+              {{ $t('applicationManagement.modal.keys.generate') }}
+            </Button>
             <Button
               v-if="keyData.systemKey"
               type="primary"
               @click="handleCopyKey"
             >
-              复制
+              {{ $t('applicationManagement.modal.keys.copy') }}
             </Button>
           </div>
         </div>
@@ -762,53 +879,62 @@ function resetFormData() {
       v-if="activeMenu === 'basic'"
       class="flex justify-end gap-2 border-t pt-4"
     >
-      <Button @click="handleCancel">取消</Button>
-      <Button type="primary" @click="handleSave">保存</Button>
+      <Button @click="handleCancel">
+        {{ $t('applicationManagement.modal.cancel') }}
+      </Button>
+      <Button type="primary" @click="handleSave">
+        {{ $t('applicationManagement.modal.save') }}
+      </Button>
     </div>
 
     <Modal
       v-model:open="userModalOpen"
       :footer="null"
-      title="添加用户"
+      :title="$t('applicationManagement.modal.users.addUser')"
       width="700"
     >
       <div class="space-y-4">
         <Input
           v-model:value="userSearchKeyword"
-          placeholder="搜索用户"
+          :placeholder="
+            $t('applicationManagement.modal.users.searchPlaceholder')
+          "
           @change="handleUserSearch"
         />
         <Table
           :columns="[
             {
-              title: '账户',
+              title: $t('applicationManagement.modal.users.account'),
               dataIndex: 'account',
               key: 'account',
               ellipsis: true,
               width: 120,
             },
             {
-              title: '姓名',
+              title: $t('applicationManagement.modal.users.name'),
               dataIndex: 'name',
               key: 'name',
               ellipsis: true,
               width: 120,
             },
             {
-              title: '邮箱',
+              title: $t('applicationManagement.modal.users.emailAddress'),
               dataIndex: 'emailAddress',
               key: 'emailAddress',
               ellipsis: true,
               width: 150,
             },
             {
-              title: '电话号码',
+              title: $t('applicationManagement.modal.users.cellPhone'),
               dataIndex: 'cellPhone',
               key: 'cellPhone',
               ellipsis: true,
               width: 120,
             },
-            { title: '操作', key: 'action' },
+            {
+              title: $t('applicationManagement.modal.users.action'),
+              key: 'action',
+            },
           ]"
           :data-source="allUsers"
           :pagination="{
@@ -816,7 +942,8 @@ function resetFormData() {
             pageSize: userPagination.pageSize,
             total: userPagination.total,
             showSizeChanger: true,
-            showTotal: (total: number) => `共 ${total} 条`,
+            showTotal: (total: number) =>
+              $t('applicationManagement.modal.users.total', { total }),
           }"
           :scroll="{ y: 460 }"
           class="user-table"
@@ -829,7 +956,7 @@ function resetFormData() {
                 type="primary"
                 @click="handleUserSelect(record)"
               >
-                选择
+                {{ $t('applicationManagement.modal.users.select') }}
               </Button>
             </template>
           </template>

+ 40 - 21
apps/web-velofex/src/views/dashboard/application-management/index.vue

@@ -75,11 +75,11 @@ function handleMenuClick({ key }: { key: string }, item: any) {
     handleEdit(item);
   } else if (key === 'Remove') {
     Modal.confirm({
-      title: 'Are you sure delete this task?',
-      content: 'Some descriptions',
-      okText: 'Yes',
+      title: $t('applicationManagement.deleteConfirm'),
+      content: $t('applicationManagement.deleteDescription'),
+      okText: $t('btn.yes'),
       okType: 'danger',
-      cancelText: 'No',
+      cancelText: $t('btn.no'),
       onOk() {
         deleteApplication(item);
       },
@@ -183,7 +183,7 @@ async function deleteApplication(item: any) {
     });
     if (result?.result) {
       fetchApplicationList();
-      message.success('删除成功!');
+      message.success($t('applicationManagement.deleteSuccess'));
     }
   } catch (error) {
     console.error('删除应用失败:', error);
@@ -208,13 +208,22 @@ watch(
   <div class="p-5">
     <div class="mb-4 flex items-center justify-between">
       <div class="text-sm text-[#462424] text-gray-500">
-        Dashboard / Application Management
+        {{ $t('applicationManagement.breadcrumb') }}
       </div>
       <div
-        class="cursor-pointer text-[16px] font-bold text-[#462424]"
+        class="flex cursor-pointer items-center gap-[9px] text-[16px] font-bold text-[#462424]"
         @click="handleBack"
       >
-        Back
+        <div
+          class="global-color flex h-[22px] w-[22px] items-center justify-center rounded-full"
+        >
+          <img
+            alt=""
+            class="h-[11px] w-[10px]"
+            src="@/assets/image/the-left.png"
+          />
+        </div>
+        {{ $t('btn.back') }}
       </div>
     </div>
 
@@ -224,7 +233,9 @@ watch(
 
     <div class="mb-4 flex flex-wrap items-center gap-4">
       <div class="flex flex-col gap-1">
-        <label class="text-[11px] text-[#000]">Application Name:</label>
+        <label class="text-[11px] text-[#000]">{{
+          $t('applicationManagement.applicationName')
+        }}</label>
         <Input
           v-model:value="searchParams.applicationName"
           class="h-[42px] w-[147px] rounded-[11px] border-[#707070]"
@@ -232,7 +243,9 @@ watch(
         />
       </div>
       <div class="flex flex-col gap-1">
-        <label class="text-[11px] text-[#000]">Application ID:</label>
+        <label class="text-[11px] text-[#000]">{{
+          $t('applicationManagement.applicationId')
+        }}</label>
         <Input
           v-model:value="searchParams.applicationId"
           class="h-[42px] w-[89px] rounded-[11px] border-[#707070]"
@@ -240,16 +253,20 @@ watch(
         />
       </div>
       <div class="flex flex-col gap-1">
-        <label class="text-[11px] text-[#000]">Cooperate Partner:</label>
+        <label class="text-[11px] text-[#000]">{{
+          $t('applicationManagement.cooperatePartner')
+        }}</label>
         <Select
           v-model:value="searchParams.cooperatePartner"
           :options="applicationMenu"
+          :placeholder="$t('applicationManagement.chooseCooperatePartner')"
           class="h-[42px] w-[168px] rounded-[11px] border-[#707070] text-[12px]"
-          placeholder="Choose Coope Partner"
         />
       </div>
       <div class="ml-[86px] flex flex-col gap-1">
-        <label class="text-[11px] text-[#000]">Activate Now:</label>
+        <label class="text-[11px] text-[#000]">{{
+          $t('applicationManagement.activateNow')
+        }}</label>
         <div class="flex h-[42px] items-center gap-2">
           <label
             class="flex cursor-pointer items-center gap-2 text-sm"
@@ -263,7 +280,7 @@ watch(
                 class="h-[14px] w-[14px] flex-shrink-0 rounded-[3px] bg-[#462424]"
               ></div>
             </div>
-            Yes
+            {{ $t('btn.yes') }}
           </label>
           <label
             class="flex cursor-pointer items-center gap-2 text-sm"
@@ -277,7 +294,7 @@ watch(
                 class="h-[14px] w-[14px] flex-shrink-0 rounded-[3px] bg-[#462424]"
               ></div>
             </div>
-            No
+            {{ $t('btn.no') }}
           </label>
         </div>
       </div>
@@ -304,7 +321,7 @@ watch(
               stroke-width="2"
             />
           </svg>
-          Search
+          {{ $t('btn.search') }}
         </Button>
         <Button class="h-[42px]" @click="handleClear">
           <svg
@@ -328,7 +345,7 @@ watch(
               stroke-width="2"
             />
           </svg>
-          Clear
+          {{ $t('btn.reset') }}
         </Button>
         <Button class="h-[42px]" type="primary" @click="handleAddNew">
           <img
@@ -336,12 +353,14 @@ watch(
             class="h-[21.5px] w-[21.5px] cursor-pointer"
             src="@/assets/image/new.png"
           />
-          Add New
+          {{ $t('btn.addNew') }}
         </Button>
       </div>
     </div>
 
-    <div v-if="loading" class="py-8 text-center">加载中...</div>
+    <div v-if="loading" class="py-8 text-center">
+      {{ $t('applicationManagement.loading') }}
+    </div>
     <div
       v-else-if="applicationList.length === 0"
       class="mt-[100px] py-8 text-center text-gray-500"
@@ -362,8 +381,8 @@ watch(
         <Dropdown
           :menu="{
             items: [
-              { key: 'Edit', label: 'Edit' },
-              { key: 'Remove', label: 'Remove' },
+              { key: 'Edit', label: $t('applicationManagement.edit') },
+              { key: 'Remove', label: $t('applicationManagement.remove') },
             ],
           }"
           placement="bottom"

+ 1 - 1
apps/web-velofex/src/views/dashboard/home/sales-partners.vue

@@ -11,7 +11,7 @@ const isLogin = computed(() => !!userStore.userInfo);
 
 <template>
   <div class="info-card border-box h-[217px] w-full rounded-lg p-5 shadow-md">
-    <div class="items-flex-start flex justify-between">
+    <div class="flex items-start justify-between">
       <div>
         <h2 class="text-lg font-bold">{{ $t('homeModule.salesPartners') }}</h2>
         <div class="text-xs text-[#9A9BA3]">Sales Partners</div>

+ 4 - 2
apps/web-velofex/src/views/dashboard/home/user-info.vue

@@ -48,7 +48,9 @@ function openLogin() {
     >
       <img alt="" class="h-[3px] w-[15px]" src="@/assets/image/more.png" />
     </div>
-    <div v-if="logOutShow" class="more-bg" @click="handleLogout">log out</div>
+    <div v-if="logOutShow" class="more-bg" @click="handleLogout">
+      {{ $t('auth.logout') }}
+    </div>
     <div v-if="!isLogin">
       <h2 class="mb-[5px] mt-[15px] text-[15px] font-bold">
         {{ $t('homeModule.helloWelcome') }}
@@ -90,7 +92,7 @@ function openLogin() {
         class="h-[12.95px] w-[12.95px]"
         src="@/assets/image/edit.png"
       />
-      <span>Edit Profile</span>
+      <span>{{ $t('homeModule.editProfile') }}</span>
     </div>
   </div>
 </template>