合并master

master
lemon橪 2021-05-25 14:27:45 +08:00
commit 020ddf0588
21 changed files with 499 additions and 401 deletions

365
README.md
View File

@ -1,11 +1,19 @@
## Lilishop B2B2C商城系统
##### 官方公众号 & 开源不易如有帮助请点Star
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
[![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
### 介绍
**官网**https://pickmall.cn
Lilishop 是一款Java开发基于SpringBoot的B2B2C多用户商城前端使用 Vue、uniapp-app开发 **系统全端全部代码开源**
Lilishop 是一款Java开发基于SpringBoot研发的B2B2C多用户商城前端使用 Vue、uniapp开发 **系统全端全部代码开源**
商城展示端包含 PC、H5、小程序、APP。
产品前后端分离、支持分布式部署。
商城展示端包含 PC、H5、微信小程序、APP。
商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
@ -13,14 +21,12 @@ Lilishop 是一款Java开发基于SpringBoot的B2B2C多用户商城前端
开箱即用,简单配置即可部署一套属于您的系统。
完美支持二开、学生毕业设计答辩等各个场景
### 文档
**产品文档**需求、架构、使用、部署、开发https://docs.pickmall.cn
### 项目链接
### 项目链接(gitee)
**Java后台**https://gitee.com/beijing_hongye_huicheng/lilishop.git
@ -30,6 +36,16 @@ Lilishop 是一款Java开发基于SpringBoot的B2B2C多用户商城前端
**docker一键部署**https://gitee.com/beijing_hongye_huicheng/docker.git
### 项目链接(github)
**Java后台**https://github.com/hongyehuicheng/lilishop.git
**Vue后台前端** https://github.com/hongyehuicheng/lilishop-ui.git
**Uni-app**https://github.com/hongyehuicheng/lilishop-uniapp.git
**docker一键部署**https://github.com/hongyehuicheng/docker.git
### 演示地址
**运营后台**https://admin-b2b2c.pickmall.cn 账号admin/123456
@ -44,175 +60,218 @@ Lilishop 是一款Java开发基于SpringBoot的B2B2C多用户商城前端
### 3行命令搭建本地环境
温馨提示由于服务较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
##### 下载docker脚本
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
##### 部署基础环境
`docker-compose up -d`
##### 部署应用
`docker-compose -f docker-compose-application.yml up -d`
PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql
##### 各个地址
| API | 地址 |
| -------------- | --------------- |
| 买家api | http://127.0.0.1:8888 |
| 商家api | http://127.0.0.1:8889 |
| 管理端api | http://127.0.0.1:8887 |
| 通用api | http://127.0.0.1:8890 |
| 买家API | http://127.0.0.1:8888 |
| 商家API | http://127.0.0.1:8889 |
| 管理端API | http://127.0.0.1:8887 |
| 通用API | http://127.0.0.1:8890 |
| 演示 | 地址 |
| 前端演示 | 地址 |
| -------------- | --------------- |
| PC | http://127.0.0.1:10000 |
| WAP | http://127.0.0.1:10001 |
| 商家 | http://127.0.0.1:10002 |
| 管理端 | http://127.0.0.1:10003 |
### 交流群
**QQ群**961316482
### 技术选型
##### Java后台
| 说明 | 框架 |
| -------------- | --------------- |
| 基础框架 | Spring Boot |
| MVC框架 | Spring MVC |
| 持久框架 | Mybatis-Plus |
| 程序构建 | Maven |
| 关系型数据库 | MySQL |
| 消息中间件AMQP | RocketMQ |
| 缓存 | Redis +MongoDB |
| 搜索引擎 | Elasticsearch |
| 安全框架 | Spring Security |
| 数据库连接池 | Druid |
| 数据库分库分表 | sharding |
| 定时任务 | xxl-job |
| 负载均衡 | Nginx |
| 静态资源 | 阿里云OSS |
| 短信 | 阿里云短信 |
| 日志处理 | Log4j |
| 接口规范 | RESTful |
| 接口文档 | Swagger |
| 认证 | JWT |
##### 前端-运营后台、店铺后台
| 说明 | 框架 |
| ---------- | ---------- |
| 构建工具 | webpack |
| JS版本 | ES6 |
| 基础JS框架 | Vue.js |
| 视频播放器 | Dplayer |
| 路由管理 | Vue Router |
| 状态管理 | Vuex |
| 基础UI库 | iView |
| UI界面基于 | iView |
| 网络请求 | axios |
| CSS预处理 | scss |
| 代码检查 | ESLint |
| 数据可视化 | AntV g2 |
| 地图引擎 | amap |
##### 前端-移动端
| 说明 | 架构 |
| --------- | ------- |
| 基础UI库 | uViewui |
| 基础框架 | uni-app |
| CSS预处理 | scss |
| 地图引擎 | amap |
### 功能列表
<table>
<tr><td colspan="2">运营后台功能</td></tr>
<tr><td>首页</td><td>平台统计、待办事项、流量统计</td></tr>
<tr><td rowspan="5">会员</td><td>会员列表</td></tr>
<tr><td>评价列表</td></tr>
<tr><td>积分历史</td></tr>
<tr><td>会员资金</td></tr>
<tr><td>充值记录</td></tr>
<tr><td rowspan="6">订单</td><td>商品订单</td></tr>
<tr><td>订单售后</td></tr>
<tr><td>交易投诉</td></tr>
<tr><td>售后原因</td></tr>
<tr><td>收款流水</td></tr>
<tr><td>退款流水</td></tr>
<tr><td rowspan="6">商品</td><td>商品列表</td></tr>
<tr><td>商品审核</td></tr>
<tr><td>商品分类</td></tr>
<tr><td>商品品牌</td></tr>
<tr><td>商品规格</td></tr>
<tr><td>计量单位</td></tr>
<tr><td rowspan="5">促销</td><td>优惠券</td></tr>
<tr><td>秒杀活动</td></tr>
<tr><td>拼团活动</td></tr>
<tr><td>积分商品</td></tr>
<tr><td>积分分类</td></tr>
<tr><td rowspan="5">店铺</td><td>店铺管理</td></tr>
<tr><td>店铺结算</td></tr>
<tr><td>店铺结算</td></tr>
<tr><td>店铺结算</td></tr>
<tr><td>店铺对账</td></tr>
<tr><td rowspan="9">运营</td><td>店铺对账</td></tr>
<tr><td>PC端楼层装修</td></tr>
<tr><td>移动端楼层装修</td></tr>
<tr><td>分销管理</td></tr>
<tr><td>文章管理</td></tr>
<tr><td>意见反馈</td></tr>
<tr><td>站内信</td></tr>
<tr><td>短信管理</td></tr>
<tr><td>APP版本管理</td></tr>
<tr><td rowspan="4">统计</td><td>会员统计</td></tr>
<tr><td>订单统计</td></tr>
<tr><td>商品统计</td></tr>
<tr><td>流量统计</td></tr>
<tr><td rowspan="11">设置</td><td>用户管理</td></tr>
<tr><td>菜单管理</td></tr>
<tr><td>部门管理</td></tr>
<tr><td>系统设置</td></tr>
<tr><td>OSS资源</td></tr>
<tr><td>行政地区</td></tr>
<tr><td>物流公司</td></tr>
<tr><td>信任登录</td></tr>
<tr><td>支付设置</td></tr>
<tr><td>验证码管理</td></tr>
<tr><td>敏感词管理</td></tr>
</table>
<table>
<tr><td colspan="2">店铺后台功能列表</td></tr>
<tr><td rowspan="3">首页</td><td>店铺信息</td></tr>
<tr><td>待办事项</td></tr>
<tr><td>平台公告</td></tr>
<tr><td rowspan="3">商品</td><td>商品发布</td></tr>
<tr><td>商品列表</td></tr>
<tr><td>店铺商品分类</td></tr>
<tr><td rowspan="5">订单</td><td>商品订单</td></tr>
<tr><td>退货管理</td></tr>
<tr><td>退款管理</td></tr>
<tr><td>投诉管理</td></tr>
<tr><td>评价管理</td></tr>
<tr><td rowspan="3">财务</td><td>财务对账</td></tr>
<tr><td>店铺结算</td></tr>
<tr><td>发票管理</td></tr>
<tr><td rowspan="5">促销</td><td>拼团管理</td></tr>
<tr><td>秒杀活动</td></tr>
<tr><td>满额活动</td></tr>
<tr><td>优惠券</td></tr>
<tr><td>分销商品</td></tr>
<tr><td rowspan="2">统计</td><td>商品统计</td></tr>
<tr><td>订单统计</td></tr>
<tr><td rowspan="5">设置</td><td>配送模板</td></tr>
<tr><td>物流公司</td></tr>
<tr><td>店铺设置</td></tr>
<tr><td>自提点管理</td></tr>
<tr><td>系统消息</td></tr>
</table>
### 授权
Lilishop学习免费限制商用如果需要商业使用请联系我们。QQ3409056806
#### 平台功能
![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg)
#### 商家端功能
![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg)
### 功能展示
#### 移动端
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="管理端功能展示" style="zoom:50%;" />
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" />
#### 管理端
![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif)
### 技术选型
#### 架构图
![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png)
##### Java后台
| 说明 | 框架 | 说明 | |
| -------------- | --------------- | -------------- | ------------- |
| 基础框架 | Spring Boot | MVC框架 | Spring MVC |
| 持久框架 | Mybatis-Plus | 程序构建 | Maven |
| 关系型数据库 | MySQL | 消息中间件AMQP | RocketMQ |
| 缓存 | Redis +MongoDB | 搜索引擎 | Elasticsearch |
| 安全框架 | Spring Security | 数据库连接池 | Druid |
| 数据库分库分表 | sharding | 定时任务 | xxl-job |
| 负载均衡 | Nginx | 静态资源 | 阿里云OSS |
| 短信 | 阿里云短信 | 认证 | JWT |
| 日志处理 | Log4j | 接口规范 | RESTful |
##### 前端-运营后台、店铺后台
| 说明 | 框架 | 说明 | 框架 |
| ---------- | ---------- | ---------- | ------- |
| 构建工具 | webpack | JS版本 | ES6 |
| 基础JS框架 | Vue.js | 视频播放器 | Dplayer |
| 路由管理 | Vue Router | 状态管理 | Vuex |
| 基础UI库 | iView | UI界面基于 | iView |
| 网络请求 | axios | | |
##### 前端-移动端
| 说明 | 架构 | 说明 | 架构 |
| --------- | ------- | -------- | ------- |
| 基础UI库 | uViewui | 基础框架 | uni-app |
| CSS预处理 | scss | 地图引擎 | amap |
### 升级计划
#### 计划每个月发布一个版本,具体时间可能有出入
时间2021年6月15日
```
新增功能:
1.微信小程序直播
2.优惠券活动
3.新人赠券
4.准确发券
5.用户等级
6.数据导出
7.订单批量
8.APP版本升级检测
9.积分商城
功能优化:
1.优惠券有效期增加类型:设置领取后*内有效。
2.秒杀活动设置为每天开启,需设置秒杀活动开启时间。
3.店铺配送模板,配送地区如果选择省份则下方的市级地址不展示。
4.店铺配送模板支持,店铺包邮。
5.普通商品设置去除卖家承担运费。
```
时间2021年7月15日
```
新增功能:
1.会员权益
2.支持用户升级会员
3.供求单
4.IM腾讯云智服
5.服务商品
6.店铺支持订单核销
7.店铺自提点
功能优化:
1.用户分享商城、关注店铺、邀请新用户可获取积分、经验值。
```
时间2021年8月16日
```
新增功能:
1.微淘功能
2.店铺移动端
3.店铺发货单
```
时间2021年9月15日
```
新增功能:
增加供应商功能
```
### 版本升级
```
后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
后续会考虑推出微服务/中台等 企业级版本
```
### 技术亮点
1.后端框架基于Springboot构建基于maven持久层使用MyBatisPlus。使用elasticsearch、redis、mongodb、rocketmq 等各种中间健。都是主流架构,轻松应对各种环境。
2.支持集群、分布式支持docker 轻松部署,解决各种复杂场景!
3.代码模块清晰主要分为三端api买家、卖家、管理各端API互相隔离自己鉴权自己操作业务。
4.使用阿里开源的RocketMQ基于mq解决各种并发场景解决事务一致性解决搞并发延迟场景问题。
5.项目使用多级缓存应用不同场景redis缓存业务数据、mongodb缓存关系型多对多关系问题、nginx缓存高频访问低频修改的页面。
6.支持各种联合登陆,支持各种客户端的支付问题,灵活配置灵活开启。
7.内置完善的楼层装修机制,各种拖拉拽,维护跳转页面或外网,即便是一个什么都不懂的运营也可以轻松掌握。
8.内置阿里短信接口可以在线申请短信模版。内置阿里oss系统可以对文件执行各种操作。oss商家端资源相互隔离。
10.强大的统计报表,统计效果,可以实现各个场景,包含在线人数,历史在线人数,活跃人数等信息。
11.标准Api接口、提供swagger文档快速二开。
12.分布式调度任务中心,解决分布式定时任务多次执行问题。
13.代码注释完善,快速上手。
14.非移动端采用IView框架各种自定义插件、选择器实现。移动端采用uniapp一次编写全端使用
15.已经对接好各种第三方插件,支持各种复杂等联合登陆,联合支付等场景。
### 开源须知
1.仅允许用于个人学习研究使用.
2.禁止将本开源的代码和资源进行任何形式任何名义的出售.
3.限制商用如果需要商业使用请联系我们。QQ3409056806.
### 交流群
**QQ群**961316482

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -116,11 +116,13 @@
<span v-if="item.couponType === 'DISCOUNT'" class="fontsize_12 global_color"><span class="price">{{item.couponDiscount}}</span></span>
<span class="describe">{{item.consumeThreshold}}元可用</span>
</div>
<p>使用范围{{useScope(item.scopeType)}}</p>
<p>有效期{{item.endTime}}</p>
<p>使用范围{{useScope(item.scopeType)}}</p>
<p>有效期{{item.endTime}}</p>
</div>
<img class="used" v-if="usedCouponId.includes(item.id)" src="../../assets/images/geted.png" alt="">
<b></b>
<a class="c-right" @click="useCoupon(item.id)">使</a>
<a class="c-right" @click="useCoupon(item.id, true)">立即使用</a>
<a class="c-right" v-if="usedCouponId.includes(item.id)" @click="useCoupon(item.id, false)"></a>
<i class="circle-top"></i>
<i class="circle-bottom"></i>
</li>
@ -207,7 +209,9 @@ export default {
moreAddr: false, //
canUseCouponNum: 0, //
couponList: [], //
logoImg: '' // logo
logoImg: '', // logo
usedCouponId: [], // 使id
selectedCoupon: {} //
};
},
mounted () {
@ -250,7 +254,10 @@ export default {
this.goodsList = res.result.cartList;
this.priceDetailDTO = res.result.priceDetailDTO;
this.skuList = res.result.skuList;
let notSupArea = res.result.notSupportFreight
let notSupArea = res.result.notSupportFreight;
this.selectedCoupon = {}
if (res.result.platformCoupon) this.selectedCoupon.platformCoupon = res.result.platformCoupon
Object.assign(this.selectedCoupon, res.result.storeCoupons)
if (notSupArea) {
let content = [];
let title = ''
@ -295,8 +302,22 @@ export default {
storeId: storeArr.toString(),
totalPrice: this.priceDetailDTO.goodsPrice
}
canUseCouponList(params).then(res => {
canUseCouponList(params).then(res => { //
if (res.success) this.couponList = res.result.records
const couponKeys = Object.keys(this.selectedCoupon)
this.usedCouponId = []
if (couponKeys.length) {
this.couponList.forEach(e => {
if (e.id === this.selectedCoupon[couponKeys].memberCoupon.id) {
this.usedCouponId.push(e.id)
}
})
this.$nextTick(() => {
this.$forceUpdate()
})
}
})
}
})
@ -361,16 +382,14 @@ export default {
});
},
useCoupon (id) { // 使
useCoupon (id, used) { // 使
let params = {
way: this.$route.query.way,
memberCouponId: id,
used: true
used: used // true 使 false
}
selectCoupon(params).then(res => {
if (res.success) {
this.init()
}
if (res.success) this.init()
})
},
editInvoice () { //
@ -774,5 +793,16 @@ export default {
.circle-top,.circle-bottom{
right: 22px;
}
.used {
position: absolute;
top: 60px;
right: 40px;
width: 50px;
height: 50px;
}
}
.coupon-list {
max-height: 260px;
overflow: scroll;
}
</style>

View File

@ -45,8 +45,6 @@ export default {
type: "multiple", // single multiple
skuList: [], // sku
selectedWay: [], //
total: "", //
goodsParams: { //
pageNumber: 1,
@ -64,7 +62,12 @@ export default {
loading: false, //
};
},
props: ["clearFlag"],
props: {
selectedWay: {
type: Array,
default: new Array()
}
},
watch: {
category(val) {
this.goodsParams.categoryPath = val[0];
@ -74,6 +77,7 @@ export default {
this.$emit("selected", this.selectedWay);
},
deep: true,
immediate: true
},
"goodsParams.categoryPath": {
@ -110,6 +114,11 @@ export default {
res.result.records.forEach((item) => {
item.selected = false;
item.___type = "goods"; //goodspc wap
this.selectedWay.forEach(e => {
if (e.id === item.id) {
item.selected = true
}
})
});
/**
* 解决数据请求中滚动栏会一直上下跳动
@ -117,7 +126,6 @@ export default {
this.total = res.result.total;
this.goodsData.push(...res.result.records);
// console.log(this.goodsData);
} else {
this.empty = true;
}
@ -193,9 +201,13 @@ export default {
this.selectedWay.push(val);
} else {
val.selected = false;
this.selectedWay.splice(index, 1);
for (let i = 0; i<this.selectedWay.length; i++ ) {
if (this.selectedWay[i].id===val.id) {
this.selectedWay.splice(i,1)
break;
}
}
}
// console.log(this.selectedWay);
},
},
};

View File

@ -1,10 +1,7 @@
<template>
<Modal :styles="{ top: '120px' }" width="1160" @on-cancel="clickClose" @on-ok="clickOK" v-model="flag" :mask-closable="false" scrollable>
<goodsDialog @selected="
(val) => {
goodsData = val;
}
" v-if="goodsFlag" ref="goodsDialog" />
<goodsDialog @selected="(val) => {goodsData = val;}"
v-if="goodsFlag" ref="goodsDialog" :selectedWay='goodsData'/>
<linkDialog @selectedLink="
(val) => {
linkData = val;
@ -23,7 +20,7 @@ export default {
data() {
return {
goodsFlag: false, //
goodsData: "", //
goodsData: [], //
linkData: "", //
flag: false, // modal
};

View File

@ -7,9 +7,7 @@
<div class="form-item-view">
<FormItem astyle="width: 100%">
<div style="display: flex; margin-bottom: 10px">
<Button type="primary" @click="$refs.skuSelect.open('goods')"
>选择商品</Button
>
<Button type="primary" @click="openSkuList"></Button>
<Button
type="error"
ghost
@ -20,22 +18,19 @@
</div>
<Table
border
v-if="showTable"
:columns="columns"
:data="form.promotionGoodsList"
:data="promotionGoodsList"
@on-selection-change="changeSelect"
>
<template slot-scope="{ row }" slot="skuId">
<div>{{ row.skuId }}</div>
</template>
<template slot-scope="{ row, index }" slot="settlementPrice">
<template slot-scope="{ index }" slot="settlementPrice">
<Input
type="number"
v-model="row.settlementPrice"
@input="
pointsGoodsList[index].settlementPrice =
row.settlementPrice
"
v-model="promotionGoodsList[index].settlementPrice"
/>
</template>
@ -44,7 +39,7 @@
slot="pointsGoodsCategory"
>
<Select
v-model="pointsGoodsList[index].pointsGoodsCategoryId"
v-model="promotionGoodsList[index].pointsGoodsCategoryId"
transfer="true"
label-in-value="true"
@on-change="
@ -62,21 +57,17 @@
</Select>
</template>
<template slot-scope="{ row, index }" slot="activeStock">
<template slot-scope="{ index }" slot="activeStock">
<Input
type="number"
v-model="row.activeStock"
@input="
pointsGoodsList[index].activeStock = row.activeStock
"
v-model="promotionGoodsList[index].activeStock"
/>
</template>
<template slot-scope="{ row, index }" slot="points">
<template slot-scope="{ index }" slot="points">
<Input
type="number"
v-model="row.points"
@input="pointsGoodsList[index].points = row.points"
v-model="promotionGoodsList[index].points"
/>
</template>
</Table>
@ -151,22 +142,10 @@ export default {
};
return {
form: {
/** 店铺承担比例 */
sellerCommission: 0,
/** 发行数量 */
publishNum: 1,
/** 运费承担者 */
scopeType: "ALL",
/** 限领数量 */
couponLimitNum: 1,
/** 活动类型 */
couponType: "PRICE",
/** 优惠券名称 */
couponName: "",
getType: "FREE",
promotionGoodsList: [],
promotionGoodsList: [], //
},
pointsGoodsList: [], //
showTable: true,
promotionGoodsList: [], //
categoryList: [], //
submitLoading: false, //
selectedGoods: [], // 便
@ -226,6 +205,12 @@ export default {
title: "商品名称",
key: "goodsName",
minWidth: 120,
render: (h, params) => {
return h(
"div",
params.row.goodsSku.goodsName
);
},
},
{
title: "SKU编码",
@ -236,6 +221,12 @@ export default {
title: "店铺名称",
key: "storeName",
minWidth: 60,
render: (h, params) => {
return h(
"div",
params.row.goodsSku.storeName
);
},
},
{
title: "商品价格",
@ -244,7 +235,7 @@ export default {
render: (h, params) => {
return h(
"div",
this.$options.filters.unitPrice(params.row.price, "¥")
this.$options.filters.unitPrice(params.row.goodsSku.price, "¥")
);
},
},
@ -252,6 +243,12 @@ export default {
title: "库存",
key: "quantity",
minWidth: 20,
render: (h, params) => {
return h(
"div",
params.row.goodsSku.quantity
);
},
},
{
title: "结算价格",
@ -313,11 +310,11 @@ export default {
let res = await getPointsGoodsCategoryList();
this.categoryList = res.result.records;
},
/** 保存平台优惠券 */
/** 保存积分商品 */
handleSubmit() {
this.$refs.form.validate((valid) => {
if (valid) {
let params = this.pointsGoodsList;
let params = this.promotionGoodsList;
const start = this.$options.filters.unixToDate(
this.form.startTime / 1000
);
@ -355,7 +352,8 @@ export default {
this.$router.go(-1);
},
changeCategory(val, index) {
this.pointsGoodsList[index].pointsGoodsCategoryName = val.label;
this.promotionGoodsList[index].pointsGoodsCategoryName = val.label;
console.log(this.promotionGoodsList);
},
changeSelect(e) {
//
@ -363,7 +361,7 @@ export default {
},
delSelectGoods() {
//
if (this.pointsGoodsList.length <= 0) {
if (this.selectedGoods.length <= 0) {
this.$Message.warning("您还未选择要删除的数据");
return;
}
@ -375,55 +373,42 @@ export default {
this.selectedGoods.forEach(function (e) {
ids.push(e.id);
});
this.form.promotionGoodsList = this.form.promotionGoodsList.filter(
this.promotionGoodsList = this.promotionGoodsList.filter(
(item) => {
return !ids.includes(item.id);
}
);
this.pointsGoodsList = this.pointsGoodsList.filter((item) => {
return !ids.includes(item.id);
});
},
});
},
delGoods(index) {
//
this.form.promotionGoodsList.splice(index, 1);
this.pointsGoodsList.splice(index, 1);
this.promotionGoodsList.splice(index, 1);
},
openSkuList() { //
this.$refs.skuSelect.open("goods");
let data = JSON.parse(JSON.stringify(this.promotionGoodsList))
data.forEach(e => {
e.id = e.skuId
})
this.$refs.skuSelect.goodsData = data;
},
selectedGoodsData(item) {
//
let ids = [];
let list = [];
this.form.promotionGoodsList.forEach((e) => {
ids.push(e.skuId);
});
item.forEach((e) => {
if (!ids.includes(e.id)) {
list.push({
goodsName: e.goodsName,
price: e.price,
originalPrice: e.price,
quantity: e.quantity,
storeId: e.storeId,
storeName: e.storeName,
skuId: e.id,
...e,
});
this.pointsGoodsList.push({
settlementPrice: 0,
pointsGoodsCategoryId: 0,
pointsGoodsCategoryName: "",
activeStock: 0,
points: 0,
goodsSku: {
...e,
},
skuId: e.id,
});
const obj = {
settlementPrice: e.settlementPrice || 0,
pointsGoodsCategoryId: e.pointsGoodsCategoryId || 0,
pointsGoodsCategoryName:e.pointsGoodsCategoryName || "",
activeStock:e.activeStock || 0,
points:e.points || 0,
skuId: e.id,
goodsSku: e.goodsSku || e
}
list.push(obj);
});
this.form.promotionGoodsList.push(...list);
this.promotionGoodsList = list;
},
},
};

View File

@ -127,7 +127,7 @@
</Row>
<Row type="flex" justify="end" class="page">
<Page
:current="searchForm.pageNumber + 1"
:current="searchForm.pageNumber"
:total="total"
:page-size="searchForm.pageSize"
@on-change="changePage"
@ -157,7 +157,7 @@ export default {
loading: true, //
searchForm: {
//
pageNumber: 0, //
pageNumber: 1, //
pageSize: 10, //
order: "desc", //
},
@ -248,18 +248,17 @@ export default {
this.$router.push({ name: "add-points-goods" });
},
changePage(v) {
this.searchForm.pageNumber = v - 1;
this.searchForm.pageNumber = v;
this.getDataList();
this.clearSelectAll();
},
changePageSize(v) {
this.searchForm.pageSize = v;
this.getDataList();
},
handleSearch() {
this.searchForm.pageNumber = 0;
this.searchForm.pageNumber = 1;
this.searchForm.pageSize = 10;
if (this.searchForm.pointsS !== "") {
if (this.searchForm.pointsS) {
this.searchForm.points =
this.searchForm.pointsS +
"_" +

View File

@ -168,7 +168,7 @@
</p>
<p class="item">
<span class="label">结算周期</span>
<span class="info">
<span class="info" v-if="storeInfo.settlementCycle">
<Tag
v-for="item in storeInfo.settlementCycle.split(',')"
:key="item"

View File

@ -1,13 +1,13 @@
<template>
<div class="layout">
<Form ref="formValidate" :label-width="150" label-position="right" :model="formValidate" :rules="ruleValidate">
<FormItem label="企业id" prop="ebusinessID">
<FormItem label="ebusinessID" prop="ebusinessID">
<Input v-model="formValidate.ebusinessID" />
</FormItem>
<FormItem label="密钥" prop="appKey">
<FormItem label="appKey" prop="appKey">
<Input class="label-appkey" v-model="formValidate.appKey" />
</FormItem>
<FormItem label="api地址" prop="reqURL">
<FormItem label="reqURL" prop="reqURL">
<Input v-model="formValidate.reqURL" />
</FormItem>
<div class="label-btns">
@ -78,15 +78,13 @@ export default {
@import "./style.scss";
.label-item {
display: flex;
> .ivu-input {
width: 200px;
margin: 0 10px;
}
}
.label-appkey {
/deep/ .ivu-input {
width: 300px !important;
/deep/ input {
width: 300px !important;
}
margin: 0 10px;
}
.ivu-input-wrapper {
width: 300px;
margin-right: 10px;
}
</style>

View File

@ -31,16 +31,22 @@ export default {
type: "GOODS_SETTING",
name: "商品设置",
},
//
{
type: "KUAIDI_SETTING",
name: "快递鸟设置",
},
//
{
type: "ORDER_SETTING",
name: "订单配置",
},
//
{type: "POINT_SETTING", name: "积分设置"},
{
type: "WITHDRAWAL_SETTING",
name: "提现设置",
},
//
{
type: "KUAIDI_SETTING",
name: "快递鸟设置",
},
//OSS
{
type: "OSS_SETTING",
@ -51,12 +57,6 @@ export default {
type: "SMS_SETTING",
name: "阿里短信配置",
},
//
{type: "POINT_SETTING", name: "积分设置"},
{
type: "WITHDRAWAL_SETTING",
name: "提现设置",
},
],
authLogin: [
//

18
pushGithub.sh Normal file
View File

@ -0,0 +1,18 @@
echo '开始推送github'
echo '切换git地址'
git remote rm origin
git remote add origin git@github.com:hongyehuicheng/lilishop-ui.git
echo '设置上传代码分支推送github'
git push --set-upstream origin master --force
echo '推送github完成'
git remote rm origin
git remote add origin git@gitee.com:beijing_hongye_huicheng/lilishop-ui.git
git pull origin master
echo '切回gitee资源'
git branch --set-upstream-to=origin/master master
echo '设置git跟踪资源'

View File

@ -41,12 +41,17 @@
<script>
import * as API_Goods from "@/api/goods";
export default {
data() {
props: {
selectedWay: {
type: Array,
default: new Array()
}
},
data () {
return {
type: "multiple", // single multiple
cateList: [], //
selectedWay: [], //
total: "", //
goodsParams: { //
pageNumber: 1,
@ -64,18 +69,17 @@ export default {
loading: false, // loading
};
},
props: ["clearFlag"],
watch: {
category(val) {
this.goodsParams.categoryPath = val[2];
},
selectedWay: {
handler() {
handler(val) {
this.$emit("selected", this.selectedWay);
},
deep: true,
immediate: true
},
"goodsParams.categoryPath": {
handler: function () {
this.goodsData = [];
@ -88,7 +92,7 @@ export default {
this.init();
},
methods: {
handleReachBottom() {
handleReachBottom() { //
setTimeout(() => {
if (
this.goodsParams.pageNumber * this.goodsParams.pageSize <=
@ -99,17 +103,24 @@ export default {
}
}, 1500);
},
getQueryGoodsList() {
getQueryGoodsList() { //
API_Goods.getGoodsSkuData(this.goodsParams).then((res) => {
this.initGoods(res);
});
},
initGoods(res) {
initGoods(res) { //
if (res.result.records.length !=0) {
res.result.records.forEach((item) => {
let data = res.result.records;
data.forEach((item) => {
item.selected = false;
item.___type = "goods"; //goodspc wap
this.selectedWay.forEach(e => {
if (e.id === item.id) {
item.selected = true
}
})
});
/**
* 解决数据请求中滚动栏会一直上下跳动
@ -141,7 +152,6 @@ export default {
deepGroup(val) {
val.forEach((item) => {
let childWay = []; //
let grandWay = []; //
//
if (item.children) {
item.children.forEach((child) => {
@ -196,7 +206,12 @@ export default {
this.selectedWay.push(val);
} else {
val.selected = false;
this.selectedWay.splice(index, 1);
for (let i = 0; i<this.selectedWay.length; i++ ) {
if (this.selectedWay[i].id===val.id) {
this.selectedWay.splice(i,1)
break;
}
}
}
},
},

View File

@ -10,20 +10,13 @@
scrollable
>
<goodsDialog
@selected="
(val) => {
goodsData = val;
}
"
@selected="(val) => {goodsData = val;}"
:selectedWay='goodsData'
ref="goodsDialog"
v-if="goodsFlag"
/>
<linkDialog
@selectedLink="
(val) => {
linkData = val;
}
"
@selectedLink="(val) => {linkData = val;}"
v-else
class="linkDialog"
/>
@ -41,14 +34,11 @@ export default {
return {
title: "选择", //
goodsFlag: false, //
goodsData: "", //
goodsData: [], //
linkData: "", //
flag: false, //
};
},
props: ["types"],
watch: {},
mounted() {},
methods: {
//
clickClose() {
@ -58,7 +48,6 @@ export default {
//
singleGoods(){
var timer = setInterval(() => {
if (this.$refs.goodsDialog) {
@ -66,19 +55,16 @@ export default {
clearInterval(timer);
}
}, 100);
},
clickOK() {
clickOK() { //
if (this.goodsFlag) {
this.$emit("selectedGoodsData", this.goodsData);
} else {
this.$emit("selectedLink", this.linkData);
}
this.clickClose();
// this.clearFlag = false
},
open(type){
open (type) { // ref
this.flag = true;
if(type == 'goods'){
this.goodsFlag = true;
@ -87,7 +73,7 @@ export default {
}
},
close(){
close(){ //
this.flag = false;
}
},

View File

@ -223,7 +223,7 @@ export default {
{
title: "状态",
key: "promotionStatus",
minWidth: 100,
width: 100,
fixed: "right",
render: (h, params) => {
let text = "未知",
@ -250,9 +250,9 @@ export default {
},
},
text
),
)
]);
},
}
},
{
title: "操作",

View File

@ -114,9 +114,8 @@
v-if="form.scopeType == 'PORTION_GOODS'"
>
<div style="display: flex; margin-bottom: 10px">
<Button type="primary" @click="$refs.skuSelect.open('goods')"
>选择商品</Button
>
<Button type="primary" @click="openSkuList"
>选择商品</Button>
<Button
type="error"
ghost
@ -466,6 +465,14 @@ export default {
name: "coupon",
});
},
openSkuList() { //
this.$refs.skuSelect.open("goods");
let data = JSON.parse(JSON.stringify(this.form.promotionGoodsList))
data.forEach(e => {
e.id = e.skuId
})
this.$refs.skuSelect.goodsData = data;
},
changeSelect(e) {
//
this.selectedGoods = e;
@ -497,15 +504,9 @@ export default {
this.form.promotionGoodsList.splice(index, 1);
},
selectedGoodsData(item) {
console.log(item);
//
let ids = [];
let list = [];
this.form.promotionGoodsList.forEach((e) => {
ids.push(e.skuId);
});
item.forEach((e) => {
if (!ids.includes(e.id)) {
list.push({
goodsName: e.goodsName,
price: e.price,
@ -515,9 +516,8 @@ export default {
sellerName: e.sellerName,
skuId: e.id,
});
}
});
this.form.promotionGoodsList.push(...list);
this.form.promotionGoodsList = list;
},
getGoodsCategory(e) {
// id

View File

@ -140,12 +140,12 @@ export default {
{
title: "活动类型",
slot: "promotionType",
minWidth: 60,
width: 100,
},
{
title: "活动状态",
key: "promotionStatus",
minWidth: 60,
width: 100,
render: (h, params) => {
let text = "未知",
color = "default";

View File

@ -183,7 +183,7 @@
style="display: flex; margin-bottom: 10px"
v-if="form.promotionStatus == 'NEW'"
>
<Button type="primary" @click="$refs.skuSelect.open('goods')"
<Button type="primary" @click="openSkuList"
>选择商品</Button
>
<Button
@ -376,6 +376,14 @@ export default {
);
this.$router.go(-1);
},
openSkuList() { //
this.$refs.skuSelect.open("goods");
let data = JSON.parse(JSON.stringify(this.form.promotionGoodsList))
data.forEach(e => {
e.id = e.skuId
})
this.$refs.skuSelect.goodsData = data;
},
getDetail() {
//
getFullDiscountById(this.id).then((res) => {
@ -496,28 +504,20 @@ export default {
this.form.promotionGoodsList.splice(index, 1);
},
selectedGoodsData(item) {
console.log(item);
//
let ids = [];
let list = [];
this.form.promotionGoodsList.forEach((e) => {
ids.push(e.skuId);
});
item.forEach((e) => {
if (!ids.includes(e.id)) {
list.push({
goodsName: e.goodsName,
price: e.price,
quantity: e.quantity,
storeId: e.storeId,
storeName: e.storeName,
thumbnail: e.thumbnail,
skuId: e.id,
});
}
list.push({
goodsName: e.goodsName,
price: e.price,
quantity: e.quantity,
storeId: e.storeId,
storeName: e.storeName,
thumbnail: e.thumbnail,
skuId: e.id,
});
});
console.log(list);
this.form.promotionGoodsList.push(...list);
this.form.promotionGoodsList = list;
},
getCouponList(query) {
//

View File

@ -155,17 +155,15 @@ export default {
{
title: "活动开始时间",
key: "startTime",
minWidth: 120
},
{
title: "活动结束时间",
key: "endTime",
minWidth: 120
},
{
title: "状态",
key: "promotionStatus",
minWidth: 100,
width: 100,
render: (h, params) => {
let text = "未知",
color = "default";

View File

@ -36,7 +36,7 @@
</Row>
</Card>
<sku-select ref="skuSelect" @selectedGoodsData="selectedGoodsData"></sku-select>
<sku-select ref="skuSelect" :goodsData="goodsData" @selectedGoodsData="selectedGoodsData"></sku-select>
</div>
</template>
<script>
@ -65,7 +65,7 @@ export default {
data: [], //
total: 0, //
status: this.$route.query.status, //
columns: [
columns: [ //
{
title: "活动名称",
key: "promotionName",
@ -111,7 +111,7 @@ export default {
},
},
],
goodsColumns: [
goodsColumns: [ //
{ type: "selection", width: 60, align: "center" },
{
title: "商品名称",
@ -202,7 +202,6 @@ export default {
handleReset() {
//
// this.$refs.searchForm.resetFields();
this.searchForm.pageNumber = 0;
this.searchForm.promotionName = "";
this.selectDate = null;
@ -211,7 +210,7 @@ export default {
this.getDataList();
},
clearSelectAll() {
clearSelectAll() { //
this.$refs.table.selectAll(false);
},
changeSelect(e) {
@ -220,7 +219,7 @@ export default {
this.selectCount = e.length;
},
getDataList() {
getDataList() { //
this.loading = true;
this.searchForm.pintuanId = this.$route.query.id;
@ -233,14 +232,12 @@ export default {
});
},
getPintuanMsg() {
//
getPintuanMsg() { //
getPintuanDetail(this.$route.query.id).then((res) => {
if (res.success) this.data.push(res.result);
});
},
delGoods(index) {
//
delGoods(index) { //
this.goodsData.splice(index, 1);
},
delAll() { //
@ -263,13 +260,9 @@ export default {
});
},
selectedGoodsData(item) { //
let ids = [];
console.log(item);
let list = [];
this.goodsData.forEach((e) => {
ids.push(e.skuId);
});
item.forEach((e) => {
if (!ids.includes(e.id)) {
list.push({
goodsName: e.goodsName,
price: e.price,
@ -281,15 +274,19 @@ export default {
skuId: e.id,
categoryPath: e.categoryPath,
});
}
});
this.goodsData.push(...list);
this.goodsData = list;
},
openSkuList() { //
this.$refs.skuSelect.open("goods");
let data = JSON.parse(JSON.stringify(this.goodsData))
data.forEach(e => {
e.id = e.skuId
})
this.$refs.skuSelect.goodsData = data;
},
},
mounted() {
mounted () {
this.init();
},
};

View File

@ -134,6 +134,7 @@ export default {
{
title: "状态",
key: "promotionStatus",
width: 100,
render: (h, params) => {
let text = "未知",
color = "default";

View File

@ -318,19 +318,19 @@ export default {
},
delGoods(index, id) {
//
if (id) {
removeSeckillGoods(this.$route.query.id, id).then((res) => {
if (res.success) {
this.goodsList[this.tabIndex].list.splice(index, 1);
this.$Message.success("删除成功!");
}
});
} else {
// if (id) {
// removeSeckillGoods(this.$route.query.id, id).then((res) => {
// if (res.success) {
// this.goodsList[this.tabIndex].list.splice(index, 1);
// this.$Message.success("");
// }
// });
// } else {
this.goodsList[this.tabIndex].list.splice(index, 1);
this.$Message.success("删除成功!");
}
// }
},
delAll() {
delAll() { //
if (this.selectCount <= 0) {
this.$Message.warning("您还未选择要删除的数据");
return;
@ -350,43 +350,46 @@ export default {
].list.filter((item) => {
return !ids.includes(item.id);
});
removeSeckillGoods(this.$route.query.id, ids).then((res) => {
if (res.success) {
this.$Message.success("删除成功!");
}
});
// removeSeckillGoods(this.$route.query.id, ids).then((res) => {
// if (res.success) {
// this.$Message.success("");
// }
// });
},
});
},
selectedGoodsData(item) {
//
let ids = [];
let list = [];
this.goodsList[this.tabIndex].list.forEach((e) => {
ids.push(e.skuId);
});
console.log(item);
item.forEach((e) => {
if (!ids.includes(e.id)) {
list.push({
goodsName: e.goodsName,
price: e.price,
originalPrice: e.price,
promotionApplyStatus: "",
quantity: e.quantity,
seckillId: this.$route.query.id,
storeId: e.storeId,
storeName: e.storeName,
skuId: e.id,
timeLine: this.data[0].hours.split(",")[this.tabIndex],
});
}
list.push({
goodsName: e.goodsName,
price: e.price,
originalPrice: e.price,
promotionApplyStatus: e.promotionApplyStatus || '',
quantity: e.quantity,
seckillId: this.$route.query.id,
storeId: e.storeId,
storeName: e.storeName,
skuId: e.id,
timeLine: this.data[0].hours.split(",")[this.tabIndex],
});
});
this.goodsList[this.tabIndex].list.push(...list);
this.goodsList[this.tabIndex].list = list;
this.$nextTick(()=> {
this.$forceUpdate()
})
},
openSkuList() {
openSkuList() { //
this.$refs.skuSelect.open("goods");
let data = JSON.parse(JSON.stringify(this.goodsList[this.tabIndex].list))
data.forEach(e => {
e.id = e.skuId
})
this.$refs.skuSelect.goodsData = data;
},
unixDate(time) {
//