weixin_52219567 1 ay önce
ebeveyn
işleme
c818e8188e

+ 55 - 0
src/api/breg/index.ts

@@ -0,0 +1,55 @@
+import request from '@/utils/request';
+
+//获取验证码
+export const smsCode = (query: any) => {
+  return request({
+    url: '/resource/sms/code',
+    method: 'get',
+    params: query
+  });
+};
+
+//查询企业工商信息
+export const selectBusinessByCustomerName = (name: any) => {
+  return request({
+    url: '/customer/businessInfo/selectBusinessByCustomerName/' + name,
+    method: 'get'
+  });
+};
+
+//企业注册
+export const registerCustomer = (params: any) => {
+  return request({
+    url: '/customer/pcCustomer/registerCustomer',
+    method: 'post',
+    data: params
+  });
+};
+
+//企业规模
+export const enterpriseScale = (query: any) => {
+  return request({
+    url: '/customer/enterpriseScale/list',
+    method: 'get',
+    params: query
+  });
+};
+
+//获取经营类目
+export const getProductCategoryList = (query: any) => {
+  return request({
+    url: '/product/category/getProductCategoryList',
+    method: 'get',
+    params: query
+  });
+};
+
+//供应商注册
+
+export const registerSupplier = (params: any) => {
+  return request({
+    url: '/customer/pcCustomer/registerSupplier',
+    method: 'post',
+    data: params
+  });
+};

BIN
src/assets/images/breg.png


+ 3 - 1
src/permission.ts

