weixin_52219567 2 месяцев назад
Родитель
Сommit
463fe5d49a

BIN
src/assets/images/1、密码登录_slices/Frame_27893.png


BIN
src/assets/images/1、密码登录_slices/Rectangle 1276.png


BIN
src/assets/images/1、密码登录_slices/Rectangle 1276@2x.png


BIN
src/assets/images/1、密码登录_slices/Rectangle_296.png


BIN
src/assets/images/1、密码登录_slices/image 5.png


BIN
src/assets/images/1、密码登录_slices/image 5@2x.png


BIN
src/assets/images/1、密码登录_slices/image_5.png


BIN
src/assets/images/1、密码登录_slices/image_5@2x.png


BIN
src/assets/images/login/login1.png


BIN
src/assets/images/login/login2.png


+ 43 - 0
src/assets/styles/common.scss

@@ -13,3 +13,46 @@
 
 .ellipsis{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
 
+
+  //分页
+  .pagination-bos {
+    width: 1200px;
+    margin: 0 auto;
+    padding-bottom: 60px;
+    :deep(.el-select__wrapper) {
+      background: #f4f4f4;
+      box-shadow: 0 0 0 1px #e5e6eb inset;
+      border-radius: 2px;
+    }
+    :deep(.el-select__placeholder) {
+      color: #1d2129;
+    }
+    :deep(.el-input__wrapper) {
+      background: #f4f4f4;
+      box-shadow: 0 0 0 1px #e5e6eb inset;
+      border-radius: 2px;
+    }
+    :deep(.el-input__inner) {
+      color: #1d2129;
+    }
+
+    :deep(.btn-prev) {
+      background: #f4f4f4;
+      border: 1px solid #e5e6eb;
+      margin-right: 8px;
+    }
+    :deep(.btn-next) {
+      background: #f4f4f4;
+      border: 1px solid #e5e6eb;
+      margin-left: 8px;
+    }
+    :deep(.el-pager) {
+      gap: 0 8px;
+      li {
+        background: #f4f4f4;
+        border: 1px solid #e5e6eb;
+        color: #1d2129;
+      }
+    }
+  }
+

+ 49 - 3
src/router/index.ts

@@ -72,6 +72,54 @@ export const constantRoutes: RouteRecordRaw[] = [
         component: () => import('@/views/index.vue'),
         name: 'Index',
         meta: { title: '首页', icon: 'dashboard', affix: true }
+      },
+      {
+        path: 'solve/index',
+        component: () => import('@/views/solve/index.vue'),
+        name: 'solveIndex',
+        meta: { title: '解决方案' }
+      },
+      {
+        path: 'solve/info',
+        component: () => import('@/views/solve/info.vue'),
+        name: 'solveInfo',
+        meta: { title: '解决方案详情' }
+      },
+      {
+        path: 'solve/real',
+        component: () => import('@/views/solve/real.vue'),
+        name: 'solveReal',
+        meta: { title: '资讯' }
+      },
+      {
+        path: 'shop/info',
+        component: () => import('@/views/shop/info.vue'),
+        name: 'shopInfo',
+        meta: { title: '商品详情' }
+      },
+      {
+        path: 'shop/cart',
+        component: () => import('@/views/shop/cart.vue'),
+        name: 'shopCart',
+        meta: { title: '我的购物车' }
+      },
+      {
+        path: 'shop/create',
+        component: () => import('@/views/shop/create.vue'),
+        name: 'shopCreate',
+        meta: { title: '确认订单信息' }
+      },
+      {
+        path: 'shop/pay',
+        component: () => import('@/views/shop/pay.vue'),
+        name: 'shopPay',
+        meta: { title: '支付订单' }
+      },
+      {
+        path: 'register/enterprise',
+        component: () => import('@/views/register/enterprise.vue'),
+        name: 'registerEnterprise',
+        meta: { title: '企业注册' }
       }
     ]
   },
@@ -92,9 +140,7 @@ export const constantRoutes: RouteRecordRaw[] = [
 ];
 
 // 动态路由,基于用户权限动态去加载
