Jelajahi Sumber

修改部分UI

Huanyi 2 minggu lalu
induk
melakukan
0b849fbb57

+ 2 - 0
src/api/system/phone/index.ts

@@ -4,6 +4,7 @@ export interface PhoneVO {
   id: number;
   expertPhone: string;
   servicePhone: string;
+  salesPhone: string;
   updateTime: string;
 }
 
@@ -11,6 +12,7 @@ export interface PhoneForm {
   id: number;
   expertPhone: string;
   servicePhone: string;
+  salesPhone: string;
 }
 
 /**

+ 258 - 127
src/views/login.vue

@@ -1,51 +1,66 @@
 <template>
-  <div class="login" v-loading="pageLoading" element-loading-background="rgba(0,0,0,0.6)">
+  <div class="login" v-loading="pageLoading" element-loading-background="rgba(255,255,255,0.9)">
     <template v-if="!pageLoading">
-      <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
-        <div class="title-box">
-          <h3 class="title">{{ title }}</h3>
-          <lang-select />
+      <div class="login-container">
+        <div class="login-left">
+          <div class="brand-area">
+            <div class="brand-logo">
+              <svg-icon icon-class="system" class="logo-icon" />
+            </div>
+            <h1 class="brand-title">{{ title }}</h1>
+            <p class="brand-desc">华晟ERP订单管理系统</p>
+          </div>
         </div>
-        <el-form-item v-if="tenantEnabled" prop="tenantId">
-          <el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')"
-            style="width: 100%">
-            <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName"
-              :value="item.tenantId"></el-option>
-            <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-          </el-select>
-        </el-form-item>
-        <el-form-item prop="username">
-          <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off"
-            :placeholder="proxy.$t('login.username')">
-            <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-          </el-input>
-        </el-form-item>
-        <el-form-item prop="password">
-          <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off"
-            :placeholder="proxy.$t('login.password')" @keyup.enter="handleLogin">
-            <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-          </el-input>
-        </el-form-item>
-        <el-form-item v-if="captchaEnabled" prop="code">
-          <el-input v-model="loginForm.code" size="large" auto-complete="off" :placeholder="proxy.$t('login.code')"
-            style="width: 63%" @keyup.enter="handleLogin">
-            <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-          </el-input>
-          <div class="login-code">
-            <img :src="codeUrl" class="login-code-img" @click="getCode" />
+        <div class="login-right">
+          <div class="login-card">
+            <h2 class="card-title">欢迎登录</h2>
+            <p class="card-sub">请输入您的账号信息</p>
+            <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+              <el-form-item v-if="tenantEnabled" prop="tenantId">
+                <el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')"
+                  style="width: 100%" size="large">
+                  <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName"
+                    :value="item.tenantId"></el-option>
+                  <template #prefix><svg-icon icon-class="company" class="input-icon" /></template>
+                </el-select>
+              </el-form-item>
+              <el-form-item prop="username">
+                <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off"
+                  :placeholder="proxy.$t('login.username')">
+                  <template #prefix><svg-icon icon-class="user" class="input-icon" /></template>
+                </el-input>
+              </el-form-item>
+              <el-form-item prop="password">
+                <el-input v-model="loginForm.password" type="password" size="large" auto-complete="off"
+                  :placeholder="proxy.$t('login.password')" @keyup.enter="handleLogin">
+                  <template #prefix><svg-icon icon-class="password" class="input-icon" /></template>
+                </el-input>
+              </el-form-item>
+              <el-form-item v-if="captchaEnabled" prop="code">
+                <el-input v-model="loginForm.code" size="large" auto-complete="off"
+                  :placeholder="proxy.$t('login.code')" style="width: 63%" @keyup.enter="handleLogin">
+                  <template #prefix><svg-icon icon-class="validCode" class="input-icon" /></template>
+                </el-input>
+                <div class="login-code">
+                  <img :src="codeUrl" class="login-code-img" @click="getCode" />
+                </div>
+              </el-form-item>
+              <div class="form-options">
+                <el-checkbox v-model="loginForm.rememberMe">{{ proxy.$t('login.rememberPassword') }}</el-checkbox>
+              </div>
+              <el-form-item style="width: 100%; margin-bottom: 0">
+                <el-button :loading="loading" size="large" type="primary" class="login-btn"
+                  @click.prevent="handleLogin">
+                  <span v-if="!loading">{{ proxy.$t('login.login') }}</span>
+                  <span v-else>{{ proxy.$t('login.logging') }}</span>
+                </el-button>
+              </el-form-item>
+            </el-form>
           </div>
-        </el-form-item>
-        <el-checkbox v-model="loginForm.rememberMe" style="margin: 0 0 25px 0">{{ proxy.$t('login.rememberPassword')
-          }}</el-checkbox>
-        <el-form-item style="width: 100%">
-          <el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleLogin">
-            <span v-if="!loading">{{ proxy.$t('login.login') }}</span>
-            <span v-else>{{ proxy.$t('login.logging') }}</span>
-          </el-button>
-        </el-form-item>
-      </el-form>
-      <div class="el-login-footer">
-        <span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
+        </div>
+      </div>
+      <div class="login-footer">
+        <span>Copyright © 2026 华晟ERP订单管理系统</span>
       </div>
     </template>
   </div>
@@ -213,87 +228,207 @@ onMounted(async () => {
 <style lang="scss" scoped>
 .login {
   display: flex;
+  flex-direction: column;
   justify-content: center;
   align-items: center;
   height: 100%;
-  background-image: url('../assets/images/login-background.jpg');
-  background-size: cover;
-  background-position: center;
-}
+  min-height: 100vh;
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e9f0 50%, #dce3eb 100%);
+  position: relative;
+  overflow: hidden;
 
-.title-box {
-  display: flex;
-  align-items: center;
-  gap: 8px;
-
-  .title {
-    margin: 0px auto 26px auto;
-    text-align: center;
-    color: var(--el-text-color-primary);
-    font-weight: 600;
-    letter-spacing: 0.5px;
+  &::before {
+    content: '';
+    position: absolute;
+    top: -50%;
+    right: -20%;
+    width: 600px;
+    height: 600px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, rgba(26, 115, 232, 0.06) 0%, rgba(26, 115, 232, 0.02) 100%);
+    pointer-events: none;
   }
 
-  :deep(.lang-select--style) {
-    line-height: 0;
-    color: var(--el-text-color-secondary);
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: -30%;
+    left: -10%;
+    width: 400px;
+    height: 400px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, rgba(66, 133, 244, 0.05) 0%, rgba(66, 133, 244, 0.02) 100%);
+    pointer-events: none;
   }
 }
 
-.login-form {
-  border-radius: var(--app-radius-lg);
-  background: rgba(255, 255, 255, 0.94);
-  border: 1px solid rgba(255, 255, 255, 0.5);
-  width: min(420px, 90vw);
-  padding: 32px 30px 12px 30px;
+.login-container {
+  display: flex;
+  width: 960px;
+  min-height: 520px;
+  background: #fff;
+  border-radius: 16px;
+  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
+  overflow: hidden;
   z-index: 1;
-  box-shadow: var(--app-shadow-lg);
-  backdrop-filter: blur(6px);
-  -webkit-backdrop-filter: blur(6px);
+}
 
-  .el-input {
-    height: 40px;
+.login-left {
+  flex: 0 0 420px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #1a73e8 0%, #4285f4 50%, #5b9cf6 100%);
+  position: relative;
+  overflow: hidden;
 
-    input {
-      height: 40px;
-    }
+  &::before {
+    content: '';
+    position: absolute;
+    top: -60px;
+    right: -60px;
+    width: 200px;
+    height: 200px;
+    border-radius: 50%;
+    background: rgba(255, 255, 255, 0.06);
+    pointer-events: none;
   }
 
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 0px;
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: -40px;
+    left: -40px;
+    width: 160px;
+    height: 160px;
+    border-radius: 50%;
+    background: rgba(255, 255, 255, 0.04);
+    pointer-events: none;
   }
 }
 
-.login-tip {
-  font-size: 13px;
+.brand-area {
   text-align: center;
-  color: #bfbfbf;
+  color: #fff;
+  z-index: 1;
+}
+
+.brand-logo {
+  width: 72px;
+  height: 72px;
+  margin: 0 auto 24px;
+  background: rgba(255, 255, 255, 0.15);
+  border-radius: 18px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  backdrop-filter: blur(10px);
+}
+
+.logo-icon {
+  width: 40px;
+  height: 40px;
+  color: #fff;
+}
+
+.brand-title {
+  font-size: 28px;
+  font-weight: 700;
+  margin: 0 0 12px;
+  letter-spacing: 2px;
+}
+
+.brand-desc {
+  font-size: 14px;
+  opacity: 0.85;
+  margin: 0;
+  letter-spacing: 1px;
+}
+
+.login-right {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 48px 40px;
 }
 
-.login-form :deep(.el-input__wrapper) {
-  background-color: rgba(255, 255, 255, 0.9);
+.login-card {
+  width: 100%;
+  max-width: 360px;
+}
+
+.card-title {
+  font-size: 24px;
+  font-weight: 700;
+  color: #1a1a2e;
+  margin: 0 0 8px;
 }
 
-.login-form :deep(.el-input__wrapper.is-focus) {
-  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+.card-sub {
+  font-size: 14px;
+  color: #909399;
+  margin: 0 0 32px;
 }
 
-.login-form :deep(.el-button--primary) {
-  border-radius: var(--app-radius-md);
-  box-shadow: 0 8px 20px rgba(59, 130, 246, 0.25);
+.login-form {
+  .input-icon {
+    height: 16px;
+    width: 16px;
+    color: #909399;
+  }
+
+  :deep(.el-input__wrapper) {
+    border-radius: 8px;
+    box-shadow: 0 0 0 1px #e4e7ed inset;
+    transition: all 0.3s ease;
+
+    &:hover {
+      box-shadow: 0 0 0 1px #c0c4cc inset;
+    }
+  }
+
+  :deep(.el-input__wrapper.is-focus) {
+    box-shadow: 0 0 0 1px #1a73e8 inset;
+  }
+
+  :deep(.el-select .el-input__wrapper) {
+    border-radius: 8px;
+  }
 }
 
-.login-form :deep(.el-button.is-circle) {
-  background: rgba(15, 23, 42, 0.04);
-  border: 1px solid rgba(15, 23, 42, 0.08);
-  color: var(--el-text-color-regular);
+.form-options {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 24px;
+
+  :deep(.el-checkbox__label) {
+    font-size: 13px;
+    color: #606266;
+  }
 }
 
-.login-form :deep(.el-button.is-circle:hover) {
-  background: rgba(59, 130, 246, 0.1);
-  border-color: rgba(59, 130, 246, 0.2);
+.login-btn {
+  width: 100%;
+  height: 44px;
+  border-radius: 8px;
+  font-size: 16px;
+  font-weight: 600;
+  letter-spacing: 2px;
+  background: linear-gradient(135deg, #1a73e8 0%, #4285f4 100%);
+  border: none;
+  box-shadow: 0 4px 15px rgba(26, 115, 232, 0.3);
+  transition: all 0.3s ease;
+
+  &:hover {
+    transform: translateY(-1px);
+    box-shadow: 0 6px 20px rgba(26, 115, 232, 0.4);
+  }
+
+  &:active {
+    transform: translateY(0);
+  }
 }
 
 .login-code {
@@ -301,58 +436,54 @@ onMounted(async () => {
   height: 40px;
   float: right;
   margin-left: 10px;
-  box-sizing: border-box;
-  border-radius: var(--app-radius-sm);
+  border-radius: 8px;
   overflow: hidden;
-  background: rgba(255, 255, 255, 0.9);
-  border: 1px solid var(--el-border-color-light);
+  cursor: pointer;
+  border: 1px solid #e4e7ed;
 
   img {
-    cursor: pointer;
-    vertical-align: middle;
     display: block;
     width: 100%;
-    height: 40px;
+    height: 100%;
     object-fit: cover;
   }
 }
 
-.el-login-footer {
-  height: 40px;
-  line-height: 40px;
+.login-footer {
   position: fixed;
-  bottom: 0;
+  bottom: 24px;
   width: 100%;
   text-align: center;
-  color: rgba(255, 255, 255, 0.75);
-  font-family: Arial, serif;
+  color: #909399;
   font-size: 12px;
-  letter-spacing: 1px;
+  letter-spacing: 0.5px;
+  z-index: 1;
 }
 
-.login-code-img {
-  height: 40px;
-  padding-left: 0;
-}
+@media (max-width: 1000px) {
+  .login-container {
+    width: 90vw;
+    flex-direction: column;
+    min-height: auto;
+  }
 
-:global(html.dark) {
-  .login-form {
-    background: rgba(17, 24, 39, 0.9);
-    border-color: rgba(148, 163, 184, 0.2);
+  .login-left {
+    flex: 0 0 auto;
+    padding: 40px 20px;
   }
 
-  .login-form :deep(.el-input__wrapper) {
-    background-color: rgba(17, 24, 39, 0.7);
+  .login-right {
+    padding: 32px 24px;
   }
 
-  .login-form :deep(.el-button.is-circle) {
-    background: rgba(148, 163, 184, 0.12);
-    border-color: rgba(148, 163, 184, 0.25);
-    color: #e5e7eb;
+  .brand-logo {
+    width: 56px;
+    height: 56px;
+    margin-bottom: 16px;
   }
 
-  .el-login-footer {
-    color: rgba(226, 232, 240, 0.65);
+  .brand-title {
+    font-size: 22px;
   }
 }
 </style>

+ 13 - 2
src/views/order/index.vue

@@ -35,6 +35,11 @@
 
       <el-table v-loading="loading" :data="orderList" border>
         <el-table-column label="订单单号" align="center" prop="code" />
+        <el-table-column label="ERP 单号" align="center" prop="erpDocCode">
+          <template #default="scope">
+            <span>{{ scope.row.erpDocCode || '-' }}</span>
+          </template>
+        </el-table-column>
         <el-table-column label="下单人" align="center" prop="placerName" />
         <el-table-column label="下单时间" align="center" prop="placeTime" width="180">
           <template #default="scope">
@@ -44,7 +49,9 @@
         <el-table-column label="总支数" align="center" prop="totalCount" />
         <el-table-column label="状态" align="center" prop="status">
           <template #default="scope">
-            <el-tag v-if="scope.row.status === 0" type="warning">待审核</el-tag>
+            <el-tag v-if="scope.row.status === -1" type="danger">已撤销</el-tag>
+            <el-tag v-else-if="scope.row.status === 0" type="warning">待审核</el-tag>
+            <el-tag v-else-if="scope.row.status === 1" type="danger">已驳回</el-tag>
             <el-tag v-else-if="scope.row.status === 2" type="primary">待签批</el-tag>
             <el-tag v-else-if="scope.row.status === 3" type="info">生产中</el-tag>
             <el-tag v-else-if="scope.row.status === 4" type="success">已完成</el-tag>
@@ -74,9 +81,12 @@
         <div class="section-title">订单信息</div>
         <el-descriptions :column="2" border size="small">
           <el-descriptions-item label="订单单号" :span="2">{{ detailOrder.code }}</el-descriptions-item>
+          <el-descriptions-item label="ERP 单号" :span="2">{{ detailOrder.erpDocCode || '-' }}</el-descriptions-item>
           <el-descriptions-item label="下单人">{{ detailOrder.placerName }}</el-descriptions-item>
           <el-descriptions-item label="订单状态">
-            <el-tag v-if="detailOrder.status === 0" type="warning">待审核</el-tag>
+            <el-tag v-if="detailOrder.status === -1" type="danger">已撤销</el-tag>
+            <el-tag v-else-if="detailOrder.status === 0" type="warning">待审核</el-tag>
+            <el-tag v-else-if="detailOrder.status === 1" type="danger">已驳回</el-tag>
             <el-tag v-else-if="detailOrder.status === 2" type="primary">待签批</el-tag>
             <el-tag v-else-if="detailOrder.status === 3" type="info">生产中</el-tag>
             <el-tag v-else-if="detailOrder.status === 4" type="success">已完成</el-tag>
@@ -132,6 +142,7 @@ const currentTab = ref(undefined);
 const statusTabs = [
   { label: '全部', value: undefined },
   { label: '待审核', value: 0 },
+  { label: '已驳回', value: 1 },
   { label: '待签批', value: 2 },
   { label: '生产中', value: 3 },
   { label: '已完成', value: 4 }

+ 287 - 104
src/views/register.vue

@@ -1,73 +1,72 @@
 <template>
   <div class="register">
-    <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
-      <div class="title-box">
-        <h3 class="title">{{ title }}</h3>
-        <lang-select />
-      </div>
-      <el-form-item v-if="tenantEnabled" prop="tenantId">
-        <el-select v-model="registerForm.tenantId" filterable :placeholder="proxy.$t('register.selectPlaceholder')" style="width: 100%">
-          <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"> </el-option>
-          <template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
-        </el-select>
-      </el-form-item>
-      <el-form-item prop="username">
-        <el-input v-model="registerForm.username" type="text" size="large" auto-complete="off" :placeholder="proxy.$t('register.username')">
-          <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="password">
-        <el-input
-          v-model="registerForm.password"
-          type="password"
-          size="large"
-          auto-complete="off"
-          :placeholder="proxy.$t('register.password')"
-          @keyup.enter="handleRegister"
-        >
-          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-        </el-input>
-      </el-form-item>
-      <el-form-item prop="confirmPassword">
-        <el-input
-          v-model="registerForm.confirmPassword"
-          type="password"
-          size="large"
-          auto-complete="off"
-          :placeholder="proxy.$t('register.confirmPassword')"
-          @keyup.enter="handleRegister"
-        >
-          <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
-        </el-input>
-      </el-form-item>
-      <el-form-item v-if="captchaEnabled" prop="code">
-        <el-input
-          v-model="registerForm.code"
-          size="large"
-          auto-complete="off"
-          :placeholder="proxy.$t('register.code')"
-          style="width: 63%"
-          @keyup.enter="handleRegister"
-        >
-          <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
-        </el-input>
-        <div class="register-code">
-          <img :src="codeUrl" class="register-code-img" @click="getCode" />
+    <div class="register-container">
+      <div class="register-left">
+        <div class="brand-area">
+          <div class="brand-logo">
+            <svg-icon icon-class="system" class="logo-icon" />
+          </div>
+          <h1 class="brand-title">{{ title }}</h1>
+          <p class="brand-desc">华晟ERP订单管理系统</p>
         </div>
-      </el-form-item>
-      <el-form-item style="width: 100%">
-        <el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleRegister">
-          <span v-if="!loading">{{ proxy.$t('register.register') }}</span>
-          <span v-else>{{ proxy.$t('register.registering') }}</span>
-        </el-button>
-        <div style="float: right">
-          <router-link class="link-type" :to="'/login'">{{ proxy.$t('register.switchLoginPage') }}</router-link>
+      </div>
+      <div class="register-right">
+        <div class="register-card">
+          <h2 class="card-title">创建账号</h2>
+          <p class="card-sub">注册一个新账号以开始使用</p>
+          <el-form ref="registerRef" :model="registerForm" :rules="registerRules" class="register-form">
+            <el-form-item v-if="tenantEnabled" prop="tenantId">
+              <el-select v-model="registerForm.tenantId" filterable
+                :placeholder="proxy.$t('register.selectPlaceholder')" style="width: 100%" size="large">
+                <el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName"
+                  :value="item.tenantId">
+                </el-option>
+                <template #prefix><svg-icon icon-class="company" class="input-icon" /></template>
+              </el-select>
+            </el-form-item>
+            <el-form-item prop="username">
+              <el-input v-model="registerForm.username" type="text" size="large" auto-complete="off"
+                :placeholder="proxy.$t('register.username')">
+                <template #prefix><svg-icon icon-class="user" class="input-icon" /></template>
+              </el-input>
+            </el-form-item>
+            <el-form-item prop="password">
+              <el-input v-model="registerForm.password" type="password" size="large" auto-complete="off"
+                :placeholder="proxy.$t('register.password')" @keyup.enter="handleRegister">
+                <template #prefix><svg-icon icon-class="password" class="input-icon" /></template>
+              </el-input>
+            </el-form-item>
+            <el-form-item prop="confirmPassword">
+              <el-input v-model="registerForm.confirmPassword" type="password" size="large" auto-complete="off"
+                :placeholder="proxy.$t('register.confirmPassword')" @keyup.enter="handleRegister">
+                <template #prefix><svg-icon icon-class="password" class="input-icon" /></template>
+              </el-input>
+            </el-form-item>
+            <el-form-item v-if="captchaEnabled" prop="code">
+              <el-input v-model="registerForm.code" size="large" auto-complete="off"
+                :placeholder="proxy.$t('register.code')" style="width: 63%" @keyup.enter="handleRegister">
+                <template #prefix><svg-icon icon-class="validCode" class="input-icon" /></template>
+              </el-input>
+              <div class="register-code">
+                <img :src="codeUrl" class="register-code-img" @click="getCode" />
+              </div>
+            </el-form-item>
+            <el-form-item style="width: 100%; margin-bottom: 0">
+              <el-button :loading="loading" size="large" type="primary" class="register-btn"
+                @click.prevent="handleRegister">
+                <span v-if="!loading">{{ proxy.$t('register.register') }}</span>
+                <span v-else>{{ proxy.$t('register.registering') }}</span>
+              </el-button>
+            </el-form-item>
+            <div class="form-footer">
+              <router-link class="link-type" :to="'/login'">{{ proxy.$t('register.switchLoginPage') }}</router-link>
+            </div>
+          </el-form>
         </div>
-      </el-form-item>
-    </el-form>
-    <!--  底部  -->
-    <div class="el-register-footer">
-      <span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
+      </div>
+    </div>
+    <div class="register-footer">
+      <span>Copyright © 2026 华晟ERP订单管理系统</span>
     </div>
   </div>
 </template>
@@ -183,81 +182,265 @@ onMounted(() => {
 <style lang="scss" scoped>
 .register {
   display: flex;
+  flex-direction: column;
   justify-content: center;
   align-items: center;
   height: 100%;
-  background-image: url('../assets/images/login-background.jpg');
-  background-size: cover;
+  min-height: 100vh;
+  background: linear-gradient(135deg, #f5f7fa 0%, #e4e9f0 50%, #dce3eb 100%);
+  position: relative;
+  overflow: hidden;
+
+  &::before {
+    content: '';
+    position: absolute;
+    top: -50%;
+    right: -20%;
+    width: 600px;
+    height: 600px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, rgba(26, 115, 232, 0.06) 0%, rgba(26, 115, 232, 0.02) 100%);
+    pointer-events: none;
+  }
+
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: -30%;
+    left: -10%;
+    width: 400px;
+    height: 400px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, rgba(66, 133, 244, 0.05) 0%, rgba(66, 133, 244, 0.02) 100%);
+    pointer-events: none;
+  }
+}
+
+.register-container {
+  display: flex;
+  width: 960px;
+  min-height: 560px;
+  background: #fff;
+  border-radius: 16px;
+  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(0, 0, 0, 0.04);
+  overflow: hidden;
+  z-index: 1;
 }
 
-.title-box {
+.register-left {
+  flex: 0 0 420px;
   display: flex;
+  align-items: center;
+  justify-content: center;
+  background: linear-gradient(135deg, #1a73e8 0%, #4285f4 50%, #5b9cf6 100%);
+  position: relative;
+  overflow: hidden;
 
-  .title {
-    margin: 0px auto 30px auto;
-    text-align: center;
-    color: #707070;
+  &::before {
+    content: '';
+    position: absolute;
+    top: -60px;
+    right: -60px;
+    width: 200px;
+    height: 200px;
+    border-radius: 50%;
+    background: rgba(255, 255, 255, 0.06);
+    pointer-events: none;
   }
 
-  :deep(.lang-select--style) {
-    line-height: 0;
-    color: #7483a3;
+  &::after {
+    content: '';
+    position: absolute;
+    bottom: -40px;
+    left: -40px;
+    width: 160px;
+    height: 160px;
+    border-radius: 50%;
+    background: rgba(255, 255, 255, 0.04);
+    pointer-events: none;
   }
 }
 
+.brand-area {
+  text-align: center;
+  color: #fff;
+  z-index: 1;
+}
+
+.brand-logo {
+  width: 72px;
+  height: 72px;
+  margin: 0 auto 24px;
+  background: rgba(255, 255, 255, 0.15);
+  border-radius: 18px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  backdrop-filter: blur(10px);
+}
+
+.logo-icon {
+  width: 40px;
+  height: 40px;
+  color: #fff;
+}
+
+.brand-title {
+  font-size: 28px;
+  font-weight: 700;
+  margin: 0 0 12px;
+  letter-spacing: 2px;
+}
+
+.brand-desc {
+  font-size: 14px;
+  opacity: 0.85;
+  margin: 0;
+  letter-spacing: 1px;
+}
+
+.register-right {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 48px 40px;
+}
+
+.register-card {
+  width: 100%;
+  max-width: 360px;
+}
+
+.card-title {
+  font-size: 24px;
+  font-weight: 700;
+  color: #1a1a2e;
+  margin: 0 0 8px;
+}
+
+.card-sub {
+  font-size: 14px;
+  color: #909399;
+  margin: 0 0 32px;
+}
+
 .register-form {
-  border-radius: 6px;
-  background: #ffffff;
-  width: 400px;
-  padding: 25px 25px 5px 25px;
+  .input-icon {
+    height: 16px;
+    width: 16px;
+    color: #909399;
+  }
 
-  .el-input {
-    height: 40px;
+  :deep(.el-input__wrapper) {
+    border-radius: 8px;
+    box-shadow: 0 0 0 1px #e4e7ed inset;
+    transition: all 0.3s ease;
 
-    input {
-      height: 40px;
+    &:hover {
+      box-shadow: 0 0 0 1px #c0c4cc inset;
     }
   }
 
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 0;
+  :deep(.el-input__wrapper.is-focus) {
+    box-shadow: 0 0 0 1px #1a73e8 inset;
+  }
+
+  :deep(.el-select .el-input__wrapper) {
+    border-radius: 8px;
+  }
+}
+
+.register-btn {
+  width: 100%;
+  height: 44px;
+  border-radius: 8px;
+  font-size: 16px;
+  font-weight: 600;
+  letter-spacing: 2px;
+  background: linear-gradient(135deg, #1a73e8 0%, #4285f4 100%);
+  border: none;
+  box-shadow: 0 4px 15px rgba(26, 115, 232, 0.3);
+  transition: all 0.3s ease;
+
+  &:hover {
+    transform: translateY(-1px);
+    box-shadow: 0 6px 20px rgba(26, 115, 232, 0.4);
+  }
+
+  &:active {
+    transform: translateY(0);
   }
 }
 
-.register-tip {
-  font-size: 13px;
+.form-footer {
   text-align: center;
-  color: #bfbfbf;
+  margin-top: 20px;
+
+  .link-type {
+    font-size: 14px;
+    color: #1a73e8;
+    text-decoration: none;
+
+    &:hover {
+      text-decoration: underline;
+    }
+  }
 }
 
 .register-code {
-  width: 33%;
+  width: calc(37% - 10px);
   height: 40px;
   float: right;
+  margin-left: 10px;
+  border-radius: 8px;
+  overflow: hidden;
+  cursor: pointer;
+  border: 1px solid #e4e7ed;
 
   img {
-    cursor: pointer;
-    vertical-align: middle;
+    display: block;
+    width: 100%;
+    height: 100%;
+    object-fit: cover;
   }
 }
 
-.el-register-footer {
-  height: 40px;
-  line-height: 40px;
+.register-footer {
   position: fixed;
-  bottom: 0;
+  bottom: 24px;
   width: 100%;
   text-align: center;
-  color: #fff;
-  font-family: Arial, serif;
+  color: #909399;
   font-size: 12px;
-  letter-spacing: 1px;
+  letter-spacing: 0.5px;
+  z-index: 1;
 }
 
-.register-code-img {
-  height: 40px;
-  padding-left: 12px;
+@media (max-width: 1000px) {
+  .register-container {
+    width: 90vw;
+    flex-direction: column;
+    min-height: auto;
+  }
+
+  .register-left {
+    flex: 0 0 auto;
+    padding: 40px 20px;
+  }
+
+  .register-right {
+    padding: 32px 24px;
+  }
+
+  .brand-logo {
+    width: 56px;
+    height: 56px;
+    margin-bottom: 16px;
+  }
+
+  .brand-title {
+    font-size: 22px;
+  }
 }
 </style>

+ 8 - 2
src/views/system/phone/index.vue

@@ -12,6 +12,9 @@
         <el-form-item label="客服电话" prop="servicePhone">
           <el-input v-model="form.servicePhone" placeholder="请输入客服电话" style="width: 300px" maxlength="20" />
         </el-form-item>
+        <el-form-item label="业务员电话" prop="salesPhone">
+          <el-input v-model="form.salesPhone" placeholder="请输入业务员电话" style="width: 300px" maxlength="20" />
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" icon="Check" :loading="saving" @click="handleSave">
             保存
@@ -34,12 +37,14 @@ const formRef = ref();
 const form = reactive<PhoneForm>({
   id: 1,
   expertPhone: '',
-  servicePhone: ''
+  servicePhone: '',
+  salesPhone: ''
 });
 
 const rules = {
   expertPhone: [{ required: true, message: '专家电话不能为空', trigger: 'blur' }],
-  servicePhone: [{ required: true, message: '客服电话不能为空', trigger: 'blur' }]
+  servicePhone: [{ required: true, message: '客服电话不能为空', trigger: 'blur' }],
+  salesPhone: [{ required: true, message: '业务员电话不能为空', trigger: 'blur' }]
 };
 
 /** 加载联系电话 */
