浏览代码

feat:"优化部分页面,远程退币使用MQTT"

soobin 2 月之前
父节点
当前提交
16307ac210

+ 3 - 1
src/assets/language/en.json

@@ -1409,7 +1409,8 @@
     "forgetPassWord": "Forgot Password?",
     "regusterButton": "Register",
     "loginButton": "Login",
-    "loginSucess": "Login Success"
+    "loginSucess": "Login Success",
+    "loginWithWechat": "Login with WeChat"
   },
   "register": {
     "header": "Registration",
@@ -1449,6 +1450,7 @@
     "emailLabel": "Email",
     "emailPlaceholder": "Enter email",
     "emailRequired": "Required",
+    "emailInvalid": "Please enter a valid email address",
     "emailCodeLabel": "Code",
     "emailCodePlaceholder": "Enter code",
     "emailCodeRequired": "Required",

+ 3 - 1
src/assets/language/es.json

@@ -1408,7 +1408,8 @@
         "forgetPassWord": "¿Olvidó contraseña?",
         "regusterButton": "Registrarse",
         "loginButton": "Iniciar sesión",
-        "loginSucess": "Acceso exitoso"
+        "loginSucess": "Acceso exitoso",
+        "loginWithWechat": "Iniciar sesión con WeChat"
     },
     "register": {
         "header": "Registro usuario",
@@ -1448,6 +1449,7 @@
         "emailLabel": "Email",
         "emailPlaceholder": "email",
         "emailRequired": "Requerido",
+        "emailInvalid": "Por favor, introduzca una dirección de correo electrónico válida",
         "emailCodeLabel": "Código email",
         "emailCodePlaceholder": "Ej: ABCD12",
         "emailCodeRequired": "Requerido",

+ 3 - 1
src/assets/language/fr.json

@@ -1439,7 +1439,8 @@
         "forgetPassWord": "Mot de passe oublié ?",
         "regusterButton": "S'inscrire",
         "loginButton": "Connexion",
-        "loginSucess": "Connexion réussie"
+        "loginSucess": "Connexion réussie",
+        "loginWithWechat": "Connexion via WeChat"
     },
     "register": {
         "header": "Inscription",
@@ -1479,6 +1480,7 @@
         "emailLabel": "Email",
         "emailPlaceholder": "Email",
         "emailRequired": "Email requis",
+        "emailInvalid": "Veuillez saisir une adresse e-mail valide",
         "emailCodeLabel": "Code de vérification",
         "emailCodePlaceholder": "Code reçu par email",
         "emailCodeRequired": "Code requis",

+ 3 - 1
src/assets/language/ja.json

@@ -1402,7 +1402,8 @@
         "forgetPassWord": "パスワードを忘れる?",
         "regusterButton": "登録する",
         "loginButton": "ログイン",
-        "loginSucess": "ログイン成功"
+        "loginSucess": "ログイン成功",
+        "loginWithWechat": "WeChatでログイン"
     },
     "register": {
         "header": "ユーザー登録",
@@ -1442,6 +1443,7 @@
         "emailLabel": "メールアドレス",
         "emailPlaceholder": "メールアドレスを入力してください",
         "emailRequired": "メールアドレスを入力してください",
+        "emailInvalid": "有効なメールアドレスを入力してください",
         "emailCodeLabel": "メール認証コード",
         "emailCodePlaceholder": "メール認証コードを入力してください",
         "emailCodeRequired": "メール認証コードを入力してください",

+ 3 - 1
src/assets/language/pt.json

@@ -1408,7 +1408,8 @@
         "forgetPassWord": "Esqueceu a senha?",
         "regusterButton": "Cadastre-se",
         "loginButton": "Entrar",
-        "loginSucess": "Login realizado"
+        "loginSucess": "Login realizado",
+        "loginWithWechat": "Entrar com WeChat"
     },
     "register": {
         "header": "Cadastro de Usuário",
@@ -1448,6 +1449,7 @@
         "emailLabel": "E-mail",
         "emailPlaceholder": "email",
         "emailRequired": "Campo obrigatório",
+        "emailInvalid": "Por favor, insira um endereço de e-mail válido",
         "emailCodeLabel": "Código por E-mail",
         "emailCodePlaceholder": "Ex: ABCD12",
         "emailCodeRequired": "Digite o código",

+ 3 - 1
src/assets/language/ru.json

@@ -1439,7 +1439,8 @@
         "forgetPassWord": "Забыли пароль?",
         "regusterButton": "Регистрация",
         "loginButton": "Войти",
-        "loginSucess": "Успешный вход"
+        "loginSucess": "Успешный вход",
+        "loginWithWechat": "Войти через WeChat"
     },
     "register": {
         "header": "Регистрация",
@@ -1479,6 +1480,7 @@
         "emailLabel": "Email",
         "emailPlaceholder": "Введите email",
         "emailRequired": "Обязательное поле",
+        "emailInvalid": "Пожалуйста, введите действительный адрес электронной почты",
         "emailCodeLabel": "Код из email",
         "emailCodePlaceholder": "Введите код",
         "emailCodeRequired": "Обязательное поле",

+ 3 - 1
src/assets/language/uk.json

@@ -1409,7 +1409,8 @@
         "forgetPassWord": "Забули пароль?",
         "regusterButton": "Реєстрація",
         "loginButton": "Увійти",
-        "loginSucess": "Успішний вхід"
+        "loginSucess": "Успішний вхід",
+        "loginWithWechat": "Увійти через WeChat"
     },
     "register": {
         "header": "Реєстрація",
@@ -1449,6 +1450,7 @@
         "emailLabel": "Пошта",
         "emailPlaceholder": "example@domain.com",
         "emailRequired": "Некоректна пошта",
+        "emailInvalid": "Будь ласка, введіть дійсну адресу електронної пошти",
         "emailCodeLabel": "Код з пошти",
         "emailCodePlaceholder": "Введіть код",
         "emailCodeRequired": "Введіть код",

+ 12 - 10
src/assets/language/zh.json

@@ -1413,22 +1413,23 @@
     "forgetPassWord": "忘记密码 ?",
     "regusterButton": "点击注册",
     "loginButton": "登录",
-    "loginSucess": "登陆成功"
+    "loginSucess": "登陆成功",
+    "loginWithWechat": "快速登录"
   },
   "register": {
     "header": "用户注册",
     "usernameLabel": "登录用户名",
-    "usernamePlaceholder": "请输入登录用户名",
+    "usernamePlaceholder": "登录用户名",
     "usernameRequired": "由字母或数字组成,且只能字母开头",
     "nameLabel": "用户名称",
-    "namePlaceholder": "请输入用户名称",
+    "namePlaceholder": "用户名称",
     "nameRequired": "请输入用户名称",
     "passwordLabel": "登录密码",
-    "passwordPlaceholder": "请输入10位以上密码,包含字母和数字",
+    "passwordPlaceholder": "10位以上密码,包含字母和数字",
     "passwordRequired": "请输入密码",
     "passwordPattern": "密码必须包含字母与数字",
     "passwordCheckLabel": "确认密码",
-    "passwordCheckPlaceholder": "请再次输入密码进行确认",
+    "passwordCheckPlaceholder": "确认密码",
     "passwordCheckRequired": "请再次输入密码进行确认",
     "countryCity": "国家城市",
     "clickCountryCity": "点击选择国家城市",
@@ -1441,23 +1442,24 @@
     "areaRequired": "请选择省市",
     "logonMode": "注册方式",
     "phoneLabel": "手机号码",
-    "phonePlaceholder": "请输入手机号码",
+    "phonePlaceholder": "手机号码",
     "phoneRequired": "请输入正确的手机号码",
     "emailWordSpan": "输入注册海外账户邮箱",
     "emailWordSpanChina": "输入注册时的国内邮箱",
     "seedVerCode": "发送验证码",
     "sending": "发送中",
     "codeLabel": "短信验证码",
-    "codePlaceholder": "请输入短信验证码",
+    "codePlaceholder": "短信验证码",
     "codeRequired": "请输入短信验证码",
     "emailLabel": "邮箱",
-    "emailPlaceholder": "请输入邮箱",
+    "emailPlaceholder": "邮箱",
     "emailRequired": "请输入邮箱",
+    "emailInvalid": "请输入正确的邮箱地址",
     "emailCodeLabel": "验证码",
-    "emailCodePlaceholder": "请输入邮箱验证码",
+    "emailCodePlaceholder": "邮箱验证码",
     "emailCodeRequired": "请输入邮箱验证码",
     "invitationCode": "邀请码",
-    "invitationCodePlaceholder": "请输入邀请码",
+    "invitationCodePlaceholder": "邀请码",
     "registerButton": "注册",
     "replaysInSeconds": "秒后可重发",
     "emailRegistration": "邮箱注册",

+ 1 - 1
src/service/device/index.js

@@ -303,7 +303,7 @@ export function returnCoinList(params) {
 
 // 提交远程退币申请
 export function applyReturnCoin(params) {
-    return axios.post(`/SZWL-SERVER/returnCoinRecord/apply`, params)
+    return axios.post(`/SZWL-SERVER/returnCoinRecord/applyReturn`, params)
 }
 
 // 修改税费开关状态

+ 56 - 2
src/views/device/maintenance/add.vue

@@ -300,8 +300,14 @@ export default {
     const handleFileUpload = async (file) => {
       // 此处添加文件上传逻辑
       try {
-        const fileData = new FormData();
-        fileData.append("file", file.file);
+        const fileData = new FormData();   
+        if (file.file.size > 1000 * 1024) {
+          // 压缩文件
+          const compressedFile = await createCompressedImage(file);
+          fileData.append("file", compressedFile)
+        } else {
+          fileData.append("file", file.file);
+        }
         const { data } = await uploadPic(fileData);
         if (data.code === "00000") {
           pics.value.push(data.data);
@@ -313,6 +319,54 @@ export default {
       }
     };
 
+    // 压缩文件
+    const createCompressedImage = (file) => {
+      return new Promise((resolve, reject) => {
+        const img = new Image();
+        img.src = file.content;
+        
+        img.onload = () => {
+          // 计算新尺寸(保持宽高比)
+          const maxSize = 1920;
+          let width = img.width;
+          let height = img.height;
+          
+          if (width > maxSize || height > maxSize) {
+            const ratio = Math.min(maxSize / width, maxSize / height);
+            width = Math.floor(width * ratio);
+            height = Math.floor(height * ratio);
+          }
+
+          // 创建Canvas进行压缩
+          const canvas = document.createElement('canvas');
+          canvas.width = width;
+          canvas.height = height;
+          
+          const ctx = canvas.getContext('2d');
+          ctx.drawImage(img, 0, 0, width, height);
+
+          // 调整压缩质量(大图用0.7,中等图用0.8)
+          // const quality = file.file.size > 1500 * 1024 ? 0.7 : 0.8;
+          const quality = 0.95;
+
+          
+          canvas.toBlob(
+            blob => {
+              const compressedFile = new File([blob], file.file.name, {
+                type: 'image/jpeg',
+                lastModified: Date.now()
+              });
+              resolve(compressedFile);
+            },
+            'image/jpeg',
+            quality
+          );
+        };
+
+        img.onerror = reject;
+      });
+    }
+
     const handleFileDelete = (file) => {
       pics.value = pics.value.filter(
         (item) => item.split("/pic/")[1] !== file.tempName

+ 0 - 1
src/views/device/paramsSet/paramsSetInfo.vue

@@ -77,7 +77,6 @@
                 v-for="preset in presets"
                 :key="preset.type"
                 type="primary"
-                plain
                 @click="updateInterval(preset.type)"
                 class="preset-btn"
               >

+ 1 - 1
src/views/device/returnCoin/index.vue

@@ -153,7 +153,7 @@ export default {
       }
     };
 
-    // 获取做糖列表数据
+    // 获取退币记录列表数据
     const returnCoinListFun = async () => {
       finished.value = false;
       const { data } = await returnCoinList(searchParams);

+ 0 - 5
src/views/discountCode/index.vue

@@ -23,7 +23,6 @@
         <template v-if="isDelete">
           <van-button
             size="small"
-            plain
             class="action-button"
             @click="cancelClk"
           >
@@ -31,7 +30,6 @@
           </van-button>
           <van-button
             size="small"
-            plain
             type="primary"
             class="action-button"
             @click="allClk"
@@ -59,7 +57,6 @@
             icon="plus"
             type="primary"
             size="small"
-            plain
             class="action-button"
             @click="payCode"
           >
@@ -69,7 +66,6 @@
             icon="delete"
             size="small"
             type="danger"
-            plain
             class="action-button"
             @click="isDelete = true"
           >
@@ -78,7 +74,6 @@
           <van-button
             icon="down"
             size="small"
-            plain
             type="success"
             class="action-button"
             @click="clickExport"

+ 363 - 68
src/views/forgetPassword.vue

@@ -1,67 +1,190 @@
 <template>
-  <!-- 找回密码 -->
-  <div class="forgetPassword flex-col">
-    <s-header :name="$t('forgetPassword.header')" :noback="false"></s-header>
-    <div class="forgetPasswordFormBox">
-      <van-form @submit="forgetPasswordSubmit">
-        <van-field v-model="username" name="username" :placeholder="$t('forgetPassword.usernamePlaceholder')"
-          :rules="[{ required: true, message: $t('forgetPassword.usernameRequired') }]" />
-        <span class="word1">{{ $t('forgetPassword.selectForgetPassword') }}</span>
-        <div class="van-cell van-field">
-          <div class="van-cell__value van-field__value radioBox">
-            <van-radio-group v-model="ifForeign" direction="horizontal">
-              <van-radio name="0" icon-size="18px">{{ $t('forgetPassword.phone') }}</van-radio>
-              <van-radio name="2" icon-size="18px">{{ $t('forgetPassword.emailChina') }}</van-radio>
-              <van-radio name="1" icon-size="18px">{{ $t('forgetPassword.emailAbroad') }}</van-radio>
-            </van-radio-group>
-          </div>
+  <div class="forget-password-container">
+    <!-- 系统头部 -->
+    <s-header :name="$t('forgetPassword.header')" :noback="false" />
+
+    <!-- 主要内容区域 -->
+    <div class="forget-content">
+
+      <!-- 找回密码表单 -->
+      <van-form @submit="forgetPasswordSubmit" class="password-form">
+        <!-- 用户名输入 -->
+        <van-field
+          v-model="username"
+          name="username"
+          :placeholder="$t('forgetPassword.usernamePlaceholder')"
+          :rules="[
+            { required: true, message: $t('forgetPassword.usernameRequired') },
+          ]"
+          label=""
+          class="form-field"
+        >
+          <template #left-icon>
+            <van-icon name="user-o" size="20" class="field-icon" />
+          </template>
+        </van-field>
+
+        <!-- 选择找回方式 -->
+        <div class="recovery-methods">
+          <p class="method-title">
+            {{ $t("forgetPassword.selectForgetPassword") }}
+          </p>
+          <van-radio-group
+            v-model="ifForeign"
+            direction="vertical"
+            class="radio-group"
+          >
+            <van-radio
+              name="0"
+              shape="square"
+              icon-size="20"
+              checked-color="@theme-color"
+            >
+              <div class="radio-option">
+                <van-icon name="phone" size="20" class="radio-icon" />
+                <span>{{ $t("forgetPassword.phone") }}</span>
+              </div>
+            </van-radio>
+
+            <van-radio
+              name="2"
+              shape="square"
+              icon-size="20"
+              checked-color="@theme-color"
+            >
+              <div class="radio-option">
+                <van-icon name="envelop-o" size="20" class="radio-icon" />
+                <span>{{ $t("forgetPassword.emailChina") }}</span>
+              </div>
+            </van-radio>
+
+            <van-radio
+              name="1"
+              shape="square"
+              icon-size="20"
+              checked-color="@theme-color"
+            >
+              <div class="radio-option">
+                <van-icon name="envelop-o" size="20" class="radio-icon" />
+                <span>{{ $t("forgetPassword.emailAbroad") }}</span>
+              </div>
+            </van-radio>
+          </van-radio-group>
         </div>
-        <div v-if="ifForeign === '0'">
-          <span class="word2">{{ $t('forgetPassword.phoneWordSpan') }}</span>
-          <van-field v-model="phone" name="phone" type="tel" :placeholder="$t('forgetPassword.phonePlaceholder')"
-            :rules="[{ required: true, message: $t('forgetPassword.phoneRequired') }]" />
+
+        <!-- 联系方式输入 -->
+        <div class="contact-input" v-if="ifForeign === '0'">
+          <p class="method-title">{{ $t("forgetPassword.phoneWordSpan") }}</p>
+          <van-field
+            v-model="phone"
+            name="phone"
+            type="tel"
+            :placeholder="$t('forgetPassword.phonePlaceholder')"
+            :rules="[
+              { required: true, message: $t('forgetPassword.phoneRequired') },
+            ]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="phone-o" size="20" class="field-icon" />
+            </template>
+          </van-field>
         </div>
-        <div v-if="ifForeign === '2'">
-          <span class="word2">{{ $t('forgetPassword.emailWordSpanChina') }}</span>
-          <van-field v-model="email" name="email" :placeholder="$t('forgetPassword.emailPlaceholder')"
-            :rules="[{ required: true, message: $t('forgetPassword.emailRequired') }]" />
+
+        <div class="contact-input" v-if="ifForeign === '2'">
+          <p class="method-title">
+            {{ $t("forgetPassword.emailWordSpanChina") }}
+          </p>
+          <van-field
+            v-model="email"
+            name="email"
+            :placeholder="$t('forgetPassword.emailPlaceholder')"
+            :rules="[
+              { required: true, message: $t('forgetPassword.emailRequired') },
+            ]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="envelop-o" size="20" class="field-icon" />
+            </template>
+          </van-field>
         </div>
-        <div v-if="ifForeign === '1'">
-          <span class="word2">{{ $t('forgetPassword.emailWordSpan') }}</span>
-          <van-field v-model="email" name="email" :placeholder="$t('forgetPassword.emailPlaceholder')"
-            :rules="[{ required: true, message: $t('forgetPassword.emailRequired') }]" />
+
+        <div class="contact-input" v-if="ifForeign === '1'">
+          <p class="method-title">{{ $t("forgetPassword.emailWordSpan") }}</p>
+          <van-field
+            v-model="email"
+            name="email"
+            :placeholder="$t('forgetPassword.emailPlaceholder')"
+            :rules="[
+              { required: true, message: $t('forgetPassword.emailRequired') },
+            ]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="envelop-o" size="20" class="field-icon" />
+            </template>
+          </van-field>
         </div>
-        <van-field v-model="code" name="code" :placeholder="$t('forgetPassword.codePlaceholder')"
-          :rules="[{ required: true, message: $t('forgetPassword.codeRequired') }]">
-          <template #button>
-            <van-button size="small" type="primary" @click="seedVerCode()" :disabled="time !== 0">{{ time === 0 ?
-              $t('forgetPassword.seedVerCode') : time + '秒后可重发' }}</van-button>
-          </template>
-        </van-field>
-        <van-button round type="primary" class="register" native-type="submit">{{ $t('forgetPassword.registerButton')
-        }}</van-button>
+
+        <!-- 验证码输入 -->
+        <div class="verification-code">
+          <van-field
+            v-model="code"
+            name="code"
+            :placeholder="$t('forgetPassword.codePlaceholder')"
+            :rules="[
+              { required: true, message: $t('forgetPassword.codeRequired') },
+            ]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="comment-o" size="20" class="field-icon" />
+            </template>
+
+            <template #button>
+              <van-button
+                size="small"
+                class="code-button"
+                @click="seedVerCode()"
+                :disabled="time !== 0"
+              >
+                {{
+                  time === 0
+                    ? $t("forgetPassword.seedVerCode")
+                    : `${time} s`
+                }}
+              </van-button>
+            </template>
+          </van-field>
+        </div>
+
+        <!-- 提交按钮 -->
+        <van-button round block native-type="submit" class="submit-button">
+          {{ $t("forgetPassword.registerButton") }}
+        </van-button>
       </van-form>
     </div>
   </div>
 </template>
 
 <script>
-import { ref, reactive, toRefs, onMounted } from 'vue';
-import { showToast, showFailToast  } from 'vant';
-import { setLocal, getLocal, styleUrl } from '@/common/js/utils';
+import { ref, reactive, toRefs, onMounted } from "vue";
+import { showToast, showFailToast } from "vant";
+import { setLocal, getLocal, styleUrl } from "@/common/js/utils";
 import sHeader from "@/components/SimpleHeader";
 import { useRouter } from "vue-router";
-import { sentForgetCode, checkForgetCode } from '@/service/forgetPassword';
+import { sentForgetCode, checkForgetCode } from "@/service/forgetPassword";
 
 export default {
   setup() {
-    const username = ref(''); // 用户名
-    const ifForeign = ref('0'); // 手机号&邮箱状态
-    const email = ref(''); // 邮箱
-    const phone = ref(''); // 手机号
-    const code = ref(''); // 验证码
+    const username = ref(""); // 用户名
+    const ifForeign = ref("0"); // 手机号&邮箱状态
+    const email = ref(""); // 邮箱
+    const phone = ref(""); // 手机号
+    const code = ref(""); // 验证码
     const verCodeTime = reactive({
-      time: 0
+      time: 0,
     }); // 验证码间隔时间及状态
     const router = useRouter();
     // 发送验证码
@@ -69,31 +192,40 @@ export default {
       const { data } = await sentForgetCode({
         username: username.value,
         ifForeign: ifForeign.value,
-        phoneOrEmail: ifForeign.value === '0' ? phone.value : email.value,
-        hostName: 'Sunzee'
+        phoneOrEmail: ifForeign.value === "0" ? phone.value : email.value,
+        hostName: "Sunzee",
       });
-      if (data.code === '00000') {
-        showToast('验证码发送成功');
+      if (data.code === "00000") {
+        showToast("验证码发送成功");
         verCodeTime.time = 3 * 60;
         verCodeTimeInterval();
-      } else { showFailToast(data.message); }
-    }
+      } else {
+        showFailToast(data.message);
+      }
+    };
     // 验证码发送成功开始3分钟倒计时
     const verCodeTimeInterval = () => {
       verCodeTime.time--;
-      setLocal('forgetVerCodeTime', verCodeTime.time)
-      if (verCodeTime.time !== 0) { setTimeout(() => { verCodeTimeInterval(); }, 1000); }
-    }
+      setLocal("forgetVerCodeTime", verCodeTime.time);
+      if (verCodeTime.time !== 0) {
+        setTimeout(() => {
+          verCodeTimeInterval();
+        }, 1000);
+      }
+    };
     // 验证-表单
     const forgetPasswordSubmit = async () => {
       const { data } = await checkForgetCode({
         ifForeign: ifForeign.value,
-        phoneOrEmail: ifForeign.value === '0' ? phone.value : email.value,
-        code: code.value
+        phoneOrEmail: ifForeign.value === "0" ? phone.value : email.value,
+        code: code.value,
       });
-      if (data.code === '00000') {
-        showToast('校验成功');
-        router.push({ path: '/changepassword', query: { name: username.value } });
+      if (data.code === "00000") {
+        showToast("校验成功");
+        router.push({
+          path: "/changepassword",
+          query: { name: username.value },
+        });
       } else {
         showFailToast(data.message);
       }
@@ -101,12 +233,16 @@ export default {
 
     // 初始化页面获取验证码倒计时
     onMounted(async () => {
-      styleUrl('forgetPassword');
-      verCodeTime.time = getLocal('forgetVerCodeTime');
-      if (verCodeTime.time && verCodeTime.time !== '') {
+      styleUrl("forgetPassword");
+      verCodeTime.time = getLocal("forgetVerCodeTime");
+      if (verCodeTime.time && verCodeTime.time !== "") {
         verCodeTime.time = parseInt(verCodeTime.time);
-        if (verCodeTime.time > 0) { verCodeTimeInterval(); }
-      } else { verCodeTime.time = 0; }
+        if (verCodeTime.time > 0) {
+          verCodeTimeInterval();
+        }
+      } else {
+        verCodeTime.time = 0;
+      }
     });
 
     return {
@@ -117,7 +253,7 @@ export default {
       email,
       code,
       seedVerCode,
-      forgetPasswordSubmit
+      forgetPasswordSubmit,
     };
   },
   components: { sHeader },
@@ -125,5 +261,164 @@ export default {
 </script>
 
 <style lang="less" scoped>
-@import "../common/style/mixin";
+@theme-color: #4d6add;
+
+.forget-password-container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  background: #f5f8ff;
+  overflow-y: auto;
+}
+
+.forget-content {
+  background: #f5f6fa;
+  height: calc(100% - 45px);
+  overflow: auto;
+  overflow-x: hidden;
+}
+
+.password-form {
+  background-color: #fff;
+  border-radius: 16px;
+  padding: 25px;
+  margin: 15px;
+  box-shadow: 0 8px 20px rgba(77, 106, 221, 0.12);
+}
+
+.form-field {
+  display: flex;
+  align-items: center;
+  text-align: center;
+  margin-bottom: 20px;
+  border-radius: 12px;
+  background-color: #f9faff;
+  padding: 15px 16px;
+
+  :deep(.van-field__control) {
+    padding-left: 8px;
+    font-size: 15px;
+  }
+
+  :deep(.van-field__error-message) {
+    margin-left: 10px;
+  }
+
+  .field-icon {
+    color: @theme-color;
+  }
+}
+
+.recovery-methods {
+  margin-bottom: 15px;
+
+  .method-title {
+    font-size: 15px;
+    color: #1c2b56;
+    font-weight: 500;
+    margin-bottom: 12px;
+  }
+}
+
+.radio-group {
+  .van-radio {
+    margin-bottom: 12px;
+
+    :deep(.van-radio__label) {
+      flex: 1;
+      margin-left: 12px;
+    }
+
+    :deep(.van-radio__icon--checked .van-icon) {
+      background-color: @theme-color;
+      border-color: @theme-color;
+    }
+  }
+
+  .radio-option {
+    display: flex;
+    align-items: center;
+    padding: 12px 0;
+    font-size: 16px;
+
+    .radio-icon {
+      color: @theme-color;
+      margin-right: 10px;
+    }
+  }
+}
+
+.contact-input,
+.verification-code {
+  margin-bottom: 5px;
+
+  .method-title {
+    font-size: 15px;
+    color: #1c2b56;
+    font-weight: 500;
+    margin: 15px 0 12px;
+  }
+}
+
+.verification-code {
+  margin-top: 15px;
+}
+
+.code-button {
+  background-color: @theme-color;
+  color: white;
+  border-radius: 20px;
+  font-size: 14px;
+  padding: 0 15px;
+  height: 34px;
+
+  &:disabled {
+    background-color: #ccc;
+    color: #fff;
+  }
+}
+
+.submit-button {
+  background: linear-gradient(to right, @theme-color, #6878eb);
+  color: white;
+  border: none;
+  height: 50px;
+  font-size: 17px;
+  font-weight: 500;
+  margin-top: 25px;
+  box-shadow: 0 4px 15px rgba(77, 106, 221, 0.35);
+
+  &:active {
+    opacity: 0.9;
+  }
+}
+
+.password-footer {
+  text-align: center;
+  padding: 25px 0;
+  font-size: 15px;
+  color: #666;
+
+  .login-link {
+    color: @theme-color;
+    font-weight: 500;
+    margin-left: 5px;
+    cursor: pointer;
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+}
+
+@media (max-width: 480px) {
+  .password-form {
+    padding: 20px 18px;
+  }
+
+  .submit-button {
+    height: 48px;
+    font-size: 16px;
+  }
+}
 </style>

+ 347 - 73
src/views/login.vue

@@ -1,45 +1,99 @@
 <template>
-  <!-- 登录 -->
-  <div class="login">
-    <!-- <s-header :name="sys ? sys.title : $t('public.sysName')" :noback="true"></s-header> -->
-    <s-header :name="sys ? sys.title : (sysTitle == 'AETI GLOBAL' ? sysTitle : $t('public.sysName'))" :noback="true"></s-header>
-    <div class="loginLogoBox">
-      <div class="loginLogo">
-        <img :src="logoName" alt="Logo">
-      </div>
-    </div>
-    <div class="loginFormBox">
-      <van-form @submit="onSubmit">
-        <van-field v-model="userName" name="userName" label="" :placeholder="$t('login.userNameInput')"
-          :rules="[{ required: true, message: $t('login.userNameInput') }]" />
-        <van-field v-model="userPwd" type="password" name="userPwd" label="" :placeholder="$t('login.passWordInput')"
-          :rules="[{ required: true, message: $t('login.passWordInput') }]" />
-        <div class="checkedPasswordBox l-flex-RC">
-          <van-checkbox style="font-size: 0.5rem;" class="checkedPassWord" v-model="checked">
-            {{ $t("login.checkedPassWord") }}
-          </van-checkbox>
-          <span class="forgetPassWord" @click="forgetPassword">{{
-            $t("login.forgetPassWord")
-          }}</span>
-        </div>
-        <br>
-        <br>
-        <!-- 微信登录 -->
-        <div v-if="isInWeChat" class="loginWithWechatClass">
-          <van-button class="wechat-btn" type="primary" size="large" @click="wxLoginHandler">
-            <van-icon name="wechat" color="#1bd66c" size="40" class="wechat-icon" />
-          </van-button>
+  <div class="login-container">
+    <!-- 系统头部 -->
+    <s-header
+      :name="
+        sys
+          ? sys.title
+          : sysTitle == 'AETI GLOBAL'
+          ? sysTitle
+          : $t('public.sysName')
+      "
+      :noback="true"
+    />
+
+    <!-- 主要内容区域 -->
+    <div class="login-content">
+      <!-- Logo区域 -->
+      <div class="logo-section">
+        <div class="logo-container">
+          <img :src="logoName" alt="System Logo" class="system-logo" />
         </div>
+      </div>
 
-        <div class="buttonBox">
-          <van-button round type="primary" class="register" @click="registerClick">{{ $t("login.regusterButton") }}
-          </van-button>
-          <van-button round type="primary" native-type="submit">{{
-            $t("login.loginButton")
-          }}
+      <!-- 登录表单 -->
+      <div class="form-container">
+        <van-form @submit="onSubmit" class="login-form">
+          <!-- 用户名输入 -->
+          <van-field
+            v-model="userName"
+            name="userName"
+            :placeholder="$t('login.userNameInput')"
+            :rules="[{ required: true, message: $t('login.userNameInput') }]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="user-o" size="22" class="field-icon" />
+            </template>
+          </van-field>
+
+          <!-- 密码输入 -->
+          <van-field
+            v-model="userPwd"
+            name="userPwd"
+            type="password"
+            :placeholder="$t('login.passWordInput')"
+            :rules="[{ required: true, message: $t('login.passWordInput') }]"
+            class="form-field"
+          >
+            <template #left-icon>
+              <van-icon name="lock" size="22" class="field-icon" />
+            </template>
+          </van-field>
+
+          <!-- 记住密码和忘记密码 -->
+          <div class="password-options">
+            <div class="remember-me">
+              <van-checkbox v-model="checked" shape="square" icon-size="20">
+                {{ $t("login.checkedPassWord") }}
+              </van-checkbox>
+            </div>
+
+            <div class="forgot-password" @click="forgetPassword">
+              <span>{{ $t("login.forgetPassWord") }}</span>
+              <van-icon name="arrow" size="16" />
+            </div>
+          </div>
+
+          <!-- 登录按钮 -->
+          <van-button
+            round
+            block
+            type="primary"
+            native-type="submit"
+            class="login-button"
+          >
+            {{ $t("login.loginButton") }}
           </van-button>
-        </div>
-      </van-form>
+
+          <!-- 微信登录 -->
+          <div v-if="isInWeChat" class="wechat-login" @click="wxLoginHandler">
+            <van-button round block class="wechat-button">
+              <div class="wechat-container">
+                <van-icon name="wechat" size="28" class="wechat-icon" />
+                <span>{{ $t("login.loginWithWechat") }}</span>
+              </div>
+            </van-button>
+          </div>
+
+          <!-- 注册选项 -->
+          <div class="register-option">
+            <span class="register-link" @click="registerClick">{{
+              $t("login.regusterButton")
+            }}</span>
+          </div>
+        </van-form>
+      </div>
     </div>
   </div>
 </template>
@@ -47,14 +101,25 @@
 <script>
 import md5 from "js-md5";
 import { onMounted, ref, computed, reactive } from "vue";
-import { showSuccessToast, showFailToast, showDialog, Dialog, Button } from "vant";
+import {
+  showSuccessToast,
+  showFailToast,
+  showDialog,
+  Dialog,
+  Button,
+} from "vant";
 import { login, getSys, getOpenid } from "../service/login";
-import { setLocal, getLocal, navigatorLanguage, styleUrl } from "../common/js/utils";
+import {
+  setLocal,
+  getLocal,
+  navigatorLanguage,
+  styleUrl,
+} from "../common/js/utils";
 import sHeader from "../components/SimpleHeader";
 import { useRoute, useRouter } from "vue-router";
 import { useI18n } from "vue-i18n";
-import defaultLogo from '../assets/login/logo.png';
-import aetiLogo from '../assets/login/aetiLogo.png';
+import defaultLogo from "../assets/login/logo.png";
+import aetiLogo from "../assets/login/aetiLogo.png";
 
 export default {
   setup() {
@@ -66,14 +131,14 @@ export default {
     const router = useRouter();
     const route = useRoute();
     const sys = ref(null);
-    const currentLan = ref(''); // 当前语言
+    const currentLan = ref(""); // 当前语言
     const logoName = ref(defaultLogo); // Logo图片名称
-    const sysTitle = ref(''); // 页头标题
+    const sysTitle = ref(""); // 页头标题
 
     // 页面初始化
     onMounted(() => {
       // 加载样式
-      styleUrl('login');
+      styleUrl("login");
       // 如果没有语言缓存
       if (!getLocal("curLang")) {
         //  根据浏览器语言重新缓存到localstorage
@@ -83,7 +148,7 @@ export default {
       if (route.query.relation_admin_id) {
         getSysFun();
       }
-      const savedCredentials = localStorage.getItem('savedCredentials');
+      const savedCredentials = localStorage.getItem("savedCredentials");
       if (savedCredentials) {
         checked.value = true;
         const { savedUsername, savedPassword } = JSON.parse(savedCredentials);
@@ -98,15 +163,15 @@ export default {
       // console.log("href >>>", currentDomain);
       // console.log("hostname >>>", window.location.hostname);
       switch (true) {
-        case currentDomain.includes('/aeti/'): // aeti是美国孙总portalmcc.com.cn
+        case currentDomain.includes("/aeti/"): // aeti是美国孙总portalmcc.com.cn
           logoName.value = aetiLogo;
-          sysTitle.value = 'AETI GLOBAL';
+          sysTitle.value = "AETI GLOBAL";
           break;
         default:
           logoName.value = defaultLogo;
-          sysTitle.value = t('public.sysName');
+          sysTitle.value = t("public.sysName");
       }
-    }
+    };
 
     const getSysFun = async () => {
       const { data } = await getSys({
@@ -125,22 +190,25 @@ export default {
       const { data } = await login({
         username: values.userName,
         password: md5(values.userPwd),
-        hostName: 'Sunzee',
+        hostName: "Sunzee",
       });
       console.log(checked.value);
       if (data.code === "00000") {
         setLocal("loginUser", JSON.stringify(data.data));
         if (checked.value) {
-          const savedCredentials = JSON.stringify({ savedUsername: values.userName, savedPassword: values.userPwd });
-          localStorage.setItem('savedCredentials', savedCredentials);
+          const savedCredentials = JSON.stringify({
+            savedUsername: values.userName,
+            savedPassword: values.userPwd,
+          });
+          localStorage.setItem("savedCredentials", savedCredentials);
         } else {
-          const savedCredentials = localStorage.getItem('savedCredentials');
+          const savedCredentials = localStorage.getItem("savedCredentials");
           if (savedCredentials) {
-            localStorage.removeItem('savedCredentials', savedCredentials);
+            localStorage.removeItem("savedCredentials", savedCredentials);
           }
         }
-        showSuccessToast(t('login.loginSucess'));
-        localStorage.setItem('firstLogin', true);
+        showSuccessToast(t("login.loginSucess"));
+        localStorage.setItem("firstLogin", true);
 
         // 需要刷新页面,否则 axios.js 文件里的 token 不会被重置
         // window.location.href = '/shenze/';
@@ -149,7 +217,6 @@ export default {
         }, 200);
       } else {
         showFailToast(data.message);
-
       }
     };
     // 跳转注册页面
@@ -162,39 +229,38 @@ export default {
     };
 
     const state = reactive({
-      isLoading: false
-    })
+      isLoading: false,
+    });
     // 微信登录
     const wxLoginHandler = async () => {
       state.isLoading = true;
       try {
         // 用户静默授权,获取 用户信息
-        const { data } = await getOpenid({ hostName: 'Sunzee' });
-        console.log("微信登录:", data)
+        const { data } = await getOpenid({ hostName: "Sunzee" });
+        console.log("微信登录:", data);
         if (data.code === "00000") {
           window.location.href = data.data;
         } else {
-          showFailToast('微信登录失败:' + data.message);
+          showFailToast("微信登录失败:" + data.message);
         }
       } catch (error) {
-        handleError(error.message || '微信登录失败,请重试');
+        handleError(error.message || "微信登录失败,请重试");
       } finally {
         state.isLoading = false;
       }
-    }
+    };
 
     const isInWeChat = computed(() => {
       const ua = window.navigator.userAgent.toLowerCase();
-      return new RegExp('micromessenger').test(ua);
+      return new RegExp("micromessenger").test(ua);
     });
 
     const handleError = (errMsg) => {
       showDialog({
-        title: '错误提示',
-        message: errMsg
-      })
-    }
-
+        title: "错误提示",
+        message: errMsg,
+      });
+    };
 
     return {
       checked,
@@ -216,11 +282,219 @@ export default {
   components: {
     sHeader,
     [Button.name]: Button,
-    [Dialog.name]: Dialog
+    [Dialog.name]: Dialog,
   },
 };
 </script>
 
 <style lang="less" scoped>
-@import "../common/style/mixin";
+// @import "../common/style/mixin";
+@theme-color: #4d6add;
+
+.login-container {
+  display: flex;
+  flex-direction: column;
+  height: 100vh;
+  overflow: hidden;
+}
+
+.login-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding-top: 30px;
+  // justify-content: center;
+  background: #f5f6fa;
+  height: calc(100% - 45px);
+  overflow: auto;
+  overflow-x: hidden;
+}
+
+.logo-section {
+  margin-bottom: 20px;
+
+  .logo-container {
+    width: 120px;
+    height: 120px;
+    border-radius: 50%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: #fff;
+    box-shadow: 0 4px 20px rgba(2, 77, 163, 0.25);
+    border: 2px solid rgba(2, 77, 163, 0.1);
+    padding: 10px;
+
+    .system-logo {
+      width: 90%;
+    }
+  }
+}
+
+.form-container {
+  width: 100%;
+  max-width: 400px;
+
+  .login-form {
+    margin: 15px;
+    background-color: white;
+    border-radius: 20px;
+    padding: 20px;
+    box-shadow: 0 8px 30px rgba(2, 77, 163, 0.15);
+  }
+
+  .form-field {
+    margin-bottom: 22px;
+    padding: 16px 15px;
+    background-color: #f5f9ff;
+    border-radius: 12px;
+
+    :deep(.van-field__control) {
+      padding-left: 10px;
+      font-size: 16px;
+    }
+
+    .field-icon {
+      color: @theme-color;
+      margin-right: 8px;
+    }
+
+    :deep(.van-field__error-message) {
+      margin-left: 10px;
+    }
+  }
+}
+
+.password-options {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: -8px;
+  margin-bottom: 20px;
+
+  .remember-me {
+    :deep(.van-checkbox__label) {
+      color: #666;
+      font-size: 14px;
+    }
+
+    :deep(.van-checkbox__icon--checked .van-icon) {
+      background-color: @theme-color;
+      border-color: @theme-color;
+    }
+  }
+
+  .forgot-password {
+    display: flex;
+    align-items: center;
+    color: @theme-color;
+    font-size: 14px;
+    cursor: pointer;
+
+    span {
+      margin-right: 4px;
+    }
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+}
+
+.login-button {
+  height: 50px;
+  font-size: 18px;
+  font-weight: 500;
+  color: white;
+  background: linear-gradient(135deg, @theme-color, #0f6fee);
+  border: none;
+  margin-top: 15px;
+  margin-bottom: 20px;
+  box-shadow: 0 4px 15px rgba(2, 77, 163, 0.3);
+
+  &:active {
+    opacity: 0.95;
+    transform: translateY(1px);
+  }
+}
+
+.wechat-login {
+  margin: 20px 0;
+
+  .wechat-button {
+    height: 50px;
+    background-color: #07c160;
+    border: none;
+    color: white;
+    font-weight: 500;
+
+    &:active {
+      background-color: #06ae56;
+    }
+  }
+
+  .wechat-container {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+
+    .wechat-icon {
+      margin-right: 10px;
+      color: white;
+    }
+  }
+}
+
+.register-option {
+  text-align: center;
+  margin-top: 25px;
+  color: #666;
+  font-size: 15px;
+
+  .register-link {
+    color: @theme-color;
+    font-weight: 500;
+    margin-left: 8px;
+    cursor: pointer;
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+}
+
+.footer-container {
+  text-align: center;
+  padding: 15px 0;
+
+  .app-version {
+    font-size: 13px;
+    color: #888;
+    margin-bottom: 5px;
+  }
+
+  .copyright {
+    font-size: 12px;
+    color: #999;
+  }
+}
+
+@media (max-width: 480px) {
+
+  .logo-section .logo-container {
+    width: 150px;
+    height: 150px;
+  }
+
+  .login-button,
+  .wechat-button {
+    height: 46px;
+    font-size: 16px;
+  }
+
+  .form-field {
+    padding: 12px 15px;
+  }
+}
 </style>

文件差异内容过多而无法显示
+ 651 - 229
src/views/register.vue