-export const dynamicRoutes: RouteRecordRaw[] = [
-
-];
+export const dynamicRoutes: RouteRecordRaw[] = [];
 
 /**
  * 创建路由

+ 3 - 263
src/views/index.vue

@@ -1,267 +1,7 @@
 <template>
-  <div class="solve">
-    <div class="solve-head">
-      <div class="head-bos">
-        <div class="nav-bos flex-row-start">
-          <div v-for="(item, index) in navList" :key="index" class="nav-list" :class="navIndex == index ? 'hig' : ''">
-            {{ item.title }}
-          </div>
-        </div>
-        <div class="filter-bos">
-          <div v-for="(item1, index1) in filterListy" :key="index1" class="filter-list flex-row-start">
-            <div class="filter-title">{{ item1.title }}</div>
-            <div v-for="(item2, index2) in item1.list" :key="index2" class="filter-item" :class="item1.hig == item2.id ? 'hig' : ''">
-              {{ item2.title }}
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <!-- 数据 -->
-    <div class="data-bos">
-      <div v-for="(item, index) in 9" :key="index" class="data-list">
-        <img class="data-img" src="@/assets/images/login-background.jpg" alt="" />
-        <div class="data-box flex-column-between">
-          <div>
-            <div class="title ellipsis">2025中秋福利 企业团购方案</div>
-            <div class="info ellipsis">干款好礼·百大品牌·个性定制</div>
-          </div>
-          <div class="text flex-row-start">
-            <div>了解详情</div>
-            <el-icon color="#e7000b" size="14" style="margin: 0 0 0 10px">
-              <ArrowRight />
-            </el-icon>
-          </div>
-        </div>
-      </div>
-    </div>
-    <!-- 分页 -->
-    <div class="pagination-bos flex-row-between">
-      <div></div>
-      <el-pagination
-        v-model:current-page="currentPage1"
-        v-model:page-size="pageSize2"
-        layout="sizes, prev, pager, next ,jumper"
-        :total="1000"
-        @size-change="handleSizeChange"
-        @current-change="handleCurrentChange"
-      />
-    </div>
-  </div>
+  <div class=""></div>
 </template>
 
-<script setup lang="ts">
-const currentPage1 = ref(5);
-const pageSize2 = ref(100);
+<script setup lang="ts"></script>
 
-const navList = ref<any>([
-  { title: '专题分类' },
-  { title: '大中型企业采购' },
-  { title: '政府&公共采购' },
-  { title: '营销福利' },
-  { title: '商用工程' },
-  { title: '中小型企业采购' }
-]);
-const filterListy = ref<any>([
-  {
-    title: '适配场景',
-    hig: 1,
-    list: [
-      { title: '全部', id: 1 },
-      { title: '1-100', id: 2 },
-      { title: '100-500', id: 3 },
-      { title: '1000+', id: 4 }
-    ]
-  },
-  {
-    title: '适配行业',
-    hig: 1,
-    list: [
-      { title: '全部', id: 1 },
-      { title: '食品饮料', id: 2 },
-      { title: '食品饮料', id: 3 },
-      { title: '食品饮料', id: 4 }
-    ]
-  },
-  {
-    title: '价格区间',
-    hig: 1,
-    list: [
-      { title: '全部', id: 1 },
-      { title: '香港小熊', id: 2 }
-    ]
-  },
-  {
-    title: '推荐标签',
-    hig: 1,
-    list: [
-      { title: '全部', id: 1 },
-      { title: '香港小熊', id: 2 }
-    ]
-  }
-]);
-const navIndex = ref(0);
-
-const handleSizeChange = (val: number) => {
-  console.log(`${val} items per page`);
-};
-const handleCurrentChange = (val: number) => {
-  console.log(`current page: ${val}`);
-};
-</script>
-
-<style lang="scss" scoped>
-.solve {
-  width: 100%;
-
-  .solve-head {
-    width: 100%;
-    background: #ffffff;
-
-    .head-bos {
-      width: 1200px;
-      margin: 0 auto;
-      padding-bottom: 20px;
-    }
-  }
-
-  .nav-bos {
-    border-bottom: 1px solid #e5e7eb;
-    width: 1200px;
-    padding-bottom: 20px;
-
-    .nav-list {
-      height: 32px;
-      padding: 0 12px;
-      background: #f7f8fa;
-      border-radius: 2px 2px 2px 2px;
-      font-size: 14px;
-      color: #4e5969;
-      margin-right: 8px;
-      line-height: 32px;
-      cursor: pointer;
-
-      &.hig {
-        background: #ffe8e8;
-        color: #e7000b;
-      }
-
-      &:hover {
-        color: #e7000b;
-      }
-    }
-  }
-
-  .filter-bos {
-    .filter-list {
-      margin-top: 20px;
-
-      .filter-title {
-        font-size: 14px;
-        color: #101828;
-        margin-right: 40px;
-      }
-
-      .filter-item {
-        font-size: 14px;
-        color: #364153;
-        margin-right: 30px;
-        cursor: pointer;
-
-        &.hig {
-          color: #e7000b;
-        }
-      }
-    }
-  }
-
-  // 数据
-  .data-bos {
-    width: 1200px;
-    margin: 0 auto;
-    display: flex;
-    gap: 20px;
-    flex-wrap: wrap;
-    padding: 22px 0 40px 0;
-
-    .data-list {
-      width: 386px;
-      height: 302px;
-      background: #ffffff;
-      border-radius: 10px;
-      overflow: hidden;
-      cursor: pointer;
-
-      .data-img {
-        height: 200px;
-        width: 386px;
-      }
-
-      .data-box {
-        height: 102px;
-        width: 386px;
-        padding: 12px 20px;
-
-        .title {
-          font-weight: 600;
-          font-size: 14px;
-          color: #101828;
-        }
-
-        .info {
-          font-size: 12px;
-          color: #364153;
-          margin-top: 4px;
-        }
-
-        .text {
-          font-size: 14px;
-          color: #e7000b;
-        }
-      }
-    }
-  }
-
-  //分页
-  .pagination-bos {
-    width: 1200px;
-    margin: 0 auto;
-    padding-bottom: 60px;
-    :deep(.el-select__wrapper) {
-      background: #f4f4f4;
-      box-shadow: 0 0 0 1px #e5e6eb inset;
-      border-radius: 2px;
-    }
-    :deep(.el-select__placeholder) {
-      color: #1d2129;
-    }
-    :deep(.el-input__wrapper) {
-      background: #f4f4f4;
-      box-shadow: 0 0 0 1px #e5e6eb inset;
-      border-radius: 2px;
-    }
-    :deep(.el-input__inner) {
-      color: #1d2129;
-    }
-
-    :deep(.btn-prev) {
-      background: #f4f4f4;
-      border: 1px solid #e5e6eb;
-      margin-right: 8px;
-    }
-    :deep(.btn-next) {
-      background: #f4f4f4;
-      border: 1px solid #e5e6eb;
-      margin-left: 8px;
-    }
-    :deep(.el-pager) {
-      gap: 0 8px;
-      li {
-        background: #f4f4f4;
-        border: 1px solid #e5e6eb;
-        color: #1d2129;
-      }
-    }
-  }
-}
-</style>
+<style lang="scss" scoped></style>

+ 314 - 0
src/views/login copy.vue

@@ -0,0 +1,314 @@
+<template>
+  <div class="login">
+    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-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="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>
+      </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="float: right">
+        <el-button circle :title="proxy.$t('login.social.wechat')" @click="doSocialLogin('wechat')">
+          <svg-icon icon-class="wechat" />
+        </el-button>
+        <el-button circle :title="proxy.$t('login.social.maxkey')" @click="doSocialLogin('maxkey')">
+          <svg-icon icon-class="maxkey" />
+        </el-button>
+        <el-button circle :title="proxy.$t('login.social.topiam')" @click="doSocialLogin('topiam')">
+          <svg-icon icon-class="topiam" />
+        </el-button>
+        <el-button circle :title="proxy.$t('login.social.gitee')" @click="doSocialLogin('gitee')">
+          <svg-icon icon-class="gitee" />
+        </el-button>
+        <el-button circle :title="proxy.$t('login.social.github')" @click="doSocialLogin('github')">
+          <svg-icon icon-class="github" />
+        </el-button>
+      </el-form-item>
+      <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>
+        <div v-if="register" style="float: right">
+          <router-link class="link-type" :to="'/register'">{{ proxy.$t('login.switchRegisterPage') }}</router-link>
+        </div>
+      </el-form-item>
+    </el-form>
+    <!--  底部  -->
+    <div class="el-login-footer">
+      <span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { getCodeImg, getTenantList } from '@/api/login';
+import { authRouterUrl } from '@/api/system/social/auth';
+import { useUserStore } from '@/store/modules/user';
+import { LoginData, TenantVO } from '@/api/types';
+import { to } from 'await-to-js';
+import { HttpStatus } from '@/enums/RespEnum';
+import { useI18n } from 'vue-i18n';
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const title = import.meta.env.VITE_APP_TITLE;
+const userStore = useUserStore();
+const router = useRouter();
+const { t } = useI18n();
+
+const loginForm = ref<LoginData>({
+  tenantId: '000000',
+  username: 'admin',
+  password: 'admin123',
+  rememberMe: false,
+  code: '',
+  uuid: ''
+} as LoginData);
+
+const loginRules: ElFormRules = {
+  tenantId: [{ required: true, trigger: 'blur', message: t('login.rule.tenantId.required') }],
+  username: [{ required: true, trigger: 'blur', message: t('login.rule.username.required') }],
+  password: [{ required: true, trigger: 'blur', message: t('login.rule.password.required') }],
+  code: [{ required: true, trigger: 'change', message: t('login.rule.code.required') }]
+};
+
+const codeUrl = ref('');
+const loading = ref(false);
+// 验证码开关
+const captchaEnabled = ref(true);
+// 租户开关
+const tenantEnabled = ref(true);
+
+// 注册开关
+const register = ref(false);
+const redirect = ref('/');
+const loginRef = ref<ElFormInstance>();
+// 租户列表
+const tenantList = ref<TenantVO[]>([]);
+
+watch(
+  () => router.currentRoute.value,
+  (newRoute: any) => {
+    redirect.value = newRoute.query && newRoute.query.redirect && decodeURIComponent(newRoute.query.redirect);
+  },
+  { immediate: true }
+);
+
+const handleLogin = () => {
+  loginRef.value?.validate(async (valid: boolean, fields: any) => {
+    if (valid) {
+      loading.value = true;
+      // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
+      if (loginForm.value.rememberMe) {
+        localStorage.setItem('tenantId', String(loginForm.value.tenantId));
+        localStorage.setItem('username', String(loginForm.value.username));
+        localStorage.setItem('password', String(loginForm.value.password));
+        localStorage.setItem('rememberMe', String(loginForm.value.rememberMe));
+      } else {
+        // 否则移除
+        localStorage.removeItem('tenantId');
+        localStorage.removeItem('username');
+        localStorage.removeItem('password');
+        localStorage.removeItem('rememberMe');
+      }
+      // 调用action的登录方法
+      const [err] = await to(userStore.login(loginForm.value));
+      if (!err) {
+        const redirectUrl = redirect.value || '/';
+        await router.push(redirectUrl);
+        loading.value = false;
+      } else {
+        loading.value = false;
+        // 重新获取验证码
+        if (captchaEnabled.value) {
+          await getCode();
+        }
+      }
+    } else {
+      console.log('error submit!', fields);
+    }
+  });
+};
+
+/**
+ * 获取验证码
+ */
+const getCode = async () => {
+  const res = await getCodeImg();
+  const { data } = res;
+  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
+  if (captchaEnabled.value) {
+    // 刷新验证码时清空输入框
+    loginForm.value.code = '';
+    codeUrl.value = 'data:image/gif;base64,' + data.img;
+    loginForm.value.uuid = data.uuid;
+  }
+};
+
+const getLoginData = () => {
+  const tenantId = localStorage.getItem('tenantId');
+  const username = localStorage.getItem('username');
+  const password = localStorage.getItem('password');
+  const rememberMe = localStorage.getItem('rememberMe');
+  loginForm.value = {
+    tenantId: tenantId === null ? String(loginForm.value.tenantId) : tenantId,
+    username: username === null ? String(loginForm.value.username) : username,
+    password: password === null ? String(loginForm.value.password) : String(password),
+    rememberMe: rememberMe === null ? false : Boolean(rememberMe)
+  } as LoginData;
+};
+
+/**
+ * 获取租户列表
+ */
+const initTenantList = async () => {
+  const { data } = await getTenantList(false);
+  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
+  if (tenantEnabled.value) {
+    tenantList.value = data.voList;
+    if (tenantList.value != null && tenantList.value.length !== 0) {
+      loginForm.value.tenantId = tenantList.value[0].tenantId;
+    }
+  }
+};
+
+/**
+ * 第三方登录
+ * @param type
+ */
+const doSocialLogin = (type: string) => {
+  authRouterUrl(type, loginForm.value.tenantId).then((res: any) => {
+    if (res.code === HttpStatus.SUCCESS) {
+      // 获取授权地址跳转
+      window.location.href = res.data;
+    } else {
+      ElMessage.error(res.msg);
+    }
+  });
+};
+
+onMounted(() => {
+  getCode();
+  initTenantList();
+  getLoginData();
+});
+</script>
+
+<style lang="scss" scoped>
+.login {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  height: 100%;
+  background-image: url('../assets/images/login-background.jpg');
+  background-size: cover;
+}
+
+.title-box {
+  display: flex;
+
+  .title {
+    margin: 0px auto 30px auto;
+    text-align: center;
+    color: #707070;
+  }
+
+  :deep(.lang-select--style) {
+    line-height: 0;
+    color: #7483a3;
+  }
+}
+
+.login-form {
+  border-radius: 6px;
+  background: #ffffff;
+  width: 400px;
+  padding: 25px 25px 5px 25px;
+  z-index: 1;
+  .el-input {
+    height: 40px;
+    input {
+      height: 40px;
+    }
+  }
+
+  .input-icon {
+    height: 39px;
+    width: 14px;
+    margin-left: 0px;
+  }
+}
+
+.login-tip {
+  font-size: 13px;
+  text-align: center;
+  color: #bfbfbf;
+}
+
+.login-code {
+  width: 33%;
+  height: 40px;
+  float: right;
+
+  img {
+    cursor: pointer;
+    vertical-align: middle;
+  }
+}
+
+.el-login-footer {
+  height: 40px;
+  line-height: 40px;
+  position: fixed;
+  bottom: 0;
+  width: 100%;
+  text-align: center;
+  color: #fff;
+  font-family: Arial, serif;
+  font-size: 12px;
+  letter-spacing: 1px;
+}
+
+.login-code-img {
+  height: 40px;
+  padding-left: 12px;
+}
+</style>

+ 115 - 288
src/views/login.vue

@@ -1,314 +1,141 @@
 <template>
   <div class="login">
-    <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-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="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" />
+    <img class="head" src="@/assets/images/head.png" alt="" />
+    <div class="login-info flex-row-between">
+      <div></div>
+      <div class="login-bos">
+        <div class="login-type flex-row-between">
+          <div :class="type == 1 ? 'hig' : ''" @click="onType(1)">密码登录</div>
+          <div class="border"></div>
+          <div :class="type == 2 ? 'hig' : ''" @click="onType(2)">短信登录</div>
         </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="float: right">