@@ -48,6 +53,7 @@ const loadPhone = async () => {
   form.id = res.data.id;
   form.expertPhone = res.data.expertPhone;
   form.servicePhone = res.data.servicePhone;
+  form.salesPhone = res.data.salesPhone;
 };
 
 /** 保存 */

+ 4 - 4
src/views/system/user/profile/userAvatar.vue

@@ -27,16 +27,16 @@
           </el-upload>
         </el-col>
         <el-col :lg="{ span: 1, offset: 2 }" :md="2">
-          <el-button icon="Plus" @click="changeScale(1)">放大</el-button>
+          <el-button icon="Plus" @click="changeScale(1)"></el-button>
         </el-col>
         <el-col :lg="{ span: 1, offset: 1 }" :md="2">
-          <el-button icon="Minus" @click="changeScale(-1)">缩小</el-button>
+          <el-button icon="Minus" @click="changeScale(-1)"></el-button>
         </el-col>
         <el-col :lg="{ span: 1, offset: 1 }" :md="2">
-          <el-button icon="RefreshLeft" @click="rotateLeft()">左转</el-button>
+          <el-button icon="RefreshLeft" @click="rotateLeft()"></el-button>
         </el-col>
         <el-col :lg="{ span: 1, offset: 1 }" :md="2">
-          <el-button icon="RefreshRight" @click="rotateRight()">右转</el-button>
+          <el-button icon="RefreshRight" @click="rotateRight()"></el-button>
         </el-col>
         <el-col :lg="{ span: 2, offset: 6 }" :md="2">
           <el-button type="primary" icon="Check" @click="uploadImg()">提 交</el-button>