first commit
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
const BANNER = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="banner-container">
|
||||
<el-carousel :interval="5000" arrow="always" height="480px">
|
||||
<el-carousel-item v-for="(banner, index) in banners" :key="index">
|
||||
<a :href="banner.link" class="banner-item">
|
||||
<img :src="banner.image" :alt="banner.title" class="banner-image">
|
||||
<div class="banner-title">{{ banner.title }}</div>
|
||||
</a>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
banners: [
|
||||
{
|
||||
id: 1,
|
||||
title: '618年中大促',
|
||||
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/211815/34/8529/107925/6111c8c9E4a1f8d2b/291c9c66391b8c6d.jpg',
|
||||
link: '#'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '手机5折起',
|
||||
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/198372/22/19657/123948/6111c8c9E0d8a5c8d/1c8e6b1c8b5e5b8a.jpg',
|
||||
link: '#'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '家电清凉一夏',
|
||||
image: 'https://img10.360buyimg.com/babel/s1920x600_jfs/t1/198372/22/19657/123948/6111c8c9E0d8a5c8d/1c8e6b1c8b5e5b8a.jpg',
|
||||
link: '#'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.banner-container {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.banner-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.banner-title {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: white;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
<!--#include("breadcrumbNav.js"){}#-->
|
||||
const HEADER = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<div class="header-top">
|
||||
<div class="container">
|
||||
<div class="welcome">欢迎来到京东商城</div>
|
||||
<div class="user-info">
|
||||
<template v-if="isLogin">
|
||||
<a href="javascript:void(0)">我的订单</a>
|
||||
<a href="javascript:void(0)">我的京东</a>
|
||||
<a href="javascript:void(0)" @click="logout">退出</a>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a href="javascript:void(0)" @click="login">登录</a>
|
||||
<a href="javascript:void(0)" @click="register">注册</a>
|
||||
</template>
|
||||
<a href="javascript:void(0)">我的订单</a>
|
||||
<a href="javascript:void(0)">我的京东</a>
|
||||
<a href="javascript:void(0)">企业采购</a>
|
||||
<el-dropdown @command="handleService">
|
||||
<span class="el-dropdown-link">
|
||||
客户服务<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="help">帮助中心</el-dropdown-item>
|
||||
<el-dropdown-item command="customer">在线客服</el-dropdown-item>
|
||||
<el-dropdown-item command="after-sales">售后服务</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-dropdown @command="handleApp">
|
||||
<span class="el-dropdown-link">
|
||||
手机京东<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="app">京东APP</el-dropdown-item>
|
||||
<el-dropdown-item command="wechat">微信小程序</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-main">
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<a href="/">
|
||||
<img src="https://img11.360buyimg.com/jdcdh/s150x50_jfs/t1/173705/37/11987/5525/60b3d1c7E56f89c06/899d8b19c09f7d2c.png" alt="京东商城">
|
||||
</a>
|
||||
</div>
|
||||
<div class="search-box">
|
||||
<el-input
|
||||
v-model="searchQuery"
|
||||
placeholder="搜索商品"
|
||||
@keyup.enter.native="handleSearch">
|
||||
<el-button slot="append" type="danger" icon="el-icon-search" @click="handleSearch"></el-button>
|
||||
</el-input>
|
||||
<div class="hot-keys">
|
||||
<a href="javascript:void(0)" v-for="(keyword, index) in hotSearch" :key="index">{{ keyword }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cart-box">
|
||||
<el-badge :value="cartCount" :max="99">
|
||||
<el-button type="danger" icon="el-icon-shopping-cart-2" size="medium">我的购物车</el-button>
|
||||
</el-badge>
|
||||
<div class="cart-dropdown" v-if="cartCount > 0">
|
||||
<p>最近加入的商品</p>
|
||||
<div class="cart-items">
|
||||
<div class="cart-item" v-for="(item, index) in cartItems" :key="index">
|
||||
<div class="item-image">
|
||||
<img :src="item.image" alt="商品图片">
|
||||
</div>
|
||||
<div class="item-info">
|
||||
<div class="item-name">{{ item.name }}</div>
|
||||
<div class="item-price">¥{{ item.price }} × {{ item.quantity }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cart-footer">
|
||||
<span>共 {{ cartCount }} 件商品</span>
|
||||
<el-button type="danger" size="small">去购物车</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-bottom">
|
||||
<div class="container">
|
||||
<nav class="main-nav">
|
||||
<ul class="nav-list">
|
||||
<li :class="{ 'active': activeNav === 'home' }">
|
||||
<a href="/">首页</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'electronics' }">
|
||||
<a href="/category/electronics">手机数码</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'home-appliance' }">
|
||||
<a href="/category/appliance">家用电器</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'computer' }">
|
||||
<a href="/category/computer">电脑办公</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'furniture' }">
|
||||
<a href="/category/furniture">家居家装</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'food' }">
|
||||
<a href="/category/food">食品生鲜</a>
|
||||
</li>
|
||||
<li :class="{ 'active': activeNav === 'book' }">
|
||||
<a href="/category/book">图书</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
searchQuery: '',
|
||||
hotSearch: ['手机', '笔记本', '电视', '空调', '洗衣机', '冰箱'],
|
||||
cartCount: 3,
|
||||
cartItems: [
|
||||
{ id: 1, name: 'Apple iPhone 13', price: 5999, quantity: 1, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 2, name: '华为MateBook X Pro', price: 8999, quantity: 1, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 3, name: '小米电视6 OLED', price: 5999, quantity: 1, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
isLogin: false,
|
||||
activeNav: 'home'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSearch() {
|
||||
if (this.searchQuery.trim()) {
|
||||
this.$emit('search', this.searchQuery);
|
||||
console.log('搜索:', this.searchQuery);
|
||||
}
|
||||
},
|
||||
handleService(command) {
|
||||
console.log('客户服务:', command);
|
||||
},
|
||||
handleApp(command) {
|
||||
console.log('手机京东:', command);
|
||||
},
|
||||
login() {
|
||||
this.isLogin = true;
|
||||
console.log('登录');
|
||||
},
|
||||
register() {
|
||||
console.log('注册');
|
||||
},
|
||||
logout() {
|
||||
this.isLogin = false;
|
||||
console.log('退出');
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.site-header {
|
||||
background: #fff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.header-top {
|
||||
background: #f5f5f5;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.user-info a {
|
||||
color: #999;
|
||||
margin-left: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.user-info a:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.header-main {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
.logo img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
float: left;
|
||||
width: 550px;
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
.hot-keys {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.hot-keys a {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-right: 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hot-keys a:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.cart-box {
|
||||
float: right;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cart-box:hover .cart-dropdown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.cart-dropdown {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 300px;
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.cart-items {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.cart-item {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.item-image {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.item-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.item-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.item-price {
|
||||
font-size: 12px;
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.cart-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
|
||||
.header-bottom {
|
||||
background: #c81623;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.main-nav {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.nav-list li {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.nav-list a {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nav-list a:hover {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.nav-list .active a {
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-list .active a::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: #fff;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
const HOT_BRANDS = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="hot-brands">
|
||||
<div class="section-header">
|
||||
<h2 class="title">热门品牌</h2>
|
||||
<div class="more">
|
||||
<a href="javascript:void(0)">查看全部品牌 <i class="el-icon-arrow-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="brands-content">
|
||||
<div class="brand-item" v-for="(brand, index) in brands" :key="index">
|
||||
<a :href="brand.link">
|
||||
<img :src="brand.logo" :alt="brand.name">
|
||||
<div class="brand-name">{{ brand.name }}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return{
|
||||
brands: [
|
||||
{ id: 1, name: 'Apple', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/17745/33/1524/7225/5c3b6c97E0c4c9e92/44a8b4c0e0c8f8d8.png', link: '#' },
|
||||
{ id: 2, name: '华为', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/35476/25/11785/6489/5d1c3e74E1c4c5a5b/0e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 3, name: '小米', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/18563/13/11786/5790/5d1c3e74E0c4c5a5b/1e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 4, name: '联想', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/36547/27/11785/5678/5d1c3e74E1c4c5a5b/2e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 5, name: '海尔', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/37547/29/11785/5890/5d1c3e74E1c4c5a5b/3e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 6, name: '美的', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/38547/31/11785/5987/5d1c3e74E1c4c5a5b/4e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 7, name: '三星', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/39547/33/11785/6123/5d1c3e74E1c4c5a5b/5e0b8b6c8d7e8e8e.png', link: '#' },
|
||||
{ id: 8, name: '索尼', logo: 'https://img10.360buyimg.com/uba/s96x32_jfs/t1/40547/35/11785/6234/5d1c3e74E1c4c5a5b/6e0b8b6c8d7e8e8e.png', link: '#' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.hot-brands {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.more a {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.more a:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.brands-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.brand-item {
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.brand-item:hover {
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-3px);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.brand-item img {
|
||||
width: 80%;
|
||||
height: auto;
|
||||
max-height: 40px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.brand-name {
|
||||
margin-top: 8px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,855 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
|
||||
.jd-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.jd-header {
|
||||
height: 110px;
|
||||
background: #c81623;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.jd-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jd-logo img {
|
||||
height: 60px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.jd-logo h1 {
|
||||
font-size: 28px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.jd-logo span {
|
||||
font-size: 16px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* 购物车标题 */
|
||||
.cart-title {
|
||||
padding: 20px 20px 10px;
|
||||
border-bottom: 2px solid #c81623;
|
||||
}
|
||||
|
||||
.cart-title h2 {
|
||||
font-size: 24px;
|
||||
color: #c81623;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* 购物车表格 */
|
||||
.cart-table {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
border: 1px solid #e6e6e6;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background-color: #f5f5f5;
|
||||
padding: 10px 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.product-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border: 1px solid #eee;
|
||||
margin-right: 15px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #333;
|
||||
margin-bottom: 5px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-desc {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.spec-select {
|
||||
width: 120px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.price-cell {
|
||||
color: #c81623;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.quantity-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-input-number {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-input-number--mini .el-input__inner {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.el-input-number--mini .el-input-number__decrease,
|
||||
.el-input-number--mini .el-input-number__increase {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.subtotal {
|
||||
color: #c81623;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.delete-btn {
|
||||
color: #999;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.delete-btn:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
/* 底部操作栏 */
|
||||
.cart-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
background: #fff;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.footer-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.select-all {
|
||||
margin-right: 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.selected-count {
|
||||
color: #c81623;
|
||||
font-weight: bold;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.total-price {
|
||||
font-size: 18px;
|
||||
color: #c81623;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.settlement-btn {
|
||||
background: #c81623;
|
||||
border-color: #c81623;
|
||||
color: #fff;
|
||||
padding: 0 25px;
|
||||
height: 36px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.settlement-btn:hover {
|
||||
background: #a7141f;
|
||||
border-color: #a7141f;
|
||||
}
|
||||
|
||||
.settlement-btn:disabled {
|
||||
background: #ccc;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
/* 地址选择区域 */
|
||||
.address-section {
|
||||
padding: 15px 20px;
|
||||
background: #f9f9f9;
|
||||
border-top: 1px dashed #e6e6e6;
|
||||
}
|
||||
|
||||
.address-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.address-title i {
|
||||
margin-right: 5px;
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.address-list {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.address-card {
|
||||
border: 1px solid #e6e6e6;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.address-card:hover {
|
||||
border-color: #c81623;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.address-card.active {
|
||||
border-color: #c81623;
|
||||
background: #fff9f9;
|
||||
}
|
||||
|
||||
.address-card.active::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border-width: 0 16px 16px 0;
|
||||
border-style: solid;
|
||||
border-color: #c81623 transparent;
|
||||
}
|
||||
|
||||
.address-card.active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
width: 12px;
|
||||
height: 6px;
|
||||
border: 2px solid #fff;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
transform: rotate(-45deg);
|
||||
}
|
||||
|
||||
.address-name {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.address-detail {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.address-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.address-actions .el-button {
|
||||
padding: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 空购物车状态 */
|
||||
.empty-cart {
|
||||
text-align: center;
|
||||
padding: 50px 0;
|
||||
}
|
||||
|
||||
.empty-cart img {
|
||||
width: 180px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.empty-cart p {
|
||||
color: #999;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.continue-shopping {
|
||||
background: #c81623;
|
||||
color: #fff;
|
||||
padding: 8px 25px;
|
||||
border-radius: 2px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.continue-shopping:hover {
|
||||
background: #a7141f;
|
||||
}
|
||||
|
||||
/* 优惠信息 */
|
||||
.promotion {
|
||||
padding: 10px 20px;
|
||||
background: #fff9f9;
|
||||
border: 1px solid #ffeaea;
|
||||
color: #c81623;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.promotion i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.cart-table {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.cart-footer {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.footer-right {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="jd-container">
|
||||
<!-- 顶部导航 -->
|
||||
<header class="jd-header">
|
||||
<a href="#" class="jd-logo">
|
||||
<img src="https://img12.360buyimg.com/img/jfs/t1/2022/36/7653/3103/5b9f5f5cE6c40a453/9c4c3d0a0e0d6e0d.png" alt="京东">
|
||||
<div>
|
||||
<h1>京东</h1>
|
||||
<span>品质购物,品质生活</span>
|
||||
</div>
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<!-- 购物车标题 -->
|
||||
<div class="cart-title">
|
||||
<h2>我的购物车</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 购物车内容 -->
|
||||
<div v-if="cartItems.length > 0">
|
||||
<div class="cart-table">
|
||||
<!-- 购物车表格 -->
|
||||
<el-table :data="cartItems" style="width: 100%" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center"></el-table-column>
|
||||
|
||||
<el-table-column label="商品" min-width="400">
|
||||
<template slot-scope="scope">
|
||||
<div class="product-cell">
|
||||
<img :src="scope.row.image" :alt="scope.row.name" class="product-image">
|
||||
<div class="product-info">
|
||||
<div class="product-name">{{ scope.row.name }}</div>
|
||||
<div class="product-desc">{{ scope.row.description }}</div>
|
||||
<el-select v-model="scope.row.selectedSpec" size="mini" class="spec-select" @change="updateSpec(scope.row)">
|
||||
<el-option
|
||||
v-for="spec in scope.row.specs"
|
||||
:key="spec.value"
|
||||
:label="spec.label"
|
||||
:value="spec.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="单价" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div class="price-cell">¥{{ scope.row.price.toFixed(2) }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="数量" width="150" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div class="quantity-cell">
|
||||
<el-input-number
|
||||
v-model="scope.row.quantity"
|
||||
:min="1"
|
||||
:max="99"
|
||||
size="mini"
|
||||
@change="updateQuantity(scope.row)">
|
||||
</el-input-number>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="小计" width="120" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div class="subtotal">¥{{ (scope.row.price * scope.row.quantity).toFixed(2) }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span class="delete-btn" @click="removeItem(scope.row)">删除</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 收货地址选择 -->
|
||||
<div class="address-section">
|
||||
<div class="address-title">
|
||||
<i class="el-icon-location-outline"></i>
|
||||
<span>收货地址</span>
|
||||
</div>
|
||||
<div class="address-list">
|
||||
<div
|
||||
v-for="(address, index) in addresses"
|
||||
:key="index"
|
||||
class="address-card"
|
||||
:class="{active: selectedAddress === index}"
|
||||
@click="selectAddress(index)">
|
||||
<div class="address-name">{{ address.name }} {{ address.phone }}</div>
|
||||
<div class="address-detail">{{ address.province }} {{ address.city }} {{ address.district }} {{ address.street }}</div>
|
||||
<div class="address-actions">
|
||||
<el-button type="text" @click.stop="editAddress(index)">编辑</el-button>
|
||||
<el-button type="text" @click.stop="removeAddress(index)">删除</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="address-card" @click="addNewAddress">
|
||||
<div style="text-align: center; padding: 20px 0; color: #c81623;">
|
||||
<i class="el-icon-plus" style="font-size: 24px; display: block; margin-bottom: 5px;"></i>
|
||||
<div>添加新地址</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="cart-footer">
|
||||
<div class="footer-left">
|
||||
<div class="select-all">
|
||||
<el-checkbox v-model="selectAll" @change="toggleSelectAll">全选</el-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
已选择 <span class="selected-count">{{ selectedItems.length }}</span> 件商品
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-right">
|
||||
<div>
|
||||
合计:<span class="total-price">¥{{ totalPrice.toFixed(2) }}</span>
|
||||
<span style="color: #999; font-size: 13px; margin-left: 5px;">(不含运费)</span>
|
||||
</div>
|
||||
<el-button
|
||||
type="danger"
|
||||
class="settlement-btn"
|
||||
:disabled="selectedItems.length === 0"
|
||||
@click="checkout">
|
||||
去结算
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空购物车 -->
|
||||
<div v-else class="empty-cart">
|
||||
<img src="https://img11.360buyimg.com/imagetools/jfs/t1/186857/25/10011/5375/60d9e586Ee3b46c7a/5a3d5c5b0d3a7a9d.png" alt="空购物车">
|
||||
<p>您的购物车空空如也,快去挑选心仪的商品吧!</p>
|
||||
<a href="#" class="continue-shopping">继续购物</a>
|
||||
</div>
|
||||
|
||||
<!-- 地址编辑弹窗 -->
|
||||
<el-dialog title="编辑收货地址" :visible.sync="addressDialogVisible" width="500px">
|
||||
<el-form :model="currentAddress" label-width="80px">
|
||||
<el-form-item label="收货人">
|
||||
<el-input v-model="currentAddress.name" placeholder="请输入收货人姓名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码">
|
||||
<el-input v-model="currentAddress.phone" placeholder="请输入手机号码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所在地区">
|
||||
<el-cascader
|
||||
v-model="currentAddress.region"
|
||||
:options="regionOptions"
|
||||
placeholder="请选择省市区"
|
||||
style="width: 100%;"></el-cascader>
|
||||
</el-form-item>
|
||||
<el-form-item label="详细地址">
|
||||
<el-input
|
||||
v-model="currentAddress.street"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入详细地址,如街道、门牌号等"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="设为默认">
|
||||
<el-switch v-model="currentAddress.isDefault"></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="addressDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="saveAddress">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
// 购物车商品数据
|
||||
cartItems: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Apple iPhone 13 256GB 国行正品 全网通5G手机',
|
||||
description: '全新国行,官方正品,全国联保',
|
||||
image: 'https://img14.360buyimg.com/n1/s200x200_jfs/t1/213334/24/9509/167699/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
|
||||
price: 6999.00,
|
||||
quantity: 1,
|
||||
specs: [
|
||||
{ label: '256GB 星光色', value: '256GB-星光色' },
|
||||
{ label: '256GB 午夜色', value: '256GB-午夜色' },
|
||||
{ label: '256GB 蓝色', value: '256GB-蓝色' },
|
||||
{ label: '512GB 星光色', value: '512GB-星光色' }
|
||||
],
|
||||
selectedSpec: '256GB 星光色'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '小米电视6 OLED 55英寸 4K超高清 HDR10+ 智能液晶电视机',
|
||||
description: 'OLED屏幕,极致色彩,智能语音控制',
|
||||
image: 'https://img10.360buyimg.com/n1/s200x200_jfs/t1/197519/35/11029/141950/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
|
||||
price: 4999.00,
|
||||
quantity: 1,
|
||||
specs: [
|
||||
{ label: '55英寸', value: '55英寸' },
|
||||
{ label: '65英寸', value: '65英寸' }
|
||||
],
|
||||
selectedSpec: '55英寸'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '飞利浦电动牙刷HX6730/02 成人声波震动牙刷',
|
||||
description: '3种清洁模式,智能计时,30天超长续航',
|
||||
image: 'https://img12.360buyimg.com/n1/s200x200_jfs/t1/199876/28/10998/98765/616d8d9aE7c89c58e/3a5d4b9a5b9b1e8c.jpg',
|
||||
price: 299.00,
|
||||
quantity: 2,
|
||||
specs: [
|
||||
{ label: '标准版', value: '标准版' },
|
||||
{ label: '旅行套装', value: '旅行套装' }
|
||||
],
|
||||
selectedSpec: '标准版'
|
||||
}
|
||||
],
|
||||
// 选中的商品
|
||||
selectedItems: [],
|
||||
// 收货地址
|
||||
addresses: [
|
||||
{
|
||||
name: '张三',
|
||||
phone: '138****1234',
|
||||
province: '北京市',
|
||||
city: '北京市',
|
||||
district: '海淀区',
|
||||
street: '中关村大街1号',
|
||||
isDefault: true
|
||||
},
|
||||
{
|
||||
name: '李四',
|
||||
phone: '139****5678',
|
||||
province: '上海市',
|
||||
city: '上海市',
|
||||
district: '浦东新区',
|
||||
street: '张江高科技园区',
|
||||
isDefault: false
|
||||
}
|
||||
],
|
||||
selectedAddress: 0,
|
||||
// 地址编辑相关
|
||||
addressDialogVisible: false,
|
||||
currentAddress: {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
street: '',
|
||||
isDefault: false
|
||||
},
|
||||
regionOptions: [
|
||||
{
|
||||
value: '北京市',
|
||||
label: '北京市',
|
||||
children: [
|
||||
{
|
||||
value: '北京市',
|
||||
label: '北京市',
|
||||
children: [
|
||||
{ value: '东城区', label: '东城区' },
|
||||
{ value: '西城区', label: '西城区' },
|
||||
{ value: '朝阳区', label: '朝阳区' },
|
||||
{ value: '海淀区', label: '海淀区' },
|
||||
{ value: '丰台区', label: '丰台区' },
|
||||
{ value: '石景山区', label: '石景山区' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '上海市',
|
||||
label: '上海市',
|
||||
children: [
|
||||
{
|
||||
value: '上海市',
|
||||
label: '上海市',
|
||||
children: [
|
||||
{ value: '黄浦区', label: '黄浦区' },
|
||||
{ value: '徐汇区', label: '徐汇区' },
|
||||
{ value: '长宁区', label: '长宁区' },
|
||||
{ value: '静安区', label: '静安区' },
|
||||
{ value: '浦东新区', label: '浦东新区' },
|
||||
{ value: '闵行区', label: '闵行区' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '广东省',
|
||||
label: '广东省',
|
||||
children: [
|
||||
{
|
||||
value: '广州市',
|
||||
label: '广州市',
|
||||
children: [
|
||||
{ value: '越秀区', label: '越秀区' },
|
||||
{ value: '海珠区', label: '海珠区' },
|
||||
{ value: '天河区', label: '天河区' },
|
||||
{ value: '白云区', label: '白云区' }
|
||||
]
|
||||
},
|
||||
{
|
||||
value: '深圳市',
|
||||
label: '深圳市',
|
||||
children: [
|
||||
{ value: '福田区', label: '福田区' },
|
||||
{ value: '罗湖区', label: '罗湖区' },
|
||||
{ value: '南山区', label: '南山区' },
|
||||
{ value: '宝安区', label: '宝安区' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 全选状态
|
||||
selectAll: {
|
||||
get() {
|
||||
return this.selectedItems.length === this.cartItems.length && this.cartItems.length > 0;
|
||||
},
|
||||
set(value) {
|
||||
if (value) {
|
||||
this.selectedItems = [...this.cartItems];
|
||||
} else {
|
||||
this.selectedItems = [];
|
||||
}
|
||||
}
|
||||
},
|
||||
// 计算总价
|
||||
totalPrice() {
|
||||
return this.selectedItems.reduce((total, item) => {
|
||||
return total + (item.price * item.quantity);
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 选择/取消选择商品
|
||||
handleSelectionChange(selection) {
|
||||
this.selectedItems = selection;
|
||||
},
|
||||
// 全选/取消全选
|
||||
toggleSelectAll(value) {
|
||||
this.selectAll = value;
|
||||
},
|
||||
// 更新商品数量
|
||||
updateQuantity(item) {
|
||||
const index = this.cartItems.findIndex(i => i.id === item.id);
|
||||
if (index !== -1) {
|
||||
this.$set(this.cartItems, index, { ...item });
|
||||
}
|
||||
},
|
||||
// 更新商品规格
|
||||
updateSpec(item) {
|
||||
const index = this.cartItems.findIndex(i => i.id === item.id);
|
||||
if (index !== -1) {
|
||||
this.$set(this.cartItems, index, { ...item });
|
||||
}
|
||||
},
|
||||
// 删除商品
|
||||
removeItem(item) {
|
||||
this.cartItems = this.cartItems.filter(i => i.id !== item.id);
|
||||
this.selectedItems = this.selectedItems.filter(i => i.id !== item.id);
|
||||
},
|
||||
// 选择收货地址
|
||||
selectAddress(index) {
|
||||
this.selectedAddress = index;
|
||||
},
|
||||
// 编辑地址
|
||||
editAddress(index) {
|
||||
const address = this.addresses[index];
|
||||
this.currentAddress = {
|
||||
name: address.name,
|
||||
phone: address.phone,
|
||||
region: [address.province, address.city, address.district],
|
||||
street: address.street,
|
||||
isDefault: address.isDefault
|
||||
};
|
||||
this.addressDialogVisible = true;
|
||||
},
|
||||
// 删除地址
|
||||
removeAddress(index) {
|
||||
if (this.addresses.length <= 1) {
|
||||
this.$message.warning('至少保留一个收货地址');
|
||||
return;
|
||||
}
|
||||
|
||||
this.addresses.splice(index, 1);
|
||||
|
||||
if (this.selectedAddress >= this.addresses.length) {
|
||||
this.selectedAddress = this.addresses.length - 1;
|
||||
}
|
||||
|
||||
this.$message.success('地址已删除');
|
||||
},
|
||||
// 添加新地址
|
||||
addNewAddress() {
|
||||
this.currentAddress = {
|
||||
name: '',
|
||||
phone: '',
|
||||
region: [],
|
||||
street: '',
|
||||
isDefault: false
|
||||
};
|
||||
this.addressDialogVisible = true;
|
||||
},
|
||||
// 保存地址
|
||||
saveAddress() {
|
||||
if (!this.currentAddress.name || !this.currentAddress.phone) {
|
||||
this.$message.error('请填写收货人和手机号');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.currentAddress.region.length < 3) {
|
||||
this.$message.error('请选择完整的省市区');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.currentAddress.street) {
|
||||
this.$message.error('请填写详细地址');
|
||||
return;
|
||||
}
|
||||
|
||||
const newAddress = {
|
||||
name: this.currentAddress.name,
|
||||
phone: this.currentAddress.phone,
|
||||
province: this.currentAddress.region[0],
|
||||
city: this.currentAddress.region[1],
|
||||
district: this.currentAddress.region[2],
|
||||
street: this.currentAddress.street,
|
||||
isDefault: this.currentAddress.isDefault
|
||||
};
|
||||
|
||||
if (this.currentAddress.isDefault) {
|
||||
// 如果设为默认,取消其他地址的默认状态
|
||||
this.addresses.forEach(addr => {
|
||||
addr.isDefault = false;
|
||||
});
|
||||
}
|
||||
|
||||
this.addresses.push(newAddress);
|
||||
this.selectedAddress = this.addresses.length - 1;
|
||||
this.addressDialogVisible = false;
|
||||
this.$message.success('地址保存成功');
|
||||
},
|
||||
// 结算
|
||||
checkout() {
|
||||
if (this.selectedItems.length === 0) {
|
||||
this.$message.warning('请至少选择一件商品');
|
||||
return;
|
||||
}
|
||||
|
||||
const address = this.addresses[this.selectedAddress];
|
||||
this.$alert('是否确认订单', '确认订单', {
|
||||
dangerouslyUseHTMLString: true,
|
||||
confirmButtonText: '确认提交',
|
||||
callback: action => {
|
||||
if (action === 'confirm') {
|
||||
this.$message.success('订单提交成功!');
|
||||
// 清空购物车中已选商品
|
||||
this.cartItems = this.cartItems.filter(item =>
|
||||
!this.selectedItems.some(selected => selected.id === item.id)
|
||||
);
|
||||
this.selectedItems = [];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// 初始化选中所有商品
|
||||
this.selectedItems = [...this.cartItems];
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
const PRODUCT_SECTION = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="product-section" :style="{ backgroundColor: sectionBg }">
|
||||
<div class="section-header">
|
||||
<h2 class="title">{{ sectionTitle }}</h2>
|
||||
<div class="section-tabs">
|
||||
<span
|
||||
v-for="(tab, index) in tabs"
|
||||
:key="index"
|
||||
:class="{ active: activeTab === tab }"
|
||||
@click="activeTab = tab">
|
||||
{{ tab }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="more">
|
||||
<a href="javascript:void(0)">更多 <i class="el-icon-arrow-right"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-content">
|
||||
<div class="product-sidebar" v-if="sidebarProducts && sidebarProducts.length > 0">
|
||||
<div
|
||||
v-for="(product, index) in sidebarProducts"
|
||||
:key="index"
|
||||
class="sidebar-item"
|
||||
:class="{ 'big-item': index === 0 }">
|
||||
<a href="javascript:void(0)">
|
||||
<img :src="product.image" :alt="product.name">
|
||||
<div class="info">
|
||||
<div class="name">{{ product.name }}</div>
|
||||
<div class="price">¥{{ product.price }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="product-list">
|
||||
<div
|
||||
v-for="(product, index) in displayedProducts"
|
||||
:key="index"
|
||||
class="product-item">
|
||||
<a href="javascript:void(0)">
|
||||
<div class="product-image">
|
||||
<img :src="product.image" :alt="product.name">
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<div class="product-name">{{ product.name }}</div>
|
||||
<div class="product-price">¥{{ product.price }}</div>
|
||||
<div class="product-desc">{{ product.desc }}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
props: {
|
||||
sectionTitle: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
products: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
sidebarProducts: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
sectionBg: {
|
||||
type: String,
|
||||
default: '#fff'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeTab: '推荐',
|
||||
tabs: ['推荐', '热卖', '新品']
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
displayedProducts() {
|
||||
// 这里可以根据activeTab筛选不同类别的商品
|
||||
// 为简化示例,这里只返回前8个商品
|
||||
return this.products.slice(0, 8);
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.product-section {
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.section-tabs {
|
||||
display: flex;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.section-tabs span {
|
||||
margin: 0 10px;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border-radius: 15px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.section-tabs span.active {
|
||||
background: #c81623;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.more a {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.more a:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.product-content {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.product-sidebar {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.sidebar-item {
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.sidebar-item:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.sidebar-item a {
|
||||
display: block;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar-item img {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: #c81623;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.big-item {
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.big-item img {
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.product-list {
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.product-item:hover {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-3px);
|
||||
}
|
||||
|
||||
.product-item a {
|
||||
display: block;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f9f9f9;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.product-image img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
color: #e4393c;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.product-desc {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
const SIDEBAR = {
|
||||
template: /*language=HTML*/ `
|
||||
<div class="sidebar">
|
||||
<ul class="category-list">
|
||||
<li class="category-item"
|
||||
v-for="category in categories"
|
||||
:key="category.id"
|
||||
@mouseenter="showSubCategories(category)"
|
||||
@mouseleave="hideSubCategories">
|
||||
<router-link :to="'/category/' + category.id" class="category-link">
|
||||
<span class="category-name">{{ category.name }}</span>
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</router-link>
|
||||
|
||||
<!-- 二级分类面板 -->
|
||||
<div class="sub-category-panel" v-if="activeCategory && activeCategory.id === category.id">
|
||||
<div class="sub-category-content">
|
||||
<div class="sub-category-group" v-for="group in category.children" :key="group.id">
|
||||
<h3 class="sub-category-title">
|
||||
<router-link :to="'/category/' + group.id">{{ group.name }}</router-link>
|
||||
</h3>
|
||||
<ul class="sub-category-list">
|
||||
<li v-for="child in group.children" :key="child.id">
|
||||
<router-link :to="'/category/' + child.id">{{ child.name }}</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
categories: [],
|
||||
activeCategory: null,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showSubCategories(category) {
|
||||
this.activeCategory = category;
|
||||
},
|
||||
hideSubCategories() {
|
||||
setTimeout(() => {
|
||||
if (!this.$el.matches(':hover') && !this.$el.querySelector('.sub-category-panel:hover')) {
|
||||
this.activeCategory = null;
|
||||
}
|
||||
}, 300);
|
||||
},
|
||||
async getCategories() {
|
||||
this.loading = true;
|
||||
try {
|
||||
this.categories = [
|
||||
{
|
||||
"id": "1348576427268399553",
|
||||
"name": "家用电器",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"sortOrder": 1,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399567",
|
||||
"name": "生活电器",
|
||||
"parentId": "1348576427268399553",
|
||||
"level": 1,
|
||||
"sortOrder": 0,
|
||||
"children": [
|
||||
{"id": "1348576427268399568", "name": "电风扇", "level": 2},
|
||||
{"id": "1348576427268399569", "name": "吸尘器", "level": 2},
|
||||
{"id": "1348576427268399570", "name": "加湿器", "level": 2},
|
||||
{"id": "1348576427268399571", "name": "净水设备", "level": 2},
|
||||
{"id": "1348576427268399572", "name": "饮水机", "level": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399580",
|
||||
"name": "大家电",
|
||||
"parentId": "1348576427268399553",
|
||||
"level": 1,
|
||||
"sortOrder": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399581", "name": "电视", "level": 2},
|
||||
{"id": "1348576427268399582", "name": "空调", "level": 2},
|
||||
{"id": "1348576427268399583", "name": "冰箱", "level": 2},
|
||||
{"id": "1348576427268399584", "name": "洗衣机", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399600",
|
||||
"name": "手机通讯",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"sortOrder": 2,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399601",
|
||||
"name": "手机",
|
||||
"parentId": "1348576427268399600",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399602", "name": "智能手机", "level": 2},
|
||||
{"id": "1348576427268399603", "name": "游戏手机", "level": 2},
|
||||
{"id": "1348576427268399604", "name": "老人手机", "level": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399605",
|
||||
"name": "运营商",
|
||||
"parentId": "1348576427268399600",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399606", "name": "合约机", "level": 2},
|
||||
{"id": "1348576427268399607", "name": "选号中心", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399700",
|
||||
"name": "电脑办公",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"sortOrder": 3,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399701",
|
||||
"name": "笔记本",
|
||||
"parentId": "1348576427268399700",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399702", "name": "轻薄本", "level": 2},
|
||||
{"id": "1348576427268399703", "name": "游戏本", "level": 2},
|
||||
{"id": "1348576427268399704", "name": "商务本", "level": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399710",
|
||||
"name": "台式机",
|
||||
"parentId": "1348576427268399700",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399711", "name": "游戏台式机", "level": 2},
|
||||
{"id": "1348576427268399712", "name": "设计师主机", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399800",
|
||||
"name": "食品生鲜",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"sortOrder": 4,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399801",
|
||||
"name": "水果",
|
||||
"parentId": "1348576427268399800",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399802", "name": "苹果", "level": 2},
|
||||
{"id": "1348576427268399803", "name": "香蕉", "level": 2},
|
||||
{"id": "1348576427268399804", "name": "橙子", "level": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399810",
|
||||
"name": "肉禽蛋",
|
||||
"parentId": "1348576427268399800",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399811", "name": "猪肉", "level": 2},
|
||||
{"id": "1348576427268399812", "name": "牛肉", "level": 2},
|
||||
{"id": "1348576427268399813", "name": "鸡蛋", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
} catch (error) {
|
||||
console.error('获取分类失败:', error);
|
||||
this.$message.error('获取分类数据失败');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.getCategories()
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.sidebar {
|
||||
width: 210px;
|
||||
background: #222;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.category-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.category-item {
|
||||
position: relative;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
|
||||
.category-link {
|
||||
display: block;
|
||||
padding: 12px 15px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.category-link:hover {
|
||||
background: #c81623;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.category-link:hover .el-icon-arrow-right {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.category-name {
|
||||
display: inline-block;
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.el-icon-arrow-right {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.sub-category-panel {
|
||||
position: absolute;
|
||||
left: 210px;
|
||||
top: 0;
|
||||
width: 700px;
|
||||
min-height: 400px;
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
padding: 20px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.sub-category-content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.sub-category-group {
|
||||
width: 230px;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.sub-category-title {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.sub-category-title a {
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sub-category-title a:hover {
|
||||
color: #c81623;
|
||||
}
|
||||
|
||||
.sub-category-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.sub-category-list li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.sub-category-list li a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.sub-category-list li a:hover {
|
||||
color: #c81623;
|
||||
padding-left: 5px;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style>
|
||||
.home-page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="home-page">
|
||||
<!-- 顶部导航 -->
|
||||
<header-component></header-component>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<div class="main-content">
|
||||
<div class="container">
|
||||
<div class="content-wrapper">
|
||||
<!-- 左侧分类导航 -->
|
||||
<category-nav :categories="categoryData"
|
||||
@category-selected="handleCategorySelect"></category-nav>
|
||||
|
||||
<!-- 右侧内容区域 -->
|
||||
<div class="content-area">
|
||||
<!-- 轮播图 -->
|
||||
<banner :banners="banners"></banner>
|
||||
|
||||
<!-- 热门品牌 -->
|
||||
<hot-brands :brands="hotBrands"></hot-brands>
|
||||
|
||||
<!-- 家用电器专区 -->
|
||||
<product-section
|
||||
section-title="家用电器"
|
||||
:products="applianceProducts"
|
||||
:sidebar-products="applianceSidebar"
|
||||
section-bg="#f9f9f9"></product-section>
|
||||
|
||||
<!-- 手机数码专区 -->
|
||||
<product-section
|
||||
section-title="手机数码"
|
||||
:products="digitalProducts"
|
||||
:sidebar-products="digitalSidebar"
|
||||
section-bg="#fff"></product-section>
|
||||
|
||||
<!-- 电脑办公专区 -->
|
||||
<product-section
|
||||
section-title="电脑办公"
|
||||
:products="computerProducts"
|
||||
:sidebar-products="computerSidebar"
|
||||
section-bg="#f9f9f9"></product-section>
|
||||
|
||||
<!-- 食品生鲜专区 -->
|
||||
<product-section
|
||||
section-title="食品生鲜"
|
||||
:products="foodProducts"
|
||||
:sidebar-products="foodSidebar"
|
||||
section-bg="#fff"></product-section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer-component></footer-component>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return{
|
||||
// 分类数据(简化版,实际应用中从API获取)
|
||||
categoryData: [
|
||||
{
|
||||
"id": "1348576427268399553",
|
||||
"name": "家用电器",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399567",
|
||||
"name": "生活电器",
|
||||
"parentId": "1348576427268399553",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399568", "name": "电风扇", "level": 2},
|
||||
{"id": "1348576427268399569", "name": "吸尘器", "level": 2},
|
||||
{"id": "1348576427268399570", "name": "加湿器", "level": 2},
|
||||
{"id": "1348576427268399571", "name": "净水设备", "level": 2}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399580",
|
||||
"name": "大家电",
|
||||
"parentId": "1348576427268399553",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399581", "name": "电视", "level": 2},
|
||||
{"id": "1348576427268399582", "name": "空调", "level": 2},
|
||||
{"id": "1348576427268399583", "name": "冰箱", "level": 2},
|
||||
{"id": "1348576427268399584", "name": "洗衣机", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399600",
|
||||
"name": "手机通讯",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399601",
|
||||
"name": "手机",
|
||||
"parentId": "1348576427268399600",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399602", "name": "智能手机", "level": 2},
|
||||
{"id": "1348576427268399603", "name": "游戏手机", "level": 2},
|
||||
{"id": "1348576427268399604", "name": "老人手机", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1348576427268399700",
|
||||
"name": "电脑办公",
|
||||
"parentId": "0",
|
||||
"level": 0,
|
||||
"children": [
|
||||
{
|
||||
"id": "1348576427268399701",
|
||||
"name": "笔记本",
|
||||
"parentId": "1348576427268399700",
|
||||
"level": 1,
|
||||
"children": [
|
||||
{"id": "1348576427268399702", "name": "轻薄本", "level": 2},
|
||||
{"id": "1348576427268399703", "name": "游戏本", "level": 2}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// 轮播图数据
|
||||
banners: [
|
||||
{ id: 1, image: 'https://img10.360buyimg.com/cms/jfs/t1/206882/36/9500/185895/613f845aE6f4c0d13/7b8c6a5a5e9b6e3a.jpg', url: '#' },
|
||||
{ id: 2, image: 'https://img14.360buyimg.com/cms/jfs/t1/196395/24/18927/188310/613f845aE3d0e6e57/3d0e8b9b8b8e3a9f.jpg', url: '#' },
|
||||
{ id: 3, image: 'https://img12.360buyimg.com/cms/jfs/t1/178900/38/20300/177950/613f845aE7e9c9c5f/9d1b4c7b3d7b6e3a.jpg', url: '#' }
|
||||
],
|
||||
|
||||
// 热门品牌
|
||||
hotBrands: [
|
||||
{ id: 1, name: 'Apple', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
|
||||
{ id: 2, name: '华为', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
|
||||
{ id: 3, name: '小米', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
|
||||
{ id: 4, name: '格力', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' },
|
||||
{ id: 5, name: '联想', logo: 'https://img11.360buyimg.com/vclist/jfs/t1/196565/35/10440/7517/613f845aE7b4d9c5f/7b8c6a5a5e9b6e3a.png' }
|
||||
],
|
||||
|
||||
// 家用电器商品
|
||||
applianceProducts: [
|
||||
{ id: 1, name: '美的电风扇FS40-15HR', price: 199.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 2, name: '戴森V11吸尘器', price: 4999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 3, name: '小米加湿器2', price: 199.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 4, name: '海尔净水器HRO75H1', price: 1299.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 5, name: '格力冷风扇', price: 599.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 6, name: '飞利浦空气净化器', price: 1599.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
applianceSidebar: [
|
||||
{ id: 1, name: '电视', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 2, name: '空调', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 3, name: '冰箱', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
|
||||
// 手机数码商品
|
||||
digitalProducts: [
|
||||
{ id: 7, name: '华为Mate 50 Pro', price: 6999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 8, name: '小米13 Ultra', price: 5999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 9, name: 'iPhone 14 Pro', price: 8999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 10, name: 'vivo X90 Pro+', price: 4999.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 11, name: 'OPPO Find X6', price: 4499.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 12, name: '荣耀Magic5 Pro', price: 4699.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
digitalSidebar: [
|
||||
{ id: 1, name: '手机配件', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 2, name: '智能手表', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 3, name: '耳机', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
|
||||
// 电脑办公商品
|
||||
computerProducts: [
|
||||
{ id: 13, name: '联想拯救者Y9000P', price: 8999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 14, name: 'MacBook Pro 14', price: 15999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 15, name: '华为MateBook X Pro', price: 8999.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 16, name: '戴尔XPS 13', price: 9999.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 17, name: '惠普暗影精灵9', price: 6999.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 18, name: '外星人m16', price: 12999.00, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
computerSidebar: [
|
||||
{ id: 1, name: '台式机', image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 2, name: '平板电脑', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 3, name: '办公设备', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
|
||||
// 食品生鲜商品
|
||||
foodProducts: [
|
||||
{ id: 19, name: '五常大米5kg', price: 69.90, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 20, name: '进口牛排10片装', price: 199.00, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 21, name: '智利车厘子5kg', price: 299.00, image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 22, name: '阳澄湖大闸蟹4只装', price: 258.00, image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg', hot: true },
|
||||
{ id: 23, name: '每日坚果750g', price: 89.90, image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 24, name: '进口橄榄油500ml', price: 79.90, image: 'https://img12.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' }
|
||||
],
|
||||
foodSidebar: [
|
||||
{ id: 1, name: '新鲜水果', image: 'https://img13.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' },
|
||||
{ id: 2, name: '肉禽蛋品', image: 'https://img14.360buyimg.com/n7/jfs/t1/142701/17/20119/143370/60d4d5a4E9d0a7c96/6a0c6c4e0b7b0b3e.jpg' },
|
||||
{ id: 3, name: '海鲜水产', image: 'https://img10.360buyimg.com/n7/jfs/t1/159523/33/20120/137983/60d4d5a4E1d0b4c96/5c5a5c4e0b7b0b3e.jpg' }
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCategorySelect(category) {
|
||||
console.log('Selected category:', category)
|
||||
// 这里可以添加跳转到分类页面的逻辑
|
||||
// this.$router.push({ name: 'category', params: { id: category.id } })
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,127 @@
|
||||
const ADD_GOODS_FIRST = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<!-- 商品分类 -->
|
||||
<div class="content-goods-publish">
|
||||
<div class="goods-category">
|
||||
<ul v-if="categoryListLevel1.length > 0">
|
||||
<li
|
||||
v-for="(item, index) in categoryListLevel1"
|
||||
:class="{ activeClass: category[0].name === item.name }"
|
||||
@click="handleSelectCategory(item, index, 1)"
|
||||
:key="index"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
<span>></span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="categoryListLevel2.length > 0">
|
||||
<li
|
||||
v-for="(item, index) in categoryListLevel2"
|
||||
:class="{ activeClass: category[1].name === item.name }"
|
||||
@click="handleSelectCategory(item, index, 2)"
|
||||
:key="index"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
<span>></span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="categoryListLevel3.length > 0">
|
||||
<li
|
||||
v-for="(item, index) in categoryListLevel3"
|
||||
:class="{ activeClass: category[2].name === item.name }"
|
||||
@click="handleSelectCategory(item, index, 3)"
|
||||
:key="index"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p class="current-goods-category">
|
||||
您当前选择的商品类别是:
|
||||
<span>{{ category[0].name }}</span>
|
||||
<span v-show="category[1].name">> {{ category[1].name }}</span>
|
||||
<span v-show="category[2].name">> {{ category[2].name }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<!-- 底部按钮 -->
|
||||
<div class="footer">
|
||||
<el-button-group>
|
||||
<el-button type="primary" @click="next">下一步</el-button>
|
||||
</el-button-group>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
data(){
|
||||
return {
|
||||
// 商品分类选择数组
|
||||
category: [
|
||||
{ name: "", id: "" },
|
||||
{ name: "", id: "" },
|
||||
{ name: "", id: "" },
|
||||
],
|
||||
// 商品类型
|
||||
goodsType: "PHYSICAL_GOODS",
|
||||
/** 1级分类列表*/
|
||||
categoryListLevel1: [],
|
||||
/** 2级分类列表*/
|
||||
categoryListLevel2: [],
|
||||
/** 3级分类列表*/
|
||||
categoryListLevel3: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 选择商城商品分类 */
|
||||
handleSelectCategory(row, index, level) {
|
||||
if (level === 1) {
|
||||
this.category.forEach((cate) => {
|
||||
(cate.name = ""), (cate.id = "");
|
||||
});
|
||||
this.category[0].name = row.name;
|
||||
this.category[0].id = row.id;
|
||||
this.categoryListLevel2 = this.categoryListLevel1[index].children;
|
||||
this.categoryListLevel3 = [];
|
||||
} else if (level === 2) {
|
||||
this.category[1].name = row.name;
|
||||
this.category[1].id = row.id;
|
||||
this.category[2].name = "";
|
||||
this.category[2].id = "";
|
||||
this.categoryListLevel3 = this.categoryListLevel2[index].children;
|
||||
} else {
|
||||
this.category[2].name = row.name;
|
||||
this.category[2].id = row.id;
|
||||
}
|
||||
},
|
||||
/** 查询下一级 商城商品分类*/
|
||||
getAllCategory() {
|
||||
this.$axios.post('/platform/mall/category/manage/allChildren').then((res) => {
|
||||
if (res.code === 0 && res.data) {
|
||||
this.categoryListLevel1 = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 下一步
|
||||
next() {
|
||||
window.scrollTo(0, 0);
|
||||
if (!this.category[0].name) {
|
||||
this.$message.error("请选择商品分类");
|
||||
} else if (!this.category[2].name) {
|
||||
this.$message.error("必须选择到三级分类");
|
||||
} else if (this.category[2].name) {
|
||||
let params = {
|
||||
category: this.category,
|
||||
goodsType: this.goodsType,
|
||||
};
|
||||
this.$emit("change", params);
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.getAllCategory();
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
/deep/ .ivu-scroll-container {
|
||||
height: 450px !important;
|
||||
}
|
||||
`,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
const ADD_GOODS_THIRD = {
|
||||
template: /*language=HTML*/ `
|
||||
|
||||
`,
|
||||
data(){
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/module/mall/addGoods.css" />
|
||||
<div id="app">
|
||||
<div>
|
||||
<div class="step-list">
|
||||
<el-steps :active="activestep" align-center finish-status="success">
|
||||
<el-step title="选择商品品类"></el-step>
|
||||
<el-step title="填写商品详情"></el-step>
|
||||
<el-step title="商品发布成功"></el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
|
||||
<!-- 第一步 选择分类 -->
|
||||
<first-step ref='first' v-show="activestep === 0" @change="getFirstData"></first-step>
|
||||
<!-- 第二步 商品详细信息 -->
|
||||
<second-step ref='second' :first-data="firstData" v-if="activestep === 1"></second-step>
|
||||
<!-- 第三步 发布完成 -->
|
||||
<third-step ref='third' v-if="activestep === 2"></third-step>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
<!--#include("addGoodsFirst.js"){}#-->
|
||||
<!--#include("addGoodsSecond.js"){}#-->
|
||||
<!--#include("addGoodsThird.js"){}#-->
|
||||
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
data(){
|
||||
return {
|
||||
/** 当前激活步骤*/
|
||||
activestep: 0,
|
||||
firstData: {}, // 第一步传递的数据
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'first-step': ADD_GOODS_FIRST,
|
||||
'second-step': ADD_GOODS_SECOND,
|
||||
'third-step': ADD_GOODS_THIRD,
|
||||
},
|
||||
methods: {
|
||||
// 选择商品分类回调
|
||||
getFirstData (item) {
|
||||
this.firstData = item;
|
||||
this.activestep = 1;
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.id = GetQueryString("id")
|
||||
},
|
||||
mounted () {
|
||||
// 编辑商品、模板
|
||||
if (this.id) {
|
||||
this.activestep = 1;
|
||||
} else {
|
||||
this.activestep = 0
|
||||
// this.$refs.first.selectGoodsType = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,411 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app">
|
||||
<el-card>
|
||||
<!-- 顶部按钮 -->
|
||||
<div style="margin-bottom:10px">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="addParent">
|
||||
添加一级分类
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
row-key="id"
|
||||
:data="tableData"
|
||||
style="width:100%"
|
||||
lazy
|
||||
:load="loadChildren"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column label="分类名称" prop="name"></el-table-column>
|
||||
<el-table-column label="当前层级" prop="level">
|
||||
<template slot-scope="{ row }">
|
||||
{{ (row.level + 1) + '级' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 状态列 -->
|
||||
<el-table-column label="状态" prop="delFlag">
|
||||
<template slot-scope="{ row }">
|
||||
<el-tag :type="row.delFlag ? 'danger' : 'success'">
|
||||
{{ !row.delFlag ? '正常启用' : '禁用' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 你的业务列请自行补充 -->
|
||||
<el-table-column label="操作" width="260">
|
||||
<template slot-scope="scope">
|
||||
<!-- 通用操作下拉 -->
|
||||
<el-dropdown trigger="click" style="margin-right:6px">
|
||||
<el-button size="mini">
|
||||
操作<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="edit(scope.row)">
|
||||
编辑
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="scope.row.delFlag == true"
|
||||
@click.native="enable(scope.row)"
|
||||
>
|
||||
启用
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="scope.row.delFlag == false"
|
||||
@click.native="disable(scope.row)"
|
||||
>
|
||||
禁用
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="remove(scope.row)">
|
||||
删除
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<!-- 添加子分类(level ≠ 2 时显示) -->
|
||||
<el-button
|
||||
v-if="scope.row.level !== 2"
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-plus"
|
||||
@click="addChildren(scope.row)"
|
||||
>
|
||||
添加子分类
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 新增/编辑分类弹窗 -->
|
||||
<el-dialog
|
||||
:title="modalTitle"
|
||||
:visible.sync="modalVisible"
|
||||
width="40%"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form ref="form" :model="formAdd" label-width="100px" :rules="formValidate">
|
||||
<el-form-item
|
||||
v-if="showParent"
|
||||
label="上级分类"
|
||||
prop="parentId"
|
||||
style="display:none"
|
||||
>
|
||||
<el-input v-model="formAdd.parentId" placeholder="请输入上级分类" clearable></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="层级" prop="level" style="display:none">
|
||||
<el-input v-model="formAdd.level" placeholder="请输入层级" clearable></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="分类名称" prop="name">
|
||||
<el-input v-model="formAdd.name" placeholder="请输入分类名称" clearable></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="formAdd.level !== 1" label="分类图标" prop="image">
|
||||
<file-upload
|
||||
:value.sync="formAdd.image"
|
||||
:upload_number="1"
|
||||
upload_mode="image"
|
||||
upload_result_category="interval"
|
||||
upload_result_type="url"
|
||||
></file-upload>
|
||||
<!--<upload-pic-input
|
||||
v-model="formAdd.image"
|
||||
style="width:100%"></upload-pic-input>-->
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="排序值" prop="sortOrder">
|
||||
<el-input-number v-model="formAdd.sortOrder"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否启用" prop="delFlag">
|
||||
<el-switch
|
||||
v-model="formAdd.delFlag"
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
active-text="启用"
|
||||
inactive-text="禁用"
|
||||
></el-switch>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer">
|
||||
<el-button @click="modalVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="Submit">提交</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</div>
|
||||
<script>
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data() {
|
||||
return {
|
||||
recordLevel:[], // 记录当前层级
|
||||
submitLoading: false, //加载状态
|
||||
categoryList: [], // 分类列表
|
||||
loading: false, // 加载状态
|
||||
brands: [], //品牌集合
|
||||
specifications: [], //规格集合
|
||||
categoryId: "", // 分类id
|
||||
categorySpecs: [], //已经选择的规格
|
||||
modalType: 0, // 添加或编辑标识
|
||||
modalVisible: false, // 添加或编辑显示
|
||||
modalBrandVisible: false, //品牌关联编辑显示
|
||||
modalSpecVisible: false, //品牌关联编辑显示
|
||||
modalTitle: "", // 添加或编辑标题
|
||||
showParent: false, // 是否展示上级菜单
|
||||
parentTitle: "", // 父级菜单名称
|
||||
modalBrandTitle: "", // 品牌弹窗标题
|
||||
modalSpecTitle: "", // 规格弹窗标题
|
||||
formAdd: {
|
||||
// 添加或编辑表单对象初始化数据
|
||||
parentId: "",
|
||||
name: "",
|
||||
image: "",
|
||||
sortOrder: 0,
|
||||
delFlag: 0,
|
||||
level: 0,
|
||||
},
|
||||
brandForm: {
|
||||
categoryBrands: [],
|
||||
},
|
||||
brandWay: "", //请求绑定品牌的信息
|
||||
specForm: {}, // 规格数据
|
||||
// 表单验证规则
|
||||
formValidate: {
|
||||
name: [{required: true, message: "请输入分类名称", trigger: ["blur", "change"]}],
|
||||
sortOrder: [{required: true, message: "请输入排序值", trigger: ["blur", "change"]}],
|
||||
},
|
||||
tableColumns: [
|
||||
{label: "分类名称", prop: "name"},
|
||||
{label: "状态", prop: "delFlag"},
|
||||
{label: "操作", prop: "action"},
|
||||
],
|
||||
tableData: [], // 表格数据
|
||||
checkedCategoryChildren: "", //选中的分类子级
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 初始化数据
|
||||
init() {
|
||||
this.getAllList(0);
|
||||
},
|
||||
// 添加子分类
|
||||
addChildren(v) {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加子分类";
|
||||
this.parentTitle = v.name;
|
||||
this.formAdd.level = eval(v.level + "+1");
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.showParent = true;
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = v.id;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 编辑分类
|
||||
edit(v) {
|
||||
this.modalType = 1;
|
||||
this.modalTitle = "编辑";
|
||||
this.formAdd.id = v.id;
|
||||
this.formAdd.name = v.name;
|
||||
this.formAdd.level = v.level;
|
||||
this.formAdd.parentId = v.parentId;
|
||||
this.formAdd.sortOrder = v.sortOrder;
|
||||
this.formAdd.commissionRate = v.commissionRate;
|
||||
this.formAdd.delFlag = v.delFlag;
|
||||
this.formAdd.image = v.image;
|
||||
this.showParent = false;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 添加一级分类
|
||||
addParent() {
|
||||
this.modalType = 0;
|
||||
this.modalTitle = "添加一级分类";
|
||||
this.parentTitle = "顶级分类";
|
||||
this.showParent = true;
|
||||
// this.$refs.form.resetFields();
|
||||
delete this.formAdd.id;
|
||||
this.formAdd.parentId = 0;
|
||||
this.modalVisible = true;
|
||||
},
|
||||
// 提交
|
||||
Submit() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.submitLoading = true;
|
||||
if (this.modalType === 0) {
|
||||
// 添加 避免编辑后传入id等数据 记得删除
|
||||
delete this.formAdd.id;
|
||||
this.$axios.post("/platform/mall/category/manage/saveCategory", this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.code === 0) {
|
||||
this.$message.success("添加成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
// this.$refs.form.resetFields();
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 编辑
|
||||
this.$axios.post("/platform/mall/category/manage/updateCategory", this.formAdd).then((res) => {
|
||||
this.submitLoading = false;
|
||||
if (res.code === 0) {
|
||||
this.$message.success("修改成功");
|
||||
this.getAllList();
|
||||
this.modalVisible = false;
|
||||
// this.$refs.form.resetFields();
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除分类
|
||||
remove(v) {
|
||||
this.$confirm("确定要删除 " + v.name + " ?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/mall/category/manage/delAllByIds", {
|
||||
id: v.id
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success("操作成功");
|
||||
this.getAllList();
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
|
||||
// 异步手动加载分类名称
|
||||
loadChildren(row, treeNode, resolve) {
|
||||
// 记录层级(可选)
|
||||
this.recordLevel[row.level] = row.id;
|
||||
|
||||
if (row.level === 0) {
|
||||
// 根节点 -> 拿一级子节点
|
||||
const children = this.categoryList
|
||||
.find(item => item.id === row.id)
|
||||
?.children || [];
|
||||
// 给下一级节点加 hasChildren
|
||||
children.forEach(child => {
|
||||
child.hasChildren = !!(child.children && child.children.length);
|
||||
});
|
||||
setTimeout(() => resolve(children), 100);
|
||||
} else {
|
||||
// 非根节点 -> 用你原来的递归方法
|
||||
this.deepCategoryChildren(row.id, this.categoryList);
|
||||
setTimeout(() => {
|
||||
const list = this.checkedCategoryChildren || [];
|
||||
list.forEach(item => {
|
||||
item.hasChildren = !!(item.children && item.children.length);
|
||||
});
|
||||
resolve(list);
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
|
||||
// 通过递归children来实现手动加载数据
|
||||
deepCategoryChildren(id, list) {
|
||||
if (id != "0" && list.length != 0) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let item = list[i];
|
||||
if (item.id == id) {
|
||||
this.checkedCategoryChildren = item.children;
|
||||
return;
|
||||
} else {
|
||||
this.deepCategoryChildren(id, item.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 获取分类数据
|
||||
getAllList() {
|
||||
this.loading = true;
|
||||
this.$axios.post("/platform/mall/category/manage/allChildren").then((res) => {
|
||||
this.loading = false;
|
||||
if (res.code === 0) {
|
||||
localStorage.setItem("category", JSON.stringify(res.data));
|
||||
this.categoryList = JSON.parse(JSON.stringify(res.data));
|
||||
this.tableData = res.data
|
||||
// this.tableData = res.data.map((item) => {
|
||||
// if(this.recordLevel[0] && item.id === this.recordLevel[0]) {
|
||||
// item._showChildren = true
|
||||
// // 继续判断第二层
|
||||
// if(this.recordLevel[1] && item.children){
|
||||
// item.children.map((child)=>{
|
||||
// if(this.recordLevel[1] && child.id === this.recordLevel[1]){
|
||||
// child._showChildren = true
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }else{
|
||||
// if (item.children.length !== 0) {
|
||||
// item.children = [];
|
||||
// item._loading = false;
|
||||
// }
|
||||
// }
|
||||
// return item;
|
||||
// });
|
||||
}
|
||||
});
|
||||
},
|
||||
// 启用分类
|
||||
enable(v) {
|
||||
this.$confirm("您是否要启用当前分类 " + v.name + " 及其子分类?", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/mall/category/manage/disable", {
|
||||
id: v.id,
|
||||
enableOperations: false
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
// 禁用分类
|
||||
disable(v) {
|
||||
this.$confirm("您是否要启用当前分类 " + v.name + " 及其子分类?", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/mall/category/manage/disable", {
|
||||
id: v.id,
|
||||
enableOperations: true
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success("操作成功");
|
||||
this.getAllList(0);
|
||||
} else {
|
||||
this.$message.error(res.message);
|
||||
}
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.init();
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user