-        <el-button circle :title="proxy.$t('login.social.wechat')" @click="doSocialLogin('wechat')">
-          <svg-icon icon-class="wechat" />
-        </el-button>
-        <el-button circle :title="proxy.$t('login.social.maxkey')" @click="doSocialLogin('maxkey')">
-          <svg-icon icon-class="maxkey" />
-        </el-button>
-        <el-button circle :title="proxy.$t('login.social.topiam')" @click="doSocialLogin('topiam')">
-          <svg-icon icon-class="topiam" />
-        </el-button>
-        <el-button circle :title="proxy.$t('login.social.gitee')" @click="doSocialLogin('gitee')">
-          <svg-icon icon-class="gitee" />
-        </el-button>
-        <el-button circle :title="proxy.$t('login.social.github')" @click="doSocialLogin('github')">
-          <svg-icon icon-class="github" />
-        </el-button>
-      </el-form-item>
-      <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>
-        <div v-if="register" style="float: right">
-          <router-link class="link-type" :to="'/register'">{{ proxy.$t('login.switchRegisterPage') }}</router-link>
+        <template v-if="type == 1">
+          <el-input class="login-input" v-model="loginForm.username" placeholder="账号名" />
+          <el-input style="margin-top: 18px" type="password" class="login-input" v-model="loginForm.password" placeholder="请输入登录密码" />
+        </template>
+        <template v-else>
+          <el-input :maxlength="11" class="login-input" v-model="loginForm.mobile" placeholder="手机号" />
+          <el-input style="margin-top: 18px" :maxlength="6" class="login-input" v-model="loginForm.mobile" placeholder="手机号">
+            <template #suffix>
+              <span class="code">发送验证码</span>
+            </template>
+          </el-input>
+        </template>
+        <el-button class="login-btn" type="primary">登录</el-button>
+        <div class="login-text flex-row-between">
+          <div>忘记密码</div>
+          <div class="border"></div>
+          <div>免费注册</div>
         </div>
-      </el-form-item>
-    </el-form>
-    <!--  底部  -->
-    <div class="el-login-footer">
-      <span>Copyright © 2018-2026 疯狂的狮子Li All Rights Reserved.</span>
+      </div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { getCodeImg, getTenantList } from '@/api/login';
-import { authRouterUrl } from '@/api/system/social/auth';
-import { useUserStore } from '@/store/modules/user';
-import { LoginData, TenantVO } from '@/api/types';
-import { to } from 'await-to-js';
-import { HttpStatus } from '@/enums/RespEnum';
-import { useI18n } from 'vue-i18n';
-
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-
-const title = import.meta.env.VITE_APP_TITLE;
-const userStore = useUserStore();
-const router = useRouter();
-const { t } = useI18n();
+const type = ref<any>(1);
 
-const loginForm = ref<LoginData>({
-  tenantId: '000000',
+const loginForm = ref<any>({
   username: 'admin',
   password: 'admin123',
-  rememberMe: false,
-  code: '',
-  uuid: ''
-} as LoginData);
-
-const loginRules: ElFormRules = {
-  tenantId: [{ required: true, trigger: 'blur', message: t('login.rule.tenantId.required') }],
-  username: [{ required: true, trigger: 'blur', message: t('login.rule.username.required') }],
-  password: [{ required: true, trigger: 'blur', message: t('login.rule.password.required') }],
-  code: [{ required: true, trigger: 'change', message: t('login.rule.code.required') }]
-};
-
-const codeUrl = ref('');
-const loading = ref(false);
-// 验证码开关
-const captchaEnabled = ref(true);
-// 租户开关
-const tenantEnabled = ref(true);
-
-// 注册开关
-const register = ref(false);
-const redirect = ref('/');
-const loginRef = ref<ElFormInstance>();
-// 租户列表
-const tenantList = ref<TenantVO[]>([]);
-
-watch(
-  () => router.currentRoute.value,
-  (newRoute: any) => {
-    redirect.value = newRoute.query && newRoute.query.redirect && decodeURIComponent(newRoute.query.redirect);
-  },
-  { immediate: true }
-);
-
-const handleLogin = () => {
-  loginRef.value?.validate(async (valid: boolean, fields: any) => {
-    if (valid) {
-      loading.value = true;
-      // 勾选了需要记住密码设置在 localStorage 中设置记住用户名和密码
-      if (loginForm.value.rememberMe) {
-        localStorage.setItem('tenantId', String(loginForm.value.tenantId));
-        localStorage.setItem('username', String(loginForm.value.username));
-        localStorage.setItem('password', String(loginForm.value.password));
-        localStorage.setItem('rememberMe', String(loginForm.value.rememberMe));
-      } else {
-        // 否则移除
-        localStorage.removeItem('tenantId');
-        localStorage.removeItem('username');
-        localStorage.removeItem('password');
-        localStorage.removeItem('rememberMe');
-      }
-      // 调用action的登录方法
-      const [err] = await to(userStore.login(loginForm.value));
-      if (!err) {
-        const redirectUrl = redirect.value || '/';
-        await router.push(redirectUrl);
-        loading.value = false;
-      } else {
-        loading.value = false;
-        // 重新获取验证码
-        if (captchaEnabled.value) {
-          await getCode();
-        }
-      }
-    } else {
-      console.log('error submit!', fields);
-    }
-  });
-};
-
-/**
- * 获取验证码
- */
-const getCode = async () => {
-  const res = await getCodeImg();
-  const { data } = res;
-  captchaEnabled.value = data.captchaEnabled === undefined ? true : data.captchaEnabled;
-  if (captchaEnabled.value) {
-    // 刷新验证码时清空输入框
-    loginForm.value.code = '';
-    codeUrl.value = 'data:image/gif;base64,' + data.img;
-    loginForm.value.uuid = data.uuid;
-  }
-};
-
-const getLoginData = () => {
-  const tenantId = localStorage.getItem('tenantId');
-  const username = localStorage.getItem('username');
-  const password = localStorage.getItem('password');
-  const rememberMe = localStorage.getItem('rememberMe');
-  loginForm.value = {
-    tenantId: tenantId === null ? String(loginForm.value.tenantId) : tenantId,
-    username: username === null ? String(loginForm.value.username) : username,
-    password: password === null ? String(loginForm.value.password) : String(password),
-    rememberMe: rememberMe === null ? false : Boolean(rememberMe)
-  } as LoginData;
-};
-
-/**
- * 获取租户列表
- */
-const initTenantList = async () => {
-  const { data } = await getTenantList(false);
-  tenantEnabled.value = data.tenantEnabled === undefined ? true : data.tenantEnabled;
-  if (tenantEnabled.value) {
-    tenantList.value = data.voList;
-    if (tenantList.value != null && tenantList.value.length !== 0) {
-      loginForm.value.tenantId = tenantList.value[0].tenantId;
-    }
-  }
-};
-
-/**
- * 第三方登录
- * @param type
- */
-const doSocialLogin = (type: string) => {
-  authRouterUrl(type, loginForm.value.tenantId).then((res: any) => {
-    if (res.code === HttpStatus.SUCCESS) {
-      // 获取授权地址跳转
-      window.location.href = res.data;
-    } else {
-      ElMessage.error(res.msg);
-    }
-  });
-};
-
-onMounted(() => {
-  getCode();
-  initTenantList();
-  getLoginData();
+  mobile: ''
 });
+const onType = (res: any) => {
+  type.value = res;
+};
 </script>
 
 <style lang="scss" scoped>
 .login {
-  display: flex;
-  justify-content: center;
-  align-items: center;
   height: 100%;
-  background-image: url('../assets/images/login-background.jpg');
+  width: 100%;
+  background-image: url('@/assets/images/login/login1.png');
+  overflow: auto;
+  background-position: center center;
+  background-repeat: no-repeat;
   background-size: cover;
-}
-
-.title-box {
-  display: flex;
-
-  .title {
-    margin: 0px auto 30px auto;
-    text-align: center;
-    color: #707070;
-  }
 
-  :deep(.lang-select--style) {
-    line-height: 0;
-    color: #7483a3;
+  .head {
+    width: 185px;
+    height: 90px;
+    margin-top: 53px;
+    margin-left: 84px;
   }
-}
 
-.login-form {
-  border-radius: 6px;
-  background: #ffffff;
-  width: 400px;
-  padding: 25px 25px 5px 25px;
-  z-index: 1;
-  .el-input {
-    height: 40px;
-    input {
-      height: 40px;
+  .login-info {
+    width: 100%;
+    height: 660px;
+    background-image: url('@/assets/images/login/login2.png');
+    overflow: hidden;
+    background-position: center center;
+    background-repeat: no-repeat;
+    background-size: cover;
+    margin-top: 68px;
+    min-width: 1200px;
+    padding: 0 5%;
+
+    .login-bos {
+      width: 520px;
+      height: 510px;
+      background: #ffffff;
+      border-radius: 30px 30px 30px 30px;
+      padding: 90px 85px 0 85px;
+      .login-type {
+        font-weight: 600;
+        font-size: 22px;
+        color: #101828;
+        padding: 0 67px;
+        margin-bottom: 40px;
+        div {
+          cursor: pointer;
+        }
+        .hig {
+          color: #e7000b;
+        }
+        .border {
+          width: 1px;
+          height: 16px;
+          background: #e6e8ec;
+        }
+      }
+      .login-input {
+        width: 350px;
+        height: 50px;
+        font-size: 16px;
+        .code {
+          font-size: 14px;
+          color: #e7000b;
+          cursor: pointer;
+        }
+      }
+      :deep(.el-input__wrapper) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+      .login-btn {
+        width: 350px;
+        height: 50px;
+        margin-top: 60px;
+        font-size: 16px;
+      }
+      .login-text {
+        font-size: 14px;
+        color: #6a7282;
+        padding: 0 107px;
+        margin-top: 14px;
+        div {
+          cursor: pointer;
+        }
+        .border {
+          width: 1px;
+          height: 12px;
+          background: #e6e8ec;
+        }
+      }
     }
   }
-
-  .input-icon {
-    height: 39px;
-    width: 14px;
-    margin-left: 0px;
-  }
-}
-
-.login-tip {
-  font-size: 13px;
-  text-align: center;
-  color: #bfbfbf;
-}
-
-.login-code {
-  width: 33%;
-  height: 40px;
-  float: right;
-
-  img {
-    cursor: pointer;
-    vertical-align: middle;
-  }
-}
-
-.el-login-footer {
-  height: 40px;
-  line-height: 40px;
-  position: fixed;
-  bottom: 0;
-  width: 100%;
-  text-align: center;
-  color: #fff;
-  font-family: Arial, serif;
-  font-size: 12px;
-  letter-spacing: 1px;
-}
-
-.login-code-img {
-  height: 40px;
-  padding-left: 12px;
 }
 </style>

+ 234 - 0
src/views/register/enterprise.vue

@@ -0,0 +1,234 @@
+<template>
+  <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>
+          <span>已有账号?直接</span>
+          <span class="zhu">登录>></span>
+        </div>
+      </div>
+      <div class="progress-bos">
+        <div class="progress-bar hig">
+          <div>01、基本资料</div>
+          <div class="triangle1"></div>
+          <div class="triangle2"></div>
+          <div></div>
+        </div>
+        <div class="progress-bar progress-bar2">
+          <div>02、企业信息</div>
+          <div class="triangle1"></div>
+          <div class="triangle2"></div>
+        </div>
+        <div class="progress-bar progress-bar2">
+          <div>03、完成</div>
+        </div>
+      </div>
+      <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.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>
+        <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>
+        <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>
+        <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>
+        <el-input type="password" show-password style="width: 448px" v-model="form.value5" placeholder="请输入密码" />
+      </div>
+      <div class="agreement flex-row-start">
+        <el-radio v-model="radio" value="disabled">
+          <span>我已阅读并同意</span>
+          <span> 《某某政策》</span>
+        </el-radio>
+      </div>
+    </div>
+    <div class="pay-foot">
+      <div class="foot-bos">
+        <el-button class="bnt2" type="primary">下一步</el-button>
+        <el-button class="bnt1">供应商注册</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const form = ref<any>({
+  value1: '',
+  value2: '',
+  value3: '',
+  value4: '',
+  value5: ''
+});
+const radio = ref<any>(true);
+</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: 324px;
+        height: 40px;
+        background: #f7f8fa;
+        font-weight: 500;
+        font-size: 16px;
+        line-height: 40px;
+        padding-left: 16px;
+        color: #4e5969;
+        position: relative;
+        &.hig {
+          background: #e7000b;
+          color: #ffffff;
+          z-index: 2;
+          .triangle1 {
+            border-bottom: 20px solid #e7000b;
+          }
+        }
+        .triangle1 {
+          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度 */
+          top: 10px;
+          right: -30px;
+          transform-origin: 50% 50%; /* 设置旋转中心点在元素的中心 */
+          z-index: 3;
+        }
+        .triangle2 {
+          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度 */
+          top: 10px;
+          right: -35px;
+          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;
+        /* 可选:去除聚焦时的高亮 */
+        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;
+      }
+    }
+    .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;
+        height: 32px;
+        background: #f7f8fa;
+      }
+      .bnt2 {
+        width: 74px;
+        height: 32px;
+      }
+    }
+  }
+}
+</style>