@@ -23,7 +23,9 @@ const whiteList = [
   '/indexFuli',
   '/reg',
   '/search',
-  '/item'
+  '/item',
+  '/breg',
+  '/greg'
 ];
 
 const isWhiteList = (path: string) => {

+ 2 - 1
src/utils/request.ts

@@ -174,7 +174,8 @@ service.interceptors.response.use(
       return Promise.reject('无效的会话,或者会话已过期,请重新登录。');
     } else if (code === HttpStatus.SERVER_ERROR) {
       ElMessage({ message: msg, type: 'error' });
-      return Promise.reject(new Error(msg));
+      // return Promise.reject(new Error(msg));
+      return Promise.resolve(res.data);
     } else if (code === HttpStatus.WARN) {
       ElMessage({ message: msg, type: 'warning' });
       return Promise.reject(new Error(msg));

+ 333 - 75
src/views/breg/index.vue

@@ -4,106 +4,287 @@
       <img class="head-img" src="@/assets/images/head.png" alt="" />
       <div class="register-login flex-row-between">
         <div></div>
-        <div>
+        <div @click="goLogin">
           <span>已有账号?直接</span>
           <span class="zhu">登录>></span>
         </div>
       </div>
       <div class="progress-bos">
-        <div class="progress-bar hig">
+        <div class="progress-bar" :class="nextNum == 1 ? 'hig1' : 'hig2'">
           <div>01、基本资料</div>
-          <div class="triangle1"></div>
-          <div class="triangle2"></div>
-          <div></div>
         </div>
-        <div class="progress-bar progress-bar2">
+        <div class="progress-bar progress-bar2" :class="nextNum == 2 || nextNum == 3 ? 'hig1' : 'hig2'">
           <div>02、企业信息</div>
-          <div class="triangle1"></div>
-          <div class="triangle2"></div>
         </div>
-        <div class="progress-bar progress-bar2">
+        <div class="progress-bar progress-bar2" :class="nextNum == 4 ? 'hig1' : ''">
           <div>03、完成</div>
         </div>
       </div>
-      <div class="form-bos">
-        <div class="form-title flex-row-start">
-          <div class="star">*</div>
-          <div>姓名</div>
+      <template v-if="nextNum == 1">
+        <div class="form-bos">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>姓名</div>
+          </div>
+          <el-input style="width: 448px" v-model="form.purchaseName" placeholder="请输入姓名" />
+          <div class="form-tip">请输入采购人全名,方便与您联系!</div>
         </div>
-        <el-input style="width: 448px" v-model="form.value1" placeholder="请输入姓名" />
-        <div class="form-tip">请输入采购人全名,方便与您联系!</div>
-      </div>
-      <div class="form-bos" style="margin-top: 8px">
-        <div class="form-title flex-row-start">
-          <div class="star">*</div>
-          <div>手机号码</div>
+        <div class="form-bos" style="margin-top: 8px">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>手机号码</div>
+          </div>
+          <el-input :maxlength="11" style="width: 448px" v-model="form.purchasePhone" placeholder="请输入手机号码">
+            <template #suffix>
+              <span @click="sendSmsCode" :class="['code', countdown > 0 ? 'disabled' : '']">
+                {{ codeText }}
+              </span>
+            </template>
+          </el-input>
         </div>
-        <el-input style="width: 448px" v-model="form.value2" placeholder="请输入手机号码">
-          <template #suffix>
-            <span class="code">发送验证码</span>
-          </template>
-        </el-input>
-      </div>
-      <div class="form-bos form-bos1">
-        <div class="form-title flex-row-start">
-          <div class="star">*</div>
-          <div>验证码</div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>验证码</div>
+          </div>
+          <el-input style="width: 448px" v-model="form.code" placeholder="请输入验证码" />
         </div>
-        <el-input style="width: 448px" v-model="form.value3" placeholder="请输入验证码" />
-      </div>
-      <div class="form-bos form-bos1">
-        <div class="form-title flex-row-start">
-          <div class="star">*</div>
-          <div>密码</div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>密码</div>
+          </div>
+          <el-input type="password" show-password style="width: 448px" v-model="form.password" placeholder="请输入密码" />
         </div>
-        <el-input type="password" show-password style="width: 448px" v-model="form.value4" placeholder="请输入密码" />
-      </div>
-      <div class="form-bos form-bos1">
-        <div class="form-title flex-row-start">
-          <div class="star">*</div>
-          <div>请再次输入密码</div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>请再次输入密码</div>
+          </div>
+          <el-input type="password" show-password style="width: 448px" v-model="form.confirmPassword" placeholder="请输入密码" />
         </div>
-        <el-input type="password" show-password style="width: 448px" v-model="form.value5" placeholder="请输入密码" />
-      </div>
-      <div class="agreement flex-row-start">
+      </template>
+      <template v-if="nextNum == 2">
+        <div class="form-bos">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>企业全称</div>
+          </div>
+          <el-input style="width: 448px" v-model="form.customerName" placeholder="请输入企业全称" />
+        </div>
+      </template>
+      <template v-if="nextNum == 3">
+        <div style="padding: 0 20px">
+          <div class="descriptions-head">{{ enterprise.businessCustomerName || '' }}</div>
+          <el-descriptions class="margin-top" :column="2" border>
+            <template #title>
+              <div class="descriptions-title">工商信息</div>
+            </template>
+            <el-descriptions-item label="企业名称" :span="2">{{ enterprise.businessCustomerName || '' }}</el-descriptions-item>
+            <el-descriptions-item label="法定代表人">{{ enterprise.legalPersonName || '' }}</el-descriptions-item>
+            <el-descriptions-item label="成立时间">{{ enterprise.establishmentDate || '' }}</el-descriptions-item>
+            <el-descriptions-item label="登记状态">{{ enterprise.registrationStatus || '' }}</el-descriptions-item>
+            <el-descriptions-item label="统一社会信用代码">{{ enterprise.socialCreditCode || '' }}</el-descriptions-item>
+            <el-descriptions-item label="注册资本">{{ enterprise.businessCustomerName || '' }}</el-descriptions-item>
+            <el-descriptions-item label="注册地址">{{ enterprise.registeredCapital || '' }}</el-descriptions-item>
+          </el-descriptions>
+        </div>
+      </template>
+      <template v-if="nextNum == 4">
+        <div class="register-success flex-column-center">
+          <img src="@/assets/images/breg.png" alt="" />
+          <div class="success-text">您的账户还在审核中,如有疑问,请致电400-111-0027</div>
+          <el-button @click="goLogin" type="primary">返回登录</el-button>
+        </div>
+      </template>
+      <div class="agreement flex-row-start" v-if="nextNum != 4">
         <el-radio v-model="radio" value="disabled">
           <span>我已阅读并同意</span>
           <span> 《某某政策》</span>
         </el-radio>
       </div>
     </div>
-    <div class="pay-foot">
+    <div class="pay-foot" v-if="nextNum != 4">
       <div class="foot-bos">
-        <el-button class="bnt2" type="primary">下一步</el-button>
-        <el-button class="bnt1">供应商注册</el-button>
+        <el-button @click="previousStep" v-if="nextNum == 2 || nextNum == 3" class="bnt1">返回上一步</el-button>
+        <el-button @click="nextStep" class="bnt2" type="primary" :loading="loading">{{ nextNum == 3 ? '提交并完成注册' : '下一步' }}</el-button>
+        <el-button @click="onPath('/greg')" v-if="nextNum == 1" class="bnt1">供应商注册</el-button>
       </div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
+import { smsCode, selectBusinessByCustomerName, registerCustomer } from '@/api/breg/index';
+import { onUnmounted } from 'vue';
+import { onPath } from '@/utils/siteConfig';
+const nextNum = ref<any>(1);
+const codeText = ref<string>('发送验证码');
+const countdown = ref<number>(0);
+const timer = ref<any>(null);
+const enterprise = ref<any>({});
+const loading = ref(false);
 const form = ref<any>({
-  value1: '',
-  value2: '',
-  value3: '',
-  value4: '',
-  value5: ''
+  purchaseName: '',
+  purchasePhone: '',
+  code: '',
+  password: '',
+  confirmPassword: '',
+  customerName: ''
 });
+
+// 启动倒计时
+const startCountdown = () => {
+  countdown.value = 60;
+  codeText.value = `${countdown.value}s 后重新发送`;
+
+  timer.value = setInterval(() => {
+    countdown.value--;
+    if (countdown.value > 0) {
+      codeText.value = `${countdown.value}s 后重新发送`;
+    } else {
+      clearInterval(timer.value);
+      timer.value = null;
+      codeText.value = '发送验证码';
+    }
+  }, 1000);
+};
+
+// 获取验证码
+const sendSmsCode = () => {
+  if (countdown.value > 0) return;
+
+  if (validateMobile(form.value.purchasePhone)) {
+    smsCode({ phonenumber: form.value.purchasePhone }).then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: '验证码已发送',
+          type: 'success'
+        });
+        startCountdown();
+      }
+    });
+  } else {
+    ElMessage({
+      message: '请输入正确的手机号码',
+      type: 'warning'
+    });
+    return;
+  }
+};
+
+// 验证手机号
+const validateMobile = (phone: any) => {
+  const reg = /^1[3-9]\d{9}$/;
+  return reg.test(phone);
+};
+
+// 验证企业名字
+const validateStrict = (str: any) => {
+  if (typeof str !== 'string') return false;
+
+  const trimmed = str.trim();
+  if (trimmed.length === 0) return false; // 去空格后为空
+
+  return /^[^a-zA-Z0-9]+$/.test(trimmed);
+};
+
+const nextStep = () => {
+  if (nextNum.value == 1) {
+    const errorMsg = {
+      purchaseName: '请输入姓名',
+      purchasePhone: '请输入手机号码',
+      code: '请输入验证码',
+      password: '请输入密码',
+      confirmPassword: '请再次输入密码'
+    };
+    let next1 = true;
+    Object.keys(errorMsg).forEach((key) => {
+      if ((form.value[key] == '' || form.value[key] == undefined || form.value[key] == null) && next1) {
+        next1 = false;
+        ElMessage({
+          message: `${errorMsg[key]}`,
+          type: 'warning'
+        });
+        return;
+      }
+    });
+    if (!next1) return;
+    if (form.value.password != form.value.confirmPassword) {
+      ElMessage({
+        message: `密码不一致`,
+        type: 'warning'
+      });
+      return;
+    }
+    nextNum.value = 2;
+  } else if (nextNum.value == 2) {
+    if (validateStrict(form.value.customerName)) {
+      loading.value = true;
+      selectBusinessByCustomerName(form.value.customerName).then((res: any) => {
+        loading.value = false;
+        if (res.code == 200) {
+          enterprise.value = res.data;
+          nextNum.value = 3;
+        }
+      });
+    } else {
+      ElMessage({
+        message: '企业全称不能有数字或字母',
+        type: 'warning'
+      });
+    }
+  } else {
+    loading.value = true;
+    registerCustomer(form.value).then((res: any) => {
+      loading.value = false;
+      if (res.code == 200) {
+        nextNum.value = 4;
+      }
+    });
+  }
+};
+
+//上一步
+const previousStep = () => {
+  if (nextNum.value == 2) {
+    nextNum.value = 1;
+  }
+  if (nextNum.value == 3) {
+    nextNum.value = 2;
+  }
+};
+
+const goLogin = () => {
+  onPath('/login');
+};
+
 const radio = ref<any>(true);