+ 244 - 0
src/views/shop/cart.vue

@@ -0,0 +1,244 @@
+<template>
+  <div class="cart-pages">
+    <div class="cart-bos">
+      <div class="cart-head flex-row-between">
+        <div class="flex-row-start head1">
+          <img src="@/assets/images/dark.svg" alt="" />
+          <div>我的购物车</div>
+        </div>
+        <div class="head2">导出订单</div>
+      </div>
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        :header-cell-style="{
+          color: '#1D2129',
+          backgroundColor: '#F2F3F5',
+          fontWeight: 'normal'
+        }"
+      >
+        <el-table-column type="selection" width="55" />
+        <el-table-column label="商品信息" width="490">
+          <template #default="scope">
+            <div class="cart-info">
+              <img class="cart-img" src="@/assets/images/login-background.jpg" alt="" />
+              <div class="cart-text">
+                <div class="text1">清华同方超越E500台式机电脑超越E500台式机电脑(i3-6100/4G/1T/19.5寸)</div>
+                <div class="text2">
+                  <span>规格01</span>
+                  <span>规格02</span>
+                </div>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="单价" width="130">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="数量" width="200">
+          <template #default="scope">
+            <el-input-number v-model="scope.row.num" :min="1" :max="10" />
+          </template>
+        </el-table-column>
+        <el-table-column label="小计" width="140">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <div>
+              <el-button link> 移入收藏 </el-button>
+            </div>
+            <div>
+              <el-button link> 删除 </el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="cart-shi">失效商品</div>
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        :header-cell-style="{
+          color: '#1D2129',
+          backgroundColor: '#F2F3F5',
+          fontWeight: 'normal'
+        }"
+        :row-style="{
+          backgroundColor: '#F9F9F9'
+        }"
+      >
+        <el-table-column type="selection" width="55" />
+        <el-table-column label="商品信息" width="490">
+          <template #default="scope">
+            <div class="cart-info">
+              <img class="cart-img" src="@/assets/images/login-background.jpg" alt="" />
+              <div class="cart-text">
+                <div class="text1">清华同方超越E500台式机电脑超越E500台式机电脑(i3-6100/4G/1T/19.5寸)</div>
+                <div class="text2">
+                  <span>规格01</span>
+                  <span>规格02</span>
+                </div>
+                <div class="text3">当前商品库存不足,当前库存量:999把</div>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="单价" width="130">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="数量" width="200">
+          <template #default="scope">
+            <el-input-number v-model="scope.row.num" :min="1" :max="10" />
+          </template>
+        </el-table-column>
+        <el-table-column label="小计" width="140">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <div>
+              <el-button link> 移入收藏 </el-button>
+            </div>
+            <div>
+              <el-button link> 删除 </el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="cart-bnt">
+      <div class="bnt-bos flex-row-between">
+        <div class="flex-row-start">
+          <el-checkbox v-model="checked1" label="全选" />
+          <el-button style="margin-left: 10px">删除</el-button>
+          <el-button>移入收藏</el-button>
+        </div>
+        <div class="bnt-box flex-row-start">
+          <span>共</span>
+          <span class="hig">1</span>
+          <span>种商品,已选择</span>
+          <span class="hig">2</span>
+          <span>件,商品合计:</span>
+          <span class="hig">¥938.00</span>
+          <span>,活动优惠:0.00</span>
+          <span class="span1">合计:</span>
+          <span class="span2">¥0.00</span>
+          <el-button class="bnt" type="primary">去结算</el-button>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const tableData = ref<any>([{}, {}, {}, {}]);
+const checked1 = ref(false);
+</script>
+
+<style lang="scss" scoped>
+.cart-pages {
+  width: 100%;
+  background: #ffffff;
+  .cart-bos {
+    width: 1200px;
+    margin: 0 auto;
+  }
+  .cart-head {
+    margin-bottom: 20px;
+    .head1 {
+      font-weight: 600;
+      font-size: 16px;
+      color: #101828;
+      img {
+        width: 18px;
+        height: 18px;
+        margin-right: 6px;
+      }
+    }
+    .head2 {
+      width: 88px;
+      height: 25px;
+      border-radius: 4px 4px 4px 4px;
+      border: 1px solid #e7000b;
+      font-size: 12px;
+      color: #e7000b;
+      line-height: 25px;
+      text-align: center;
+    }
+  }
+  .cart-info {
+    width: 490px;
+    height: 94px;
+    display: flex;
+    .cart-img {
+      width: 94px;
+      height: 94px;
+      border-radius: 6px;
+    }
+    .cart-text {
+      flex: 1;
+      width: 0;
+      padding-left: 10px;
+      .text1 {
+        font-size: 14px;
+        color: #000000;
+        height: 50px;
+      }
+      .text2 {
+        font-size: 14px;
+        color: #364153;
+        span {
+          margin-right: 10px;
+        }
+      }
+      .text3 {
+        font-size: 14px;
+        color: #e7000b;
+      }
+    }
+  }
+  .cart-shi {
+    font-weight: 600;
+    font-size: 16px;
+    color: #101828;
+    padding: 20px 0;
+  }
+  .cart-bnt {
+    width: 100%;
+    height: 82px;
+    background: #ffffff;
+    box-shadow: 0px -2px 13px 0px rgba(0, 0, 0, 0.05);
+    margin-top: 48px;
+    .bnt-bos {
+      width: 1200px;
+      margin: 0 auto;
+      height: 82px;
+      .bnt-box {
+        font-size: 14px;
+        color: #000000;
+        .span1 {
+          font-weight: 600;
+          color: #101828;
+          margin-left: 20px;
+        }
+        .span2 {
+          font-weight: 600;
+          color: #e7000b;
+          font-size: 16px;
+          margin-top: 2px;
+          margin-left: 2px;
+        }
+        .hig {
+          color: #e7000b;
+        }
+        .bnt {
+          width: 142px;
+          height: 50px;
+          font-size: 16px;
+          margin-left: 20px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 357 - 0
src/views/shop/create.vue

@@ -0,0 +1,357 @@
+<template>
+  <div class="create-pages">
+    <div class="create-bos">
+      <div class="create-title flex-row-start">
+        <el-icon color="#101828" size="16"><Document /></el-icon>
+        <div style="margin-left: 6px">确认订单信息</div>
+      </div>
+      <div class="create-head flex-row-start">
+        <span>中国南方电网有限公司</span>
+        <span class="border"></span>
+        <span>某某部门</span>
+      </div>
+      <div class="address-title">收货地址</div>
+      <div class="address-bos">
+        <div v-for="(item, index) in 4" :key="index" class="address-list flex-column-between" :class="index == 0 ? 'hig' : ''">
+          <div class="address1">广东省 广州市 萝岗区科学城11号</div>
+          <div class="address2">中国南方电网有限公司</div>
+          <div class="address3">18062697722</div>
+        </div>
+      </div>
+      <div class="address-more flex-row-start">
+        <div>展开全部地址</div>
+        <el-icon style="margin-left: 6px" color="#6A7282" size="14"><ArrowDown /></el-icon>
+      </div>
+      <div class="form-bos">
+        <div class="form-title flex-row-start">
+          <div class="asterisk">*</div>
+          <div>配送时间</div>
+        </div>
+        <el-date-picker style="width: 340px" v-model="form.value1" type="date" placeholder="选择日期" />
+      </div>
+      <div class="form-bos">
+        <div class="form-title flex-row-start">
+          <div class="asterisk">*</div>
+          <div>费用类型</div>
+        </div>
+        <el-select v-model="form.value2" placeholder="请选择费用类型" style="width: 340px">
+          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+        </el-select>
+      </div>
+      <div class="form-bos">
+        <div class="form-title flex-row-start">
+          <div class="asterisk">*</div>
+          <div>采购事由</div>
+        </div>
+        <el-input
+          :maxlength="50"
+          v-model="form.value3"
+          style="width: 340px"
+          :autosize="{ minRows: 2, maxRows: 4 }"
+          type="textarea"
+          show-word-limit
+          placeholder="请输入采购事由"
+        />
+      </div>
+      <div class="form-bos">
+        <div class="form-title flex-row-start">
+          <div class="asterisk"></div>
+          <div>订单备注</div>
+        </div>
+        <el-input
+          :maxlength="50"
+          v-model="form.value3"
+          style="width: 340px"
+          :autosize="{ minRows: 2, maxRows: 4 }"
+          type="textarea"
+          show-word-limit
+          placeholder="请输入订单备注"
+        />
+      </div>
+      <el-table
+        :data="tableData"
+        style="width: 100%"
+        :header-cell-style="{
+          color: '#1D2129',
+          backgroundColor: '#F2F3F5',
+          fontWeight: 'normal'
+        }"
+      >
+        <el-table-column label="商品信息" width="490">
+          <template #default="scope">
+            <div class="cart-info">
+              <img class="cart-img" src="@/assets/images/login-background.jpg" alt="" />
+              <div class="cart-text">
+                <div class="text1">清华同方超越E500台式机电脑超越E500台式机电脑(i3-6100/4G/1T/19.5寸)</div>
+                <div class="text2">
+                  <span>规格01</span>
+                  <span>规格02</span>
+                </div>
+              </div>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="单价" width="150">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="数量" width="160">
+          <template #default="scope"> 1 </template>
+        </el-table-column>
+        <el-table-column label="小计" width="160">
+          <template #default="scope"> ¥1,299 </template>
+        </el-table-column>
+        <el-table-column label="操作">
+          <template #default="scope">
+            <div>
+              <el-button link> 移入收藏 </el-button>
+            </div>
+            <div>
+              <el-button link> 删除 </el-button>
+            </div>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="create-foot">
+      <div class="foot-bos flex-row-between">
+        <div></div>
+        <div class="foot-box flex-column-between">
+          <div class="flex-row-between" style="width: 100%">
+            <div>商品件数</div>
+            <div>6</div>
+          </div>
+          <div class="flex-row-between" style="width: 100%">
+            <div>商品总额</div>
+            <div>¥1,299</div>
+          </div>
+          <div class="foot-yun flex-row-between">
+            <div>运费</div>
+            <div>¥48</div>
+          </div>
+          <div class="flex-row-between" style="width: 100%">
+            <div>共计</div>
+            <div class="zhu">¥1,299</div>
+          </div>
+          <div class="flex-row-between" style="width: 100%">
+            <div></div>
+            <div class="bnt-bos">
+              <el-button class="bnt1">返回购物车修改</el-button>
+              <el-button class="bnt2" type="primary">提交订单</el-button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const form = ref<any>({
+  value1: '',
+  value2: '',
+  value3: '',
+  value4: ''
+});
+const tableData = ref<any>([{}, {}, {}, {}]);
+const options = [
+  {
+    value: 'Option1',
+    label: 'Option1'
+  },
+  {
+    value: 'Option2',
+    label: 'Option2'
+  },
+  {
+    value: 'Option3',
+    label: 'Option3'
+  },
+  {
+    value: 'Option4',
+    label: 'Option4'
+  },
+  {
+    value: 'Option5',
+    label: 'Option5'
+  }
+];
+</script>
+
+<style lang="scss" scoped>
+.create-pages {
+  width: 100%;
+  background-color: #ffffff;
+  .create-bos {
+    width: 1200px;
+    margin: 0 auto;
+    .create-title {
+      font-size: 16px;
+      color: #101828;
+    }
+    .create-head {
+      width: 1200px;
+      height: 40px;
+      background: #f9fafb;
+      margin-top: 10px;
+      font-weight: 600;
+      font-size: 14px;
+      color: #101828;
+      padding-left: 10px;
+      .border {
+        display: inline-block;
+        width: 1px;
+        height: 12px;
+        background-color: #e5e7eb;
+        margin: 0 10px;
+      }
+    }
+    .address-title {
+      font-weight: 600;
+      font-size: 14px;
+      color: #101828;
+      margin: 30px 0 10px 0;
+    }
+    .address-bos {
+      display: flex;
+      gap: 10px 12px;
+      .address-list {
+        width: 291px;
+        height: 92px;
+        background: #ffffff;
+        border-radius: 10px 10px 10px 10px;
+        border: 1px solid #e5e7eb;
+        padding: 12px;
+        cursor: pointer;
+        &.hig {
+          border: 1px solid #e7000b;
+        }
+        .address1 {
+          font-size: 14px;
+          color: #364153;
+        }
+        .address2 {
+          font-size: 14px;
+          color: #101828;
+        }
+        .address3 {
+          font-size: 14px;
+          color: #364153;
+        }
+      }
+    }
+    .address-more {
+      font-size: 14px;
+      color: #6a7282;
+      margin: 10px 0 30px 0;
+    }
+    .form-bos {
+      margin-bottom: 20px;
+      display: flex;
+      align-items: start;
+      .form-title {
+        font-size: 14px;
+        color: #1d2129;
+        width: 80px;
+        .asterisk {
+          color: #f53f3f;
+          width: 10px;
+        }
+      }
+
+      :deep(.el-select__wrapper) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+      :deep(.el-input__wrapper) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+      :deep(.el-textarea__inner) {
+        border: none;
+        /* 可选:去除聚焦时的高亮 */
+        box-shadow: none;
+        outline: none;
+        background: #f4f6f8;
+      }
+    }
+    .cart-info {
+      width: 490px;
+      height: 94px;
+      display: flex;
+      .cart-img {
+        width: 94px;
+        height: 94px;
+        border-radius: 6px;
+      }
+      .cart-text {
+        flex: 1;
+        width: 0;
+        padding-left: 10px;
+        .text1 {
+          font-size: 14px;
+          color: #000000;
+          height: 50px;
+        }
+        .text2 {
+          font-size: 14px;
+          color: #364153;
+          span {
+            margin-right: 10px;
+          }
+        }
+        .text3 {
+          font-size: 14px;
+          color: #e7000b;
+        }
+      }
+    }
+  }
+  .create-foot {
+    width: 100%;
+    height: 245px;
+    background: #ffffff;
+    box-shadow: 0px -2px 13px 0px rgba(0, 0, 0, 0.05);
+    margin-top: 30px;
+    .foot-bos {
+      width: 1200px;
+      margin: 0 auto;
+      .foot-box {
+        width: 458px;
+        font-weight: 600;
+        font-size: 14px;
+        color: #101828;
+        padding: 18px 0 20px 0;
+        height: 245px;
+        .foot-yun {
+          width: 100%;
+          height: 40px;
+          background: #f7f8fc;
+          border-radius: 10px;
+          padding: 0 10px;
+          font-weight: 400;
+          font-size: 14px;
+          color: #000000;
+        }
+        .zhu {
+          color: #e7000b;
+        }
+        .bnt1 {
+          width: 198px;
+          height: 50px;
+          background: #f7f8fa;
+        }
+        .bnt2 {
+          width: 156px;
+          height: 50px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 464 - 0
src/views/shop/info.vue

@@ -0,0 +1,464 @@
+<template>
+  <div class="shop-pages">
+    <div class="shop-head flex-row-start">
+      <div class="head-left">
+        <div class="left-carousel">
+          <div v-for="(item, index) in carousel" :key="index" class="carousel-item" :class="carouselIndex == index ? 'hig' : ''">
+            <img :src="item.img" alt="" @click="onCarousel(1, index)" />
+          </div>
+        </div>
+        <div class="left-next flex-row-center" @click="onCarousel(2)">
+          <el-icon color="#6A7282" size="15">
+            <ArrowDown />
+          </el-icon>
+        </div>
+      </div>
+      <img :src="carousel[carouselIndex].img" alt="" class="carousel-img" />
+      <div class="head-right flex-column-between">
+        <div>
+          <div class="right-title">格力KFR-72LW/(72532)NhAa-3定频冷暖空调柜机3P格力KFR-72LW定频冷暖空调柜机3P</div>
+          <div class="right-num">商品库存 999套</div>
+          <div class="right-price flex-row-between">
+            <div class="flex-row-start">
+              <div class="price1">
+                <span>¥</span>
+                <span style="font-size: 24px">2654.00</span>
+              </div>
+              <div class="price2">平台价</div>
+              <div class="price3">
+                <span>¥</span>
+                <span style="font-size: 16px">2654.00</span>
+              </div>
+            </div>
+            <div class="right-collect flex-row-start">
+              <img src="@/assets/images/dark.svg" alt="" />
+              <span>收藏</span>
+            </div>
+          </div>
+          <div class="address flex-row-start">
+            <img class="address-img" src="@/assets/images/dark.svg" alt="" />
+            <div>配送至</div>
+            <div class="address-text ellipsis">湖北省武汉市洪山区湖北省武汉市洪山区</div>
+            <el-icon color="#000000" size="15"><ArrowDown /></el-icon>
+          </div>
+          <div class="specs-bos">
+            <div v-for="(item1, index1) in specsList" :key="index1" class="specs-list">
+              <div>{{ item1.title }}</div>
+              <div class="specs-box">
+                <div
+                  v-for="(item2, index2) in item1.list"
+                  :key="index2"
+                  class="specs-item"
+                  :class="item2.id == item1.id ? 'hig' : item2.disabled ? 'disabled' : ''"
+                >
+                  {{ item2.title }}
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="number-bos">
+            <div>数量</div>
+            <div class="flex-row-start number-box">
+              <el-input-number v-model="num" :min="1" :max="10" @change="handleChange" />
+              <div style="margin-left: 10px">本产品限购2件</div>
+            </div>
+          </div>
+        </div>
+        <div class="bnt-bos flex-row-start">
+          <div>加入购物车</div>
+          <div>立即购买</div>
+        </div>
+      </div>
+    </div>
+    <div class="nav-bos flex-row-start">
+      <div v-for="(item, index) in navList" :key="index" :class="index == 0 ? 'hig' : ''">{{ item.title }}</div>
+    </div>
+    <img class="shop-img" src="@/assets/images/login-background.jpg" alt="" />
+    <div class="shop-more flex-row-between">
+      <div class="flex-row-start">
+        <div class="more1">更多推荐</div>
+        <div class="more2">甄选大牌,优质好品</div>
+      </div>
+      <div class="flex-row-start">
+        <div class="more3">查看更多</div>
+        <el-icon color="#364153" size="14"><ArrowRight /></el-icon>
+      </div>
+    </div>
+    <div class="data-bos">
+      <div v-for="(item, index) in 3" :key="index" class="data-list">
+        <img class="data-img" src="@/assets/images/login-background.jpg" alt="" />
+        <div class="data-title">格力KFR-72LW/定频冷暖空调柜机3P</div>
+        <div class="money">
+          <span class="money1">¥1,299</span>
+          <span class="money2">¥1,899</span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import back1 from '@/assets/images/login-background.jpg';
+import back2 from '@/assets/images/login-background.jpg';
+import back3 from '@/assets/images/login-background.jpg';
+import back4 from '@/assets/images/login-background.jpg';
+import back5 from '@/assets/images/login-background.jpg';
+import { el } from 'element-plus/es/locale/index.mjs';
+import { title } from 'process';
+
+const num = ref<any>(1);
+const carousel = ref<any>([
+  {
+    img: back1,
+    id: 1
+  },
+  {
+    img: back2,
+    id: 2
+  },
+  {
+    img: back3,
+    id: 3
+  },
+  {
+    img: back4,
+    id: 4
+  },
+  {
+    img: back5,
+    id: 5
+  }
+]);
+const navList = ref<any>([{ title: '商品详情' }, { title: '参数信息' }, { title: '售后服务说明' }, { title: '品牌信息' }, { title: '商品评价' }]);
+const specsList = ref<any>([
+  {
+    title: '规格参数01',
+    id: 1,
+    list: [
+      { title: '极光蓝', id: 1, disabled: false },
+      { title: '极光蓝', id: 2, disabled: false },
+      { title: '极光蓝', id: 3, disabled: false }
+    ]
+  },
+  {
+    title: '规格参数02',
+    id: 1,
+    list: [
+      { title: '极光蓝', id: 1, disabled: false },
+      { title: '极光蓝', id: 2, disabled: false },
+      { title: '极光蓝', id: 3, disabled: true }
+    ]
+  }
+]);
+const carouselIndex = ref<any>(0);
+
+const onCarousel = (type: number, index?: any) => {
+  if (type == 1) {
+    carouselIndex.value = index;
+  } else {
+    carouselIndex.value++;
+    if (carouselIndex.value > carousel.value.length - 1) {
+      carouselIndex.value = 0;
+    }
+  }
+};
+
+const handleChange = (val: any) => {
+  // num.value = val;
+};
+</script>
+
+<style lang="scss" scoped>
+.shop-pages {
+  width: 1200px;
+  margin: 0 auto;
+
+  .shop-head {
+    width: 1200px;
+    padding-top: 16px;
+
+    .head-left {
+      width: 106px;
+
+      .left-carousel {
+        height: 540px;
+        overflow-y: auto;
+
+        .carousel-item {
+          width: 100px;
+          height: 100px;
+          border-radius: 6px;
+          overflow: hidden;
+          margin-top: 10px;
+          cursor: pointer;
+
+          &:nth-of-type(1) {
+            margin-top: 0px;
+          }
+
+          &.hig {
+            border: 1.5px solid #e7000b;
+          }
+
+          img {
+            width: 100px;
+            height: 100px;
+          }
+        }
+      }
+
+      .left-next {
+        width: 100px;
+        height: 36px;
+        background: #ffffff;
+        border-radius: 6px 6px 6px 6px;
+        margin-top: 10px;
+        cursor: pointer;
+      }
+    }
+
+    .carousel-img {
+      width: 586px;
+      height: 586px;
+      border-radius: 10px;
+      margin-left: 4px;
+      margin-right: 10px;
+    }
+
+    .head-right {
+      width: 494px;
+      height: 586px;
+      background: #ffffff;
+      border-radius: 10px 10px 10px 10px;
+      padding: 20px 20px 30px 20px;
+
+      .right-title {
+        height: 56px;
+        font-weight: 600;
+        font-size: 20px;
+        color: #101828;
+      }
+
+      .right-num {
+        font-size: 14px;
+        color: #6a7282;
+      }
+
+      .right-price {
+        margin-top: 10px;
+        .price1 {
+          font-size: 12px;
+          color: #e7000b;
+        }
+
+        .price2 {
+          width: 52px;
+          height: 21px;
+          background: #e7000b;
+          border-radius: 2px;
+          font-size: 12px;
+          color: #ffffff;
+          line-height: 21px;
+          text-align: center;
+          margin: 0 16px 0 8px;
+        }
+
+        .price3 {
+          font-size: 12px;
+          color: #6a7282;
+          text-decoration: line-through;
+        }
+
+        .right-collect {
+          font-size: 14px;
+          color: #6a7282;
+
+          img {
+            width: 12px;
+            height: 12px;
+            margin-right: 6px;
+          }
+        }
+      }
+
+      .address {
+        height: 44px;
+        width: 100%;
+        border-top: 1px solid #e5e7eb;
+        border-bottom: 1px solid #e5e7eb;
+        margin-top: 20px;
+        font-size: 14px;
+        color: #000000;
+
+        .address-img {
+          width: 16px;
+          height: 16px;
+          margin-right: 10px;
+          margin-top: 2px;
+        }
+        .address-text {
+          margin-left: 10px;
+          width: 138px;
+        }
+      }
+
+      .specs-bos {
+        .specs-list {
+          margin-top: 20px;
+          font-size: 14px;
+          color: #364153;
+        }
+        .specs-box {
+          display: flex;
+          gap: 8px 10px;
+          padding-top: 8px;
+          .specs-item {
+            padding: 0 14px;
+            height: 32px;
+            border-radius: 4px 4px 4px 4px;
+            border: 1px solid #e8e8ea;
+            line-height: 32px;
+            cursor: pointer;
+            &.hig {
+              border: 1px solid #e7000b;
+              color: #e7000b;
+            }
+            &.disabled {
+              opacity: 0.5;
+              &:hover {
+                cursor: not-allowed;
+              }
+            }
+          }
+        }
+      }
+      .number-bos {
+        margin-top: 20px;
+        font-size: 14px;
+        color: #364153;
+        .number-box {
+          font-size: 14px;
+          color: #6a7282;
+          margin-top: 8px;
+        }
+      }
+      .bnt-bos {
+        width: 428px;
+        height: 44px;
+        border-radius: 10px;
+        overflow: hidden;
+        div {
+          width: 214px;
+          height: 44px;
+          line-height: 44px;
+          text-align: center;
+          cursor: pointer;
+          &:nth-of-type(1) {
+            background: #fcecf1;
+            color: #e7000b;
+          }
+          &:nth-of-type(2) {
+            background: #e7000b;
+            color: #ffffff;
+          }
+        }
+      }
+    }
+  }
+
+  .nav-bos {
+    width: 696px;
+    height: 48px;
+    background: #f9fafb;
+    border: 1px solid #e5e7eb;
+    margin-top: 20px;
+    gap: 0 32px;
+    padding-left: 32px;
+    font-size: 16px;
+    color: #364153;
+    div {
+      cursor: pointer;
+    }
+    .hig {
+      color: #101828;
+    }
+  }
+  .shop-img {
+    width: 696px;
+    height: 752px;
+    margin-top: 20px;
+  }
+
+  .shop-more {
+    width: 696px;
+    margin-top: 34px;
+    .more1 {
+      font-weight: 600;
+      font-size: 20px;
+      color: #101828;
+    }
+    .more2 {
+      font-size: 14px;
+      color: #364153;
+      margin-left: 10px;
+    }
+    .more3 {
+      font-size: 14px;
+      color: #364153;
+      margin-right: 6px;
+      cursor: pointer;
+    }
+  }
+
+  //数据
+  .data-bos {
+    display: flex;
+    gap: 20px;
+    flex-wrap: wrap;
+    margin-bottom: 40px;
+    margin-top: 24px;
+    .data-list {
+      width: 224px;
+      background: #ffffff;
+      border-radius: 10px;
+      padding: 20px 20px 22px 20px;
+      cursor: pointer;
+      .data-img {
+        width: 184px;
+        height: 184px;
+        border-radius: 10px;
+      }
+      .data-title {
+        margin-top: 4px;
+        font-size: 14px;
+        color: #101828;
+        height: 40px;
+      }
+      .money {
+        margin-top: 4px;
+        .money1 {
+          font-size: 16px;
+          color: #e7000b;
+        }
+        .money2 {
+          font-size: 12px;
+          color: #99a1af;
+          text-decoration: line-through;
+          padding-left: 6px;
+        }
+      }
+      .data-cat {
+        width: 86px;
+        height: 26px;
+        background: #e7000b;
+        border-radius: 2px;
+        font-size: 14px;
+        color: #ffffff;
+        line-height: 26px;
+        text-align: center;
+        margin-top: 16px;
+      }
+    }
+  }
+}
+</style>

+ 160 - 0
src/views/shop/pay.vue

@@ -0,0 +1,160 @@
+<template>
+  <div class="pay-pages">
+    <div class="pay-bos">
+      <div class="create-title flex-row-start">
+        <el-icon color="#101828" size="16"><Document /></el-icon>
+        <div style="margin-left: 6px">支付订单</div>
+      </div>
+      <div class="pay-bos flex-column-between">
+        <div class="pay-box flex-column-center">
+          <img src="@/assets/images/dark.svg" alt="" />
+          <div class="pay-text1">订单提交成功!请尽快完成支付。</div>
+          <div class="pay-text2">请在2小时0分内完成支付,超时后将取消订单</div>
+        </div>
+        <div class="pay-bnt flex-row-center">
+          <span class="bnt1">应付总额:</span>
+          <span class="bnt2">¥0.00</span>
+        </div>
+      </div>
+      <div class="pay-head1">选择支付方式</div>
+      <div class="pay-for">
+        <div v-for="(item, index) in payList" :key="index" class="pay-list flex-row-center" :class="index == 0 ? 'hig' : ''">
+          <img src="@/assets/images/dark.svg" alt="" />
+          <div>{{ item.title }}</div>
+        </div>
+      </div>
+      <div class="pay-head2">选择“暂存订单”,订单将在我的订单中査看,您可以在我的订单中进行完成支付。</div>
+      <div class="pay-for">
+        <div class="pay-list flex-row-center">
+          <img src="@/assets/images/dark.svg" alt="" />
+          <div>暂存订单</div>
+        </div>
+      </div>
+    </div>
+    <div class="pay-foot">
+      <div class="foot-bos">
+        <el-button class="bnt1">返回购物车修改</el-button>
+        <el-button class="bnt2" type="primary">提交订单</el-button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const payList = ref<any>([{ title: '信用支付' }, { title: '支付宝支付' }, { title: '微信支付' }, { title: '货到付款' }]);
+</script>
+
+<style lang="scss" scoped>
+.pay-pages {
+  width: 100%;
+  background-color: #ffffff;
+  .pay-bos {
+    width: 1200px;
+    margin: 0 auto;
+    .create-title {
+      font-size: 16px;
+      color: #101828;
+    }
+    .pay-bos {
+      width: 1200px;
+      height: 230px;
+      border: 1px solid #e5e7eb;
+      margin-top: 30px;
+      padding: 30px 0 20px 0;
+      .pay-box {
+        width: 1180px;
+        border-bottom: 1px solid #dfe9f1;
+        margin: 0 10px;
+        padding-bottom: 20px;
+        img {
+          width: 27px;
+          height: 27px;
+        }
+        .pay-text1 {
+          font-weight: 600;
+          font-size: 14px;
+          color: #101828;
+          margin: 8px 0;
+        }
+        .pay-text2 {
+          font-weight: 400;
+          font-size: 14px;
+          color: #364153;
+        }
+      }
+      .pay-bnt {
+        width: 428px;
+        height: 68px;
+        background: #f2f3f5;
+        border-radius: 10px 10px 10px 10px;
+        margin: 0 auto;
+        cursor: pointer;
+        .bnt1 {
+          font-weight: 400;
+          font-size: 14px;
+          color: #000000;
+        }
+        .bnt2 {
+          font-weight: 600;
+          font-size: 20px;
+          color: #e7000b;
+        }
+      }
+    }
+    .pay-head1 {
+      font-weight: 600;
+      font-size: 16px;
+      color: #101828;
+      margin: 30px 0 20px 0;
+    }
+    .pay-for {
+      display: flex;
+      gap: 0 18px;
+      .pay-list {
+        width: 180px;
+        height: 60px;
+        border-radius: 10px;
+        border: 1px solid #e5e7eb;
+        font-size: 14px;
+        color: #000000;
+        cursor: pointer;
+        &.hig {
+          background: #ffe5e5;
+          border: 1px solid #e7000b;
+        }
+        img {
+          height: 18px;
+          width: 18px;
+          margin-right: 12px;
+        }
+      }
+    }
+    .pay-head2 {
+      font-size: 13px;
+      color: #364153;
+      padding: 20px 0 12px 0;
+    }
+  }
+  .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;
+      .bnt1 {
+        width: 198px;
+        height: 50px;
+        background: #f7f8fa;
+      }
+      .bnt2 {
+        width: 156px;
+        height: 50px;
+      }
+    }
+  }
+}
+</style>

+ 271 - 0
src/views/solve/index.vue

@@ -0,0 +1,271 @@
+<template>
+  <div class="solve">
+    <div class="solve-head">
+      <div class="head-bos">
+        <div class="nav-bos flex-row-start">
+          <div v-for="(item, index) in navList" :key="index" class="nav-list" :class="navIndex == index ? 'hig' : ''">
+            {{ item.title }}
+          </div>
+        </div>
+        <div class="filter-bos">
+          <div v-for="(item1, index1) in filterListy" :key="index1" class="filter-list flex-row-start">
+            <div class="filter-title">{{ item1.title }}</div>
+            <div v-for="(item2, index2) in item1.list" :key="index2" class="filter-item" :class="item1.hig == item2.id ? 'hig' : ''">
+              {{ item2.title }}
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 数据 -->
+    <div class="data-bos">
+      <div v-for="(item, index) in 9" :key="index" class="data-list" @click="onPath">
+        <img class="data-img" src="@/assets/images/login-background.jpg" alt="" />
+        <div class="data-box flex-column-between">
+          <div>
+            <div class="title ellipsis">2025中秋福利 企业团购方案</div>
+            <div class="info ellipsis">干款好礼·百大品牌·个性定制</div>
+          </div>
+          <div class="text flex-row-start">
+            <div>了解详情</div>
+            <el-icon color="#e7000b" size="14" style="margin: 0 0 0 10px">
+              <ArrowRight />
+            </el-icon>
+          </div>
+        </div>
+      </div>
+    </div>
+    <!-- 分页 -->
+    <div class="pagination-bos flex-row-between">
+      <div></div>
+      <el-pagination
+        v-model:current-page="currentPage1"
+        v-model:page-size="pageSize2"
+        layout="sizes, prev, pager, next ,jumper"
+        :total="1000"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const currentPage1 = ref(5);
+const pageSize2 = ref(100);
+
+const navList = ref<any>([
+  { title: '专题分类' },
+  { title: '大中型企业采购' },
+  { title: '政府&公共采购' },
+  { title: '营销福利' },
+  { title: '商用工程' },
+  { title: '中小型企业采购' }
+]);
+const filterListy = ref<any>([
+  {
+    title: '适配场景',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '1-100', id: 2 },
+      { title: '100-500', id: 3 },
+      { title: '1000+', id: 4 }
+    ]
+  },
+  {
+    title: '适配行业',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '食品饮料', id: 2 },
+      { title: '食品饮料', id: 3 },
+      { title: '食品饮料', id: 4 }
+    ]
+  },
+  {
+    title: '价格区间',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '香港小熊', id: 2 }
+    ]
+  },
+  {
+    title: '推荐标签',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '香港小熊', id: 2 }
+    ]
+  }
+]);
+const navIndex = ref(0);
+const router = useRouter();
+const handleSizeChange = (val: number) => {
+  console.log(`${val} items per page`);
+};
+const handleCurrentChange = (val: number) => {
+  console.log(`current page: ${val}`);
+};
+
+const onPath = () => {
+  router.push('/solve/info');
+};
+</script>
+
+<style lang="scss" scoped>
+.solve {
+  width: 100%;
+
+  .solve-head {
+    width: 100%;
+    background: #ffffff;
+
+    .head-bos {
+      width: 1200px;
+      margin: 0 auto;
+      padding-bottom: 20px;
+    }
+  }
+
+  .nav-bos {
+    border-bottom: 1px solid #e5e7eb;
+    width: 1200px;
+    padding-bottom: 20px;
+
+    .nav-list {
+      height: 32px;
+      padding: 0 12px;
+      background: #f7f8fa;
+      border-radius: 2px 2px 2px 2px;
+      font-size: 14px;
+      color: #4e5969;
+      margin-right: 8px;
+      line-height: 32px;
+      cursor: pointer;
+
+      &.hig {
+        background: #ffe8e8;
+        color: #e7000b;
+      }
+
+      &:hover {
+        color: #e7000b;
+      }
+    }
+  }
+
+  .filter-bos {
+    .filter-list {
+      margin-top: 20px;
+
+      .filter-title {
+        font-size: 14px;
+        color: #101828;
+        margin-right: 40px;
+      }
+
+      .filter-item {
+        font-size: 14px;
+        color: #364153;
+        margin-right: 30px;
+        cursor: pointer;
+
+        &.hig {
+          color: #e7000b;
+        }
+      }
+    }
+  }
+
+  // 数据
+  .data-bos {
+    width: 1200px;
+    margin: 0 auto;
+    display: flex;
+    gap: 20px;
+    flex-wrap: wrap;
+    padding: 22px 0 40px 0;
+
+    .data-list {
+      width: 386px;
+      height: 302px;
+      background: #ffffff;
+      border-radius: 10px;
+      overflow: hidden;
+      cursor: pointer;
+
+      .data-img {
+        height: 200px;
+        width: 386px;
+      }
+
+      .data-box {
+        height: 102px;
+        width: 386px;
+        padding: 12px 20px;
+
+        .title {
+          font-weight: 600;
+          font-size: 14px;
+          color: #101828;
+        }
+
+        .info {
+          font-size: 12px;
+          color: #364153;
+          margin-top: 4px;
+        }
+
+        .text {
+          font-size: 14px;
+          color: #e7000b;
+        }
+      }
+    }
+  }
+
+  //分页
+  .pagination-bos {
+    width: 1200px;
+    margin: 0 auto;
+    padding-bottom: 60px;
+    :deep(.el-select__wrapper) {
+      background: #f4f4f4;
+      box-shadow: 0 0 0 1px #e5e6eb inset;
+      border-radius: 2px;
+    }
+    :deep(.el-select__placeholder) {
+      color: #1d2129;
+    }
+    :deep(.el-input__wrapper) {
+      background: #f4f4f4;
+      box-shadow: 0 0 0 1px #e5e6eb inset;
+      border-radius: 2px;
+    }
+    :deep(.el-input__inner) {
+      color: #1d2129;
+    }
+
+    :deep(.btn-prev) {
+      background: #f4f4f4;
+      border: 1px solid #e5e6eb;
+      margin-right: 8px;
+    }
+    :deep(.btn-next) {
+      background: #f4f4f4;
+      border: 1px solid #e5e6eb;
+      margin-left: 8px;
+    }
+    :deep(.el-pager) {
+      gap: 0 8px;
+      li {
+        background: #f4f4f4;
+        border: 1px solid #e5e6eb;
+        color: #1d2129;
+      }
+    }
+  }
+}
+</style>

+ 223 - 0
src/views/solve/info.vue

@@ -0,0 +1,223 @@
+<template>
+  <div class="solve-page">
+    <div class="solve-bos">
+      <img class="solve-img" src="@/assets/images/login-background.jpg" alt="" />
+      <div class="title">香港小熊食品 甜蜜褔利 品质之选</div>
+      <div class="info">节日专题:节日、节日等主题盒子;可定制企业及福语、传递节日贺卡 员工关怀:办公室下午茶分享</div>
+      <div class="filter-bos">
+        <div v-for="(item1, index1) in filterListy" :key="index1" class="filter-list flex-row-start">
+          <div class="filter-title">{{ item1.title }}</div>
+          <div v-for="(item2, index2) in item1.list" :key="index2" class="filter-item" :class="item1.hig == item2.id ? 'hig' : ''">
+            {{ item2.title }}
+          </div>
+        </div>
+      </div>
+      <div class="nav-bos flex-row-start">
+        <div v-for="(item, index) in navList" :key="index" class="nav-list" :class="navIndex == index ? 'hig' : ''">
+          {{ item.title }}
+        </div>
+      </div>
+      <!-- 数据 -->
+      <div class="data-bos">
+        <div v-for="(item, index) in 13" :key="index" class="data-list" @click="onPath">
+          <img class="data-img" src="@/assets/images/login-background.jpg" alt="" />
+          <div class="data-title">格力KFR-72LW/定频冷暖空调柜机3P</div>
+          <div class="money">
+            <span class="money1">¥1,299</span>
+            <span class="money2">¥1,899</span>
+          </div>
+          <div class="data-cat">加入购物车</div>
+        </div>
+      </div>
+      <!-- 分页 -->
+      <div class="pagination-bos flex-row-between">
+        <div></div>
+        <el-pagination
+          v-model:current-page="currentPage1"
+          v-model:page-size="pageSize2"
+          layout="sizes, prev, pager, next ,jumper"
+          :total="1000"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+const currentPage1 = ref(5);
+const pageSize2 = ref(100);
+const navIndex = ref(0);
+const router = useRouter();
+const navList = ref<any>([{ title: '智能匹配' }, { title: '人气排序' }, { title: '价格排序' }]);
+const filterListy = ref<any>([
+  {
+    title: '价格区间',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '1-100', id: 2 },
+      { title: '100-500', id: 3 },
+      { title: '1000+', id: 4 }
+    ]
+  },
+  {
+    title: '产品分类',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '食品饮料', id: 2 },
+      { title: '食品饮料', id: 3 },
+      { title: '食品饮料', id: 4 }
+    ]
+  },
+  {
+    title: '产品品牌',
+    hig: 1,
+    list: [
+      { title: '全部', id: 1 },
+      { title: '香港小熊', id: 2 }
+    ]
+  }
+]);
+
+const handleSizeChange = (val: number) => {
+  console.log(`${val} items per page`);
+};
+const handleCurrentChange = (val: number) => {
+  console.log(`current page: ${val}`);
+};
+
+const onPath = () => {
+  router.push('/shop/info');
+};
+</script>
+
+<style lang="scss" scoped>
+.solve-page {
+  width: 100%;
+  background-color: #ffffff;
+
+  .solve-bos {
+    width: 1200px;
+    margin: 0 auto;
+    .solve-img {
+      width: 1200px;
+      height: 380px;
+      border-radius: 10px;
+    }
+    .title {
+      font-weight: 600;
+      font-size: 20px;
+      color: #101828;
+      margin-top: 20px;
+    }
+    .info {
+      font-size: 14px;
+      color: #364153;
+      margin-top: 8px;
+      border-bottom: 1px solid #e5e7eb;
+      padding-bottom: 20px;
+    }
+    .filter-bos {
+      padding-bottom: 20px;
+      border-bottom: 1px solid #e5e7eb;
+      .filter-list {
+        margin-top: 20px;
+
+        .filter-title {
+          font-size: 14px;
+          color: #101828;
+          margin-right: 40px;
+        }
+
+        .filter-item {
+          font-size: 14px;
+          color: #364153;
+          margin-right: 30px;
+          cursor: pointer;
+
+          &.hig {
+            color: #e7000b;
+          }
+        }
+      }
+    }
+    .nav-bos {
+      width: 1200px;
+      padding: 20px 0;
+
+      .nav-list {
+        height: 32px;
+        padding: 0 12px;
+        background: #f7f8fa;
+        border-radius: 2px 2px 2px 2px;
+        font-size: 14px;
+        color: #4e5969;
+        margin-right: 8px;
+        line-height: 32px;
+        cursor: pointer;
+
+        &.hig {
+          background: #ffe8e8;
+          color: #e7000b;
+        }
+
+        &:hover {
+          color: #e7000b;
+        }
+      }
+    }
+    //数据
+    .data-bos {
+      display: flex;
+      gap: 20px;
+      flex-wrap: wrap;
+      margin-bottom: 40px;
+      .data-list {
+        width: 224px;
+        background: #f4f4f4;
+        border-radius: 10px;
+        padding: 20px 20px 22px 20px;
+        cursor: pointer;
+        .data-img {
+          width: 184px;
+          height: 184px;
+          border-radius: 10px;
+        }
+        .data-title {
+          margin-top: 4px;
+          font-size: 14px;
+          color: #101828;
+          height: 40px;
+        }
+        .money {
+          margin-top: 4px;
+          .money1 {
+            font-size: 16px;
+            color: #e7000b;
+          }
+          .money2 {
+            font-size: 12px;
+            color: #99a1af;
+            text-decoration: line-through;
+            padding-left: 6px;
+          }
+        }
+        .data-cat {
+          width: 86px;
+          height: 26px;
+          background: #e7000b;
+          border-radius: 2px;
+          font-size: 14px;
+          color: #ffffff;
+          line-height: 26px;
+          text-align: center;
+          margin-top: 16px;
+        }
+      }
+    }
+  }
+}
+</style>