+
+// 组件卸载时清除定时器
+onUnmounted(() => {
+  if (timer.value) {
+    clearInterval(timer.value);
+    timer.value = null;
+  }
+});
 </script>
 
 <style lang="scss" scoped>
 .register-pages {
   width: 100%;
   background-color: #ffffff;
+
   .register-bos {
     width: 1200px;
     margin: 0 auto;
     padding-top: 20px;
+
     .head-img {
       width: 185px;
       height: 90px;
     }
+
     .register-login {
       font-weight: 400;
       font-size: 14px;
@@ -111,17 +292,20 @@ const radio = ref<any>(true);
       margin-top: 20px;
       padding-bottom: 10px;
       border-bottom: 1px solid #e5e7eb;
+
       .zhu {
         color: #e7000b;
         cursor: pointer;
       }
     }
+
     .progress-bos {
       padding: 20px;
       display: flex;
       margin-bottom: 24px;
+
       .progress-bar {
-        width: 324px;
+        width: 320px;
         height: 40px;
         background: #f7f8fa;
         font-weight: 500;
@@ -130,49 +314,64 @@ const radio = ref<any>(true);
         padding-left: 16px;
         color: #4e5969;
         position: relative;
-        &.hig {
+
+        &.hig1 {
           background: #e7000b;
           color: #ffffff;
-          z-index: 2;
-          .triangle1 {
-            border-bottom: 20px solid #e7000b;
-          }
         }
-        .triangle1 {
+
+        &.hig2 {
+          background: #ffe8e8;
+          color: #1d2129;
+        }
+
+        .triangle10 {
           position: absolute;
           width: 0;
           height: 0;
-          border-left: 20px solid transparent; /* 左边透明 */
-          border-right: 20px solid transparent; /* 右边透明 */
-          border-bottom: 20px solid #f7f8fa; /* 底部边为实际显示的三角形部分 */
-          transform: rotate(90deg); /* 向左旋转90度 */
+          border-left: 20px solid transparent;
+          /* 左边透明 */
+          border-right: 20px solid transparent;
+          /* 右边透明 */
+          border-bottom: 20px solid #f7f8fa;
+          /* 底部边为实际显示的三角形部分 */
+          transform: rotate(90deg);
+          /* 向左旋转90度 */
           top: 10px;
           right: -30px;
-          transform-origin: 50% 50%; /* 设置旋转中心点在元素的中心 */
+          transform-origin: 50% 50%;
+          /* 设置旋转中心点在元素的中心 */
           z-index: 3;
         }
-        .triangle2 {
+
+        .triangle20 {
           position: absolute;
           width: 0;
           height: 0;
-          border-left: 20px solid transparent; /* 左边透明 */
-          border-right: 20px solid transparent; /* 右边透明 */
-          border-bottom: 20px solid #ffffff; /* 底部边为实际显示的三角形部分 */
-          transform: rotate(90deg); /* 向左旋转90度 */
+          border-left: 20px solid transparent;
+          /* 左边透明 */
+          border-right: 20px solid transparent;
+          /* 右边透明 */
+          border-bottom: 20px solid #ffffff;
+          /* 底部边为实际显示的三角形部分 */
+          transform: rotate(90deg);
+          /* 向左旋转90度 */
           top: 10px;
           right: -35px;
-          transform-origin: 50% 50%; /* 设置旋转中心点在元素的中心 */
+          transform-origin: 50% 50%;
+          /* 设置旋转中心点在元素的中心 */
           z-index: 2;
         }
       }
+
       .progress-bar2 {
-        margin-left: -30px;
-        padding-left: 100px;
         width: 354px;
       }
     }
+
     .form-bos {
       padding-left: 20px;
+
       :deep(.el-input__wrapper) {
         border: none;
         /* 可选:去除聚焦时的高亮 */
@@ -180,55 +379,114 @@ const radio = ref<any>(true);
         outline: none;
         background: #f4f6f8;
       }
+
       .form-title {
         font-size: 14px;
         color: #1d2129;
         margin-bottom: 8px;
+
         .star {
           width: 10px;
           color: #f53f3f;
         }
       }
+
       .form-tip {
         font-size: 12px;
         color: #86909c;
         margin-top: 4px;
       }
+
       .code {
         font-size: 14px;
         color: #e7000b;
         cursor: pointer;
+
+        &.disabled {
+          color: #999;
+          cursor: not-allowed;
+        }
       }
     }
+
     .form-bos1 {
       margin-top: 30px;
     }
+
     .agreement {
       padding-left: 20px;
       margin-top: 30px;
     }
   }
+
   .pay-foot {
     width: 100%;
     height: 82px;
     background: #ffffff;
     box-shadow: 0px -2px 13px 0px rgba(0, 0, 0, 0.05);
     margin-top: 47px;
+
     .foot-bos {
       width: 1200px;
       margin: 0 auto;
       padding-top: 16px;
       padding-left: 20px;
+
       .bnt1 {
-        width: 102px;
+        width: 120px;
         height: 32px;
         background: #f7f8fa;
       }
+
       .bnt2 {
-        width: 74px;
+        width: 120px;
         height: 32px;
       }
     }
   }
+
+  .descriptions-head {
+    width: 448px;
+    height: 32px;
+    background: #f2f3f5;
+    border-radius: 2px 2px 2px 2px;
+    padding: 0 12px;
+    margin-bottom: 30px;
+    font-size: 14px;
+    color: #1d2129;
+    line-height: 32px;
+  }
+  .descriptions-title {
+    font-weight: 500;
+    font-size: 16px;
+    color: #1d2129;
+    padding-left: 10px;
+    position: relative;
+    &::after {
+      content: '';
+      width: 4px;
+      height: 16px;
+      background: #e7000b;
+      position: absolute;
+      left: 0;
+      top: 4px;
+    }
+  }
+  .register-success {
+    width: 100%;
+    padding-bottom: 30px;
+    img {
+      width: 324px;
+    }
+    .success-text {
+      font-weight: 400;
+      font-size: 14px;
+      color: #000000;
+      margin: 20px 0 30px 0;
+    }
+  }
+  :deep(.is-bordered-label) {
+    font-weight: 400;
+  }
 }
 </style>

+ 788 - 4
src/views/greg/index.vue

@@ -1,9 +1,793 @@
 <template>
-  <div>
-    <h1>供应商注册</h1>
+  <div class="register-pages">
+    <div class="register-bos">
+      <img class="head-img" src="@/assets/images/head.png" alt="" />
+      <div class="register-login flex-row-between">
+        <div></div>
+        <div @click="goLogin">
+          <span>已有账号?直接</span>
+          <span class="zhu">登录>></span>
+        </div>
+      </div>
+      <div class="progress-bos">
+        <div class="progress-bar" :class="nextNum == 1 ? 'hig1' : 'hig2'">
+          <div>01、基本资料</div>
+        </div>
+        <div class="progress-bar progress-bar2" :class="nextNum == 2 ? 'hig1' : 'hig2'">
+          <div>02、完善信息</div>
+        </div>
+        <div class="progress-bar progress-bar2" :class="nextNum == 3 ? 'hig1' : ''">
+          <div>03、完成</div>
+        </div>
+      </div>
+      <template v-if="nextNum == 1">
+        <div class="form-bos">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>姓名</div>
+          </div>
+          <el-input style="width: 448px" v-model="form.purchaseName" placeholder="请输入姓名" />
+          <div class="form-tip">请输入采购人全名,方便与您联系!</div>
+        </div>
+        <div class="form-bos" style="margin-top: 8px">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>手机号码</div>
+          </div>
+          <el-input :maxlength="11" style="width: 448px" v-model="form.purchasePhone" placeholder="请输入手机号码">
+            <template #suffix>
+              <span @click="sendSmsCode" :class="['code', countdown > 0 ? 'disabled' : '']">
+                {{ codeText }}
+              </span>
+            </template>
+          </el-input>
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>验证码</div>
+          </div>
+          <el-input style="width: 448px" v-model="form.code" placeholder="请输入验证码" />
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>密码</div>
+          </div>
+          <el-input type="password" show-password style="width: 448px" v-model="form.password" placeholder="请输入密码" />
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>请再次输入密码</div>
+          </div>
+          <el-input type="password" show-password style="width: 448px" v-model="form.confirmPassword" placeholder="请输入密码" />
+        </div>
+      </template>
+      <template v-if="nextNum == 2">
+        <div class="form-head">基本信息</div>
+        <div class="form-bos">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>供应商名称</div>
+          </div>
+          <el-input style="width: 100%" v-model="form.enterpriseName" placeholder="请输入供应商名称" />
+        </div>
+        <div class="flex-row-start">
+          <div class="form-bos form-bos1" style="flex: 1">
+            <div class="form-title flex-row-start">
+              <div class="star">*</div>
+              <div>规模</div>
+            </div>
+            <el-select v-model="form.membershipSize" placeholder="请选择规模" style="width: 100%">
+              <el-option v-for="(item, index) in enterpriseList" :key="index" :label="item.enterpriseScaleName" :value="item.id" />
+            </el-select>
+          </div>
+          <div class="form-bos form-bos1" style="flex: 1">
+            <div class="form-title flex-row-start">
+              <div class="star">*</div>
+              <div>固定电话</div>
+            </div>
+            <el-input style="width: 100%" v-model="form.fixedPhone" placeholder="请输入固定电话" />
+          </div>
+        </div>
+        <div class="flex-row-start">
+          <div class="form-bos form-bos1" style="flex: 1">
+            <div class="form-title flex-row-start">
+              <div class="star"></div>
+              <div>传真</div>
+            </div>
+            <el-input style="width: 100%" v-model="form.fax" placeholder="请输入固定电话" />
+          </div>
+          <div class="form-bos form-bos1" style="flex: 1">
+            <div class="form-title flex-row-start">
+              <div class="star"></div>
+              <div>网址</div>
+            </div>
+            <el-input style="width: 100%" v-model="form.url" placeholder="请输入网址" />
+          </div>
+        </div>
+        <div class="flex-row-start">
+          <div class="form-bos form-bos1" style="flex: 1">
+            <div class="form-title flex-row-start">
+              <div class="star">*</div>
+              <div>企业邮箱</div>
+            </div>
+            <el-input style="width: 100%" v-model="form.mailbox" placeholder="请输入企业邮箱" />
+          </div>
+          <div class="form-bos form-bos1" style="flex: 1"></div>
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>办公地址</div>
+          </div>
+          <el-cascader
+            v-model="regionCodes"
+            :options="regionData as any"
+            placeholder="请选择省/市/区"
+            style="width: 100%"
+            @change="handleRegionChange"
+          />
+          <el-input
+            :maxlength="50"
+            type="textarea"
+            :rows="2"
+            style="width: 100%; margin-top: 10px"
+            v-model="form.officeAddress"
+            placeholder="请输入详细地址"
+            show-word-limit
+          />
+        </div>
+        <div class="form-head" style="margin-top: 15px">其它信息</div>
+        <div class="form-bos">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>年销量</div>
+          </div>
+          <el-input style="width: 100%" v-model="form.yearSales" placeholder="请输入年销量" />
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>主要经营品类</div>
+          </div>
+          <el-checkbox-group v-model="categoryList">
+            <el-checkbox v-for="(item, index) in productCategoryList" :key="index" :label="item.categoryName" :value="item.id" />
+          </el-checkbox-group>
+        </div>
+        <div class="form-bos form-bos1">
+          <div class="form-title flex-row-start">
+            <div class="star">*</div>
+            <div>供应区域</div>
+          </div>
+          <el-table
+            :data="tableData"
+            style="width: 100%"
+            border
+            row-class-name="static-bg-row"
+            :header-cell-style="{
+              color: '#1D2129',
+              backgroundColor: '#F2F3F5',
+              fontWeight: 'normal'
+            }"
+          >
+            <el-table-column label="供应区域" minWidth="200" align="center">
+              <template #default="scope">
+                <el-select
+                  @change="(res) => regionChange1(res, scope)"
+                  v-model="scope.row.provinceCode"
+                  placeholder="请选择供应区域"
+                  style="width: 100%"
+                >
+                  <el-option v-for="(item, index) in regionData" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="供应区域" minWidth="200" align="center">
+              <template #default="scope">
+                <el-select
+                  @change="(res) => regionChange2(res, scope)"
+                  v-model="scope.row.cityCode"
+                  placeholder="请选择供应区域"
+                  style="width: 100%"
+                  :disabled="scope.row.disabled"
+                >
+                  <el-option v-for="(item, index) in scope.row.children" :key="index" :label="item.label" :value="item.value" />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="130" align="center">
+              <template #default="scope">
+                <el-button type="primary" link @click="onDel(scope)">删除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+          <el-button style="width: 100%; margin-top: 10px" @click="addTable">添加</el-button>
+        </div>
+        <div class="form-head" style="margin-top: 15px">营业执照及相关经营许可证</div>
+        <div class="flex-row-start">
+          <el-upload
+            class="avatar-uploader"
+            :action="action"
+            :show-file-list="false"
+            :on-success="handleAvatarSuccess"
+            :before-upload="beforeAvatarUpload"
+          >
+            <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
+          </el-upload>
+          <img class="upload-img" v-if="form.businessLicense" :src="form.businessLicense" />
+        </div>
+      </template>
+      <template v-if="nextNum == 3">
+        <div class="register-success flex-column-center">
+          <img src="@/assets/images/breg.png" alt="" />
+          <div class="success-text">您的账户还在审核中,如有疑问,请致电400-111-0027</div>
+          <el-button @click="goLogin" type="primary">返回登录</el-button>
+        </div>
+      </template>
+    </div>
+    <div class="pay-foot" v-if="nextNum != 4">
+      <div class="foot-bos">
+        <el-button @click="previousStep" v-if="nextNum == 2" class="bnt1">返回上一步</el-button>
+        <el-button @click="nextStep" class="bnt2" type="primary" :loading="loading">{{ nextNum == 2 ? '提交并完成注册' : '下一步' }}</el-button>
+      </div>
+    </div>
   </div>
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { smsCode, selectBusinessByCustomerName, registerCustomer, enterpriseScale, getProductCategoryList, registerSupplier } from '@/api/breg/index';
+import { onUnmounted } from 'vue';
+import { onPath } from '@/utils/siteConfig';
+import { regionData } from 'element-china-area-data';
+const nextNum = ref<any>(1);
+const codeText = ref<string>('发送验证码');
+const countdown = ref<number>(0);
+const timer = ref<any>(null);
+const enterprise = ref<any>({});
+const loading = ref(false);
+const form = ref<any>({
+  purchaseName: '',
+  purchasePhone: '',
+  code: '',
+  password: '',
+  confirmPassword: '',
+  enterpriseName: '',
+  membershipSize: '',
+  fixedPhone: '',
+  fax: '',
+  url: '',
+  mailbox: '',
+  officeProvince: '',
+  officeCity: '',
+  officeCounty: '',
+  officeAddress: '',
+  yearSales: '',
+  operatingCategory: '',
+  supplyAreaList: [],
+  businessLicense: ''
+});
+const enterpriseList = ref<any>([]);
+const regionCodes = ref<any>([]);
+const productCategoryList = ref<any>([]);
+const categoryList = ref<any>([]);
+const tableData = ref<any>([{ province: '', provinceCode: '', city: '', cityCode: '', disabled: true, children: [] }]);
+const action = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
+console.log(regionData, '?????????');
 
-<style lang="scss" scoped></style>
+onMounted(() => {
+  //企业规模
+  enterpriseScale({ limit: 999 }).then((res) => {
+    if (res.code == 200) {
+      enterpriseList.value = res.rows;
+    }
+  });
+
+  //企业规模
+  getProductCategoryList({}).then((res) => {
+    if (res.code == 200) {
+      productCategoryList.value = res.data;
+    }
+  });
+});
+
+// 启动倒计时
+const startCountdown = () => {
+  countdown.value = 60;
+  codeText.value = `${countdown.value}s 后重新发送`;
+
+  timer.value = setInterval(() => {
+    countdown.value--;
+    if (countdown.value > 0) {
+      codeText.value = `${countdown.value}s 后重新发送`;
+    } else {
+      clearInterval(timer.value);
+      timer.value = null;
+      codeText.value = '发送验证码';
+    }
+  }, 1000);
+};
+
+// 获取验证码
+const sendSmsCode = () => {
+  if (countdown.value > 0) return;
+
+  if (validateMobile(form.value.purchasePhone)) {
+    smsCode({ phonenumber: form.value.purchasePhone }).then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: '验证码已发送',
+          type: 'success'
+        });
+        startCountdown();
+      }
+    });
+  } else {
+    ElMessage({
+      message: '请输入正确的手机号码',
+      type: 'warning'
+    });
+    return;
+  }
+};
+
+//选择省
+const regionChange1 = (res: any, scope: any) => {
+  regionData.forEach((item: any) => {
+    if (item.value === res) {
+      scope.row.province = item.label;
+      scope.row.children = item.children;
+      scope.row.city = '';
+      scope.row.cityCode = '';
+      scope.row.disabled = false;
+    }
+  });
+};
+
+//选择市
+const regionChange2 = (res: any, scope: any) => {
+  scope.row.children.forEach((item: any) => {
+    if (item.value === res) {
+      scope.row.city = item.label;
+    }
+  });
+};
+
+//新增
+const addTable = () => {
+  tableData.value.push({ province: '', provinceCode: '', city: '', cityCode: '', disabled: true, children: [] });
+};
+
+//删除
+const onDel = (scope: any) => {
+  tableData.value.splice(scope.row.$index, 1);
+};
+
+// 验证手机号
+const validateMobile = (phone: any) => {
+  const reg = /^1[3-9]\d{9}$/;
+  return reg.test(phone);
+};
+
+// 验证企业名字
+const validateStrict = (str: any) => {
+  if (typeof str !== 'string') return false;
+
+  const trimmed = str.trim();
+  if (trimmed.length === 0) return false; // 去空格后为空
+
+  return /^[^a-zA-Z0-9]+$/.test(trimmed);
+};
+
+// 处理地区选择变化
+const handleRegionChange = (value: string[]) => {
+  console.log(value);
+  if (value && value.length === 3) {
+    // 根据选中的代码查找对应的名称
+
+    // 根据编码获取名称
+    const names: string[] = [];
+    if (value[0]) {
+      const province = regionData.find((item: any) => item.value === value[0]);
+      if (province) {
+        form.value.officeProvince = province.label;
+
+        if (value[1] && province.children) {
+          const city = province.children.find((item: any) => item.value === value[1]);
+          if (city) {
+            form.value.officeCity = city.label;
+
+            if (value[2] && city.children) {
+              const county = city.children.find((item: any) => item.value === value[2]);
+              if (county) {
+                form.value.officeCounty = county.label;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+};
+
+//上传成功
+const handleAvatarSuccess = (res: any) => {
+  if (res.code == 200) {
+    form.value.businessLicense = res.data.url;
+  } else {
+    ElMessage({
+      message: res.msg,
+      type: 'warning'
+    });
+  }
+  console.log(res);
+};
+
+import type { UploadProps } from 'element-plus';
+const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
+  if (rawFile.size / 1024 / 1024 > 2) {
+    ElMessage.error('不能大于2MB!');
+    return false;
+  }
+  return true;
+};
+
+const nextStep = () => {
+  if (nextNum.value == 1) {
+    const errorMsg1 = {
+      purchaseName: '请输入姓名',
+      purchasePhone: '请输入手机号码',
+      code: '请输入验证码',
+      password: '请输入密码',
+      confirmPassword: '请再次输入密码'
+    };
+    let next1 = true;
+    Object.keys(errorMsg1).forEach((key) => {
+      if ((form.value[key] == '' || form.value[key] == undefined || form.value[key] == null) && next1) {
+        next1 = false;
+        ElMessage({
+          message: `${errorMsg1[key]}`,
+          type: 'warning'
+        });
+        return;
+      }
+    });
+    if (!next1) return;
+    if (form.value.password != form.value.confirmPassword) {
+      ElMessage({
+        message: `密码不一致`,
+        type: 'warning'
+      });
+      return;
+    }
+    nextNum.value = 2;
+  } else if (nextNum.value == 2) {
+    const errorMsg2 = {
+      enterpriseName: '请输入供应商名称',
+      membershipSize: '请选择规模',
+      fixedPhone: '请输入固定电话',
+      mailbox: '请输入企业邮箱',
+      officeCounty: '请选择省市区',
+      officeAddress: '请输入详细地址',
+      yearSales: '请输入年销量',
+      businessLicense: '请上传营业执照'
+    };
+    let next2 = true;
+    Object.keys(errorMsg2).forEach((key) => {
+      if ((form.value[key] == '' || form.value[key] == undefined || form.value[key] == null) && next2) {
+        next2 = false;
+        ElMessage({
+          message: `${errorMsg2[key]}`,
+          type: 'warning'
+        });
+        return;
+      }
+    });
+    if (!next2) return;
+    if (!validateStrict(form.value.enterpriseName)) {
+      ElMessage({
+        message: '供应商名称不能有数字或字母',
+        type: 'warning'
+      });
+      return;
+    }
+    if (categoryList.value.length == 0) {
+      ElMessage({
+        message: '请选择主要经营品类',
+        type: 'warning'
+      });
+      return;
+    }
+    form.value.operatingCategory = categoryList.value.join(',');
+    if (tableData.value.length == 0) {
+      ElMessage({
+        message: '请新增供应区域',
+        type: 'warning'
+      });
+      return;
+    }
+    form.value.supplyAreaList = [];
+    tableData.value.forEach((item: any) => {
+      if (item.province && item.provinceCode && item.city && item.cityCode) {
+        form.value.supplyAreaList.push({
+          areaCode: item.provinceCode,
+          areaName: item.province,
+          parentCode: 0,
+          level: 1
+        });
+        form.value.supplyAreaList.push({
+          areaCode: item.cityCode,
+          areaName: item.city,
+          parentCode: item.provinceCode,
+          level: 2
+        });
+      }
+    });
+    if (form.value.supplyAreaList.length == 0) {
+      ElMessage({
+        message: '供应区域不能为空',
+        type: 'warning'
+      });
+      return;
+    }
+    loading.value = true;
+    registerSupplier(form.value).then((res: any) => {
+      loading.value = false;
+      if (res.code == 200) {
+        nextNum.value = 3;
+      }
+    });
+  }
+};
+
+//上一步
+const previousStep = () => {
+  if (nextNum.value == 2) {
+    nextNum.value = 1;
+  }
+  if (nextNum.value == 3) {
+    nextNum.value = 2;
+  }
+};
+
+const goLogin = () => {
+  onPath('/login');
+};
+
+const radio = ref<any>(true);
+
+// 组件卸载时清除定时器
+onUnmounted(() => {
+  if (timer.value) {
+    clearInterval(timer.value);
+    timer.value = null;
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.register-pages {
+  width: 100%;
+  background-color: #ffffff;
+
+  .register-bos {
+    width: 1200px;
+    margin: 0 auto;
+    padding-top: 20px;
+
+    .head-img {
+      width: 185px;
+      height: 90px;
+    }
+
+    .register-login {
+      font-weight: 400;
+      font-size: 14px;
+      color: #101828;
+      margin-top: 20px;
+      padding-bottom: 10px;
+      border-bottom: 1px solid #e5e7eb;
+
+      .zhu {
+        color: #e7000b;
+        cursor: pointer;
+      }
+    }
+
+    .progress-bos {
+      padding: 20px;
+      display: flex;
+      margin-bottom: 24px;
+
+      .progress-bar {
+        width: 320px;
+        height: 40px;
+        background: #f7f8fa;
+        font-weight: 500;
+        font-size: 16px;
+        line-height: 40px;
+        padding-left: 16px;
+        color: #4e5969;
+        position: relative;
+
+        &.hig1 {
+          background: #e7000b;
+          color: #ffffff;
+        }
+
+        &.hig2 {
+          background: #ffe8e8;
+          color: #1d2129;
+        }
+      }
+
+      .progress-bar2 {
+        width: 354px;
+      }
+    }
+
+    .form-head {
+      width: calc(100% - 40px);
+      margin: 0 20px 10px 20px;
+      height: 44px;
+      background: #f7f8fa;
+      font-weight: 500;
+      font-size: 16px;
+      color: #1d2129;
+      line-height: 44px;
+      position: relative;
+      padding-left: 25px;
+      &::after {
+        content: '';
+        width: 4px;
+        height: 16px;
+        background: #e7000b;
+        position: absolute;
+        left: 10px;
+        top: 12px;
+      }
+    }
+
+    .form-bos {
+      padding: 0 20px;
+
+      :deep(.el-input__wrapper) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+
+      :deep(.el-select__wrapper) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+
+      :deep(.el-textarea__inner) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+
+      .form-title {
+        font-size: 14px;
+        color: #1d2129;
+        margin-bottom: 8px;
+
+        .star {
+          width: 10px;
+          color: #f53f3f;
+        }
+      }
+
+      .form-tip {
+        font-size: 12px;
+        color: #86909c;
+        margin-top: 4px;
+      }
+
+      .code {
+        font-size: 14px;
+        color: #e7000b;
+        cursor: pointer;
+
+        &.disabled {
+          color: #999;
+          cursor: not-allowed;
+        }
+      }
+    }
+
+    .form-bos1 {
+      margin-top: 30px;
+    }
+  }
+
+  .pay-foot {
+    width: 100%;
+    height: 82px;
+    background: #ffffff;
+    box-shadow: 0px -2px 13px 0px rgba(0, 0, 0, 0.05);
+    margin-top: 47px;
+
+    .foot-bos {
+      width: 1200px;
+      margin: 0 auto;
+      padding-top: 16px;
+      padding-left: 20px;
+
+      .bnt1 {
+        width: 120px;
+        height: 32px;
+        background: #f7f8fa;
+      }
+
+      .bnt2 {
+        width: 120px;
+        height: 32px;
+      }
+    }
+  }
+
+  .register-success {
+    width: 100%;
+    padding-bottom: 30px;
+    img {
+      width: 324px;
+    }
+    .success-text {
+      font-weight: 400;
+      font-size: 14px;
+      color: #000000;
+      margin: 20px 0 30px 0;
+    }
+  }
+  :deep(.is-bordered-label) {
+    font-weight: 400;
+  }
+
+  /* 核心代码:禁止 hover 变色 */
+  :deep(.el-table .static-bg-row:hover > td) {
+    background-color: inherit !important;
+  }
+
+  /* 兼容斑马纹情况 */
+  :deep(.el-table--striped .static-bg-row:nth-child(2n):hover > td) {
+    background-color: inherit !important;
+  }
+
+  .avatar-uploader {
+    margin: 10px 20px;
+    :deep(.el-upload) {
+      width: 108px;
+      height: 108px;
+      background: #f2f3f5;
+      border-radius: 2px;
+      cursor: pointer;
+      position: relative;
+      overflow: hidden;
+    }
+  }
+
+  .upload-img {
+    width: 108px;
+    height: 108px;
+    border-radius: 2px;
+  }
+
+  .el-icon.avatar-uploader-icon {
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    text-align: center;
+  }
+}
+</style>

+ 3 - 1
src/views/login.vue

@@ -54,7 +54,8 @@
           <div class="login-text flex-row-between">
             <div @click="handleForgetPassword">忘记密码?</div>
             <div class="border"></div>
-            <router-link to="/register" class="register-link">新用户注册</router-link>
+            <div @click="onPath('/breg')">新用户注册</div>
+            <!-- <router-link to="/register" class="register-link">新用户注册</router-link> -->
           </div>
         </el-form>
       </div>
@@ -67,6 +68,7 @@ import { useUserStore } from '@/store/modules/user';
 import { LoginData } from '@/api/types';
 import { to } from 'await-to-js';
 import { User, Lock, Iphone, Message } from '@element-plus/icons-vue';
+import { onPath } from '@/utils/siteConfig';
 
 const userStore = useUserStore();
 const router = useRouter();