+ 144 - 0
src/views/solve/real.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="real-pages">
+    <div>
+      <div class="real-info">
+        <div class="title">喜讯|优易365中标“吉林大学通用办公用品、电子耗材采购项目</div>
+        <div class="time">2025/09/22</div>
+        <img class="img" src="@/assets/images/login-background.jpg" alt="" />
+        <div class="head">项目介绍</div>
+        <div class="info">
+          吉林大学是教育部直属全国重点综合性大学,位于吉林长春。学校始建于 1946 年,是国家 “211 工程”“985 工程” 和首批 “双一流”
+          建设高校。学科门类齐全,涵盖 13 大学科门类,下设 40 多个教学单位。有专任教师 6000
+          余人,其中国家级人才众多。校园占地面积广阔,图书馆藏书丰富。学校聚焦世界名校合作,与 300 多所高校和科研机构建立合作关系。
+          2025年吉林大学启动通用办公用品及电子耗材采购项目(项目编号:JLU-XC25055-0618)的招标,优易达(武汉)有限公司凭借全国性服务网络、数字化供应链管理体系及政企集采标杆案例,从全国竞争者中脱颖而出,成为吉林大学通用办公用品及电子耗材采购项目入围供应商!
+          此次同吉林大学的合作,优易365将坚守“全国资源+本地服务”理念,以数字化采购解决方案赋能高校行政效率提升。携手共创智慧校园新生态
+        </div>
+        <img class="img" src="@/assets/images/login-background.jpg" alt="" />
+      </div>
+    </div>
+
+    <div class="real-shop">
+      <div class="shop-head flex-row-start">
+        <div class="head1">为您推荐</div>
+        <div class="head2">热门流行商品推荐</div>
+      </div>
+      <div class="data-bos">
+        <div v-for="(item, index) in 9" :key="index" class="data-list">
+          <img class="data-img" src="@/assets/images/login-background.jpg" alt="" />
+          <div class="data-title">格力KFR-72LW/定频冷暖空调柜机3P</div>
+          <div class="money">
+            <span class="money1">¥1,299</span>
+            <span class="money2">¥1,899</span>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts"></script>
+
+<style lang="scss" scoped>
+.real-pages {
+  width: 1200px;
+  margin: 0 auto;
+  display: flex;
+  gap: 0 20px;
+  padding-top: 15px;
+  padding-bottom: 50px;
+  .real-info {
+    width: 715px;
+    background: #ffffff;
+    border-radius: 10px;
+    padding: 20px;
+    .title {
+      font-size: 20px;
+      color: #101828;
+    }
+    .time {
+      font-size: 14px;
+      color: #364153;
+      margin: 10px 0 18px 0;
+    }
+    .img {
+      width: 679px;
+      height: 351px;
+      border-radius: 10px;
+    }
+    .head {
+      font-weight: 600;
+      font-size: 14px;
+      color: #101828;
+      margin: 10px 0 18px 0;
+    }
+    .info {
+      font-size: 14px;
+      color: #364153;
+      margin-bottom: 15px;
+    }
+  }
+  .real-shop {
+    flex: 1;
+    .head1 {
+      font-weight: 600;
+      font-size: 20px;
+      color: #101828;
+    }
+    .head2 {
+      font-size: 14px;
+      color: #364153;
+      margin-left: 10px;
+    }
+    //数据
+    .data-bos {
+      display: flex;
+      gap: 17px;
+      flex-wrap: wrap;
+      margin-top: 10px;
+      width: 100%;
+      .data-list {
+        width: 224px;
+        background: #ffffff;
+        border-radius: 10px;
+        padding: 20px 20px 22px 20px;
+        cursor: pointer;
+        .data-img {
+          width: 184px;
+          height: 184px;
+          border-radius: 10px;
+        }
+        .data-title {
+          margin-top: 4px;
+          font-size: 14px;
+          color: #101828;
+          height: 40px;
+        }
+        .money {
+          margin-top: 4px;
+          .money1 {
+            font-size: 16px;
+            color: #e7000b;
+          }
+          .money2 {
+            font-size: 12px;
+            color: #99a1af;
+            text-decoration: line-through;
+            padding-left: 6px;
+          }
+        }
+        .data-cat {
+          width: 86px;
+          height: 26px;
+          background: #e7000b;
+          border-radius: 2px;
+          font-size: 14px;
+          color: #ffffff;
+          line-height: 26px;
+          text-align: center;
+          margin-top: 16px;
+        }
+      }
+    }
+  }
+}
+</style>