76 Commits

Author SHA1 Message Date
lemon橪
e73d76eb57 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2022-02-14 14:31:36 +08:00
lemon橪
b9a89d7c40 新增分销模块分销业绩详细信息补充 2022-02-14 14:31:29 +08:00
paulGao
1a1bf814a0 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2022-02-14 14:21:50 +08:00
paulGao
f52e929d04 适配api 2022-02-14 14:21:48 +08:00
paulGao
38d8d2e1ca 适配修改后的api 2022-02-12 15:20:48 +08:00
paulGao
ab4015d0e0 适配修改的api 2022-02-10 18:57:17 +08:00
lemon橪
15027e51ee 优化安卓app在登录验证页面图像可能显示异常问题 2022-02-07 14:41:18 +08:00
paulGao
557d7ef1d9 fix bugs 2022-01-27 14:58:42 +08:00
paulGao
4dea906e23 修复店铺和平台优惠券同时选择时,显示问题 2022-01-21 19:02:06 +08:00
paulGao
68e25cb0b3 优化下单后退显示 2022-01-04 19:58:01 +08:00
paulGao
4d033e59f1 增加刷新token接口失效的情况处理 2022-01-04 14:22:00 +08:00
paulGao
a80c579d8a 售后获取订单过滤0元订单 2022-01-04 09:20:20 +08:00
paulGao
5cc48ed462 修复登录时uuid变化问题 2021-12-31 12:04:39 +08:00
lemon橪
2abc8ff9d8 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-12-29 09:23:06 +08:00
lemon橪
198bd6c322 修复楼层装修请求文章的接口路径 2021-12-29 09:23:05 +08:00
paulGao
7fb96f1eac 修复购物车全选显示不正确问题 2021-12-28 19:50:06 +08:00
paulGao
2020f55826 修复订单详情跳转商品页面错误 2021-12-27 18:45:39 +08:00
lemon橪
c58f8d7831 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-12-25 10:55:27 +08:00
lemon橪
32a6bbacd0 购物车新增领劵判断,优化我的优惠券中可能出现的Bug 2021-12-25 10:55:25 +08:00
夜良king
b08c77b6c0 我的足迹里-全选的改动 2021-12-24 16:41:43 +08:00
lemon橪
a8836744f6 我的收藏布局修改 2021-12-24 16:22:03 +08:00
lemon橪
3a2202a2e8 修改部分已发现的bug 2021-12-24 09:12:21 +08:00
lemon橪
896749d812 修复购物车在更新最新后端代码的时候导致的bug 2021-12-23 18:36:00 +08:00
paulGao
09ec1e8c06 修复默认弹促销 2021-12-23 16:06:59 +08:00
paulGao
07627c41e3 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2021-12-21 19:12:20 +08:00
paulGao
e4e278c2fa 适配促销活动,修复促销问题 2021-12-21 19:12:04 +08:00
lemon橪
1b1b239ba0 合并冲突提交 2021-12-20 17:35:38 +08:00
lemon橪
c1d4d39265 udesk 技术储备 2021-12-20 17:34:45 +08:00
lemon橪
dfd3885486 储备udesk方案,暂时注释 2021-12-20 17:34:27 +08:00
paulGao
892f49c83a 适配重构促销 2021-12-15 18:17:33 +08:00
paulGao
85d0671443 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2021-12-13 19:33:21 +08:00
paulGao
f22e7b9fcb 适配重构促销 2021-12-13 19:31:48 +08:00
lemon橪
d282ef1b24 化楼层装修中商品分类判断 2021-12-13 17:17:02 +08:00
lemon橪
9c2529ae3d Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-12-13 17:16:14 +08:00
lemon橪
108b7f5b0b 优化楼层装修中商品分类判断 2021-12-13 17:16:12 +08:00
paulGao
b4c8be3e63 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2021-12-13 02:26:08 +08:00
paulGao
4064c56b21 适配重构促销 2021-12-11 13:48:18 +08:00
lemon橪
1416762afe 优化楼层装修中商品分类代码可能会出现的bug 2021-12-09 18:32:01 +08:00
lemon橪
17f23fe920 砍价分享图片有误bug修改 2021-12-03 15:52:40 +08:00
lemon橪
c412c92b3e 新增取消售后 优化售后部分逻辑 2021-11-30 14:59:49 +08:00
lemon橪
deed875c1b 新增商品列表 2021-11-29 09:58:39 +08:00
lemon橪
f600b628ce 我的足迹样式优化 2021-11-22 15:25:42 +08:00
lemon橪
0c887a25e3 修改login中第三方循环判断 2021-11-22 11:18:00 +08:00
lemon橪
89dbd32351 修改商品详情中图片有空格问题 2021-11-19 15:49:42 +08:00
lemon橪
98c5863973 新增搜素样式判断优化,以及投诉图片上传内容条显示 2021-11-18 18:11:28 +08:00
lemon橪
3d1089b756 优化我的评价 2021-11-17 16:30:04 +08:00
lemon橪
6c8102aecd 新增我的评价中订单评论状态 2021-11-16 17:43:09 +08:00
lemon橪
56fdb2c2f0 退出登录 2021-11-16 11:11:54 +08:00
lemon橪
7c85460fbb Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-11-15 16:19:55 +08:00
lemon橪
47b58c290a 删除冗余选择器优化代码 2021-11-15 16:19:53 +08:00
paulGao
cdf57806d6 add logout 2021-11-11 18:46:26 +08:00
lemon橪
9671d60555 修改商品搜索样式 以及es中删除部分字段 2021-11-11 18:15:12 +08:00
lemon橪
f8b388c968 优化筛选 2021-11-11 16:42:41 +08:00
lemon橪
91cc98e853 修改筛选逻辑判断 2021-11-10 10:22:37 +08:00
lemon橪
58484f1b61 筛选中可能出现的问题 2021-11-09 19:04:38 +08:00
lemon橪
d65ad6c5fd 修改登录中可能存在的验证码bug 2021-11-08 11:21:19 +08:00
lemon橪
68bc1d6974 优化商品筛选楼层装修判断 2021-11-04 10:53:52 +08:00
lemon橪
b1c518c3a8 合并Master 2021-11-03 11:55:24 +08:00
lemon橪
48c7030c0e 修改部分页面判断问题 2021-11-03 11:54:38 +08:00
chopper711
13c9d521f9 update README.md. 2021-11-02 08:03:59 +00:00
lemon橪
375653eb78 更新微信公众号登录 2021-10-29 16:34:41 +08:00
lemon橪
8c72cdcb0a 修改我的优惠券中bug 2021-10-29 11:19:27 +08:00
lemon橪
cfb88d798b 提交上次更改多余删除部分 2021-10-26 15:45:30 +08:00
lemon橪
ebf32a18b0 1.修改商品规格中可能出现的sku判断,优化选择商品规格上下滑动。2.优化登录页面样式。3.优化购物车样式 2021-10-26 15:27:13 +08:00
lemon橪
5f6c1adf91 优化无痛刷新token 修改分销扫码bug 2021-10-22 18:03:41 +08:00
lemon橪
44648e9971 首页下拉刷新,优化商品促销界面 2021-10-15 18:01:54 +08:00
lemon橪
fd37087c43 删除冗余组件,修改搜索商品样式 2021-10-13 18:01:09 +08:00
lemon橪
4c47a1249f 优化售后方面 2021-10-12 16:31:03 +08:00
lemon橪
ea3563e4e9 解决商品详情中商品介绍判断bug 2021-10-06 16:46:47 +08:00
lemon橪
c98c5b64e1 修改部分已知的代码问题 2021-09-28 17:56:21 +08:00
lemon橪
3b9b2e8ba2 优化订单,组件页面下拉刷新,修改评论bug 2021-09-27 19:58:18 +08:00
lemon橪
cebde87682 修改小程序使用优惠券bug 2021-09-26 10:30:28 +08:00
lemon橪
0b2bf1faf1 优化购物车在微信公众号中样式问题 2021-09-22 11:31:37 +08:00
lemon橪
73560e8366 修改筛选不赋值categoryId问题 2021-09-18 10:11:29 +08:00
lemon橪
afabfdd1d5 修改发现的 商品搜索已售问题 2021-09-18 09:59:47 +08:00
lemon橪
dadce33d74 解决筛选bug 和已知的坐标问题 2021-09-17 18:08:08 +08:00
86 changed files with 3482 additions and 4735 deletions

253
README.md
View File

@@ -1,110 +1,138 @@
## Lilishop B2B2C商城系统 ## 🔥 Lilishop B2B2C商城系统
##### 🌹 开源不易如有帮助请点Star
#### 欢迎交流需求,交流业务,交流技术(基础问题自行解决,进群先看文档后提问)
##### 交流 qq 1群 961316482已满
##### 交流 qq 2群 875294241
##### 商城 公众号/小程序体验,扫描二维码
##### 官方公众号 & 开源不易如有帮助请点Star
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png) ![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) [![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
  ![github](https://img.shields.io/github/stars/hongyehuicheng/lilishop.svg?style=social&logo=#181717)
### 介绍 ### 🔥 商城介绍
**官网**https://pickmall.cn **官网**https://pickmall.cn
Lilishop 是一款Java开发基于SpringBoot研发B2B2C多用户商城前端使用 Vue、uniapp开发 **系统全端全部代码开源** Lilishop 商城系统 基于SpringBoot 研发B2B2C多用户商城系统,前端使用 Vue、uniapp开发 **系统全端全部代码开源**
产品前后端分离、支持分布式部署 业务兼容O2O商城/B2B商城/B2B2C商城/F2B2C商城/S2B2C商城。支持小程序商城、H5商城、APP商城、 PC商城
商城展示端包含 PC、H5、微信小程序、APP。
商城前后端分离、支持分布式部署。
商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块 商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
系统包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等支持Docker支持k8s。是一款高性能支持高并发商城系统。 商城包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等支持Docker支持k8s。是一款高性能支持高并发商城系统。
开箱即用,简单配置即可部署一套属于您的系统。 ##### 商城 API/消费者 聚合版
api不需要单独部署只需启动一个jar包就可以正常运转 如有需要可以点击跳转https://gitee.com/beijing_hongye_huicheng/lilishop-simplify
### 文档 ### ☃️ 商城 开发/使用/常见问题 帮助文档
**产品文档**(需求、架构、使用、部署、开发):https://docs.pickmall.cn https://docs.pickmall.cn
### 💧 开源商城项目地址(gitee)
**API商城所有API**https://gitee.com/beijing_hongye_huicheng/lilishop.git
**UI商城管理端/商家端/买家PC端** https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
**uniapp商城移动端支持小程序/APP/H5**https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
**docker一键部署商城部署脚本**https://gitee.com/beijing_hongye_huicheng/docker.git
### 💧 开源商城项目地址(github)
**API商城所有API**https://github.com/hongyehuicheng/lilishop.git
**UI商城管理端/商家端/买家PC端** https://github.com/hongyehuicheng/lilishop-ui.git
**uniapp商城移动端支持小程序/APP/H5**https://github.com/hongyehuicheng/lilishop-uniapp.git
**docker一键部署商城部署脚本**https://github.com/hongyehuicheng/docker.git
### 项目链接(gitee) ☃️ UI 项目下3个文件夹 buyer买家PC端seller商家端manager后台管理端
**Java后台**https://gitee.com/beijing_hongye_huicheng/lilishop.git
**Vue后台前端** https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git ### 💧 演示地址(手机验证码为 111111)
**Uni-app**https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git **商城管理端**https://admin-b2b2c.pickmall.cn 账号admin/123456
**docker一键部署**https://gitee.com/beijing_hongye_huicheng/docker.git **商城店铺后台**https://store-b2b2c.pickmall.cn 账号13011111111/111111
### 项目链接(github) **商城PC页面**https://pc-b2b2c.pickmall.cn
**Java后台**https://github.com/hongyehuicheng/lilishop.git **商城移动端(请使浏览器手机模式,或者用手机浏览器打开)**https://m-b2b2c.pickmall.cn
**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
**店铺后台**https://store-b2b2c.pickmall.cn 账号13011111111/111111
**用户前台**https://pc-b2b2c.pickmall.cn
**移动端**https://m-b2b2c.pickmall.cn
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png) ![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
### 3行命令搭建本地环境 ### 🚙 3行命令搭建本地商城(注:只能本机访问,如需调整,请自行操作镜像)
温馨提示由于服务较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。 温馨提示:由于服务中间件较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
##### 下载docker脚本
##### docker环境安装 [点击跳转](https://docs.pickmall.cn/deploy/%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87.html)
##### 下载docker-compose脚本
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git ` `git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
##### 部署基础环境
##### 部署商城所需中间件
`docker-compose up -d` `docker-compose up -d`
##### 部署应用 ##### 部署商城应用
`docker-compose -f docker-compose-application.yml up -d` `docker-compose -f docker-compose-application.yml up -d`
PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql PS:商城数据库单独部署 https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql 这里有与tag版本一致的sql根据tag获取sql如果使用master代码则需要在lilishop项目根目录的DB目录中获取对应的升级sql。
##### 各个地址 ##### 商城 API/UI 地址
| API | 地址 | | API | 地址 |
| -------------- | --------------- | | -------------- | --------------- |
| 买家API | http://127.0.0.1:8888 | | 商城买家API | http://127.0.0.1:8888 |
| 商家API | http://127.0.0.1:8889 | | 商城商家API | http://127.0.0.1:8889 |
| 管理端API | http://127.0.0.1:8887 | | 商城管理端API | http://127.0.0.1:8887 |
| 通用API | http://127.0.0.1:8890 | | 商城基础API | http://127.0.0.1:8890 |
| 前端演示 | 地址 | | 前端演示 | 地址 |
| -------------- | --------------- | | -------------- | --------------- |
| PC | http://127.0.0.1:10000 | | 商城PC端 | http://127.0.0.1:10000 |
| WAP | http://127.0.0.1:10001 | | 商城WAP | http://127.0.0.1:10001 |
| 商 | http://127.0.0.1:10002 | | 商城卖家端 | http://127.0.0.1:10002 |
| 管理端 | http://127.0.0.1:10003 | | 商城管理端 | http://127.0.0.1:10003 |
### 功能列表 ### ⚾️ 功能列表
#### 平台功能 #### 🥎 商城平台功能
![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg) ![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg)
#### 商家端功能 #### 🥎 商城卖家功能
![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg) ![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg)
@@ -112,30 +140,28 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
### 功能展示 ### 🧩 商城前端功能展示
#### 移动端 #### ⚽️ 商城移动端
<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%;" /> <img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" />
#### 管理端 #### ⚽️ 商城管理端
![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif) ![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif)
### 技术选型 ### 商城技术选型
#### 架构图 #### 🥅 架构图
![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png) ![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png)
##### Java后台 ##### 🕹 后台技术选型
| 说明 | 框架 | 说明 | | | 说明 | 框架 | 说明 | |
| -------------- | --------------- | -------------- | ------------- | | -------------- | --------------- | -------------- | ------------- |
@@ -149,7 +175,7 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 短信 | 阿里云短信 | 认证 | JWT | | 短信 | 阿里云短信 | 认证 | JWT |
| 日志处理 | Log4j | 接口规范 | RESTful | | 日志处理 | Log4j | 接口规范 | RESTful |
##### 前端-运营后台、店铺后台 ##### 🖥 前端-运营后台、店铺后台
| 说明 | 框架 | 说明 | 框架 | | 说明 | 框架 | 说明 | 框架 |
| ---------- | ---------- | ---------- | ------- | | ---------- | ---------- | ---------- | ------- |
@@ -159,119 +185,34 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 基础UI库 | iView | UI界面基于 | iView | | 基础UI库 | iView | UI界面基于 | iView |
| 网络请求 | axios | | | | 网络请求 | axios | | |
##### 前端-移动端 ##### 📱前端-移动端
| 说明 | 架构 | 说明 | 架构 | | 说明 | 架构 | 说明 | 架构 |
| --------- | ------- | -------- | ------- | | --------- | ------- | -------- | ------- |
| 基础UI库 | uViewui | 基础框架 | uni-app | | 基础UI库 | uViewui | 基础框架 | uni-app |
| CSS预处理 | scss | 地图引擎 | amap | | CSS预处理 | scss | 地图引擎 | amap |
### 升级计划 ### 🌟 版本升级
#### 计划每个月发布一个版本,具体时间可能有出入
时间2021年6月15日
``` ```
新增功能: 商城后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
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.仅允许用于个人学习研究使用. 1.仅允许用于个人学习研究使用.
2.禁止将本开源的代码和资源进行任何形式任何名义的出售. 2.禁止将本开源的代码和资源进行任何形式任何名义的出售.
3.限制商用如果需要商业使用请联系我们。QQ3409056806. 3.软件受国家计算机软件著作权保护登记号2021SR0805085
### 交流群 4.限制商用如果需要商业使用请联系我们。QQ3409056806.
**QQ群**961316482
### 🐧 交流群
##### 官方qq 1群 961316482已满
##### 官方qq 2群 875294241

View File

@@ -12,7 +12,7 @@ import api from "@/config/api.js";
*/ */
export function getAddressList(pageNumber, pageSize) { export function getAddressList(pageNumber, pageSize) {
return http.request({ return http.request({
url: "/memberAddress", url: "/member/address",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params: { pageNumber, pageSize }, params: { pageNumber, pageSize },
@@ -37,7 +37,7 @@ export function getLogistics() {
*/ */
export function getAddressCode(cityCode, townName) { export function getAddressCode(cityCode, townName) {
return http.request({ return http.request({
url: api.common + "/region/region", url: api.common + "/common/region/region",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params: { cityCode, townName }, params: { cityCode, townName },
@@ -51,7 +51,7 @@ export function getAddressCode(cityCode, townName) {
*/ */
export function addAddress(data) { export function addAddress(data) {
return http.request({ return http.request({
url: "/memberAddress", url: "/member/address",
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
header: { "content-type": "application/x-www-form-urlencoded" }, header: { "content-type": "application/x-www-form-urlencoded" },
@@ -67,7 +67,7 @@ export function addAddress(data) {
*/ */
export function editAddress(params) { export function editAddress(params) {
return http.request({ return http.request({
url: `/memberAddress`, url: `/member/address`,
method: Method.PUT, method: Method.PUT,
needToken: true, needToken: true,
header: { "content-type": "application/x-www-form-urlencoded" }, header: { "content-type": "application/x-www-form-urlencoded" },
@@ -81,7 +81,7 @@ export function editAddress(params) {
*/ */
export function deleteAddress(id) { export function deleteAddress(id) {
return http.request({ return http.request({
url: `/memberAddress/delById/${id}`, url: `/member/address/delById/${id}`,
method: Method.DELETE, method: Method.DELETE,
needToken: true, needToken: true,
}); });
@@ -95,7 +95,7 @@ export function deleteAddress(id) {
*/ */
export function getAddressDetail(id) { export function getAddressDetail(id) {
return http.request({ return http.request({
url: `/memberAddress/get/${id}`, url: `/member/address/get/${id}`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
needToken: true, needToken: true,
@@ -107,7 +107,7 @@ export function getAddressDetail(id) {
*/ */
export function getAddressDefault() { export function getAddressDefault() {
return http.request({ return http.request({
url: `/memberAddress/get/default`, url: `/member/address/get/default`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
needToken: true, needToken: true,

View File

@@ -34,16 +34,29 @@ export function applyCancelOrder(params) {
}); });
} }
/**
/** /**
* 获取商家售后收件地址 * 获取商家售后收件地址
*/ */
export function getstoreAfterSaleAddress(sn) { export function getStoreAfterSaleAddress(sn) {
return http.request({ return http.request({
url: `/afterSale/getStoreAfterSaleAddress/${sn}`, url: `/order/afterSale/getStoreAfterSaleAddress/${sn}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
} }
/**
* 取消售后
*/
export function cancelAfterSale(afterSaleSn) {
return http.request({
url: `/order/afterSale/cancel/${afterSaleSn}`,
method: Method.POST,
needToken: true,
});
}
/** /**
* 获取售后服务记录相关数据 * 获取售后服务记录相关数据
@@ -51,7 +64,7 @@ export function getstoreAfterSaleAddress(sn) {
*/ */
export function getAfterSaleList(params) { export function getAfterSaleList(params) {
return http.request({ return http.request({
url: `/afterSale/page`, url: `/order/afterSale/page`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -64,7 +77,7 @@ export function getAfterSaleList(params) {
*/ */
export function getServiceDetail(sn) { export function getServiceDetail(sn) {
return http.request({ return http.request({
url: `/afterSale/get/${sn}`, url: `/order/afterSale/get/${sn}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -76,7 +89,7 @@ export function getServiceDetail(sn) {
*/ */
export function addComplain(params) { export function addComplain(params) {
return http.request({ return http.request({
url: `/complain`, url: `/order/complain`,
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
header: { header: {
@@ -91,7 +104,7 @@ export function addComplain(params) {
*/ */
export function clearComplain(id, params) { export function clearComplain(id, params) {
return http.request({ return http.request({
url: `/complain/status/${id}`, url: `/order/complain/status/${id}`,
method: Method.PUT, method: Method.PUT,
needToken: true, needToken: true,
params, params,
@@ -103,7 +116,7 @@ export function clearComplain(id, params) {
*/ */
export function getAfterSaleLog(sn) { export function getAfterSaleLog(sn) {
return http.request({ return http.request({
url: `/afterSale/get/getAfterSaleLog/${sn}`, url: `/order/afterSale/get/getAfterSaleLog/${sn}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -114,7 +127,7 @@ export function getAfterSaleLog(sn) {
*/ */
export function getComplain(params) { export function getComplain(params) {
return http.request({ return http.request({
url: `/complain`, url: `/order/complain`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -126,7 +139,7 @@ export function getComplain(params) {
*/ */
export function getAfterSaleReason(serviceType) { export function getAfterSaleReason(serviceType) {
return http.request({ return http.request({
url: `/afterSale/get/afterSaleReason/${serviceType}`, url: `/order/afterSale/get/afterSaleReason/${serviceType}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -137,7 +150,7 @@ export function getAfterSaleReason(serviceType) {
*/ */
export function getClearReason() { export function getClearReason() {
return http.request({ return http.request({
url: `/afterSale/get/afterSaleReason/CANCEL`, url: `/order/afterSale/get/afterSaleReason/CANCEL`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -148,7 +161,7 @@ export function getClearReason() {
*/ */
export function getComplainReason() { export function getComplainReason() {
return http.request({ return http.request({
url: `/afterSale/get/afterSaleReason/COMPLAIN`, url: `/order/afterSale/get/afterSaleReason/COMPLAIN`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -158,7 +171,7 @@ export function getComplainReason() {
*/ */
export function getComplainDetail(id) { export function getComplainDetail(id) {
return http.request({ return http.request({
url: `/complain/${id}`, url: `/order/complain/${id}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -169,7 +182,7 @@ export function getComplainDetail(id) {
*/ */
export function getAfterSaleInfo(sn) { export function getAfterSaleInfo(sn) {
return http.request({ return http.request({
url: `/afterSale/applyAfterSaleInfo/${sn}`, url: `/order/afterSale/applyAfterSaleInfo/${sn}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -181,7 +194,7 @@ export function getAfterSaleInfo(sn) {
*/ */
export function applyReturn(orderItemSn, params) { export function applyReturn(orderItemSn, params) {
return http.request({ return http.request({
url: `/afterSale/save/${orderItemSn}`, url: `/order/afterSale/save/${orderItemSn}`,
method: Method.POST, method: Method.POST,
header: { header: {
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",
@@ -197,7 +210,7 @@ export function applyReturn(orderItemSn, params) {
*/ */
export function fillShipInfo(afterSaleSn, params) { export function fillShipInfo(afterSaleSn, params) {
return http.request({ return http.request({
url: `/afterSale/delivery/${afterSaleSn}`, url: `/order/afterSale/delivery/${afterSaleSn}`,
method: Method.POST, method: Method.POST,
header: { header: {
"Content-Type": "application/x-www-form-urlencoded", "Content-Type": "application/x-www-form-urlencoded",

View File

@@ -23,7 +23,7 @@ export function getArticleCategory(category_type) {
*/ */
export function getArticleDetail(type) { export function getArticleDetail(type) {
return http.request({ return http.request({
url: `/article/type/${type}`, url: `/other/article/get/${type}`,
method: Method.GET, method: Method.GET,
}); });
} }

View File

@@ -1,26 +1,32 @@
/** /**
* 公共API * 公共API
*/ */
import {http, Method} from '@/utils/request.js'; import { http, Method } from "@/utils/request.js";
import api from '@/config/api.js'; import api from "@/config/api.js";
/**
* 获取地区数据
/** * @param id
* 获取地区数据 */
* @param id export function getRegionsById(id = 0) {
*/ return http.request({
export function getRegionsById(id = 0) { url: `${api.common}/common/region/item/${id}`,
return http.request({ method: Method.GET,
url: `${api.common}/region/item/${id}`, message: false,
method: Method.GET, });
message: false, }
});
} // 获取IM接口前缀
export function getIMDetail() {
/** return http.request({
* 文件上传地址 url: `${api.common}/IM`,
* @type {string} method: Method.GET,
*/ message: false,
export const upload =api.common+'/upload/file'; });
}
/**
* 文件上传地址
* @type {string}
*/
export const upload = api.common + "/common/upload/file";

View File

@@ -9,7 +9,7 @@ import { http, Method } from "@/utils/request.js";
*/ */
export function getGoodsMessage(goodsId) { export function getGoodsMessage(goodsId) {
return http.request({ return http.request({
url: `/goods/get/${goodsId}`, url: `/goods/goods/get/${goodsId}`,
method: Method.GET, method: Method.GET,
}); });
} }
@@ -19,7 +19,7 @@ import { http, Method } from "@/utils/request.js";
*/ */
export function getGoodsRelated(params) { export function getGoodsRelated(params) {
return http.request({ return http.request({
url: `/goods/es/related`, url: `/goods/goods/es/related`,
method: Method.GET, method: Method.GET,
params, params,
}); });
@@ -32,7 +32,7 @@ export function getGoodsRelated(params) {
*/ */
export function getGoods(skuId, goodsId) { export function getGoods(skuId, goodsId) {
return http.request({ return http.request({
url: `/goods/sku/${goodsId}/${skuId}`, url: `/goods/goods/sku/${goodsId}/${skuId}`,
method: Method.GET, method: Method.GET,
}); });
} }
@@ -43,7 +43,7 @@ export function getGoodsRelated(params) {
*/ */
export function getGoodsDistribution(distributionId) { export function getGoodsDistribution(distributionId) {
return http.request({ return http.request({
url: `/distribution/bindingDistribution/${distributionId}`, url: `/distribution/distribution/bindingDistribution/${distributionId}`,
method: Method.GET, method: Method.GET,
}); });
} }
@@ -56,7 +56,7 @@ export function getGoodsRelated(params) {
*/ */
export function getGoodsList(params) { export function getGoodsList(params) {
return http.request({ return http.request({
url: "/goods/es", url: "/goods/goods/es",
method: Method.GET, method: Method.GET,
params, params,
}); });
@@ -112,7 +112,7 @@ export function getPlateformTagGoods(tag_id) {
*/ */
export function getCategoryList(id) { export function getCategoryList(id) {
return http.request({ return http.request({
url: `/category/get/${id}`, url: `/goods/category/get/${id}`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
}); });
@@ -126,7 +126,7 @@ export function getCategoryList(id) {
*/ */
export function distribution() { export function distribution() {
return http.request({ return http.request({
url: `/distribution`, url: `/distribution/distribution`,
method: Method.GET, method: Method.GET,
}); });
} }
@@ -136,7 +136,7 @@ export function distribution() {
*/ */
export function applyDistribution(params) { export function applyDistribution(params) {
return http.request({ return http.request({
url: `/distribution`, url: `/distribution/distribution`,
method: Method.POST, method: Method.POST,
params, params,
}); });
@@ -170,7 +170,7 @@ export function cashLog(params) {
*/ */
export function distributionOrderList(params) { export function distributionOrderList(params) {
return http.request({ return http.request({
url: `/distribution/distributionOrder`, url: `/distribution/distribution/distributionOrder`,
method: Method.GET, method: Method.GET,
params params
}); });
@@ -181,7 +181,7 @@ export function distributionOrderList(params) {
*/ */
export function distributionGoods(params) { export function distributionGoods(params) {
return http.request({ return http.request({
url: `/distributionGoods`, url: `/distribution/goods`,
method: Method.GET, method: Method.GET,
params, params,
}); });
@@ -191,7 +191,7 @@ export function distributionGoods(params) {
*/ */
export function checkedDistributionGoods(params) { export function checkedDistributionGoods(params) {
return http.request({ return http.request({
url: `/distributionGoods/checked/${params.id}`, url: `/distribution/goods/checked/${params.id}`,
method: Method.GET, method: Method.GET,
params params
}); });
@@ -202,7 +202,7 @@ export function checkedDistributionGoods(params) {
*/ */
export function getMpCode(params){ export function getMpCode(params){
return http.request({ return http.request({
url:`/mini-program/mp/unlimited`, url:`/passport/connect/miniProgram/mp/unlimited`,
method:Method.GET, method:Method.GET,
params params
}) })
@@ -213,7 +213,7 @@ export function checkedDistributionGoods(params) {
*/ */
export function getMpScene(id){ export function getMpScene(id){
return http.request({ return http.request({
url:`/mini-program/mp/unlimited/scene?id=${id}`, url:`/passport/connect/miniProgram/mp/unlimited/scene?id=${id}`,
method:Method.GET, method:Method.GET,
}) })

View File

@@ -32,7 +32,7 @@ export function getCategory(parent_id = 0) {
*/ */
export function getHotKeywords(count) { export function getHotKeywords(count) {
return http.request({ return http.request({
url: "/goods/hot-words", url: "/goods/goods/hot-words",
method: Method.GET, method: Method.GET,
loading: false, loading: false,
params: { count }, params: { count },
@@ -46,7 +46,7 @@ export function getHotKeywords(count) {
*/ */
export function getFloorData() { export function getFloorData() {
return http.request({ return http.request({
url: `/pageData/getIndex?clientType=H5`, url: `/other/pageData/getIndex?clientType=H5`,
method: "get", method: "get",
}); });
} }
@@ -56,7 +56,7 @@ export function getFloorData() {
*/ */
export function getCategoryIndexData(parentId = 0) { export function getCategoryIndexData(parentId = 0) {
return http.request({ return http.request({
url: `/category/get/${parentId}`, url: `/goods/category/get/${parentId}`,
method: "get", method: "get",
}); });
} }

View File

@@ -8,7 +8,7 @@ import api from "@/config/api.js";
*/ */
export function resetByMobile(params) { export function resetByMobile(params) {
return http.request({ return http.request({
url: `/members/resetByMobile`, url: `/passport/member/resetByMobile`,
method: "POST", method: "POST",
params, params,
}); });
@@ -20,7 +20,7 @@ export function resetByMobile(params) {
*/ */
export function sendMobile(mobile,type='LOGIN') { export function sendMobile(mobile,type='LOGIN') {
return http.request({ return http.request({
url: `${api.common}/sms/${type}/${mobile}`, url: `${api.common}/common/sms/${type}/${mobile}`,
method: "GET", method: "GET",
}); });
} }
@@ -32,7 +32,7 @@ export function sendMobile(mobile,type='LOGIN') {
*/ */
export function smsLogin(params, clientType) { export function smsLogin(params, clientType) {
return http.request({ return http.request({
url: `/members/smsLogin`, url: `/passport/member/smsLogin`,
method: "POST", method: "POST",
data: params, data: params,
header: { header: {
@@ -50,7 +50,7 @@ export function smsLogin(params, clientType) {
export function modifyPass(params) { export function modifyPass(params) {
return http.request({ return http.request({
url: `/members/modifyPass`, url: `/passport/member/modifyPass`,
method: "PUT", method: "PUT",
params, params,
}); });
@@ -61,7 +61,16 @@ export function modifyPass(params) {
*/ */
export function refreshTokenFn(refresh_token) { export function refreshTokenFn(refresh_token) {
return http.request({ return http.request({
url: `/members/refresh/${refresh_token}`, url: `/passport/member/refresh/${refresh_token}`,
method: "GET", method: "GET",
}); });
} }
// 获取密码状态
export function logout () {
return http.request({
url: '/passport/member/logout',
method: "POST",
needToken: true,
})
}

View File

@@ -6,7 +6,7 @@ import { http, Method } from "@/utils/request.js";
*/ */
export function feedBack(params) { export function feedBack(params) {
return http.request({ return http.request({
url: "/feedback", url: "/other/feedback",
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
params, params,
@@ -16,7 +16,7 @@ export function feedBack(params) {
// 提现 // 提现
export function withdrawalApply(params) { export function withdrawalApply(params) {
return http.request({ return http.request({
url: "/members/wallet/withdrawal", url: "/wallet/wallet/withdrawal",
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
params, params,
@@ -30,7 +30,7 @@ export function withdrawalApply(params) {
*/ */
export function payCallback(params) { export function payCallback(params) {
return http.request({ return http.request({
url: `/cashier/result`, url: `/payment/cashier/result`,
method: Method.GET, method: Method.GET,
params, params,
}); });
@@ -117,7 +117,7 @@ export function getPointsData(params) {
*/ */
export function getComments(params) { export function getComments(params) {
return http.request({ return http.request({
url: "/memberEvaluation", url: "/member/evaluation",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -131,7 +131,7 @@ export function getComments(params) {
*/ */
export function getFootprintNum(params) { export function getFootprintNum(params) {
return http.request({ return http.request({
url: "/footprint/getFootprintNum", url: "/member/footprint/getFootprintNum",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -144,7 +144,7 @@ export function getFootprintNum(params) {
*/ */
export function commentsMemberOrder(params) { export function commentsMemberOrder(params) {
return http.request({ return http.request({
url: "/memberEvaluation", url: "/member/evaluation",
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
header: { "content-type": "application/x-www-form-urlencoded" }, header: { "content-type": "application/x-www-form-urlencoded" },
@@ -275,7 +275,7 @@ export function collectionStore(store_id) {
*/ */
export function getUserInfo() { export function getUserInfo() {
return http.request({ return http.request({
url: "/members", url: "/passport/member",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -287,7 +287,7 @@ export function getUserInfo() {
*/ */
export function getUserWallet() { export function getUserWallet() {
return http.request({ return http.request({
url: "/members/wallet", url: "/wallet/wallet",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -300,7 +300,7 @@ export function getUserWallet() {
*/ */
export function saveUserInfo(params) { export function saveUserInfo(params) {
return http.request({ return http.request({
url: "/members/editOwn", url: "/passport/member/editOwn",
method: Method.PUT, method: Method.PUT,
header: { "content-type": "application/x-www-form-urlencoded" }, header: { "content-type": "application/x-www-form-urlencoded" },
needToken: true, needToken: true,
@@ -328,7 +328,7 @@ export function addReceipt(params) {
*/ */
export function getGoodsComments(goodsId, params) { export function getGoodsComments(goodsId, params) {
return http.request({ return http.request({
url: `/memberEvaluation/${goodsId}/goodsEvaluation`, url: `/member/evaluation/${goodsId}/goodsEvaluation`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
params, params,
@@ -341,7 +341,7 @@ export function getGoodsComments(goodsId, params) {
*/ */
export function getGoodsCommentsCount(goodsId) { export function getGoodsCommentsCount(goodsId) {
return http.request({ return http.request({
url: `/memberEvaluation/${goodsId}/evaluationNumber`, url: `/member/evaluation/${goodsId}/evaluationNumber`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
}); });
@@ -365,7 +365,7 @@ export function getNoReadMessageNum() {
*/ */
export function myTrackList(params) { export function myTrackList(params) {
return http.request({ return http.request({
url: `/footprint`, url: `/member/footprint`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -378,7 +378,7 @@ export function myTrackList(params) {
*/ */
export function deleteHistoryListId(ids) { export function deleteHistoryListId(ids) {
return http.request({ return http.request({
url: `/footprint/delByIds/${ids}`, url: `/member/footprint/delByIds/${ids}`,
method: Method.DELETE, method: Method.DELETE,
needToken: true, needToken: true,
}); });

View File

@@ -51,7 +51,7 @@ export function selectedShipMethod(params) {
*/ */
export function getOrderList(params) { export function getOrderList(params) {
return http.request({ return http.request({
url: "/orders", url: "/order/order",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -64,7 +64,7 @@ export function getOrderList(params) {
*/ */
export function getOrderDetail(orderSn) { export function getOrderDetail(orderSn) {
return http.request({ return http.request({
url: `/orders/${orderSn}`, url: `/order/order/${orderSn}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
}); });
@@ -77,7 +77,7 @@ export function getOrderDetail(orderSn) {
*/ */
export function cancelOrder(orderSn, reason) { export function cancelOrder(orderSn, reason) {
return http.request({ return http.request({
url: `/orders/${orderSn}/cancel`, url: `/order/order/${orderSn}/cancel`,
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
header: { "content-type": "application/x-www-form-urlencoded" }, header: { "content-type": "application/x-www-form-urlencoded" },
@@ -91,7 +91,7 @@ export function cancelOrder(orderSn, reason) {
*/ */
export function confirmReceipt(orderSn) { export function confirmReceipt(orderSn) {
return http.request({ return http.request({
url: `/orders/${orderSn}/receiving`, url: `/order/order/${orderSn}/receiving`,
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,
}); });

View File

@@ -4,11 +4,14 @@
import {http, Method} from '@/utils/request.js'; import {http, Method} from '@/utils/request.js';
/** /**
* 获取店铺列表 * 获取店铺列表
* @param params * @param params
*/ */
export function getstoreList(params) { export function getStoreList(params) {
return http.request({ return http.request({
url: '/store', url: '/store',
method: Method.GET, method: Method.GET,
@@ -22,7 +25,7 @@ export function getstoreList(params) {
*/ */
export function getStoreBaseInfo(storeId) { export function getStoreBaseInfo(storeId) {
return http.request({ return http.request({
url: `/store/get/detail/${storeId}`, url: `/store/store/get/detail/${storeId}`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
}); });
@@ -34,7 +37,7 @@ export function getstoreList(params) {
*/ */
export function getStoreCategory(id) { export function getStoreCategory(id) {
return http.request({ return http.request({
url: `/store/label/get/${id}`, url: `/store/store/label/get/${id}`,
method: Method.GET, method: Method.GET,
}); });
} }
@@ -46,7 +49,7 @@ export function getstoreList(params) {
*/ */
export function getLicencePhoto(id) { export function getLicencePhoto(id) {
return http.request({ return http.request({
url: `/store/get/licencePhoto/${id}`, url: `/store/store/get/licencePhoto/${id}`,
method: Method.GET, method: Method.GET,
}); });
} }

View File

@@ -177,7 +177,7 @@ export function createTrade(params) {
*/ */
export function getCashierData(params) { export function getCashierData(params) {
return http.request({ return http.request({
url: "cashier/tradeDetail", url: "payment/cashier/tradeDetail",
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -194,7 +194,7 @@ export function getCashierData(params) {
*/ */
export function initiatePay(paymentMethod, paymentClient, params) { export function initiatePay(paymentMethod, paymentClient, params) {
return http.request({ return http.request({
url: `cashier/pay/${paymentMethod}/${paymentClient}`, url: `payment/cashier/pay/${paymentMethod}/${paymentClient}`,
method: Method.GET, method: Method.GET,
needToken: true, needToken: true,
params, params,
@@ -209,7 +209,7 @@ export function initiatePay(paymentMethod, paymentClient, params) {
*/ */
export function getExpress(orderSn) { export function getExpress(orderSn) {
return http.request({ return http.request({
url: `/orders/getTraces/${orderSn}`, url: `/order/order/getTraces/${orderSn}`,
method: Method.POST, method: Method.POST,
needToken: true, needToken: true,

View File

@@ -1,31 +1,48 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode" <u-popup
:mask-close-able="isClose" :mask="isMask" :border-radius="setup.radius" @close="closeMask()"> class="popup"
v-model="buyMask"
:height="setup.height"
closeable
:mode="setup.mode"
:border-radius="setup.radius"
@close="closeMask()"
>
<!-- 商品 --> <!-- 商品 -->
<view class="goods-box bottom"> <view class="goods-box bottom">
<view class="goods-header"> <view class="goods-header">
<view class="goods-img"> <view class="goods-img">
<u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" <u-image
:src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image> width="200rpx"
border-radius="20"
class="uimage"
height="200rpx"
:src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"
></u-image>
</view> </view>
<view class="goods-skus"> <view class="goods-skus">
<!-- 有活动商品价格 --> <!-- 有活动商品价格 -->
<view class="goods-price " v-if="goodsDetail.promotionPrice"> <view class="goods-price" v-if="goodsDetail.promotionPrice && ((isGroup && buyType === 'PINTUAN') || !isGroup)">
<span> <span v-if="goodsDetail.promotionPrice && !pointDetail">
<span class="goods-price-promotionShow goods-price-bigshow" <span class="goods-price-promotionShow goods-price-bigshow">{{
v-if="goodsDetail.promotionPrice">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span> formatPrice(goodsDetail.promotionPrice)[0]
}}</span>
.{{ formatPrice(goodsDetail.promotionPrice)[1] }} .{{ formatPrice(goodsDetail.promotionPrice)[1] }}
<span></span> </span>
<span v-if="pointDetail.points">
<span class="goods-price-promotionShow goods-price-bigshow">{{
pointDetail.points
}}</span>
积分
</span> </span>
<div class="promotion-box"> <div class="promotion-box">
<span class="goods-price-bigshow">{{ <span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0] formatPrice(goodsDetail.price)[0]
}}</span> }}</span>
.{{ formatPrice(goodsDetail.price)[1] }} .{{ formatPrice(goodsDetail.price)[1] }}
</div> </div>
</view> </view>
<!-- 正常商品的价格 --> <!-- 正常商品的价格 -->
@@ -33,8 +50,8 @@
<span> <span>
<span class="goods-price-bigshow">{{ <span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0] formatPrice(goodsDetail.price)[0]
}}</span> }}</span>
.{{ formatPrice(goodsDetail.price)[1] }} .{{ formatPrice(goodsDetail.price)[1] }}
</span> </span>
</view> </view>
@@ -48,29 +65,63 @@
</view> </view>
</view> </view>
<!-- 商品信息 --> <!-- 商品信息 -->
<view class="goods-skus-box"> <scroll-view class="goods-skus-box" :scroll-y="true">
<!-- 规格 --> <!-- 规格 -->
<view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList"> <view
class="goods-skus-view"
:key="specIndex"
v-for="(spec, specIndex) in formatList"
>
<view class="skus-view-list"> <view class="skus-view-list">
<view class="view-class-title">{{ spec.name }}</view> <view class="view-class-title">{{ spec.name }}</view>
<view :class="{ active: spec_val.value == currentSelceted[specIndex] }" class="skus-view-item"
v-for="(spec_val, spec_index) in spec.values" :key="spec_index" <!-- 正常逻辑 循环出sku -->
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view> <view
v-if="!parentOrder"
:class="{ active: spec_val.value == currentSelceted[specIndex] }"
class="skus-view-item"
v-for="(spec_val, spec_index) in spec.values"
:key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)"
>{{ spec_val.value }}
</view>
<!-- 拼团购买仅筛选出当前拼团类型商品 -->
<view
v-if="parentOrder && spec_val.skuId == goodsDetail.id"
:class="{ active: spec_val.value == currentSelceted[specIndex] }"
class="skus-view-item"
v-for="(spec_val, spec_index) in spec.values"
:key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)"
>{{ spec_val.value }}
</view>
</view> </view>
</view> </view>
<!-- 数量 --> <!-- 数量 -->
<view class="goods-skus-number"> <view class="goods-skus-number">
<view class="view-class-title">数量</view> <view class="view-class-title">数量</view>
<u-number-box :bg-color="numberBox.bgColor" :color="numberBox.color" :input-width="numberBox.width" <u-number-box
:input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num"> :bg-color="numberBox.bgColor"
:max="200"
:color="numberBox.color"
:input-width="numberBox.width"
:input-height="numberBox.height"
:size="numberBox.size"
:min="1"
v-model="num"
>
</u-number-box> </u-number-box>
</view> </view>
</view> </scroll-view>
<!-- 按钮 --> <!-- 按钮 -->
<view class="btns"> <view class="btns">
<view
<view class="box-btn card" v-if="buyType != 'PINTUAN' && goodsDetail.goodsType!='VIRTUAL_GOODS'" class="box-btn card"
@click="addToCartOrBuy('cart')">加入购物车</view> v-if="buyType != 'PINTUAN' && goodsDetail.goodsType != 'VIRTUAL_GOODS'"
@click="addToCartOrBuy('cart')"
>加入购物车</view
>
<view class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view> <view class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view>
</view> </view>
</view> </view>
@@ -80,6 +131,7 @@
<script> <script>
import * as API_trade from "@/api/trade.js"; import * as API_trade from "@/api/trade.js";
import setup from "./popup"; import setup from "./popup";
export default { export default {
data() { data() {
return { return {
@@ -101,26 +153,50 @@ export default {
formatList: [], formatList: [],
currentSelceted: [], currentSelceted: [],
skuList: "", skuList: "",
isMask: false, //是否显示遮罩层
isClose: false, //是否可以点击遮罩关闭 isClose: false, //是否可以点击遮罩关闭
}; };
}, },
props: [ props: {
"goodsDetail", //商品详情 buyMask: {
"buyMask", type: Boolean,
"selectedSku", default: false,
"goodsSpec", },
"addr", isGroup: {
], type: Boolean,
default: false,
},
goodsDetail: {
default: "",
type: null,
},
selectedSku: {
default: "",
type: null,
},
goodsSpec: {
default: "",
type: null,
},
addr: {
default: "",
type: null,
},
pointDetail: {
default: "",
type: null,
},
},
watch: { watch: {
buyType: { buyType: {
handler(val) { handler(val) {
this.buyType = val; if (val) {
this.buyType = val;
}
}, },
immediate: true, immediate: true,
}, },
selectSkuList: { selectSkuList: {
handler(val) { handler(val, oldval) {
this.$emit("changed", val); this.$emit("changed", val);
}, },
deep: true, deep: true,
@@ -142,7 +218,7 @@ export default {
/**点击规格 */ /**点击规格 */
handleClickSpec(val, index, specValue) { handleClickSpec(val, index, specValue) {
this.$set(this.currentSelceted, index, specValue.value); this.currentSelceted[index] = specValue.value;
let selectedSkuId = this.goodsSpec.find((i) => { let selectedSkuId = this.goodsSpec.find((i) => {
let matched = true; let matched = true;
let specValues = i.specValues.filter((j) => j.specName !== "images"); let specValues = i.specValues.filter((j) => j.specName !== "images");
@@ -156,18 +232,44 @@ export default {
return i; return i;
} }
}); });
this.selectSkuList = { if (selectedSkuId?.skuId) {
spec: { this.$set(this.currentSelceted, index, specValue.value);
specName: val.name, this.selectSkuList = {
specValue: specValue.value, spec: {
}, specName: val.name,
data: this.goodsDetail, specValue: specValue.value,
}; },
this.selectName = specValue.value; data: this.goodsDetail,
};
this.selectName = specValue.value;
this.$emit("handleClickSku", { this.$emit("handleClickSku", {
skuId: selectedSkuId.skuId, skuId: selectedSkuId.skuId,
goodsId: this.goodsDetail.goodsId, goodsId: this.goodsDetail.goodsId,
});
} else {
uni.showToast({
title: "暂无该商品!",
duration: 2000,
icon: "none",
});
}
},
/**
* 直接购买
*/
buy(data) {
API_trade.addToCart(data).then((res) => {
if (res.data.success) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${
data.cartType
}&addr=${""}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
}); });
}, },
@@ -214,42 +316,26 @@ export default {
uni.navigateTo({ uni.navigateTo({
url: `/pages/order/fillorder?way=${data.cartType}&addr=${ url: `/pages/order/fillorder?way=${data.cartType}&addr=${
this.addr.id || "" this.addr.id || ""
}&parentOrder=${encodeURIComponent( }&parentOrder=${encodeURIComponent(JSON.stringify(this.parentOrder))}`,
JSON.stringify(this.parentOrder)
)}`,
}); });
} }
}); });
} }
}, },
/**
* 直接购买
*/
buy(data) {
API_trade.addToCart(data).then((res) => {
if (res.data.success) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${
data.cartType
}&addr=${""}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
});
},
formatSku(list) { formatSku(list) {
// 格式化数据 // 格式化数据
if (!Array.isArray(list)) return false;
let arr = [{}]; let arr = [{}];
if(!Array.isArray(list)){
return false
}
list.forEach((item, index) => { list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => { item.specValues.forEach((spec, specIndex) => {
let name = spec.specName; let name = spec.specName;
let values = { let values = {
value: spec.specValue, value: spec.specValue,
quantity: item.quantity, quantity: item.quantity,
skuId: item.skuId,
}; };
if (name === "images") { if (name === "images") {
return; return;
@@ -259,7 +345,9 @@ export default {
if ( if (
arrItem.name == name && arrItem.name == name &&
arrItem.values && arrItem.values &&
!arrItem.values.find((i) => i.value === values.value) !arrItem.values.find((i) => {
return i.value === values.value;
})
) { ) {
arrItem.values.push(values); arrItem.values.push(values);
} }
@@ -276,16 +364,20 @@ export default {
}); });
}); });
}); });
arr.shift(); arr.shift();
this.formatList = arr; this.formatList = arr;
list.forEach((item) => { list.forEach((item) => {
// 默认选中
if (item.skuId === this.goodsDetail.id) { if (item.skuId === this.goodsDetail.id) {
item.specValues item.specValues
.filter((i) => i.specName !== "images") .filter((i) => i.specName !== "images")
.forEach((value, _index) => { .forEach((value, _index) => {
this.currentSelceted[_index] = value.specValue; this.currentSelceted[_index] = value.specValue;
this.selectName = value.specValue; this.selectName = value.specValue;
this.selectSkuList = { this.selectSkuList = {
spec: value, spec: value,
data: this.goodsDetail, data: this.goodsDetail,
@@ -295,13 +387,12 @@ export default {
}); });
this.skuList = list; this.skuList = list;
// console.log(" this.skuList", this.skuList)
}, },
}, },
mounted() { mounted() {
this.formatSku(this.goodsSpec); this.formatSku(this.goodsSpec);
console.log(this.goodsDetail);
}, },
}; };
</script> </script>

View File

@@ -1,20 +1,21 @@
<template> <template>
<view class="serach"> <view class="serach">
<view class="left-box" @tap="onClickLeft"> <view class="left-box" @tap="onClickLeft">
<uni-icons style="line-height:70rpx" type="back" size="24" /> <u-icon name="arrow-left" size="40" color="#666"></u-icon>
</view> </view>
<view class="content" :style="{ 'border-radius': radius + 'px' }"> <view class="content" :style="{ 'border-radius': radius + 'px' }">
<!-- HM修改 增加进入输入状态的点击范围 --> <!-- HM修改 增加进入输入状态的点击范围 -->
<view class="content-box" :class="{ center: mode === 2 }"> <view class="content-box" :class="{ center: mode === 2 }">
<u-icon name="search" size="32" style="padding:0 15rpx;"></u-icon> <u-icon name="search" size="32" style="padding:0 15rpx;"></u-icon>
<!-- HM修改 增加placeholder input confirm-type confirm--> <!-- HM修改 增加placeholder input confirm-type confirm-->
<input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color" @input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input" <input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color"
@input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input"
:class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" /> :class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" />
<u-icon name="close" v-if="isDelShow" style="padding:0 30rpx;" @click="clear"></u-icon> <u-icon name="close" v-if="isDelShow" style="padding:0 30rpx;" @click="clear"></u-icon>
</view> </view>
<view v-show="(active && show && button === 'inside') || (isDelShow && button === 'inside')" class="serachBtn" @click="search">搜索</view>
</view> </view>
<view v-if="button === 'outside'" class="button" :class="{ active: show || active }"> <view class="button active" >
<view v-if="isShowSeachGoods !=true" class="button-item"> <view v-if="isShowSeachGoods !=true" class="button-item">
<div @click="out()">取消</div> <div @click="out()">取消</div>
</view> </view>
@@ -28,14 +29,7 @@
</template> </template>
<script> <script>
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
import uniIcons from "../uni-icons/uni-icons.vue";
export default { export default {
components: {
uniStatusBar,
uniIcons,
},
props: { props: {
mode: { mode: {
value: Number, value: Number,
@@ -50,15 +44,6 @@ export default {
type: String, type: String,
default: "", default: "",
}, },
button: {
value: String,
default: "outside",
},
//
show: {
value: Boolean,
default: true,
},
// 默认半径为60 // 默认半径为60
radius: { radius: {
value: String, value: String,
@@ -131,7 +116,6 @@ export default {
this.$emit("input", ""); this.$emit("input", "");
//this.$emit('search', '');//HM修改 清空内容时候不进行搜索 //this.$emit('search', '');//HM修改 清空内容时候不进行搜索
}, },
/** /**
* 回退到上一级 * 回退到上一级
@@ -145,7 +129,7 @@ export default {
*/ */
search() { search() {
if (!this.inputVal) { if (!this.inputVal) {
if (!this.show && this.searchName == "取消") { if (this.searchName == "取消") {
uni.hideKeyboard(); uni.hideKeyboard();
this.isFocus = false; this.isFocus = false;
this.active = false; this.active = false;
@@ -175,6 +159,9 @@ export default {
font-size: $uni-font-size-base; font-size: $uni-font-size-base;
.left-box { .left-box {
display: flex;
align-items: center;
justify-content: center;
width: 15%; width: 15%;
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
text-align: center; text-align: center;
@@ -225,19 +212,6 @@ export default {
} }
} }
} }
.serachBtn {
height: 100%;
flex-shrink: 0;
padding: 0 30rpx;
//HM修改 按钮背景色
background: linear-gradient(to right, grey, grey);
//background: $uni-color-success;
line-height: 60rpx;
color: #eee;
//border-left: 1px #ccc solid; //HM修改 去掉边框
transition: all 0.3s;
}
} }
.button { .button {

View File

@@ -1,241 +0,0 @@
<template>
<div class="dropdown-item">
<!-- selected -->
<view class="dropdown-item__selected" @click="changePopup">
<slot name="title" v-if="$slots.title"></slot>
<block v-else>
<view class="selected__name">
{{title ? title : selectItem.text}}
</view>
<!-- <view class="selected__icon"
:class="showClass === 'show'? 'up' : 'down'"
>
<span class="iconfont">&#xe851;</span>
</view> -->
</block>
</view>
<view class="dropdown-item__content" :style="{top: contentTop + 'px'}" v-if="showList">
<!-- dropdown -->
<view :class="['list', showClass]">
<slot v-if="$slots.default"></slot>
<block v-else>
<view class="list__option" v-for="(item, index) in list" :key="index" @click="choose(item)">
<view>{{item.text}}</view>
<icon v-if="item.value === value" type="success_no_circle" size="26" />
</view>
</block>
</view>
<!-- dropdown-mask -->
<!-- @touchmove 禁止滑动 -->
<view @touchmove.stop.prevent="moveHandle" :class="['dropdown-mask', showClass]" v-if="showList" @click="closePopup"></view>
</view>
</div>
</template>
<script>
export default {
components: {},
props: {
value: [Number, String, Object],
list: {
type: Array,
default: () => {
return []
}
},
title: [Number, String],
contentTopReduse: {
type: Number,
default: 0
}
},
data() {
return {
showList: "",
showClass: '',
selectItem: {},
contentTop: 0
}
},
watch: {},
mounted() {
this.showList = this.active;
this.selectItem = this.list[this.value];
// document.addEventListener('click', e => {
// //this.$el 可以获取当前组件的容器节点
// if (!this.$el.contains(e.target)) {
// console.log('change');
// this.close()
// }
// });
},
methods: {
// 禁止滑动
moveHandle() {},
choose(item) {
this.selectItem = item
this.$emit('input', item.value)
this.closePopup()
},
changePopup() {
if (this.showList) {
this.closePopup()
} else {
this.openPopup()
}
},
openPopup() {
// this.$parent -> dropdown-menu
this.$parent.$emit('close')
this.showList = true
this.$nextTick(() => {
this.getElementData('.dropdown-item__selected', (data) => {
this.contentTop = data[0].bottom - this.contentTopReduse;
this.showClass = 'show'
})
})
},
closePopup() {
this.showClass = ''
setTimeout(() => {
this.showList = false
}, 300)
},
close() {
this.showClass = ''
this.showList = false
},
getElementData(el, callback) {
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => {
callback(data[0]);
});
}
}
}
</script>
<style lang="scss">
@font-face {
font-family: 'iconfont';
/* project id 1564327 */
src: url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.eot');
src: url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.eot?#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.woff2') format('woff2'),
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.woff') format('woff'),
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.ttf') format('truetype'),
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.svg#iconfont') format('svg');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 28rpx;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.line {
position: absolute;
height: 3px;
width: 100px;
background: #1abc9c;
}
.dropdown-item {
position: relative;
&__selected {
position: relative;
display: flex;
align-items: center;
background: transparent;
// padding: 10rpx;
box-sizing: border-box;
justify-content: center;
.selected__name {
font-size: 32rpx;
white-space: nowrap;
position: relative;
}
.selected__icon {
margin-left: 8rpx;
&.down {
transition: transform .3s;
transform: rotateZ(0);
}
&.up {
transition: transform .3s;
transform: rotateZ(-180deg);
}
}
}
&__content {
position: fixed;
left: 0;
right: 0;
overflow: hidden;
top: 0;
bottom: 0;
z-index: 10;
.list {
max-height: 400px;
overflow-y: auto;
position: absolute;
left: 0;
right: 0;
z-index: 3;
background: #fff;
transform: translateY(-100%);
transition: all .3s;
&.show {
transform: translateY(0);
}
&__option {
font-size: 32rpx;
padding: 26rpx 28rpx;
display: flex;
justify-content: space-between;
&:not(:last-child) {
border-bottom: 1rpx solid #DDDDDD;
}
}
}
.dropdown-mask {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
transition: all .3s;
z-index: 2;
&.show {
background: rgba(0, 0, 0, 0.5);
}
}
}
&:not(:last-child):after {
content: ' ';
position: absolute;
width: 2rpx;
top: 36rpx;
bottom: 36rpx;
right: 0;
background: $uni-border-color;
}
}
</style>

View File

@@ -1,35 +0,0 @@
<template>
<div class="dropdown-menu">
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
}
},
mounted() {
this.$on('close', this.closeDropdown)
},
methods: {
closeDropdown() {
this.$children.forEach(item =>{
item.close();
})
}
}
}
</script>
<style lang="scss">
.dropdown-menu {
display: flex;
overflow: auto;
white-space: nowrap;
}
dropdown-item {
flex: 1;
}
</style>

View File

@@ -1,132 +0,0 @@
export default {
"pulldown": "\ue588",
"refreshempty": "\ue461",
"back": "\ue471",
"forward": "\ue470",
"more": "\ue507",
"more-filled": "\ue537",
"scan": "\ue612",
"qq": "\ue264",
"weibo": "\ue260",
"weixin": "\ue261",
"pengyouquan": "\ue262",
"loop": "\ue565",
"refresh": "\ue407",
"refresh-filled": "\ue437",
"arrowthindown": "\ue585",
"arrowthinleft": "\ue586",
"arrowthinright": "\ue587",
"arrowthinup": "\ue584",
"undo-filled": "\ue7d6",
"undo": "\ue406",
"redo": "\ue405",
"redo-filled": "\ue7d9",
"bars": "\ue563",
"chatboxes": "\ue203",
"camera": "\ue301",
"chatboxes-filled": "\ue233",
"camera-filled": "\ue7ef",
"cart-filled": "\ue7f4",
"cart": "\ue7f5",
"checkbox-filled": "\ue442",
"checkbox": "\ue7fa",
"arrowleft": "\ue582",
"arrowdown": "\ue581",
"arrowright": "\ue583",
"smallcircle-filled": "\ue801",
"arrowup": "\ue580",
"circle": "\ue411",
"eye-filled": "\ue568",
"eye-slash-filled": "\ue822",
"eye-slash": "\ue823",
"eye": "\ue824",
"flag-filled": "\ue825",
"flag": "\ue508",
"gear-filled": "\ue532",
"reload": "\ue462",
"gear": "\ue502",
"hand-thumbsdown-filled": "\ue83b",
"hand-thumbsdown": "\ue83c",
"hand-thumbsup-filled": "\ue83d",
"heart-filled": "\ue83e",
"hand-thumbsup": "\ue83f",
"heart": "\ue840",
"home": "\ue500",
"info": "\ue504",
"home-filled": "\ue530",
"info-filled": "\ue534",
"circle-filled": "\ue441",
"chat-filled": "\ue847",
"chat": "\ue263",
"mail-open-filled": "\ue84d",
"email-filled": "\ue231",
"mail-open": "\ue84e",
"email": "\ue201",
"checkmarkempty": "\ue472",
"list": "\ue562",
"locked-filled": "\ue856",
"locked": "\ue506",
"map-filled": "\ue85c",
"map-pin": "\ue85e",
"map-pin-ellipse": "\ue864",
"map": "\ue364",
"minus-filled": "\ue440",
"mic-filled": "\ue332",
"minus": "\ue410",
"micoff": "\ue360",
"mic": "\ue302",
"clear": "\ue434",
"smallcircle": "\ue868",
"close": "\ue404",
"closeempty": "\ue460",
"paperclip": "\ue567",
"paperplane": "\ue503",
"paperplane-filled": "\ue86e",
"person-filled": "\ue131",
"contact-filled": "\ue130",
"person": "\ue101",
"contact": "\ue100",
"images-filled": "\ue87a",
"phone": "\ue200",
"images": "\ue87b",
"image": "\ue363",
"image-filled": "\ue877",
"location-filled": "\ue333",
"location": "\ue303",
"plus-filled": "\ue439",
"plus": "\ue409",
"plusempty": "\ue468",
"help-filled": "\ue535",
"help": "\ue505",
"navigate-filled": "\ue884",
"navigate": "\ue501",
"mic-slash-filled": "\ue892",
"search": "\ue466",
"settings": "\ue560",
"sound": "\ue590",
"sound-filled": "\ue8a1",
"spinner-cycle": "\ue465",
"download-filled": "\ue8a4",
"personadd-filled": "\ue132",
"videocam-filled": "\ue8af",
"personadd": "\ue102",
"upload": "\ue402",
"upload-filled": "\ue8b1",
"starhalf": "\ue463",
"star-filled": "\ue438",
"star": "\ue408",
"trash": "\ue401",
"phone-filled": "\ue230",
"compose": "\ue400",
"videocam": "\ue300",
"trash-filled": "\ue8dc",
"download": "\ue403",
"chatbubble-filled": "\ue232",
"chatbubble": "\ue202",
"cloud-download": "\ue8e4",
"cloud-upload-filled": "\ue8e5",
"cloud-upload": "\ue8e6",
"cloud-download-filled": "\ue8e9",
"headphones":"\ue8bf",
"store":"\ue609"
}

File diff suppressed because one or more lines are too long

View File

@@ -1,25 +0,0 @@
<template>
<view :style="{ height: statusBarHeight }" class="uni-status-bar">
<slot />
</view>
</template>
<script>
var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
export default {
name: 'UniStatusBar',
data() {
return {
statusBarHeight: statusBarHeight
}
}
}
</script>
<style lang="scss" scoped>
.uni-status-bar {
width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
</style>

View File

@@ -1,39 +1,87 @@
<template> <template>
<view> <view>
<view v-if="!hid" class="flex-row-center" :style="{ top: scHight }" style="width: 750rpx; position: fixed; z-index: 100; left: 0"> <view
<view class="flex-column-center" style="background-color: #fcfcfc; padding: 30rpx; border-radius: 10rpx"> v-if="!hid"
<movable-area class="flex" style="width: 100%" animation="false" :style="{ height: originalHeight }"> class="flex-row-center"
<movable-view scale-value="1" animation="false" damping="5000" :x="moveX" :style="{ :style="{ top: scHight }"
style="width: 750rpx; position: fixed; z-index: 100; left: 0"
>
<view
class="flex-column-center"
style="background-color: #fcfcfc; padding: 30rpx; border-radius: 10rpx"
>
<movable-area
class="flex"
style="width: 100%"
animation="false"
:style="{ height: originalHeight }"
>
<movable-view
scale-value="1"
animation="false"
damping="5000"
:x="moveX"
:style="{
height: sliderHeight, height: sliderHeight,
width: sliderWidth, width: sliderWidth,
'z-index': 101, 'z-index': 101,
}" direction="horizontal"> }"
<image :src="imgbk" class="image" mode="aspectFit" :style="{ direction="horizontal"
>
<image
:src="imgbk"
class="image"
mode="aspectFit"
:style="{
height: sliderHeight, height: sliderHeight,
width: sliderWidth, width: sliderWidth,
'margin-top': imgbKH, 'margin-top': imgbKH,
}"></image> }"
></image>
</movable-view> </movable-view>
<image :src="img" mode="aspectFit" :style="{ height: originalHeight, width: originalWidth }" style="border-radius: 10rpx"></image> <image
:src="img"
mode="aspectFit"
:style="{ height: originalHeight, width: originalWidth }"
style="border-radius: 10rpx"
></image>
</movable-area> </movable-area>
<movable-area class="flex-row-start" style=" <movable-area
class="flex-row-start"
style="
width: 100%; width: 100%;
background-color: #efefef; background-color: #efefef;
height: 80rpx; height: 80rpx;
border-radius: 40rpx; border-radius: 40rpx;
margin-top: 30rpx; margin-top: 30rpx;
"> "
<movable-view scale-value="1" animation="false" damping="50" :x="movePv" class="flex-row-center" style=" >
<movable-view
scale-value="1"
animation="false"
damping="50"
:x="movePv"
class="flex-row-center"
style="
border-radius: 50%; border-radius: 50%;
height: 100rpx; height: 100rpx;
width: 100rpx; width: 100rpx;
background-color: #ffffff; background-color: #ffffff;
border: 2rpx solid #e3e3e3; border: 2rpx solid #e3e3e3;
margin-top: -13rpx; margin-top: -13rpx;
" direction="horizontal" @change="moveChange" @touchend="end"> "
<view :class="endLoad ? 'cuIcon-right' : 'cuIcon-loading turn-load'" class="loadIcon" style=""> direction="horizontal"
</view> @change="moveChange"
@touchend="end"
>
<u-icon
:color="mainColor"
size="40"
v-if="endLoad"
name="arrow-right"
></u-icon>
<u-icon :color="mainColor" size="40" v-else name="reload"></u-icon>
</movable-view> </movable-view>
<text style="padding-left: 140rpx" :style="{ color: col }">{{ <text style="padding-left: 140rpx" :style="{ color: col }">{{
@@ -41,15 +89,20 @@
}}</text> }}</text>
</movable-area> </movable-area>
<view class="flex-row-around padding-top" style="width: 100%"> <view class="flex-row-around padding-top" style="width: 100%">
<view @click="hide" class="cuIcon-close" style="font-size: 50rpx; color: #e25915"> <u-icon
</view> @click="hide"
:color="mainColor"
size="40"
name="close"
></u-icon>
<text class="cu-tag bg-cyan round" @click="getCode">刷新拼图</text> <text class="cu-tag bg-cyan round" @click="getCode">刷新拼图</text>
<text class="my-neirong-sm cuIcon-safe" style="color: #c1c1c1">Lili-FRAMEWORK</text> <text class="my-neirong-sm cuIcon-safe" style="color: #c1c1c1"
>Lili-FRAMEWORK</text
>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
@@ -90,6 +143,7 @@ export default {
}, },
data() { data() {
return { return {
mainColor: this.$mainColor,
flage: false, flage: false,
key: "", //key key: "", //key
vsrtx: "点击进行验证", //按钮提示语 vsrtx: "点击进行验证", //按钮提示语
@@ -144,7 +198,7 @@ export default {
storage.setUuid(uuid.v1()); storage.setUuid(uuid.v1());
} }
uni.request({ uni.request({
url: api.common + "/slider/" + this.business, url: api.common + "/common/slider/" + this.business,
header: { header: {
uuid: storage.getUuid(), uuid: storage.getUuid(),
}, },
@@ -179,7 +233,7 @@ export default {
method: "POST", method: "POST",
url: url:
api.common + api.common +
"/slider/" + "/common/slider/" +
this.business + this.business +
"?xPos=" + "?xPos=" +
parseInt(this.moveCode * this.tl), parseInt(this.moveCode * this.tl),
@@ -252,10 +306,6 @@ export default {
.border-index { .border-index {
border: 1rpx solid $main-color; border: 1rpx solid $main-color;
} }
.loadIcon {
color: $main-color;
font-size: 40rpx;
}
.status_bar { .status_bar {
height: var(--status-bar-height); height: var(--status-bar-height);

View File

@@ -0,0 +1,278 @@
<template>
<view class="xt__verify-code">
<!-- 输入框 -->
<input
id="xt__input"
:value="code"
class="xt__input"
:focus="isFocus"
:password="isPassword"
:type="inputType"
:maxlength="size"
@input="input"
@focus="inputFocus"
@blur="inputBlur"
/>
<!-- 光标 -->
<view
id="xt__cursor"
v-if="cursorVisible && type !== 'middle'"
class="xt__cursor"
:style="{ left: codeCursorLeft[code.length] + 'px', height: cursorHeight + 'px', backgroundColor: cursorColor }"
></view>
<!-- 输入框 - -->
<view id="xt__input-ground" class="xt__input-ground">
<template v-for="(item, index) in size">
<view
:key="index"
:style="{ borderColor: code.length === index && cursorVisible ? boxActiveColor : boxNormalColor }"
:class="['xt__box', `xt__box-${type + ''}`, `xt__box::after`]"
>
<view :style="{ borderColor: boxActiveColor }" class="xt__middle-line" v-if="type === 'middle' && !code[index]"></view>
<text class="xt__code-text">{{ code[index] | codeFormat(isPassword) }}</text>
</view>
</template>
</view>
</view>
</template>
<script>
/**
* @description 输入验证码组件
* @property {string} type = [box|middle|bottom] - 显示类型 默认box -eg:bottom
* @property {string} inputType = [text|number] - 输入框类型 默认number -eg:number
* @property {number} size = [4|6] - 支持的验证码数量 默认6 -eg:6
* @property {boolean} isFocus - 是否立即聚焦 默认true
* @property {boolean} isPassword - 是否以密码形式显示 默认false -eg:false
* @property {string} cursorColor - 光标颜色 默认:#cccccc
* @property {string} boxNormalColor - 光标未聚焦到的框的颜色 默认:#cccccc
* @property {string} boxActiveColor - 光标聚焦到的框的颜色 默认:#000000
* @event {Function(data)} confirm - 输入完成
*/
export default {
name: 'xt-verify-code',
props: {
value: {
type: String,
default: () => ''
},
type: {
type: String,
default: () => 'box'
},
inputType: {
type: String,
default: () => 'number'
},
size: {
type: Number,
default: () => 6
},
isFocus: {
type: Boolean,
default: () => true
},
isPassword: {
type: Boolean,
default: () => false
},
cursorColor: {
type: String,
default: () => '#cccccc'
},
boxNormalColor: {
type: String,
default: () => '#cccccc'
},
boxActiveColor: {
type: String,
default: () => '#000000'
}
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
cursorVisible: false,
cursorHeight: 35,
code: '', // 输入的验证码
codeCursorLeft: [] // 向左移动的距离数组
};
},
created() {
this.cursorVisible = this.isFocus;
},
mounted() {
this.init();
},
methods: {
/**
* @description 初始化
*/
init() {
this.getCodeCursorLeft();
this.setCursorHeight();
},
/**
* @description 获取元素节点
* @param {string} elm - 节点的id、class 相当于 document.querySelect的参数 -eg: #id
* @param {string} type = [single|array] - 单个元素获取多个元素 默认是单个元素
* @param {Function} callback - 回调函数
*/
getElement(elm, type = 'single', callback) {
uni
.createSelectorQuery()
.in(this)
[type === 'array' ? 'selectAll' : 'select'](elm)
.boundingClientRect()
.exec(data => {
callback(data[0]);
});
},
/**
* @description 计算光标的高度
*/
setCursorHeight() {
this.getElement('.xt__box', 'single', boxElm => {
this.cursorHeight = boxElm.height * 0.6;
});
},
/**
* @description 获取光标在每一个box的left位置
*/
getCodeCursorLeft() {
// 获取父级框的位置信息
this.getElement('#xt__input-ground', 'single', parentElm => {
const parentLeft = parentElm.left;
// 获取各个box信息
this.getElement('.xt__box', 'array', elms => {
this.codeCursorLeft = [];
elms.forEach(elm => {
this.codeCursorLeft.push(elm.left - parentLeft + elm.width / 2);
});
});
});
},
// 输入框输入变化的回调
input(e) {
const value = e.detail.value;
this.cursorVisible = value.length !== this.size;
this.$emit('input', value);
this.inputSuccess(value);
},
// 输入完成回调
inputSuccess(value) {
if (value.length === this.size) {
this.$emit('confirm', value);
}
},
// 输入聚焦
inputFocus() {
this.cursorVisible = this.code.length !== this.size;
},
// 输入失去焦点
inputBlur() {
this.cursorVisible = false;
}
},
watch: {
value(val) {
this.code = val;
}
},
filters: {
codeFormat(val, isPassword) {
let value = '';
if (val) {
value = isPassword ? '*' : val;
}
return value;
}
}
};
</script>
<style lang="scss" scoped>
.xt__verify-code {
position: relative;
width: 100%;
box-sizing: border-box;
.xt__input {
height: 100%;
width: 200%;
position: absolute;
left: -100%;
z-index: 1;
}
.xt__cursor {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: inline-block;
width: 2px;
animation-name: cursor;
animation-duration: 0.8s;
animation-iteration-count: infinite;
}
.xt__input-ground {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
box-sizing: border-box;
.xt__box {
position: relative;
display: inline-block;
width: 76rpx;
height: 112rpx;
&-bottom {
border-bottom-width: 2px;
border-bottom-style: solid;
}
&-box {
border-width: 2px;
border-style: solid;
}
&-middle {
border: none;
}
.xt__middle-line {
position: absolute;
top: 50%;
left: 50%;
width: 50%;
transform: translate(-50%, -50%);
border-bottom-width: 2px;
border-bottom-style: solid;
}
.xt__code-text {
position: absolute;
top: 50%;
left: 50%;
font-size:52rpx;
transform: translate(-50%, -50%);
}
}
}
}
@keyframes cursor {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>

View File

@@ -4,8 +4,11 @@
*/ */
// 开发环境 // 开发环境
const dev = { const dev = {
common: "https://common-api.pickmall.cn", // common: "https://common-api.pickmall.cn",
buyer: "https://buyer-api.pickmall.cn", // buyer: "https://buyer-api.pickmall.cn",
common: "http://192.168.111:8890",
buyer: "http://192.168.111:8888",
}; };
// 生产环境 // 生产环境

View File

@@ -2,8 +2,8 @@
"name" : "lili商城", "name" : "lili商城",
"appid" : "__UNI__C100675", "appid" : "__UNI__C100675",
"description" : "", "description" : "",
"versionName" : "4.0.42", "versionName" : "4.0.49",
"versionCode" : 4000042, "versionCode" : 4000049,
"transformPx" : false, "transformPx" : false,
"app-plus" : { "app-plus" : {
"compatible" : { "compatible" : {
@@ -72,7 +72,8 @@
"NSPhotoLibraryAddUsageDescription" : "保存商品图片到本地", "NSPhotoLibraryAddUsageDescription" : "保存商品图片到本地",
"NSFaceIDUsageDescription" : "使用面部识别进行登录", "NSFaceIDUsageDescription" : "使用面部识别进行登录",
"NSCameraUsageDescription" : "需要用与扫描二维码和商品评论图片拍摄", "NSCameraUsageDescription" : "需要用与扫描二维码和商品评论图片拍摄",
"NSLocationAlwaysAndWhenInUseUsageDescription" : "位置信息将用于高德地图的效果展示" "NSLocationAlwaysAndWhenInUseUsageDescription" : "位置信息将用于高德地图的效果展示",
"NSMicrophoneUsageDescription" : "用户上传视频时需使用音频信息"
}, },
"urltypes" : "lilishop" "urltypes" : "lilishop"
}, },

View File

@@ -10,7 +10,8 @@
"style": { "style": {
"navigationBarTitleText": "首页", "navigationBarTitleText": "首页",
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom", // 隐藏系统导航栏
"navigationBarTextStyle": "black" "navigationBarTextStyle": "black",
"enablePullDownRefresh":true
} }
}, },
@@ -18,9 +19,8 @@
"path": "pages/tabbar/cart/cartList", "path": "pages/tabbar/cart/cartList",
"style": { "style": {
"navigationBarTitleText": "购物车", "navigationBarTitleText": "购物车",
"navigationStyle": "custom", "navigationBarBackgroundColor": "#fff",
"enablePullDownRefresh":true //实现下拉刷新样式
"navigationBarBackgroundColor": "#fff"
} }
}, { }, {
@@ -42,9 +42,16 @@
"style": { "style": {
"navigationBarTitleText": "搜索", "navigationBarTitleText": "搜索",
"navigationStyle": "custom", "navigationStyle": "custom",
"app-plus": { "app-plus": {
//app页面不显示滚动条 //app页面不显示滚动条
"scrollIndicator": "none" "scrollIndicator": "none",
"bottom": "0",
"contentAdjust": "false",
"bounce": "none",
"safearea": {
"bottom": "none"
}
} }
} }
}, { }, {
@@ -80,21 +87,14 @@
"style": { "style": {
"navigationBarTitleText": "我的足迹", "navigationBarTitleText": "我的足迹",
"enablePullDownRefresh": true, "enablePullDownRefresh": true,
"app-plus": { "navigationStyle": "custom"
"titleNView": {
"buttons": [{
"text": "编辑",
"fontSize": "14"
}]
}
}
} }
}, { }, {
"path": "myCollect", "path": "myCollect",
"style": { "style": {
"navigationBarTitleText": "收藏", "navigationBarTitleText": "收藏",
"enablePullDownRefresh": true, //下拉刷新 "enablePullDownRefresh": true, //下拉刷新
"navigationStyle": "custom",
"app-plus": { "app-plus": {
"scrollIndicator": "none" "scrollIndicator": "none"
} }
@@ -340,6 +340,12 @@
"navigationBarTitleText": "", "navigationBarTitleText": "",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
},{
"path": "shopList",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},{ },{
"path": "licencePhoto", "path": "licencePhoto",
"style": { "style": {
@@ -445,14 +451,7 @@
{ {
"root": "pages/promotion", "root": "pages/promotion",
"pages": [{ "pages": [ {
"path": "sale",
"style": {
"navigationBarTitleText": "特惠推荐",
"navigationStyle": "custom"
}
}, {
"path": "seckill", "path": "seckill",
"style": { "style": {
"navigationBarTitleText": "限时抢购", "navigationBarTitleText": "限时抢购",
@@ -469,19 +468,11 @@
"style": { "style": {
"navigationBarTitleText": "拼团活动", "navigationBarTitleText": "拼团活动",
"navigationStyle": "custom", // 隐藏系统导航栏 "navigationStyle": "custom", // 隐藏系统导航栏
"app-plus": { "app-plus": {
// 将回弹属性关掉 // 将回弹属性关掉
"bounce": "none" "bounce": "none"
} }
} }
}, {
"path": "recommend",
"style": {
"navigationBarTitleText": "人气推荐",
"navigationStyle": "custom"
}
},{ },{
"path": "lives", "path": "lives",
"style": { "style": {

View File

@@ -28,7 +28,7 @@
<span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span> <span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span>
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view> <view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view>
</view> </view>
<view>有效期至{{ item.endTime.split(" ")[0] }}</view> <view v-if="item.endTime">有效期至:{{ item.endTime.split(" ")[0] }}</view>
</view> </view>
<view class="receive" @click="receive(item)"> <view class="receive" @click="receive(item)">
<text>点击</text><br /> <text>点击</text><br />

View File

@@ -1,12 +1,22 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<u-tabs :list="list" :is-scroll="false" :active-color="lightColor" :current="current" @change="(i)=>{current = i}"> <u-tabs
:list="list"
:is-scroll="false"
:active-color="lightColor"
:current="current"
@change="
(i) => {
current = i;
}
"
>
</u-tabs> </u-tabs>
<div class="empty" v-if="couponsList.length <= 0"> <div class="empty" v-if="couponsList.length <= 0">
<u-empty text="暂无优惠券" mode="coupon"></u-empty> <u-empty text="暂无优惠券" mode="coupon"></u-empty>
</div> </div>
<view class="coupon-item" v-for="(item, index) in couponsList" :key="index" > <view class="coupon-item" v-for="(item, index) in couponsList" :key="index">
<view class="left"> <view class="left">
<view class="wave-line"> <view class="wave-line">
<view class="wave" v-for="(item, index) in 12" :key="index"></view> <view class="wave" v-for="(item, index) in 12" :key="index"></view>
@@ -26,15 +36,27 @@
<view v-if="item.scopeType"> <view v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span> <span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span>
<span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span> <span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span>
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view> <view v-else
>{{
item.storeName == "platform" ? "全平台" : item.storeName + "店铺"
}}使用</view
>
</view> </view>
<view class="reason" v-if="item.reason">{{item.reason}}</view> <view class="reason" v-if="item.reason">{{ item.reason }}</view>
<view class="end-time">有效期至:{{item.endTime}}</view> <view class="end-time">有效期至:{{ item.endTime }}</view>
</view> </view>
<view class="receive" v-if="current ==0" @click="clickWay(item)"> <view
class="receive"
v-if="current == 0 && !routerVal.selectedCoupon.includes(item.id)"
@click="clickWay(item)"
>
<text>立即</text><br /> <text>立即</text><br />
<text>使用</text> <text>使用</text>
</view> </view>
<view class="used" v-else @click="clickWay(item)">
<text>取消</text><br />
<text>使用</text>
</view>
<view class="bg-quan"></view> <view class="bg-quan"></view>
</view> </view>
</view> </view>
@@ -69,6 +91,9 @@ export default {
routerVal: "", //上级传参 routerVal: "", //上级传参
}; };
}, },
onLoad(options) {
this.routerVal = options;
},
watch: { watch: {
current(val) { current(val) {
console.log(this.$store.state.cantUseCoupons); console.log(this.$store.state.cantUseCoupons);
@@ -80,6 +105,7 @@ export default {
mounted() { mounted() {
this.init(); this.init();
console.log(this.routerVal);
}, },
methods: { methods: {
@@ -95,7 +121,7 @@ export default {
clickWay(coupon) { clickWay(coupon) {
useCoupon({ useCoupon({
memberCouponId: coupon.id, memberCouponId: coupon.id,
used: true, used: !this.routerVal.selectedCoupon.includes(coupon.id),
way: this.routerVal.way, way: this.routerVal.way,
}).then((res) => { }).then((res) => {
if (res.data.success) { if (res.data.success) {
@@ -114,10 +140,11 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.desc { .desc {
height: 100%; height: 220rpx;
flex: 2;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: space-around;
} }
.end-time, .end-time,
.reason { .reason {
@@ -204,14 +231,14 @@ export default {
align-items: center; align-items: center;
width: 450rpx; width: 450rpx;
font-size: $font-sm; font-size: $font-sm;
height: 100%; height: 220rpx;
background-color: #ffffff; background-color: #ffffff;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
> view:nth-child(1) { > view:nth-child(1) {
color: #666666; color: #666666;
margin-left: 20rpx; margin-left: 20rpx;
line-height: 3em;
> view:nth-child(1) { > view:nth-child(1) {
color: #ff6262; color: #ff6262;
font-size: 30rpx; font-size: 30rpx;
@@ -232,6 +259,20 @@ export default {
z-index: 2; z-index: 2;
} }
.used {
color: #ffffff;
background-color: black;
border-radius: 50%;
width: 86rpx;
height: 86rpx;
text-align: center;
margin-right: 30rpx;
vertical-align: middle;
padding-top: 8rpx;
position: relative;
z-index: 2;
}
.bg-quan { .bg-quan {
width: 244rpx; width: 244rpx;
height: 244rpx; height: 244rpx;

View File

@@ -2,7 +2,8 @@
<view class="b-content"> <view class="b-content">
<view class="navbar"> <view class="navbar">
<!-- 循环出头部tab栏 --> <!-- 循环出头部tab栏 -->
<view v-for="(item, index) in navList" :key="index" class="nav-item" @click="handleTabClick(index)"><text :class="{ current: tabCurrentIndex === index }">{{ <view v-for="(item, index) in navList" :key="index" class="nav-item" @click="handleTabClick(index)"><text
:class="{ current: tabCurrentIndex === index }">{{
item.text item.text
}}</text></view> }}</text></view>
</view> </view>
@@ -11,9 +12,10 @@
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData"> <scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData">
<!-- 空白页 --> <!-- 空白页 -->
<u-empty mode="coupon" text="暂无优惠券了" v-if="navItem.wheterEmpty"></u-empty> <u-empty mode="coupon" text="暂无优惠券了" v-if="navItem.wheterEmpty"></u-empty>
<!-- 数据 --> <!-- 数据 -->
<view v-if="navItem.dataList && coupon" class="coupon-item" :class="{ 'coupon-used': navIndex != 0 }" v-for="(coupon, index) in navItem.dataList" :key="index"> <view v-if="navItem.dataList && coupon" class="coupon-item" :class="{ 'coupon-used': navIndex != 0 }"
v-for="(coupon, index) in navItem.dataList" :key="index">
<view class="left"> <view class="left">
<view class="wave-line"> <view class="wave-line">
<view class="wave" v-for="(item, index) in 12" :key="index"></view> <view class="wave" v-for="(item, index) in 12" :key="index"></view>
@@ -114,6 +116,8 @@ export default {
}, },
onShow() { onShow() {
this.navList[this.tabCurrentIndex].params.pageNumber = 1
this.navList[this.tabCurrentIndex].dataList = [];
this.getData(); this.getData();
}, },
@@ -158,7 +162,6 @@ export default {
this.navList[index].dataList.push(...data); this.navList[index].dataList.push(...data);
} }
} }
console.log(this.navList[index].dataList)
uni.hideLoading(); uni.hideLoading();
}); });
}, },
@@ -185,13 +188,13 @@ export default {
* 立即使用优惠券 * 立即使用优惠券
*/ */
useItNow(item) { useItNow(item) {
if (item.storeId) { if (item.storeId && item.storeId!='platform') {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/shopPage?id=${item.storeId}`, url: `/pages/product/shopPage?id=${item.storeId}`,
}); });
} else { } else {
uni.switchTab({ uni.switchTab({
url: "/pages/tabbar/home/index", url: "/pages/navigation/search/searchPage",
}); });
} }
}, },

View File

@@ -1,427 +0,0 @@
<template>
<div class="wrapper">
<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode"
:mask-close-able="isClose" :mask="isMask" :border-radius="setup.radius" @close="closeMask()">
<!-- 商品 -->
<view class="goods-box bottom">
<view class="goods-header">
<view class="goods-img">
<u-image width="200rpx" border-radius="20" class="uimage" height="200rpx"
:src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
</view>
<view class="goods-skus">
<!-- 有活动商品价格 -->
<view class="goods-price " v-if="goodsDetail.promotionPrice">
<span>
<span class="goods-price-promotionShow goods-price-bigshow"
v-if="goodsDetail.promotionPrice">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span>
.{{ formatPrice(goodsDetail.promotionPrice)[1] }}
<span></span>
</span>
<div class="promotion-box">
<span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0]
}}</span>
.{{ formatPrice(goodsDetail.price)[1] }}
</div>
</view>
<!-- 正常商品的价格 -->
<view class="goods-price" v-else>
<span>
<span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0]
}}</span>
.{{ formatPrice(goodsDetail.price)[1] }}
</span>
</view>
<view class="goods-check-skus">
已选
<span class="goods-check-skus-name">
{{ selectName }}
<span>{{ num }}</span>
</span>
</view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-skus-box">
<!-- 规格 -->
<view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList">
<view class="skus-view-list">
<view class="view-class-title">{{ spec.name }}</view>
<view :class="{ active: spec_val.value == currentSelceted[specIndex] }" class="skus-view-item"
v-for="(spec_val, spec_index) in spec.values" :key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view>
</view>
</view>
<!-- 数量 -->
<view class="goods-skus-number">
<view class="view-class-title">数量</view>
<u-number-box :bg-color="numberBox.bgColor" :color="numberBox.color" :input-width="numberBox.width"
:input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num">
</u-number-box>
</view>
</view>
<!-- 按钮 -->
<view class="btns">
<view class="box-btn card" v-if="buyType != 'PINTUAN' && goodsDetail.goodsType!='VIRTUAL_GOODS'"
@click="addToCartOrBuy('cart')">加入购物车</view>
<view class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view>
</view>
</view>
</u-popup>
</div>
</template>
<script>
import * as API_trade from "@/api/trade.js";
import setup from "./popup";
export default {
data() {
return {
setup,
num: 1,
// 步进器的大小尺寸单位是 rpx
numberBox: {
width: "50",
height: "50",
size: "22",
color: "#333",
bgColor: "#fff",
},
selectName: "", //选中商品的昵称
selectSkuList: "", //选中商铺sku,
selectedSpecImg: "", //选中的图片路径
buyType: "", //用于存储促销,拼团等活动类型
parentOrder: "", //父级拼团活动的数据 - 如果是团员则有数据
formatList: [],
currentSelceted: [],
skuList: "",
isMask: false, //是否显示遮罩层
isClose: false, //是否可以点击遮罩关闭
};
},
props: [
"goodsDetail", //商品详情
"buyMask",
"selectedSku",
"goodsSpec",
"addr",
],
watch: {
buyType: {
handler(val) {
this.buyType = val;
},
immediate: true,
},
selectSkuList: {
handler(val, oldval) {
this.$emit("changed", val);
},
deep: true,
},
},
methods: {
// 格式化金钱 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
closeMask() {
this.$emit("closeBuy", false);
},
/**点击规格 */
handleClickSpec(val, index, specValue) {
this.$set(this.currentSelceted, index, specValue.value);
let selectedSkuId = this.goodsSpec.find((i) => {
let matched = true;
let specValues = i.specValues.filter((j) => j.specName !== "images");
for (let n = 0; n < specValues.length; n++) {
if (specValues[n].specValue !== this.currentSelceted[n]) {
matched = false;
return;
}
}
if (matched) {
return i;
}
});
this.selectSkuList = {
spec: {
specName: val.name,
specValue: specValue.value,
},
data: this.goodsDetail,
};
this.selectName = specValue.value;
this.$emit("handleClickSku", {
skuId: selectedSkuId.skuId,
goodsId: this.goodsDetail.goodsId,
});
},
/**
* 添加到购物车或购买
*/
addToCartOrBuy(val) {
if (!this.selectSkuList) {
uni.showToast({
title: "请选择规格商品",
icon: "none",
});
return;
}
let data = {
skuId: this.goodsDetail.id,
num: this.num,
};
if (val == "cart") {
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.showToast({
title: "商品已添加到购物车",
icon: "none",
});
this.$emit("queryCart");
this.closeMask();
}
});
} else {
// 判断是否拼团商品
if (this.buyType) {
data.cartType = "PINTUAN";
} else if (this.goodsDetail.goodsType == "VIRTUAL_GOODS") {
data.cartType = "VIRTUAL";
} else {
data.cartType = "BUY_NOW";
}
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${data.cartType}&addr=${
this.addr.id || ""
}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
});
}
},
/**
* 直接购买
*/
buy(data) {
API_trade.addToCart(data).then((res) => {
if (res.data.success) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${
data.cartType
}&addr=${""}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
});
},
formatSku(list) {
// 格式化数据
let arr = [{}];
list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => {
let name = spec.specName;
let values = {
value: spec.specValue,
quantity: item.quantity,
};
if (name === "images") {
return;
}
arr.forEach((arrItem, arrIndex) => {
if (
arrItem.name == name &&
arrItem.values &&
!arrItem.values.find((i) => i.value === values.value)
) {
arrItem.values.push(values);
}
let keys = arr.map((key) => {
return key.name;
});
if (!keys.includes(name)) {
arr.push({
name: name,
values: [values],
});
}
});
});
});
arr.shift();
this.formatList = arr;
list.forEach((item) => {
if (item.skuId === this.goodsDetail.id) {
item.specValues
.filter((i) => i.specName !== "images")
.forEach((value, _index) => {
this.currentSelceted[_index] = value.specValue;
this.selectName = value.specValue;
this.selectSkuList = {
spec: value,
data: this.goodsDetail,
};
});
}
});
this.skuList = list;
},
},
mounted() {
this.formatSku(this.goodsSpec);
console.log(this.goodsDetail);
},
};
</script>
<style lang="scss" scoped>
@import "./popup.scss";
.buy {
background-image: linear-gradient(135deg, #ffba0d, #ffc30d 69%, #ffcf0d);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
.card {
background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
/deep/.u-icon-plus,
.u-icon-minus,
.u-icon-disabled {
height: 30rpx !important;
background: #fff !important;
}
.goods-skus-number {
justify-content: space-between;
display: flex;
}
/deep/ .uni-scroll-view {
overflow: hidden !important;
}
.active {
background: $price-light-color !important;
border: 2rpx solid $price-color;
font-weight: bold;
color: $price-color !important;
box-sizing: border-box;
}
.goods-skus-box {
overflow-y: auto;
height: 610rpx;
// #ifdef MP-WEIXIN
height: 570rpx;
// #endif
margin-bottom: 10rpx;
}
.goods-skus-view {
overflow: hidden;
.skus-view-list {
> .skus-view-item {
flex: 1;
padding: 0 36rpx;
overflow: hidden;
height: 60rpx;
line-height: 60rpx;
float: left;
text-align: center;
margin-left: 24rpx;
margin-bottom: 20rpx;
font-size: 22rpx;
color: #262626;
background: #f2f2f2;
border-radius: 30rpx;
}
}
}
.goods-header {
height: 200rpx;
display: flex;
align-items: center;
margin-bottom: 36rpx;
}
.goods-box {
padding: 50rpx 36rpx 0 36rpx;
}
.goods-skus {
padding: 0 20rpx;
}
.goods-price {
color: $price-color;
line-height: 80rpx;
display: flex;
}
.promotion-box {
line-height: 1;
display: flex;
align-items: center;
text-decoration: line-through;
color: #999;
margin-left: 10rpx;
/deep/ span {
font-size: 30rpx;
}
}
.promotion {
font-size: 30rpx;
}
.goods-price-promotionShow {
font-size: 48rpx;
}
.goods-check-skus {
font-size: 24rpx;
color: #999;
> .goods-check-skus-name {
margin-left: 4rpx;
}
> span {
color: #333;
}
}
</style>

View File

@@ -1,8 +0,0 @@
export default {
height:"1000rpx", //弹出层高度
mode:"bottom", //弹出层位置
radius:"32", //圆角 rpx,
close:false //能否点击遮罩退出
}

View File

@@ -1,37 +0,0 @@
.view-class-title {
font-size: 26rpx;
color: #262626;
font-weight: 700;
height: 80rpx;
line-height: 80rpx;
}
.confirmBtn {
width: 90%;
}
.confirmBtn,
.box-btn {
line-height: 80rpx;
height: 80rpx;
background: $price-color;
color: #fff;
border-radius: 200px;
text-align: center;
margin: 5rpx auto;
}
.btns {
display: flex;
width: 100%;
margin: 0 auto;
}
.goods-price-bigshow {
font-size: 48rpx;
font-weight: bold;
}
.box-btn {
flex: 1;
margin: 0 10rpx;
}

View File

@@ -28,7 +28,8 @@
<div class="saveBtn" @click="save">保存</div> <div class="saveBtn" @click="save">保存</div>
</u-form> </u-form>
<m-city :provinceData="list" headTitle="区域选择" ref="cityPicker" @funcValue="getpickerParentValue" pickerSize="4"></m-city> <m-city :provinceData="list" headTitle="区域选择" ref="cityPicker" @funcValue="getpickerParentValue" pickerSize="4">
</m-city>
<uniMap v-if="mapFlage" @close="closeMap" @callback="callBackAddress" /> <uniMap v-if="mapFlage" @close="closeMap" @callback="callBackAddress" />
</div> </div>
@@ -149,7 +150,7 @@ export default {
delete this.form.___path; delete this.form.___path;
addAddress(this.form).then((res) => { addAddress(this.form).then((res) => {
if (res.data.success) { if (res.data.success) {
uni.navigateBack(); uni.navigateBack();
} }
}); });
} else { } else {
@@ -190,8 +191,8 @@ export default {
return _child.id == item.id; return _child.id == item.id;
}); });
this.form.lat = _town[0].center.split(",")[0]; this.form.lat = _town[0].center.split(",")[1];
this.form.lon = _town[0].center.split(",")[1]; this.form.lon = _town[0].center.split(",")[0];
} }
}); });
}, },

View File

@@ -1,7 +1,12 @@
<template> <template>
<view class="log-list"> <view class="log-list">
<!-- 提现记录 --> <!-- 提现记录 -->
<view class="log-way" v-if="cashLogData.length != 0" v-for="(item, index) in cashLogData" :key="index"> <view
class="log-way"
v-if="cashLogData.length != 0"
v-for="(item, index) in cashLogData"
:key="index"
>
<view class="log-item"> <view class="log-item">
<view class="log-item-view"> <view class="log-item-view">
<view class="title">{{ <view class="title">{{
@@ -20,21 +25,32 @@
</view> </view>
</view> </view>
<!-- 分销业绩 --> <!-- 分销业绩 -->
<view class="log-way" v-if="achievementData.length != 0" v-for="(item, index) in achievementData" :key="index"> <view
class="log-way"
v-if="achievementData.length != 0"
v-for="(item, index) in achievementData"
:key="index"
>
<view class="log-item"> <view class="log-item">
<view class="log-item-view"> <view class="log-item-view">
<view class="title">{{item.goodsName}}</view> <view class="title">{{ item.goodsName }}</view>
<view class="price">+{{ item.rebate | unitPrice }}</view> <view class="price">提成金额+{{ item.rebate | unitPrice }}</view>
</view> </view>
<view class="log-item-view"> <view class="log-item-view">
<view>{{ item.createTime }}</view> <view>创建时间{{ item.createTime }}</view>
<view>{{item.storeName}}</view> <view>店铺{{ item.storeName }}</view>
</view>
<view class="log-item-footer">
<view>会员名称{{ item.memberName }}</view>
<view>订单金额{{ item.flowPrice | unitPrice }}</view>
</view>
<view class="log-item-footers">
<view>订单号{{ item.orderSn }}</view>
</view> </view>
</view> </view>
</view> </view>
<view class="empty" v-if="empty"> <view class="empty" v-if="empty">
<u-loadmore :status="status" :icon-type="iconType" bg-color="#f7f7f7" /> <u-loadmore :status="status" :icon-type="iconType" bg-color="#f7f7f7" />
</view> </view>
</view> </view>
</template> </template>
@@ -86,7 +102,7 @@ export default {
}); });
distributionOrderList(this.achParams).then((res) => { distributionOrderList(this.achParams).then((res) => {
if (res.data.success && res.data.result.records.length >= 1) { if (res.data.success && res.data.result.records.length >= 1) {
this.achievementData = res.data.result.records; this.achievementData.push(...res.data.result.records);
} else { } else {
this.status = "nomore"; this.status = "nomore";
this.empty = true; this.empty = true;
@@ -101,7 +117,7 @@ export default {
}); });
cashLog(this.params).then((res) => { cashLog(this.params).then((res) => {
if (res.data.success && res.data.result.records.length >= 1) { if (res.data.success && res.data.result.records.length >= 1) {
this.cashLogData = res.data.result.records; this.cashLogData.push(...res.data.result.records);
} else { } else {
this.status = "nomore"; this.status = "nomore";
this.empty = true; this.empty = true;
@@ -139,6 +155,19 @@ export default {
.log-item-view { .log-item-view {
padding: 8rpx 32rpx; padding: 8rpx 32rpx;
display: flex; display: flex;
font-size: 13px;
justify-content: space-between; justify-content: space-between;
} }
</style> .log-item-footer {
padding: 8rpx 32rpx;
display: flex;
font-size: 13px;
justify-content: space-between;
}
.log-item-footers {
padding: 8rpx 32rpx;
display: flex;
font-size: 13px;
justify-content: space-between;
}
</style>

View File

@@ -1,422 +1,440 @@
<template> <template>
<view class="content"> <view class="content">
<view class="navbar"> <u-navbar>
<!-- 循环出顶部nav栏 --> <u-tabs :active-color="lightColor" class="slot-wrap" :list="navList" count="count" :is-scroll="true" :current="tabCurrentIndex" @change="tabClick"></u-tabs>
<view v-for="(item, index) in navList" :key="index" class="nav-item" @click="tabClick(index)"> </u-navbar>
<text :class="{current: tabCurrentIndex === index}">{{item.text}}</text> <view class="swiper-box">
</view> <!-- 显示商品栏 -->
</view> <view v-if="tabCurrentIndex == 0" class="tab-content">
<view class="swiper-box"> <scroll-view class="list-scroll-content" scroll-y>
<!-- 显示商品栏 --> <!-- 空白页 -->
<view v-if="tabCurrentIndex == 0" class="tab-content"> <u-empty style="margin-top: 40rpx" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore"> <!-- 商品展示数据 -->
<!-- 空白页 --> <u-swipe-action @open="openLeftChange(item, index, 'goods')" :show="item.selected" btn-width="180"
<u-empty style="margin-top:40rpx;" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty> :options="LeftOptions" v-else v-for="(item, index) in goodList"
<!-- 商品展示数据 --> @click="clickGoodsSwiperAction(item, index)" :index="index" :key="index">
<u-swipe-action @open="openLeftChange(item,index,'goods')" :show="item.selected" btn-width="180" <view class="goods" @click="goGoodsDetail(item)">
:options="LeftOptions" v-else v-for="(item,index) in goodList" @click="clickGoodsSwiperAction(item,index)" <u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
:index="index" :key="index"> <u-loading slot="loading"></u-loading>
<view class="goods" @click="goGoodsDetail(item)"> </u-image>
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit"> <view class="goods-intro">
<u-loading slot="loading"></u-loading> <view>{{ item.goodsName }}</view>
</u-image> <view class="goods-sn">{{ item.goods_sn }}</view>
<view class="goods-intro"> <view>{{ item.price | unitPrice }}</view>
<view>{{item.goodsName}}</view> </view>
<view class="goods-sn">{{item.goods_sn}}</view> </view>
<view>{{item.price | unitPrice}}</view> </u-swipe-action>
</view>
</view> </scroll-view>
</u-swipe-action> </view>
<!-- 显示收藏的店铺栏 -->
<uni-load-more :status="goodsLoad"></uni-load-more> <view v-else class="tab-content">
</scroll-view> <scroll-view class="list-scroll-content" scroll-y>
</view> <!-- 空白页 -->
<!-- 显示收藏店铺 --> <u-empty style="margin-top: 40rpx" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
<view v-else class="tab-content"> <!-- 店铺展示数据 -->
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore"> <u-swipe-action @open="openLeftChange(item, 'store')" :show="item.selected" btn-width="180"
<!-- 空白页 --> :options="LeftOptions" v-else v-for="(item, index) in storeList" :key="index"
<u-empty style="margin-top:40rpx;" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty> @click="clickStoreSwiperAction(item)">
<!-- 店铺展示数据 --> <view class="store" @click="goStoreMainPage(item.id)">
<u-swipe-action @open="openLeftChange(item,'store')" :show="item.selected" btn-width="180" <view class="intro">
:options="LeftOptions" v-else v-for="(item,index) in storeList" :key="index" <view class="store-logo">
@click="clickstoreSwiperAction(item)"> <u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName"
<view class="store" @click="gostoreMainPage(item.id)"> mode="aspectFit">
<view class="intro"> <u-loading slot="loading"></u-loading>
<view class="store-logo"> </u-image>
<u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName" mode="aspectFit"> </view>
<u-loading slot="loading"></u-loading> <view class="store-name">
</u-image> <view>{{ item.storeName }}</view>
</view> <u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated"
<view class="store-name"> text="自营" mode="plain" shape="circle" />
<view>{{item.storeName}}</view> </view>
<u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated" text="自营" mode="plain" <view class="store-collect">
shape="circle" /> <view>进店逛逛</view>
</view> </view>
<view class="store-collect"> </view>
<view>进店逛逛</view> </view>
</view> </u-swipe-action>
</view> </scroll-view>
</view> </view>
</u-swipe-action> </view>
<uni-load-more :status="storeLoad"></uni-load-more> </view>
</scroll-view> </template>
</view>
</view> <script>
</view> import {
</template> getGoodsCollection,
deleteGoodsCollection,
<script> deleteStoreCollection,
import { } from "@/api/members.js";
getGoodsCollection, export default {
deleteGoodsCollection, data() {
deleteStoreCollection, return {
} from "@/api/members.js"; lightColor:this.$lightColor,
export default { // 商品左滑侧边栏
data() { LeftOptions: [{
return { text: "取消",
// 商品左滑侧边栏 style: {
LeftOptions: [ backgroundColor: this.$lightColor,
{ },
text: "取消", }, ],
style: { tabCurrentIndex: 0, //tab的下标默认为0也就是说会默认请求商品
backgroundColor: this.$lightColor, navList: [
}, //tab显示数据
}, {
], name: "商品(0)",
tabCurrentIndex: 0, //tab的下标默认为0也就是说会默认请求商品
navList: [ params: {
//tab显示数据 pageNumber: 1,
{ pageSize: 10,
text: "商品(0)", },
loadingType: "more", },
params: { {
pageNumber: 1, name: "店铺(0)",
pageSize: 10,
}, params: {
}, pageNumber: 1,
{ pageSize: 10,
text: "店铺(0)", },
loadingType: "more", },
params: { ],
pageNumber: 1,
pageSize: 10, goodsEmpty: false, //商品数据是否为空
}, storeEmpty: false, //店铺数据是否为空
}, goodList: [], //商品集合
], storeList: [], //店铺集合
goodsLoad: "more", //商品加载 };
storeLoad: "more", //店铺加载 },
goodsEmpty: false, //商品数据是否为空 onLoad() {
storeEmpty: false, //店铺数据是否为空 this.getGoodList();
goodList: [], //商品集合 this.getStoreList();
storeList: [], //店铺集合 },
}; onReachBottom() {
}, if (this.tabCurrentIndex == 0) {
onLoad() { this.navList[0].params.pageNumber++;
this.getGoodList(); this.getGoodList();
this.getstoreList(); } else {
}, this.navList[1].params.pageNumber++;
this.getStoreList();
methods: { }
/** },
* 打开商品左侧取消收藏
*/ methods: {
openLeftChange(val, type) { /**
const { goodList, storeList } = this; * 打开商品左侧取消收藏
let way; */
type == "goods" ? (way = goodList) : (way = storeList); openLeftChange(val, type) {
way.forEach((item) => { const {
this.$set(item, "selected", false); goodList,
}); storeList
this.$set(val, "selected", false); } = this;
val.selected = true; let way;
}, type == "goods" ? (way = goodList) : (way = storeList);
way.forEach((item) => {
/** this.$set(item, "selected", false);
* 点击商品左侧取消收藏 });
*/ this.$set(val, "selected", false);
clickGoodsSwiperAction(val) { val.selected = true;
deleteGoodsCollection(val.skuId).then((res) => { },
if (res.statusCode == 200) {
this.storeList = []; /**
this.goodList = []; * 点击商品左侧取消收藏
this.getGoodList(); */
} clickGoodsSwiperAction(val) {
}); deleteGoodsCollection(val.skuId).then((res) => {
}, if (res.statusCode == 200) {
this.storeList = [];
/** this.goodList = [];
* 点击店铺左侧取消收藏 this.getGoodList();
*/ }
clickstoreSwiperAction(val) { });
deleteStoreCollection(val.storeId).then((res) => { },
if (res.statusCode == 200) {
this.storeList = []; /**
this.getstoreList(); * 点击店铺左侧取消收藏
} */
}); clickStoreSwiperAction(val) {
}, deleteStoreCollection(val.storeId).then((res) => {
if (res.statusCode == 200) {
/** this.storeList = [];
* 顶部tab点击 this.getStoreList();
*/ }
tabClick(index) { });
this.tabCurrentIndex = index; },
},
/**
/** * 顶部tab点击
* 查看商品详情 */
*/ tabClick(index) {
goGoodsDetail(val) { this.tabCurrentIndex = index;
//商品详情 },
uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId, /**
}); * 查看商品详情
}, */
goGoodsDetail(val) {
/** //商品详情
* 查看店铺详情 uni.navigateTo({
*/ url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
gostoreMainPage(id) { });
//店铺主页 },
uni.navigateTo({
url: "/pages/product/shopPage?id=" + id, /**
}); * 查看店铺详情
}, */
goStoreMainPage(id) {
/** //店铺主页
* 获取商品集合 uni.navigateTo({
*/ url: "/pages/product/shopPage?id=" + id,
getGoodList() { });
uni.showLoading({ },
title: "加载中",
}); /**
getGoodsCollection(this.navList[0].params, "GOODS").then((res) => { * 获取商品集合
uni.hideLoading(); */
uni.stopPullDownRefresh(); getGoodList() {
if (res.data.success) { uni.showLoading({
let data = res.data.result; title: "加载中",
data.selected = false; });
this.navList[0].text = `商品(${data.total})`; getGoodsCollection(this.navList[0].params, "GOODS").then((res) => {
if (data.total == 0) { uni.hideLoading();
this.goodsEmpty = true; uni.stopPullDownRefresh();
} else if (data.total < 10) { if (res.data.success) {
this.goodsLoad = "noMore"; let data = res.data.result;
this.goodList.push(...data.records); data.selected = false;
} else { this.navList[0].name = `商品(${data.total})`;
this.goodList.push(...data.records);
if (data.total.length < 10) this.goodsLoad = "noMore"; if (data.total == 0) {
} this.goodsEmpty = true;
} } else if (data.total < 10) {
}); this.goodsLoad = "noMore";
}, this.goodList.push(...data.records);
} else {
/** this.goodList.push(...data.records);
* 获取店铺集合 if (data.total.length < 10) this.goodsLoad = "noMore";
*/ }
getstoreList() { }
uni.showLoading({ });
title: "加载中", },
});
getGoodsCollection(this.navList[1].params, "store").then((res) => { /**
uni.hideLoading(); * 获取店铺集合
uni.stopPullDownRefresh(); */
if (res.data.success) { getStoreList() {
let data = res.data.result; uni.showLoading({
data.selected = false; title: "加载中",
this.navList[1].text = `店铺(${data.total})`; });
if (data.total == 0) { getGoodsCollection(this.navList[1].params, "store").then((res) => {
this.storeEmpty = true; uni.hideLoading();
} else if (data.total < 10) { uni.stopPullDownRefresh();
this.storeLoad = "noMore"; if (res.data.success) {
this.storeList.push(...data.records); let data = res.data.result;
} else { data.selected = false;
this.storeList.push(...data.records); this.navList[1].name = `店铺(${data.total})`;
if (data.total.length < 10) this.storeLoad = "noMore"; if (data.total == 0) {
} this.storeEmpty = true;
} } else if (data.total < 10) {
});
}, this.storeList.push(...data.records);
}
/** }
* 底部加载更多 });
*/ },
loadMore() { },
if (this.tabCurrentIndex == 0) {
this.navList[0].params.pageNumber++; /**
this.getGoodList(); * 下拉刷新时
} else { */
this.navList[1].params.pageNumber++; onPullDownRefresh() {
this.getstoreList(); if (this.tabCurrentIndex == 0) {
} this.navList[0].params.pageNumber = 1;
}, this.goodList = [];
}, this.getGoodList();
} else {
/** this.navList[1].params.pageNumber = 1;
* 下拉刷新时 this.storeList = [];
*/ this.getStoreList();
onPullDownRefresh() { }
if (this.tabCurrentIndex == 0) { },
this.navList[0].params.pageNumber = 1; };
this.goodList = []; </script>
this.getGoodList();
} else { <style lang="scss">
this.navList[1].params.pageNumber = 1; page,
this.storeList = []; .content {
this.getstoreList(); background: $page-color-base;
} height: 100%;
}, }
};
</script> .slot-wrap{
flex: 1;
<style lang="scss"> display: flex;
page, justify-content: center;
.content { padding-right: 72rpx;
background: $page-color-base; }
height: 100%;
} .content {
.content { width: 100%;
width: 100%; }
overflow: hidden;
} .swiper-box {
.swiper-box { overflow-y: auto;
overflow-y: auto; }
}
.list-scroll-content {
.list-scroll-content { height: 100%;
height: 100%; width: 100%;
width: 100%; }
}
/deep/ .u-swipe-content {
/deep/ .u-swipe-content { overflow: hidden;
overflow: hidden; }
}
.goods { .goods {
background-color: #fff; background-color: #fff;
border-bottom: 1px solid $border-color-light; border-bottom: 1px solid $border-color-light;
height: 190rpx; height: 190rpx;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 30rpx 20rpx; padding: 30rpx 20rpx;
margin-top: 20rpx; margin-top: 20rpx;
image {
width: 131rpx; image {
height: 131rpx; width: 131rpx;
border-radius: 10rpx; height: 131rpx;
} border-radius: 10rpx;
.goods-intro { }
flex: 1;
font-size: $font-base; .goods-intro {
line-height: 48rpx; flex: 1;
margin-left: 30rpx; font-size: $font-base;
line-height: 48rpx;
view:nth-child(1) { margin-left: 30rpx;
line-height: 1.4em;
font-size: 24rpx; view:nth-child(1) {
max-height: 2.8em; //height是line-height的整数倍防止文字显示不全 line-height: 1.4em;
overflow: hidden; font-size: 24rpx;
color: #666; max-height: 2.8em; //height是line-height的整数倍防止文字显示不全
} overflow: hidden;
view:nth-child(2) { color: #666;
color: #cccccc; }
font-size: 24rpx;
} view:nth-child(2) {
view:nth-child(3) { color: #cccccc;
color: $light-color; font-size: 24rpx;
} }
}
button { view:nth-child(3) {
color: $main-color; color: $light-color;
height: 50rpx; }
width: 120rpx; }
font-size: $font-sm;
padding: 0; button {
line-height: 50rpx; color: $main-color;
background-color: #ffffff; height: 50rpx;
margin-top: 80rpx; width: 120rpx;
&::after { font-size: $font-sm;
border-color: $main-color; padding: 0;
} line-height: 50rpx;
} background-color: #ffffff;
} margin-top: 80rpx;
.store {
background-color: #fff; &::after {
border: 1px solid $border-color-light; border-color: $main-color;
border-radius: 16rpx; }
margin: 20rpx 10rpx; }
.intro { }
display: flex;
justify-content: space-between; .store {
align-items: center; background-color: #fff;
padding: 0 30rpx 0 40rpx; border: 1px solid $border-color-light;
height: 170rpx; border-radius: 16rpx;
margin: 20rpx 10rpx;
.store-logo {
width: 102rpx; .intro {
height: 102rpx; display: flex;
border-radius: 50%; justify-content: space-between;
overflow: hidden; align-items: center;
image { padding: 0 30rpx 0 40rpx;
width: 100%; height: 170rpx;
height: 100%;
border-radius: 50%; .store-logo {
} width: 102rpx;
} height: 102rpx;
.store-name { border-radius: 50%;
flex: 1; overflow: hidden;
margin-left: 30rpx;
line-height: 2em; image {
:first-child { width: 100%;
font-size: $font-base; height: 100%;
} border-radius: 50%;
:last-child { }
font-size: $font-sm; }
color: #999;
} .store-name {
} flex: 1;
.store-collect { margin-left: 30rpx;
border-left: 1px solid $border-color-light; line-height: 2em;
padding-left: 20rpx;
text-align: center; :first-child {
:last-child { font-size: $font-base;
color: #999; }
font-size: $font-sm;
} :last-child {
} font-size: $font-sm;
} color: #999;
} }
.navbar { }
display: flex;
height: 40px; .store-collect {
padding: 0 5px; border-left: 1px solid $border-color-light;
background: #fff; padding-left: 20rpx;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.06); text-align: center;
position: relative;
z-index: 10; :last-child {
.nav-item { color: #999;
flex: 1; font-size: $font-sm;
display: flex; }
justify-content: center; }
align-items: center; }
height: 100%; }
font-size: 26rpx;
.navbar {
text { display: flex;
position: relative; height: 40px;
} padding: 0 5px;
text.current { background: #fff;
color: $light-color; box-shadow: 0 1px 5px rgba(0, 0, 0, 0.06);
font-weight: bold; position: relative;
font-size: 28rpx; z-index: 10;
&::after {
content: ""; .nav-item {
position: absolute; flex: 1;
left: 20rpx; display: flex;
bottom: -10rpx; justify-content: center;
width: 30rpx; align-items: center;
height: 0; height: 100%;
border-bottom: 2px solid $light-color; font-size: 26rpx;
}
} text {
} position: relative;
} }
</style>
text.current {
color: $light-color;
font-weight: bold;
font-size: 28rpx;
&::after {
content: "";
position: absolute;
left: 20rpx;
bottom: -10rpx;
width: 30rpx;
height: 0;
border-bottom: 2px solid $light-color;
}
}
}
}
</style>

View File

@@ -1,13 +1,19 @@
<template> <template>
<view class="myTracks"> <view class="myTracks">
<u-navbar title="我的足迹">
<div @click="changeRightBtn" slot="right" style="margin-right:32rpx">
{{edit}}
</div>
</u-navbar>
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty> <u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty>
<div v-else> <div v-else>
<view v-for="(item, index) in trackList" :key="index"> <view v-for="(item, index) in trackList" :key="index">
<view class="myTracks-title" @click="navgaiteToStore(item)">{{item.storeName}}</view> <view class="myTracks-title" @click="navgaiteToStore(item)">{{item.storeName}}</view>
<view class="myTracks-items"> <view class="myTracks-items">
<view class="myTracks-item"> <view class="myTracks-item">
<u-checkbox-group> <u-checkbox-group>
<u-checkbox v-model="item.___isDel" v-if="editFlag" active-color="#ff6b35" style="margin-right: 10rpx" @change="changeChecked(item)"></u-checkbox> <u-checkbox v-model="item.___isDel" v-if="editFlag" active-color="#ff6b35" style="margin-right: 10rpx"
@change="changeChecked(item)"></u-checkbox>
</u-checkbox-group> </u-checkbox-group>
<view class="myTracks-item-img" @click.stop="navgaiteToDetail(item)"> <view class="myTracks-item-img" @click.stop="navgaiteToDetail(item)">
<image :src="item.thumbnail"></image> <image :src="item.thumbnail"></image>
@@ -29,17 +35,17 @@
<uni-load-more :status="loadStatus"></uni-load-more> <uni-load-more :status="loadStatus"></uni-load-more>
</div> </div>
<view v-if="editFlag"> <view v-if="editFlag">
<view class="myTracks-action-placeholder"></view>
<view class="myTracks-action"> <view class="myTracks-action">
<view class="myTracks-action-check"> <view class="myTracks-action-check">
<u-checkbox-group> <u-checkbox-group>
<u-checkbox v-model="allChecked" v-if="editFlag" active-color="#ff6b35" style="margin-right: 10rpx" @change="checkedAllitem"></u-checkbox> <u-checkbox v-model="allChecked" v-if="editFlag" active-color="#ff6b35" style="margin-right: 10rpx"
@change="checkedAllitem"></u-checkbox>
全选 全选
</u-checkbox-group> </u-checkbox-group>
</view> </view>
<view> <view>
<u-button type="warning" plain="true" @click="delAllTracks" class="myTracks-action-btn"> <u-button type="warning" @click="delAllTracks" class="myTracks-action-btn">
删除 删除
</u-button> </u-button>
</view> </view>
@@ -54,6 +60,7 @@ import { myTrackList, deleteHistoryListId } from "@/api/members.js";
export default { export default {
data() { data() {
return { return {
edit: "编辑",
editFlag: false, //是否编辑 editFlag: false, //是否编辑
allChecked: false, //是否全选 allChecked: false, //是否全选
loadStatus: "more", //底部下拉加载状态 loadStatus: "more", //底部下拉加载状态
@@ -79,6 +86,10 @@ export default {
onLoad() { onLoad() {
this.getList(); this.getList();
}, },
onPullDownRefresh() {
this.trackList = [];
this.getList();
},
methods: { methods: {
/** /**
* 导航到店铺 * 导航到店铺
@@ -159,11 +170,31 @@ export default {
/** /**
* 点击后判断是不是全选 * 点击后判断是不是全选
*/ */
changeChecked(val) { changeChecked(val) {
var opt = null;
const isCheckedAll = this.trackList.every((key) => { const isCheckedAll = this.trackList.every((key) => {
return key.___isDel == val.___isDel; key.___isDel == val.___isDel;
opt = key.___isDel;
return opt;
}); });
this.allChecked = isCheckedAll; if(opt){
this.allChecked = isCheckedAll;
}else{
this.allChecked = false;
}
},
/**
* 右侧标签栏切换
*/
changeRightBtn(e) {
if (!this.editFlag) {
this.edit = "完成";
} else {
this.edit = "编辑";
}
this.editFlag = !this.editFlag;
}, },
/** /**
@@ -202,18 +233,6 @@ export default {
}); });
}, },
}, },
/**
* 右侧标签栏切换
*/
onNavigationBarButtonTap(e) {
if (!this.editFlag) {
this.setStyle("完成");
} else {
this.setStyle("编辑");
}
this.editFlag = !this.editFlag;
},
}; };
</script> </script>
@@ -286,6 +305,18 @@ export default {
color: $light-color; color: $light-color;
padding: 10rpx 0 0 0; padding: 10rpx 0 0 0;
} }
.myTracks-action{
display: flex;
justify-content: space-between;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #fff;
height: 75rpx;
align-items: center;
padding: 0 32rpx;
}
.myTracks-action-btn { .myTracks-action-btn {
width: 130rpx; width: 130rpx;
@@ -298,9 +329,7 @@ export default {
height: 20rpx; height: 20rpx;
} }
.myTracks-action-placeholder {
height: 110rpx;
}
.myTracks-action-check { .myTracks-action-check {
align-items: center; align-items: center;

View File

@@ -2,7 +2,7 @@
<div class="feedBack"> <div class="feedBack">
<div class="feedBack-box"> <div class="feedBack-box">
<h4>猜你想问</h4> <h4>猜你想问</h4>
<div class="feedBack-item" @click="handleClick(index)" v-for="(item,index) in list" :key="index"> <div class="feedBack-item" :class="{'active':feedBack.type == item.value }" @click="handleClick(index)" v-for="(item,index) in list" :key="index">
{{item.text}} {{item.text}}
</div> </div>
</div> </div>
@@ -130,6 +130,10 @@ export default {
margin: 0 auto; margin: 0 auto;
border-radius: 100px; border-radius: 100px;
} }
.active{
color: $light-color !important;
font-weight: bold;
}
.feedBack { .feedBack {
padding-bottom: 100rpx; padding-bottom: 100rpx;
} }

View File

@@ -45,7 +45,7 @@ export default {
face: storage.getUserInfo().face || "/static/missing-face.png", //默认头像 face: storage.getUserInfo().face || "/static/missing-face.png", //默认头像
regionId: [], //地址Id regionId: [], //地址Id
region: storage.getUserInfo().region || [], //地址 region: storage.getUserInfo().region || [], //地址
sex: storage.getUserInfo().sex || 1, //性别 sex: storage.getUserInfo().sex, //性别
___path: storage.getUserInfo().region, ___path: storage.getUserInfo().region,
}, },
birthday: storage.getUserInfo().birthday || "", //生日 birthday: storage.getUserInfo().birthday || "", //生日

View File

@@ -1,7 +1,8 @@
<template> <template>
<view class="container"> <view class="container">
<view class="person" @click="checkUserInfo()"> <view class="person" @click="checkUserInfo()">
<u-image width=140 height="140" shape="circle" :src="userInfo.face || '/static/missing-face.png'" mode=""></u-image> <u-image width=140 height="140" shape="circle" :src="userInfo.face || '/static/missing-face.png'" mode="">
</u-image>
<view class="user-name"> <view class="user-name">
{{ userInfo.id ? userInfo.nickName || '' : '暂未登录' }} {{ userInfo.id ? userInfo.nickName || '' : '暂未登录' }}
@@ -22,11 +23,13 @@
<u-cell-item :title="`关于${config.name}`" @click="navigateTo('/pages/mine/set/editionIntro')"></u-cell-item> <u-cell-item :title="`关于${config.name}`" @click="navigateTo('/pages/mine/set/editionIntro')"></u-cell-item>
</u-cell-group> </u-cell-group>
<view class="submit" @click="showModalDialog">{{userInfo.id ?'退出登录':'返回登录'}}</view> <view class="submit" @click="showModalDialog">{{userInfo.id ?'退出登录':'返回登录'}}</view>
<u-modal show-cancel-button v-model="quitShow" @confirm="confirm" :confirm-color="lightColor" :async-close="true" :content="userInfo.id ? '确定要退出登录么?' : '确定要返回登录么?'"></u-modal> <u-modal show-cancel-button v-model="quitShow" @confirm="confirm" :confirm-color="lightColor" :async-close="true"
:content="userInfo.id ? '确定要退出登录么?' : '确定要返回登录么?'"></u-modal>
</view> </view>
</template> </template>
<script> <script>
import { logout } from "@/api/login";
import storage from "@/utils/storage.js"; import storage from "@/utils/storage.js";
import config from "@/config/config"; import config from "@/config/config";
export default { export default {
@@ -50,16 +53,20 @@ export default {
url: url, url: url,
}); });
}, },
clear() {
storage.setAccessToken("");
storage.setRefreshToken("");
storage.setUserInfo({});
this.$options.filters.navigateToLogin("redirectTo");
},
/** /**
* 确认退出 * 确认退出
* 清除缓存重新登录 * 清除缓存重新登录
*/ */
confirm() { async confirm() {
storage.setAccessToken(""); await logout();
storage.setRefreshToken(""); this.clear();
storage.setUserInfo({});
this.$options.filters.navigateToLogin("redirectTo");
}, },
/** /**

View File

@@ -35,13 +35,6 @@
} }
} }
} }
/deep/ .u-row {
// #ifdef MP-WEIXIN
padding: 0 5%;
// #endif
}
.status_bar { .status_bar {
height: var(--status-bar-height); height: var(--status-bar-height);
background: #fff !important; background: #fff !important;
@@ -62,6 +55,7 @@ page {
padding: 30rpx; padding: 30rpx;
> .sort-item { > .sort-item {
> .sort-title { > .sort-title {
margin: 20rpx 0;
font-size: 26rpx; font-size: 26rpx;
font-weight: bold; font-weight: bold;
} }
@@ -121,7 +115,7 @@ page {
font-size: 24rpx; font-size: 24rpx;
} }
.flex { .flex {
margin: 30rpx 0;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
> .sort-brand-item { > .sort-brand-item {
@@ -138,47 +132,36 @@ page {
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
} }
.storeSellerBox {
// #ifndef MP-WEIXIN
padding: 16rpx !important;
// #endif
}
.goodsClass {
padding: 0 20rpx;
/deep/ .u-row {
}
}
.index-nav-arrow:last-child { .index-nav-arrow:last-child {
margin-top: -22rpx; margin-top: -22rpx;
} }
.line1-store-name{
font-size: 24rpx;
color: #999;
}
.to-store{
font-size: 24rpx;
color: #333;
margin-left: 10rpx;
}
.img { .img {
width: 26rpx; width: 26rpx;
height: 26rpx; height: 26rpx;
} }
.goodsRow { .goods-row {
/deep/ .u-row {
// #ifdef MP-WEIXIN
padding: 0%;
background: #fff;
// padding: 16rpx;
border-radius: 0.4em;
margin: 0 !important;
// #endif
}
background: #fff; background: #fff;
border-radius: 0.4em; padding: 16rpx;
margin: 20rpx 0;
// #ifdef MP-WEIXIN >.goods-col{
margin: 10rpx 0; display: flex;
// #endif >.goods-img{
padding: 0 16rpx; flex: 4;
width: 100%; }
>.goods-detail{
flex: 7;
}
}
} }
.add1 { .add1 {
@@ -192,21 +175,14 @@ page {
border-bottom: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee;
} }
.logimg {
width: 40rpx;
height: 40rpx;
vertical-align: middle;
}
.clamp3 { .clamp3 {
padding-top: 30rpx;
margin-bottom: 10rpx; margin-bottom: 10rpx;
font-size: 28rpx; font-size: 28rpx;
color: #333333; color: #333333;
font-weight: 400; font-weight: 400;
display: -webkit-box; display: -webkit-box;
line-height: 40rpx; height: 80rpx;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-line-clamp: 2 !important; -webkit-line-clamp: 2 !important;
@@ -217,25 +193,12 @@ page {
} }
} }
.switchType1 {
width: 50%;
overflow: hidden;
text-align: center;
> .img {
width: 182rpx;
height: 200rpx;
}
}
.imgGoods {
width: 182rpx;
height: 200rpx;
}
view { view {
display: block; display: block;
} }
.storeSellerName { .store-seller-name {
color: #666; color: #666;
overflow: hidden; overflow: hidden;
@@ -248,7 +211,7 @@ view {
} }
} }
.countConfig { .count-config {
padding: 10rpx 0; padding: 10rpx 0;
color: #666; color: #666;
display: flex; display: flex;
@@ -635,16 +598,15 @@ view {
overflow: hidden; overflow: hidden;
} }
.countConfig, .count-config,
.storeSellerName { .store-seller-name {
font-size: $font-sm; font-size: $font-sm;
} }
.textHidden { .text-hidden {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
} }

View File

@@ -82,53 +82,49 @@
<div v-if="isSWitch"> <div v-if="isSWitch">
<scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250" <scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250"
@scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page"> @scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page">
<div class="goodsClass"> <div class="goods-class">
<u-row v-for="(item, index) in goodsList" :key="index" class="goodsRow"> <div v-for="(item, index) in goodsList" :key="index" class="goods-row">
<u-col :span="4" @click.native="navigateToDetailPage(item)" class="switchType1"> <div class="flex goods-col">
<u-image width="182rpx" height="200rpx" class="imgGoods" :src="item.content.thumbnail"> <div class="goods-img" @click="navigateToDetailPage(item)">
<u-loading slot="loading"></u-loading> <u-image width="230rpx" height="230rpx" :src="item.content.thumbnail">
</u-image> <u-loading slot="loading"></u-loading>
</u-col> </u-image>
<u-col :span="8" @click.native="navigateToDetailPage(item)" class="switchType2"> </div>
<div class="title clamp3" style="">{{ item.content.goodsName }}</div> <div class="goods-detail">
<view class="price-box"> <div class="title clamp3" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<div class="price" v-if="item.content.price!=undefined"> <view class="price-box" @click="navigateToDetailPage(item)">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{ <div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1] formatPrice(item.content.price )[1]
}} }}
</div>
</view>
<div class="promotion" @click="navigateToDetailPage(item)">
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1"></span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1">满减</span>
<span v-if="promotionItem.indexOf('SECKILL') != -1">秒杀</span>
</div>
</div> </div>
</view> <div style="overflow: hidden" @click="navigateToDetailPage(item)" class="count-config">
<div class="promotion"> <span style="float: left; font-size: 22rpx">已售 {{ item.content.buyCount || '0' }}</span>
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex"> <span style="float: right; font-size: 22rpx">{{ item.content.commentNum || '0' }}条评论</span>
</div>
<div style="overflow: hidden" @click="navigateToStoreDetailPage(item)" class="count-config">
<div class="text-hidden">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
type="error" />
<span class="line1-store-name">{{ item.content.storeName }}</span>
<span class="to-store">进店<u-icon size="24" name="arrow-right" color="#666"></u-icon></span>
</div>
<span>
<u-icon name="arrow-right" color="#c5c5c5"></u-icon>
</span>
</div>
</div>
</div>
<span v-if="promotionItem.indexOf('COUPON') != -1"></span> </div>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1">满减</span>
<span v-if="promotionItem.indexOf('SECKILL') != -1">秒杀</span>
</div>
</div>
<div style="overflow: hidden" class="countConfig">
<span style="float: left; font-size: 22rpx">已售 {{ item.buyCount || '0' }}</span>
<span style="float: right; font-size: 22rpx">{{ item.commentNum || '0' }}条评论</span>
</div>
</u-col>
<u-col :span="12" class="storeSellerBox">
<div class="storeSellerName" @click="clickTostore()">
<div class="textHidden">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
type="error" />
<span style="
color: #333333;
font-size: 28rpx;
padding-left: 17rpx;
">{{ item.storeName }}</span>
</div>
<span>
<u-icon name="arrow-right" color="#c5c5c5"></u-icon>
</span>
</div>
</u-col>
</u-row>
</div> </div>
<uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more> <uni-load-more :status="loadingType" @loadmore="loadmore()"></uni-load-more>
</scroll-view> </scroll-view>
@@ -153,39 +149,36 @@
<scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true" <scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true"
@scrolltolower="loadmore()" scroll-with-animation scroll-y lower-threshold="250" class="scoll-page"> @scrolltolower="loadmore()" scroll-with-animation scroll-y lower-threshold="250" class="scoll-page">
<view class="goods-list"> <view class="goods-list">
<view v-for="(item, index) in goodsList" :key="index" class="goods-item" <view v-for="(item, index) in goodsList" :key="index" class="goods-item">
@click="navigateToDetailPage(item)"> <view class="image-wrapper" @click="navigateToDetailPage(item)">
<view class="image-wrapper">
<image :src="item.content.thumbnail" mode="aspectFill"></image> <image :src="item.content.thumbnail" mode="aspectFill"></image>
</view> </view>
<view class="goods-detail"> <view class="goods-detail">
<div class="title clamp">{{ item.content.goodsName }}</div> <div class="title clamp" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
<view class="price-box"> <view class="price-box" @click="navigateToDetailPage(item)">
<div class="price" v-if="item.content.price!=undefined"> <div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{ ¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
formatPrice(item.content.price )[1] formatPrice(item.content.price )[1]
}} }}
</div> </div>
</view> </view>
<div class="promotion"> <div class="promotion" @click="navigateToDetailPage(item)">
<div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex"> <div v-for="(promotionItem,promotionIndex) in getPromotion(item)" :key="promotionIndex">
<span v-if="promotionItem.indexOf('COUPON') != -1">劵</span> <span v-if="promotionItem.indexOf('COUPON') != -1">劵</span>
<span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1">满减</span> <span v-if="promotionItem.indexOf('FULL_DISCOUNT') != -1">满减</span>
<span v-if="promotionItem.indexOf('SECKILL') != -1">秒杀</span> <span v-if="promotionItem.indexOf('SECKILL') != -1">秒杀</span>
</div> </div>
</div> </div>
<div class="countConfig"> <div class="count-config" @click="navigateToDetailPage(item)">
<span>已售 {{ item.buyCount || "0" }}</span> <span>已售 {{ item.content.buyCount || "0" }}</span>
<span>{{ item.commentNum || "0" }}条评论</span> <span>{{ item.content.commentNum || "0" }}条评论</span>
</div> </div>
<div class="storeSellerName"> <div class="store-seller-name" @click="navigateToStoreDetailPage(item)">
<div class="textHidden"> <div class="text-hidden">
<u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营" <u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
type="error" /> type="error" />
<span>{{ item.storeName || "暂无" }}</span> <span>{{ item.content.storeName || "暂无" }}</span>
</div> </div>
<span> <span>
<u-icon name="arrow-right"></u-icon> <u-icon name="arrow-right"></u-icon>
@@ -275,6 +268,7 @@
</view> </view>
</view> </view>
</u-popup> </u-popup>
<u-back-top :scroll-top="scrollTop"></u-back-top>
</view> </view>
</template> </template>
@@ -287,6 +281,7 @@ import storage from "@/utils/storage";
export default { export default {
data() { data() {
return { return {
scrollTop: 0,
loadIndex: 10, loadIndex: 10,
oldKeywordIndex: "", oldKeywordIndex: "",
selectedWay: { selectedWay: {
@@ -326,8 +321,7 @@ export default {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
// sort: 'grade_asc', // sort: 'grade_asc',
sort: "releaseTime",
order: "desc",
keyword: "", keyword: "",
}, },
minPrice: "", minPrice: "",
@@ -345,9 +339,13 @@ export default {
routerVal: "", routerVal: "",
}; };
}, },
onPageScroll(e) {
console.log(e);
this.scrollTop = e.scrollTop;
},
onLoad(val) { onLoad(val) {
this.init(); this.init();
this.initSortGoods(); // this.initSortGoods();
// 接收分类的数据 // 接收分类的数据
this.routerVal = val; this.routerVal = val;
@@ -355,7 +353,11 @@ export default {
// 有值 // 有值
if (this.routerVal.category) { if (this.routerVal.category) {
this.params.categoryId = this.routerVal.category; this.params.categoryId = this.routerVal.category;
this.sortParams.categoryId = this.routerVal.category;
this.isShowSeachGoods = true; this.isShowSeachGoods = true;
this.$nextTick(()=>{
this.$refs.mSearch.isShowSeachGoods = true;
})
} }
if (this.routerVal.keyword) { if (this.routerVal.keyword) {
this.params.keyword = this.routerVal.keyword; this.params.keyword = this.routerVal.keyword;
@@ -383,6 +385,12 @@ export default {
this.defaultKeyword = "请输入搜索商品"; this.defaultKeyword = "请输入搜索商品";
} }
}, },
sortPopup(val) {
if (val) {
this.selectedWay = { brand: [], categoryId: [], prop: [] };
console.log(this.selectedWay);
}
},
}, },
onReachBottom() { onReachBottom() {
@@ -458,19 +466,32 @@ export default {
// 点击确定进行筛选 // 点击确定进行筛选
sortConfim() { sortConfim() {
// 处理品牌(多选 // 处理品牌(多选
this.params.brandId = []; if (!this.params.brandId) {
this.params.brandId = [];
} else {
this.params.brandId = [this.params.brandId];
}
// 如果选中品牌 赋值
this.selectedWay["brand"].forEach((item) => { this.selectedWay["brand"].forEach((item) => {
if (item.__selected) { if (item.__selected) {
this.params.brandId.push(item.value); this.params.brandId.push(item.value);
} }
}); });
this.params.brandId = this.params.brandId.join("@");
this.params.brandId = this.params.brandId.join("@") || "";
console.log(this.params.brandId);
// 处理分类 (单选) // 处理分类 (单选)
if (this.selectedWay["categoryId"][0]) { if (this.selectedWay["categoryId"][0]) {
this.params.categoryId = this.selectedWay["categoryId"][0].value; this.params.categoryId = this.selectedWay["categoryId"][0].value;
} }
// 处理属性 if (!this.params.prop) {
this.params.prop = []; this.params.prop = [];
} else {
this.params.prop = [this.params.prop];
}
this.selectedWay["prop"].forEach((item) => { this.selectedWay["prop"].forEach((item) => {
if (item.__selected) { if (item.__selected) {
this.params.prop.push(`${item.parent}_${item.title}`); this.params.prop.push(`${item.parent}_${item.title}`);
@@ -485,19 +506,32 @@ export default {
} }
this.goodsList = []; this.goodsList = [];
this.params.pageNumber = 1;
this.sortParams = this.params;
this.loadData(); this.loadData();
this.sortPopup = false; this.sortPopup = false;
}, },
// 重置 // 重置
repick() { repick() {
this.sortParams = {
pageNumber: 1,
pageSize: 10,
categoryId: this.routerVal.category || "",
};
this.sortPopup = false;
this.initSortGoods(); this.initSortGoods();
this.minPrice = ""; this.minPrice = "";
this.maxPrice = ""; this.maxPrice = "";
this.params = { this.params = {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
categoryId: this.routerVal.category || "",
}; };
this.goodsList = [];
this.loadData(); this.loadData();
}, },
@@ -531,11 +565,18 @@ export default {
delta: 1, delta: 1,
}); });
}, },
// 跳转到商品详情
navigateToDetailPage(item) { navigateToDetailPage(item) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${item.content.id}&goodsId=${item.content.goodsId}`, url: `/pages/product/goods?id=${item.content.id}&goodsId=${item.content.goodsId}`,
}); });
}, },
// 跳转地址
navigateToStoreDetailPage(item) {
uni.navigateTo({
url: `/pages/product/shopPage?id=${item.content.storeId}`,
});
},
loadmore() { loadmore() {
this.params.pageNumber++; this.params.pageNumber++;
this.loadData(); this.loadData();

View File

@@ -1,10 +1,12 @@
<template> <template>
<view class="content"> <view class="content">
<view class="u-tabs-box"> <view class="u-tabs-box">
<u-tabs bg-color="#fff" :list="list" :is-scroll="false" :current="current" @change="change" :active-color="$lightColor"></u-tabs> <u-tabs bg-color="#fff" :list="list" :is-scroll="false" :current="current" @change="change"
:active-color="$lightColor"></u-tabs>
</view> </view>
<div class="u-tabs-search"> <div class="u-tabs-search">
<u-search placeholder="请输入订单编号" @search="handleGetOrderList(current)" @clear="handleGetOrderList(current)" @custom="handleGetOrderList(current)" v-model="params.orderSn"></u-search> <u-search placeholder="请输入订单编号" @search="handleGetOrderList(current)" @clear="handleGetOrderList(current)"
@custom="handleGetOrderList(current)" v-model="params.orderSn"></u-search>
</div> </div>
<scroll-view class="body-view" scroll-y @scrolltolower="renderDate"> <scroll-view class="body-view" scroll-y @scrolltolower="renderDate">
<view class="seller-view" v-for="(order, orderIndex) in orderList" :key="orderIndex"> <view class="seller-view" v-for="(order, orderIndex) in orderList" :key="orderIndex">
@@ -21,7 +23,7 @@
<view class="order-sn">{{ order.serviceType_text }}</view> <view class="order-sn">{{ order.serviceType_text }}</view>
</view> </view>
<view v-for="(sku, goodsIndex) in order.orderItems" :key="goodsIndex"> <view v-for="(sku, goodsIndex) in order.orderItems" :key="goodsIndex">
<view class="goods-item-view" @click="onDetail(sku)"> <view class="goods-item-view" @click="onDetail(order,sku)">
<view class="goods-img"> <view class="goods-img">
<u-image border-radius="6" width="100%" height="100%" :src="sku.image"></u-image> <u-image border-radius="6" width="100%" height="100%" :src="sku.image"></u-image>
</view> </view>
@@ -40,36 +42,45 @@
<view class="description"> <view class="description">
<!-- 售后申请 --> <!-- 售后申请 -->
<view v-if=" <view v-if="
current === 0 && order.groupAfterSaleStatus && current === 0 && order.groupAfterSaleStatus &&
order.groupAfterSaleStatus === 'ALREADY_APPLIED' order.groupAfterSaleStatus.includes('ALREADY_APPLIED')
" class="cannot_apply"> " class="cannot_apply">
<u-icon class="icon" name="info-circle-fill"></u-icon> <u-icon class="icon" name="info-circle-fill"></u-icon>
该商品已申请售后服务 该商品已申请售后服务
</view> </view>
<view class="cannot_apply" v-if="current === 0 && order.groupAfterSaleStatus && order.groupAfterSaleStatus === 'EXPIRED'" @click="tipsShow = true"> <view class="cannot_apply"
v-if="current === 0 && order.groupAfterSaleStatus && order.groupAfterSaleStatus.includes('EXPIRED') "
@click="tipsShow = true">
<u-icon class="icon" name="info-circle-fill"></u-icon> <u-icon class="icon" name="info-circle-fill"></u-icon>
该商品无法申请售后 该商品无法申请售后
</view> </view>
<div v-if="current === 1 || current === 2"> <div v-if="current === 1 || current === 2">
<!-- 申请中 --> <!-- 申请中 -->
<view class="cannot_apply" v-if="order.serviceType == 'RETURN_GOODS'">退货处理-{{ order.serviceStatus | serviceStatusList }}</view> <view class="cannot_apply" v-if="order.serviceType == 'RETURN_GOODS'">
<view class="cannot_apply" v-if="order.serviceType == 'SUPPLY_AGAIN_GOODS'">补发商品-{{ order.serviceStatus | serviceStatusList }}</view> 退货处理-{{ order.serviceStatus | serviceStatusList }}</view>
<view class="cannot_apply" v-if="order.serviceType == 'RETURN_MONEY'">退款-{{ order.serviceStatus | serviceStatusList }}</view> <view class="cannot_apply" v-if="order.serviceType == 'SUPPLY_AGAIN_GOODS'">
<view class="cannot_apply" v-if="order.serviceType == 'EXCHANGE_GOODS'">换货-{{ order.serviceStatus | serviceStatusList }}</view> 补发商品-{{ order.serviceStatus | serviceStatusList }}</view>
<view class="cannot_apply" v-if="order.serviceType == 'CANCEL'">取消订单-{{ order.serviceStatus | serviceStatusList }}</view> <view class="cannot_apply" v-if="order.serviceType == 'RETURN_MONEY'">
退款-{{ order.serviceStatus | serviceStatusList }}</view>
<view class="cannot_apply" v-if="order.serviceType == 'EXCHANGE_GOODS'">
换货-{{ order.serviceStatus | serviceStatusList }}</view>
<view class="cannot_apply" v-if="order.serviceType == 'CANCEL'">
取消订单-{{ order.serviceStatus | serviceStatusList }}</view>
</div> </div>
<!-- 申请记录 --> <!-- 申请记录 -->
</view> </view>
<!-- 售后申请 -->
<div v-if="current === 0 && sku.afterSaleStatus && (sku.afterSaleStatus.includes('NOT_APPLIED') || sku.afterSaleStatus.includes('PART_AFTER_SALE')) " @click="applyService(sku.sn, order, sku)" class="sale">
<view class=" default-btn border" >
申请售后
</view>
</div>
<view class="after-line"> <view class="after-line">
<!-- 售后申请 -->
<view v-if="
current === 0 && order.groupAfterSaleStatus=='NOT_APPLIED'
" @click="applyService(sku.sn, order, sku)" class="rebuy-btn">
申请售后
</view>
<!-- 申请中 --> <!-- 申请中 -->
<view class="rebuy-btn" v-if=" <view class="default-btn border" v-if="
current === 2 && current === 2 &&
order.serviceStatus && order.serviceStatus &&
order.serviceStatus == 'PASS' && order.serviceStatus == 'PASS' &&
@@ -77,7 +88,10 @@
" @click="onExpress(order, sku)"> " @click="onExpress(order, sku)">
提交物流 提交物流
</view> </view>
<view @click="afterDetails(order, sku)" v-if="current === 1 || current === 2" class="rebuy-btn"> <view @click="close(order,sku)" v-if="current === 1" class="default-btn close">
取消售后
</view>
<view @click="afterDetails(order, sku)" v-if="current === 1 || current === 2" class="default-btn border">
售后详情 售后详情
</view> </view>
</view> </view>
@@ -96,14 +110,16 @@
</view> </view>
<u-loadmore bg-color="#f8f8f8" :status="status" /> <u-loadmore bg-color="#f8f8f8" :status="status" />
</scroll-view> </scroll-view>
<u-modal show-cancel-button @confirm="closeService" v-model="cancelShow" content="确认取消售后"></u-modal>
<u-modal v-model="tipsShow" content="当订单未确认收货|已过售后服务有效期|已申请售后服务时,不能申请售后"></u-modal> <u-modal v-model="tipsShow" content="当订单未确认收货|已过售后服务有效期|已申请售后服务时,不能申请售后"></u-modal>
</view> </view>
</template> </template>
<script> <script>
import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue"; import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue";
import { getAfterSaleList } from "@/api/after-sale.js"; import { getAfterSaleList, cancelAfterSale } from "@/api/after-sale.js";
import { getOrderList } from "@/api/order.js"; import { getOrderList } from "@/api/order.js";
import storage from "@/utils/storage";
export default { export default {
components: { components: {
@@ -125,11 +141,14 @@ export default {
], ],
current: 0, //当前表头索引 current: 0, //当前表头索引
tipsShow: false, //提示开关 tipsShow: false, //提示开关
cancelShow: false, //取消显示开关
selectedOrder: "", //选中的order
orderList: [], //订单集合 orderList: [], //订单集合
params: { params: {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
sort: "createTime", sort: "createTime",
flowPrice: 1,
order: "desc", order: "desc",
}, },
@@ -193,12 +212,12 @@ export default {
}); });
getOrderList(this.params).then((res) => { getOrderList(this.params).then((res) => {
uni.hideLoading(); uni.hideLoading();
const orderlist = res.data.result.records; const orderList = res.data.result.records;
if (orderlist.length > 0) { if (orderList.length > 0) {
this.orderList = this.orderList.concat(orderlist); this.orderList = this.orderList.concat(orderList);
this.params.pageNumber += 1; this.params.pageNumber += 1;
} }
if (orderlist.length < 10) { if (orderList.length < 10) {
this.status = "nomore"; this.status = "nomore";
} else { } else {
this.status = "loading"; this.status = "loading";
@@ -206,6 +225,31 @@ export default {
}); });
}, },
close(order, sku) {
console.log(order, sku);
this.selectedOrder = order;
this.cancelShow = true;
},
async closeService() {
uni.showLoading({
title: "加载中",
});
console.log(this.selectedOrder);
let res = await cancelAfterSale(this.selectedOrder.sn);
if (res.data.success) {
uni.showToast({
title: "取消成功!",
duration: 2000,
icon: "none",
});
}
this.orderList = [];
this.getOrderList(this.current);
uni.hideLoading();
},
/** /**
* 售后详情 * 售后详情
*/ */
@@ -252,11 +296,9 @@ export default {
...order, ...order,
...sku, ...sku,
}; };
storage.setAfterSaleData(data);
uni.navigateTo({ uni.navigateTo({
url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}&sku=${encodeURIComponent( url: `/pages/order/afterSales/afterSalesSelect?sn=${sn}`,
JSON.stringify(data)
)}`,
}); });
}, },
@@ -266,20 +308,28 @@ export default {
onExpress(order, sku) { onExpress(order, sku) {
sku.storeName = order.storeName; sku.storeName = order.storeName;
storage.setAfterSaleData(data);
uni.navigateTo({ uni.navigateTo({
url: `./afterSalesDetailExpress?serviceSn=${ url: `./afterSalesDetailExpress?serviceSn=${order.sn}`,
order.sn
}&sku=${encodeURIComponent(JSON.stringify(sku))}`,
}); });
}, },
/** /**
* 查看详情 * 查看详情
*/ */
onDetail(sku) { onDetail(goods, sku) {
if (!this.$u.test.isEmpty(sku.skuId)) { // 售后申请
if (this.current == 0) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`, url: `/pages/product/goods?id=${sku.skuId}&goodsId=${
sku.goodsId || sku.goodsId
}`,
});
} else {
uni.navigateTo({
url: `/pages/product/goods?id=${goods.skuId}&goodsId=${
goods.goodsId || goods.goodsId
}`,
}); });
} }
}, },
@@ -306,6 +356,7 @@ page,
background: $page-color-base; background: $page-color-base;
height: 100%; height: 100%;
} }
.body-view { .body-view {
overflow-y: auto; overflow-y: auto;
height: calc(100vh - 44px - 80rpx - 104rpx); height: calc(100vh - 44px - 80rpx - 104rpx);
@@ -402,28 +453,27 @@ page,
.icon { .icon {
margin-right: 10rpx; margin-right: 10rpx;
} }
.cancel-btn {
color: #999999; .sale {
border-color: #999999; width: 100%;
margin-left: 15rpx; display: flex;
height: 60rpx; justify-content: flex-end;
} }
.pay-btn { .default-btn {
background-color: #1abc9c;
color: #ffffff;
margin-left: 15rpx;
height: 60rpx;
}
.rebuy-btn {
background-color: #ffffff; background-color: #ffffff;
margin-left: 15rpx; margin-left: 15rpx;
height: 60rpx; height: 60rpx;
line-height: 60rpx; line-height: 60rpx;
text-align: center; text-align: center;
font-size: 24rpx; font-size: 24rpx;
border: 2rpx solid $light-color;
color: $light-color;
padding: 0 24rpx; padding: 0 24rpx;
border-radius: 200px; border-radius: 200px;
} }
.close {
color: $light-color;
}
.border {
border: 2rpx solid $light-color;
color: $light-color;
}
</style> </style>

View File

@@ -10,7 +10,8 @@
</view> </view>
</view> </view>
<view> <view>
<view class="goods-item-view" v-for="(item,index) in sku.orderItems" v-if="item.sn == sn" @click="gotoGoodsDetail(sku.goods_id)"> <view class="goods-item-view" v-for="(item,index) in sku.orderItems" v-if="item.sn == sn"
@click="gotoGoodsDetail(sku.goods_id)">
<view class="goods-img"> <view class="goods-img">
<u-image border-radius="6" width="131rpx" height="131rpx" :src="item.image"></u-image> <u-image border-radius="6" width="131rpx" height="131rpx" :src="item.image"></u-image>
</view> </view>
@@ -27,7 +28,8 @@
<view class="after-num"> <view class="after-num">
<view>申请数量</view> <view>申请数量</view>
<view> <view>
<u-number-box :value="parseInt(form.num)" disabled-input :min="1" :max="parseInt(sku.num)" bg-color="#fff" @change="valChange"></u-number-box> <u-number-box :value="parseInt(form.num)" disabled-input :min="1" :max="parseInt(sku.num)" bg-color="#fff"
@change="valChange"></u-number-box>
</view> </view>
</view> </view>
</view> </view>
@@ -36,7 +38,8 @@
<!-- 退款原因 --> <!-- 退款原因 -->
<view class="opt-view"> <view class="opt-view">
<u-form-item label="申请原因" :label-width="150"> <u-form-item label="申请原因" :label-width="150">
<u-input v-model="form.reason" type="select" input-align="right" :select-open="reasonSelectShow" @click="reasonSelectShow = true" placeholder="请选择申请原因" /> <u-input v-model="form.reason" type="select" input-align="right" :select-open="reasonSelectShow"
@click="reasonSelectShow = true" placeholder="请选择申请原因" />
</u-form-item> </u-form-item>
<u-form-item label="申请说明" :label-width="150"> <u-form-item label="申请说明" :label-width="150">
<u-input input-align="right" type="textarea" v-model="form.problemDesc" placeholder="请描述申请售后的说明" /> <u-input input-align="right" type="textarea" v-model="form.problemDesc" placeholder="请描述申请售后的说明" />
@@ -47,7 +50,8 @@
<view class="opt-view"> <view class="opt-view">
<view class="img-title">上传凭证最多5张</view> <view class="img-title">上传凭证最多5张</view>
<view class="images-view"> <view class="images-view">
<u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150" @on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload> <u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150"
@on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload>
</view> </view>
</view> </view>
@@ -81,11 +85,14 @@
</u-form> </u-form>
<view class="submit-view"> <view class="submit-view">
<u-button type="primary" ripple shape="circle" v-if="applyInfo.refundWay" :custom-style="customStyle" @click="onSubmit">提交申请</u-button> <u-button type="primary" ripple shape="circle" v-if="applyInfo.refundWay" :custom-style="customStyle"
@click="onSubmit">提交申请</u-button>
</view> </view>
<u-select mode="single-column" :list="reasonList" v-model="reasonSelectShow" @confirm="reasonSelectConfirm"></u-select> <u-select mode="single-column" :list="reasonList" v-model="reasonSelectShow" @confirm="reasonSelectConfirm">
</u-select>
<u-select mode="single-column" :list="typeList" v-model="typeSelectShow" @confirm="typeSelectConfirm"></u-select> <u-select mode="single-column" :list="typeList" v-model="typeSelectShow" @confirm="typeSelectConfirm"></u-select>
<u-select mode="single-column" :list="returnList" v-model="returnSelectShow" @confirm="returnSelectConfirm"></u-select> <u-select mode="single-column" :list="returnList" v-model="returnSelectShow" @confirm="returnSelectConfirm">
</u-select>
<u-toast ref="uToast" /> <u-toast ref="uToast" />
</view> </view>
</template> </template>
@@ -188,9 +195,7 @@ export default {
title: navTitle, //此处写页面的title title: navTitle, //此处写页面的title
}); });
this.sn = options.sn; this.sn = options.sn;
let dsku = decodeURIComponent(options.sku); this.sku = storage.getAfterSaleData();;
let newSku = JSON.parse(dsku);
this.sku = newSku;
this.form.orderItemSn = options.sn; this.form.orderItemSn = options.sn;
this.form.skuId = this.sku.skuId; this.form.skuId = this.sku.skuId;
@@ -305,6 +310,7 @@ export default {
return false; return false;
} }
console.log(this.form.accountType)
if (this.form.accountType == "BANK_TRANSFER") { if (this.form.accountType == "BANK_TRANSFER") {
// 银行开户行校验 // 银行开户行校验
if (this.$u.test.isEmpty(this.form.bankDepositName)) { if (this.$u.test.isEmpty(this.form.bankDepositName)) {
@@ -462,7 +468,6 @@ page,
align-items: center; align-items: center;
} }
.images-view { .images-view {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
@@ -484,12 +489,11 @@ page,
background-color: #ffffff; background-color: #ffffff;
height: 100rpx; height: 100rpx;
width: 750rpx; width: 750rpx;
justify-content: flex-end;
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
/deep/ .u-btn{ padding-right: 32rpx;
width: 94% !important;
}
} }
</style> </style>

View File

@@ -57,6 +57,7 @@
<script> <script>
import { getLogistics } from "@/api/address.js"; import { getLogistics } from "@/api/address.js";
import { fillShipInfo } from "@/api/after-sale.js"; import { fillShipInfo } from "@/api/after-sale.js";
import storage from "@/utils/storage";
export default { export default {
data() { data() {
@@ -76,7 +77,8 @@ export default {
}; };
}, },
onLoad(options) { onLoad(options) {
this.sku = JSON.parse(decodeURIComponent(options.sku));
this.sku = storage.getAfterSaleData();
let navTitle = "服务单详情"; let navTitle = "服务单详情";
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: navTitle, //此处写页面的title title: navTitle, //此处写页面的title

View File

@@ -34,7 +34,7 @@
<view class="select-title">退货</view> <view class="select-title">退货</view>
<view class="select-sub-title"> <view class="select-sub-title">
退回收到的商品 退回收到的商品
<uni-icons color="#BABABA" type="arrowright"></uni-icons> <u-icon name="arrow-right" color="#bababa"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -46,7 +46,7 @@
<view class="select-title">退款</view> <view class="select-title">退款</view>
<view class="select-sub-title"> <view class="select-sub-title">
退款商品返还金额 退款商品返还金额
<uni-icons color="#BABABA" type="arrowright"></uni-icons> <u-icon name="arrow-right" color="#bababa"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -55,13 +55,9 @@
</template> </template>
<script> <script>
import UniIcons from "@/components/uni-icons/uni-icons.vue";
import { getAfterSaleInfo } from "@/api/after-sale"; import { getAfterSaleInfo } from "@/api/after-sale";
import storage from "@/utils/storage";
export default { export default {
components: {
UniIcons,
},
data() { data() {
return { return {
sn: "", sn: "",
@@ -71,10 +67,7 @@ export default {
}, },
onLoad(options) { onLoad(options) {
this.sn = options.sn; this.sn = options.sn;
let dData = decodeURIComponent(options.sku); this.sku = storage.getAfterSaleData();
let newData = JSON.parse(dData);
this.sku = newData;
// 查看当前商品是否支持退款退货 // 查看当前商品是否支持退款退货
this.init() this.init()
}, },
@@ -93,9 +86,7 @@ export default {
*/ */
onSelect(value) { onSelect(value) {
uni.redirectTo({ uni.redirectTo({
url: `./afterSalesDetail?sn=${this.sn}&sku=${encodeURIComponent( url: `./afterSalesDetail?sn=${this.sn}&value=${value}`,
JSON.stringify(this.sku)
)}&value=${value}`,
}); });
}, },

View File

@@ -28,7 +28,7 @@
logs[0].message logs[0].message
}}</view> }}</view>
</view> </view>
<uni-icons type="arrowright" style="margin-right: 5px"></uni-icons> <u-icon name="arrow-right" style="margin-right: 5px" size="30" color="#999"></u-icon>
</view> </view>
</view> </view>
<view class="goods-info"> <view class="goods-info">
@@ -90,11 +90,14 @@
serviceDetail.afterSaleImage && serviceDetail.afterSaleImage &&
serviceDetail.afterSaleImage.split(',').length != 0 serviceDetail.afterSaleImage.split(',').length != 0
"> ">
<image :src="img" @click="preview(serviceDetail.afterSaleImage.split(','), index)" v-for="(img, index) in serviceDetail.afterSaleImage.split(',')" :key="index" <view v-for="(img, index) in serviceDetail.afterSaleImage.split(',')" :key="index">
style="width: 50px; height: 50px; margin: 0px 5px"></image> <u-image width="100" height="100" :src="img" @click="preview(serviceDetail.afterSaleImage.split(','), index)"
></u-image>
</view>
</view> </view>
<!-- 如果服务类型为退款则不显示 --> <!-- 如果服务类型为退款则不显示 -->
<view class="detail-item" v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'"> <view class="detail-item"
v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'">
<view class="title">收货地址:</view> <view class="title">收货地址:</view>
<view class="value"> <view class="value">
<span v-if="storeAfterSaleAddress.salesConsigneeAddressPath">{{ <span v-if="storeAfterSaleAddress.salesConsigneeAddressPath">{{
@@ -103,12 +106,14 @@
</view> </view>
</view> </view>
<!-- 如果服务类型为退款则不显示 --> <!-- 如果服务类型为退款则不显示 -->
<view class="detail-item" v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'"> <view class="detail-item"
v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'">
<view class="title">联系人:</view> <view class="title">联系人:</view>
<view class="value">{{ storeAfterSaleAddress.salesConsigneeName }}</view> <view class="value">{{ storeAfterSaleAddress.salesConsigneeName }}</view>
</view> </view>
<!-- 如果服务类型为退款则不显示 --> <!-- 如果服务类型为退款则不显示 -->
<view class="detail-item" v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'"> <view class="detail-item"
v-if="serviceDetail.serviceType != 'RETURN_MONEY' && serviceDetail.serviceStatus != 'APPLY'">
<view class="title">联系方式:</view> <view class="title">联系方式:</view>
<view class="value">{{ <view class="value">{{
storeAfterSaleAddress.salesConsigneeMobile || "" | secrecyMobile storeAfterSaleAddress.salesConsigneeMobile || "" | secrecyMobile
@@ -193,16 +198,11 @@
<script> <script>
import { import {
getServiceDetail, getServiceDetail,
getstoreAfterSaleAddress, getStoreAfterSaleAddress,
getAfterSaleLog, getAfterSaleLog,
getAfterSaleReason, getAfterSaleReason,
} from "@/api/after-sale.js"; } from "@/api/after-sale.js";
import UniIcons from "@/components/uni-icons/uni-icons.vue";
export default { export default {
components: {
UniIcons,
},
data() { data() {
return { return {
reason: "", //申请原因 reason: "", //申请原因
@@ -316,7 +316,7 @@ export default {
* 获取地址信息 * 获取地址信息
*/ */
getAddress() { getAddress() {
getstoreAfterSaleAddress(this.sn).then((res) => { getStoreAfterSaleAddress(this.sn).then((res) => {
if (res.data.success) { if (res.data.success) {
this.storeAfterSaleAddress = res.data.result; this.storeAfterSaleAddress = res.data.result;
} }
@@ -339,9 +339,7 @@ export default {
getAfterSaleReason(serviceType).then((res) => { getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) { if (res.data.success) {
// 1357583466371219456 // 1357583466371219456
this.reason = res.data.result.filter((item) => { this.reason = this.serviceDetail.reason;
return item.id == this.serviceDetail.reason;
})[0].reason;
} }
}); });
}, },
@@ -367,12 +365,13 @@ export default {
(this.serviceDetail.serviceType === "RETURN_GOODS" || (this.serviceDetail.serviceType === "RETURN_GOODS" ||
this.serviceDetail.serviceType === "ORDER_CANCEL") && this.serviceDetail.serviceType === "ORDER_CANCEL") &&
this.serviceDetail.refundWay === "OFFLINE"; this.serviceDetail.refundWay === "OFFLINE";
this.bankShow = this.bankShow =
this.serviceDetail.serviceType === "RETURN_MONEY" || this.serviceDetail.accountType === "BANK_TRANSFER" &&
((this.serviceDetail.serviceType === "RETURN_GOODS" || this.serviceDetail.refundWay === "OFFLINE" &&
this.serviceDetail.serviceType === "ORDER_CANCEL") && ((this.serviceDetail.serviceType === "RETURN_GOODS") |
this.serviceDetail.refundWay === "OFFLINE" && (this.serviceDetail.serviceType === "ORDER_CANCEL") ||
this.serviceDetail.accountType === "BANK_TRANSFER"); this.serviceDetail.serviceType === "RETURN_MONEY");
this.getReasonList(this.serviceDetail.serviceType); this.getReasonList(this.serviceDetail.serviceType);
}); });

View File

@@ -45,7 +45,7 @@
<view class="cell-item"> <view class="cell-item">
<view class="cell-title"> 投诉凭证 </view> <view class="cell-title"> 投诉凭证 </view>
<view class="cell-view"> <view class="cell-view">
<u-upload ref="uUpload" :header=" { accessToken: storage.getAccessToken() }" upload-text="" :show-progress="false" :action="action" width="100" @on-uploaded="onUploaded" :max-count="5"> <u-upload ref="uUpload" :header=" { accessToken: storage.getAccessToken() }" upload-text="" :action="action" width="100" @on-uploaded="onUploaded" :max-count="5">
</u-upload> </u-upload>
</view> </view>
</view> </view>

View File

@@ -2,7 +2,8 @@
<view> <view>
<view class="wrap"> <view class="wrap">
<view class="u-tabs-box"> <view class="u-tabs-box">
<u-tabs :list="list" :is-scroll="false" inactive-color="#333" :current="current" class="utabs" :active-color="$lightColor" @change="changeTab"></u-tabs> <u-tabs :list="list" :is-scroll="false" inactive-color="#333" :current="current" class="utabs"
:active-color="$lightColor" @change="changeTab"></u-tabs>
</view> </view>
<swiper class="swiper-box" :current="current" @change="changeSwiper" duration="500"> <swiper class="swiper-box" :current="current" @change="changeSwiper" duration="500">
<swiper-item v-for="(item, listIndex) in list" :key="listIndex"> <swiper-item v-for="(item, listIndex) in list" :key="listIndex">
@@ -18,14 +19,15 @@
<view v-for="(sku, _index) in order.orderItems" :key="_index"> <view v-for="(sku, _index) in order.orderItems" :key="_index">
<view class="goods-item-view"> <view class="goods-item-view">
<view> <view>
<u-image border-radius="6rpx" width="132rpx" height="132rpx" class="goods_img" :src="sku.image" alt /> <u-image border-radius="6rpx" width="132rpx" height="132rpx" class="goods_img" :src="sku.image"
alt />
</view> </view>
<view class="goods-info"> <view class="goods-info">
<view class="goods-title u-line-2">{{ sku.name }}</view> <view class="goods-title u-line-2">{{ sku.name }}</view>
<view class="text title">{{ gradeList[order.grade] || '' }}</view> <view class="text title">{{ gradeList[order.grade] || '' }}</view>
</view> </view>
</view> </view>
<view class="btn-view u-row-between" v-if="current != 0"> <view class="btn-view u-row-between" v-if="current == 2">
<view class="description"> <view class="description">
<view class="text title"> <view class="text title">
<u-read-more ref="uReadMore" :color="$lightColor" text-indent="0"> <u-read-more ref="uReadMore" :color="$lightColor" text-indent="0">
@@ -34,7 +36,8 @@
</view> </view>
<view class="goods-imgs-view" v-if="order.image"> <view class="goods-imgs-view" v-if="order.image">
<view class="img-view" v-if="order.image" v-for="(img, imgIndex) in order.image.split(',')" :key="imgIndex"> <view class="img-view" v-if="order.image" v-for="(img, imgIndex) in order.image.split(',')"
:key="imgIndex">
<u-image v-if="order.image" @click.native=" <u-image v-if="order.image" @click.native="
preview(order.image.split(','), imgIndex) preview(order.image.split(','), imgIndex)
" width="160rpx" height="160rpx" :src="img"></u-image> " width="160rpx" height="160rpx" :src="img"></u-image>
@@ -42,17 +45,21 @@
</view> </view>
</view> </view>
</view> </view>
<view class="again-btn" @click="onDetail(order)" v-if="current == 1"> <view class="again-btn" @click="onDetail(order)" v-if="current == 2">
<u-tag text="评价详情" shape="circle" mode="plain" type="error" /> <u-tag text="评价详情" shape="circle" mode="plain" type="error" />
</view> </view>
<view v-if="current == 0 && sku.commentStatus == 'UNFINISHED'"> <view v-if="current == 1 && sku.commentStatus == 'UNFINISHED'">
<view class="evaluate"> <view class="evaluate">
<view @click="talkCommont(order)"> <view @click="talkCommont(sku)">
<u-tag text="发表评价" shape="circle" mode="plain" type="error" /> <u-tag text="发表评价" shape="circle" mode="plain" type="error" />
</view> </view>
</view> </view>
</view> </view>
<view class="tips" v-if="sku.commentStatus">
{{groupCommentStatusWay[sku.commentStatus]}}
</view>
</view> </view>
</view> </view>
<uni-load-more :status="params.loadStatus"></uni-load-more> <uni-load-more :status="params.loadStatus"></uni-load-more>
</scroll-view> </scroll-view>
@@ -69,7 +76,12 @@ import { getComments } from "@/api/members.js";
export default { export default {
data() { data() {
return { return {
list: [ //顶部tab list: [
//顶部tab
{
name: "全部订单",
},
{ {
name: "待评价", name: "待评价",
}, },
@@ -77,12 +89,19 @@ export default {
name: "已评价", name: "已评价",
}, },
], ],
gradeList: { //评论表 gradeList: {
//评论表
GOOD: "好评", GOOD: "好评",
MODERATE: "中评", MODERATE: "中评",
WORSE: "差评", WORSE: "差评",
haveImage: "有图", haveImage: "有图",
}, },
groupCommentStatusWay: {
NEW: "新订单,不能进行评论",
UNFINISHED: "未完成评论",
WAIT_CHASE: "待追评的评论信息",
FINISHED: "已经完成评论",
},
current: 0, //当前tabIndex current: 0, //当前tabIndex
orderList: [], //商品集合 orderList: [], //商品集合
params: { params: {
@@ -108,12 +127,18 @@ export default {
this.params.loadStatus = "more"; this.params.loadStatus = "more";
this.orderList = []; this.orderList = [];
//重新读取数据 //重新读取数据
if (val == 0) { if (val == 0) {
delete this.params.commentStatus
this.loadData(); this.loadData();
} } else if (val == 1) {
if (val == 1) { this.params.commentStatus = "UNFINISHED";
this.orderList = []; this.orderList = [];
this.loadComments(); this.loadData();
} else {
this.params.commentStatus = "FINISHED";
this.orderList = [];
return this.loadComments();
} }
}, },
}, },
@@ -123,7 +148,7 @@ export default {
* 判断当前店铺是否有可评价的商品 * 判断当前店铺是否有可评价的商品
*/ */
commentStatus(val) { commentStatus(val) {
if (this.current == 1) { if (this.current == 2) {
return true; return true;
} else { } else {
let show; let show;
@@ -192,10 +217,11 @@ export default {
/** /**
* 发表评价 * 发表评价
*/ */
talkCommont(order) { talkCommont(sku) {
console.log(sku);
uni.navigateTo({ uni.navigateTo({
url: `./releaseEvaluate?sn=${order.sn}&order=${encodeURIComponent( url: `./releaseEvaluate?sn=${sku.sn}&sku=${encodeURIComponent(
JSON.stringify(order) JSON.stringify(sku)
)}`, )}`,
}); });
}, },
@@ -235,11 +261,7 @@ export default {
if (this.params.loadStatus == "noMore") return; if (this.params.loadStatus == "noMore") return;
if (index == 0) { if (index == 0) {
this.loadData(); this.loadData();
} } else {
if (index == 1) {
this.params.audit_status = "PASS_AUDIT";
this.params.comments_type = "INITIAL";
this.params.comment_status = "WAIT_CHASE";
this.loadComments(); this.loadComments();
} }
}, },
@@ -261,6 +283,11 @@ export default {
page { page {
height: 100%; height: 100%;
} }
.tips {
text-align: right;
font-size: 24rpx;
color: #999;
}
.wrap { .wrap {
background: #f6f6f6; background: #f6f6f6;
height: calc(100vh - var(--window-top)); height: calc(100vh - var(--window-top));

View File

@@ -1,7 +1,7 @@
<template> <template>
<view> <view>
<!-- 遍历出评价商品 --> <!-- 遍历出评价商品 -->
<view v-for="(sku, index) in order.orderItems" :key="index"> <view>
<view class="after-sales-goods-detail-view"> <view class="after-sales-goods-detail-view">
<view> <view>
<view class="goods-item-view"> <view class="goods-item-view">
@@ -23,23 +23,27 @@
<view class="sub-title">满意请打好评哦</view> <view class="sub-title">满意请打好评哦</view>
</view> </view>
<view class="rate-view"> <view class="rate-view">
<view class="rate-btn" @click="onGrade('GOOD', index)"> <view class="rate-btn" @click="onGrade('GOOD')">
<view style="font-size: 42rpx" :style="{ color: form.grade === 'GOOD' ? 'red' : '#CCCCCC' }" class="alifont icon-haoping1"></view> <u-icon name="heart-fill" style="font-size: 42rpx"
:style="{ color: form.grade === 'GOOD' ? 'red' : '#CCCCCC' }"></u-icon>
<text>好评</text> <text>好评</text>
</view> </view>
<view class="rate-btn" @click="onGrade('MODERATE', index)"> <view class="rate-btn" @click="onGrade('MODERATE')">
<view style="font-size: 42rpx" :style="{ color: form.grade === 'MODERATE' ? 'red' : '#CCCCCC' }" class="alifont icon-zhongping1"></view> <u-icon name="heart-fill" style="font-size: 42rpx"
:style="{ color: form.grade === 'MODERATE' ? 'red' : '#CCCCCC' }"></u-icon>
<text>中评</text> <text>中评</text>
</view> </view>
<view class="rate-btn" @click="onGrade('WORSE', index)"> <view class="rate-btn" @click="onGrade('WORSE')">
<view style="font-size: 42rpx" :style="{ color: form.grade === 'WORSE' ? 'red' : '#CCCCCC' }" class="alifont icon-chaping"></view> <u-icon name="heart-fill" style="font-size: 42rpx"
:style="{ color: form.grade === 'WORSE' ? 'red' : '#CCCCCC' }"></u-icon>
<text>差评</text> <text>差评</text>
</view> </view>
</view> </view>
</view> </view>
<view class="info-evaluate-view"> <view class="info-evaluate-view">
<view class="input-view"> <view class="input-view">
<u-input v-model="form.content" height="200" placeholder-style="font-size:12px;color:#CCCCCC" :type="type" :border="border" :maxlength="maxlength" :placeholder="placeholder" /> <u-input v-model="form.content" height="200" placeholder-style="font-size:12px;color:#CCCCCC" :type="type"
:border="border" :maxlength="maxlength" :placeholder="placeholder" />
</view> </view>
<view class="input-num"> <view class="input-num">
<text>{{ form.content.length }}/{{ maxlength }}</text> <text>{{ form.content.length }}/{{ maxlength }}</text>
@@ -47,7 +51,8 @@
</view> </view>
<view class="info-evaluate-view"> <view class="info-evaluate-view">
<view class="images-view"> <view class="images-view">
<u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150" @on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload> <u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150"
@on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload>
</view> </view>
</view> </view>
</view> </view>
@@ -57,7 +62,8 @@
<view class="seller-rate-view"> <view class="seller-rate-view">
<view class="rate-title">描述相符</view> <view class="rate-title">描述相符</view>
<view> <view>
<u-rate count="count" gutter="20" active-color="#FFC71C" v-model="form.descriptionScore" :size="40"></u-rate> <u-rate count="count" gutter="20" active-color="#FFC71C" v-model="form.descriptionScore" :size="40">
</u-rate>
</view> </view>
</view> </view>
<view class="seller-rate-view"> <view class="seller-rate-view">
@@ -94,7 +100,7 @@ export default {
maxlength: 500, //评价最大字数为500字 maxlength: 500, //评价最大字数为500字
placeholder: placeholder:
"宝贝满足您的期待吗?说说它的优点和美中不足的地方吧。您的评价会帮助更多的人", "宝贝满足您的期待吗?说说它的优点和美中不足的地方吧。您的评价会帮助更多的人",
order: {}, //订单信息 sku: {}, //订单信息
form: { form: {
content: "", //评价详情 content: "", //评价详情
goodsId: "", //商品id goodsId: "", //商品id
@@ -111,10 +117,9 @@ export default {
onLoad(options) { onLoad(options) {
// 获取上一级传过来的数据进行解析 // 获取上一级传过来的数据进行解析
this.form.orderItemSn = options.sn; this.form.orderItemSn = options.sn;
this.order = JSON.parse(decodeURIComponent(options.order)); this.sku = JSON.parse(decodeURIComponent(options.sku));
this.form.goodsId = this.order.orderItems[0].goodsId; this.form.goodsId = this.sku.goodsId;
this.form.orderItemSn = this.order.orderItems[0].sn; this.form.skuId = this.sku.skuId;
this.form.skuId = this.order.orderItems[0].skuId;
}, },
methods: { methods: {
/** /**
@@ -141,7 +146,7 @@ export default {
success: () => { success: () => {
setTimeout(() => { setTimeout(() => {
uni.navigateBack(); uni.navigateBack();
}, 2000); }, 500);
}, },
}); });
} }

View File

@@ -11,8 +11,12 @@
<div class="flex flex-a-c"> <div class="flex flex-a-c">
<span class="default" v-if="address.isDefault">默认</span> <span class="default" v-if="address.isDefault">默认</span>
<div class="address-list" v-if="address.consigneeAddressPath.length != 0"> <div class="address-list" v-if="address.consigneeAddressPath.length != 0">
<span class="address-item" v-for="(item,index) in address.consigneeAddressPath" :key="index"> <span
{{item}} class="address-item"
v-for="(item, index) in address.consigneeAddressPath"
:key="index"
>
{{ item }}
</span> </span>
</div> </div>
</div> </div>
@@ -38,23 +42,46 @@
<view class="group-box" v-if="isAssemble"> <view class="group-box" v-if="isAssemble">
<view class="group-title"> <view class="group-title">
<span v-if="pintuanFlage">你正在开团购买</span> <span v-if="pintuanFlage">你正在开团购买</span>
<span v-else>为你加入仅差<span>{{routerVal.parentOrder.toBeGroupedNum }}</span>人的团购买</span> <span v-else
>为你加入仅差<span>{{ routerVal.parentOrder.toBeGroupedNum }}</span
>人的团购买</span
>
</view> </view>
<view class="group"> <view class="group">
<view> <view>
<u-image borderRadius="50%" shape="square" class="head-img" width="81rpx" height="81rpx" <u-image
:src="masterWay.face || '/static/missing-face.png'"></u-image> borderRadius="50%"
shape="square"
class="head-img"
width="81rpx"
height="81rpx"
:src="masterWay.face || '/static/missing-face.png'"
></u-image>
<view class="btn-one">团长</view> <view class="btn-one">团长</view>
</view> </view>
<view class="line"> </view> <view class="line"> </view>
<view> <view>
<!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 --> <!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 -->
<u-image class="head-img" v-if="endWay.face" :src="endWay.face" borderRadius="50%" shape="square" <u-image
width="81rpx" height="81rpx"> class="head-img"
v-if="endWay.face"
:src="endWay.face"
borderRadius="50%"
shape="square"
width="81rpx"
height="81rpx"
>
<view slot="loading"></view> <view slot="loading"></view>
</u-image> </u-image>
<u-image class="head-img" borderRadius="50%" shape="square" v-else width="81rpx" height="81rpx" <u-image
:src="endWay.face || '/static/missing-face.png'"></u-image> class="head-img"
borderRadius="50%"
shape="square"
v-else
width="81rpx"
height="81rpx"
:src="endWay.face || '/static/missing-face.png'"
></u-image>
<view class="wait">{{ endWay.nickname || "等待参团" }}</view> <view class="wait">{{ endWay.nickname || "等待参团" }}</view>
</view> </view>
@@ -68,43 +95,88 @@
<span>{{ item.storeName }}</span> <span>{{ item.storeName }}</span>
</div> </div>
</div> </div>
<div class="promotionNotice">{{ item.promotionNotice || '' }}</div> <div class="promotionNotice">{{ item.promotionNotice || "" }}</div>
<div class="flex goods-item" v-for="(val, i) in item.skuList" :key="i"> <div class="flex goods-item" v-for="(val, i) in item.skuList" :key="i">
<div class="goods-image" <div
@click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)" :span="3"> class="goods-image"
<u-image borderRadius="10rpx" width="200rpx" height="200rpx" :src="val.goodsSku.thumbnail" alt /> @click="
navigateTo(
'/pages/product/goods?id=' +
val.goodsSku.id +
'&goodsId=' +
val.goodsSku.goodsId
)
"
:span="3"
>
<u-image
borderRadius="10rpx"
width="200rpx"
height="200rpx"
:src="val.goodsSku.thumbnail"
alt
/>
</div> </div>
<div @click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)" <div
class="goods-detail"> @click="
navigateTo(
'/pages/product/goods?id=' +
val.goodsSku.id +
'&goodsId=' +
val.goodsSku.goodsId
)
"
class="goods-detail"
>
<div class="flex"> <div class="flex">
<p class="goods-name">{{ val.goodsSku.goodsName }}</p> <p class="goods-name">{{ val.goodsSku.goodsName }}</p>
<span class="nums">x{{ val.num }}</span> <span class="nums">x{{ val.num }}</span>
</div> </div>
<p class="goods-prices"> <p class="goods-prices">
<span></span> <span></span>
<span class="goods-price">{{formatPrice(val.goodsSku.price)[0]}}</span> <span class="goods-price">{{ formatPrice(val.goodsSku.price)[0] }}</span>
<span>.{{formatPrice(val.goodsSku.price)[1] }}</span> <span>.{{ formatPrice(val.goodsSku.price)[1] }}</span>
</p> </p>
</div> </div>
</div> </div>
<u-row> <u-row>
<u-col :offset="0" :span="4">发票信息</u-col> <u-col :offset="0" :span="4">发票信息</u-col>
<u-col :span="8" class="tipsColor" textAlign="right" @click.native="invoice()"> <u-col :span="8" class="tipsColor" textAlign="right" @click.native="invoice()">
<span v-if="receiptList">{{receiptList.receiptTitle}} - {{receiptList.receiptContent}}</span> <span v-if="receiptList"
>{{ receiptList.receiptTitle }} - {{ receiptList.receiptContent }}</span
>
<span v-else>不开发票</span> <span v-else>不开发票</span>
</u-col> </u-col>
</u-row> </u-row>
<u-row> <u-row>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :offset="0" :span="9" @click="shippingFlag = true">配送 <u-col
v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:offset="0"
:span="9"
@click="shippingFlag = true"
>配送
</u-col> </u-col>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="3" textAlign="right" @click="shippingFlag = true"> <u-col
{{shippingMethod.find(e=>{ return e.value == shippingText; }).label }} v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:span="3"
textAlign="right"
@click="shippingFlag = true"
>
{{
shippingMethod.find((e) => {
return e.value == shippingText;
}).label
}}
</u-col> </u-col>
</u-row> </u-row>
<u-row> <u-row>
<u-col :offset="0" :span="4" class="tl" style="text-align: left">备注信息</u-col> <u-col :offset="0" :span="4" class="tl" style="text-align: left">备注信息</u-col>
<u-col :span="8" textAlign="right"> <u-col :span="8" textAlign="right">
<u-input style="text-align:right;" class="uinput" v-model="remarkVal[index].remark" /> <u-input
style="text-align: right"
class="uinput"
v-model="remarkVal[index].remark"
/>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
@@ -125,20 +197,31 @@
<div> <div>
<u-row> <u-row>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7">运费</u-col> <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7">运费</u-col>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="5" class="tr tipsColor" textAlign="right"> <u-col
v-if="orderMessage.cartTypeEnum != 'VIRTUAL'"
:span="5"
class="tr tipsColor"
textAlign="right"
>
<span v-if="orderMessage.priceDetailDTO.freightPrice == 0">包邮</span> <span v-if="orderMessage.priceDetailDTO.freightPrice == 0">包邮</span>
<span v-else>{{ <span v-else
orderMessage.priceDetailDTO.freightPrice | unitPrice >{{ orderMessage.priceDetailDTO.freightPrice | unitPrice }}</span
}}</span> >
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
<u-row> <u-row>
<u-col :offset="0" :span="9" @click="GET_Discount()">优惠券</u-col> <u-col :offset="0" :span="9" @click="GET_Discount()">优惠券</u-col>
<u-col :span="3" v-if="orderMessage.priceDetailDTO && orderMessage.priceDetailDTO.couponPrice" textAlign="right" <u-col
@click="GET_Discount()"> :span="3"
<span class="main-color">-{{orderMessage.priceDetailDTO.couponPrice | unitPrice}}</span> v-if="orderMessage.priceDetailDTO && orderMessage.priceDetailDTO.couponPrice"
textAlign="right"
@click="GET_Discount()"
>
<span class="main-color"
>-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span
>
</u-col> </u-col>
<!-- orderMessage.priceDetailDTO.couponPrice | unitPrice --> <!-- orderMessage.priceDetailDTO.couponPrice | unitPrice -->
<u-col :span="3" v-else textAlign="right" @click="GET_Discount()"> <u-col :span="3" v-else textAlign="right" @click="GET_Discount()">
@@ -149,8 +232,15 @@
<div> <div>
<u-row> <u-row>
<u-col :span="9">优惠金额</u-col> <u-col :span="9">优惠金额</u-col>
<u-col :span="3" textAlign="right" v-if=" orderMessage.priceDetailDTO.couponPrice"> <u-col
-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</u-col> :span="3"
textAlign="right"
v-if="orderMessage.priceDetailDTO.couponPrice"
>
<span class="main-color">
-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span
></u-col
>
<u-col :span="3" textAlign="right" v-else>0.00</u-col> <u-col :span="3" textAlign="right" v-else>0.00</u-col>
</u-row> </u-row>
</div> </div>
@@ -158,18 +248,23 @@
<u-row> <u-row>
<u-col :span="6">活动优惠</u-col> <u-col :span="6">活动优惠</u-col>
<u-col :span="6" class="tr tipsColor" textAlign="right"> <u-col :span="6" class="tr tipsColor" textAlign="right">
<span <span v-if="orderMessage.priceDetailDTO.discountPrice"
v-if="orderMessage.priceDetailDTO.discountPrice">-{{orderMessage.priceDetailDTO.discountPrice | unitPrice}}</span> >-{{ orderMessage.priceDetailDTO.discountPrice | unitPrice }}</span
>
<span v-else>0.00</span> <span v-else>0.00</span>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
</div> </div>
<!-- 配送地区没有提示 --> <!-- 配送地区没有提示 -->
<div class="notSupportFreight" v-if="notSupportFreight.length !=0"> <div class="notSupportFreight" v-if="notSupportFreight.length != 0">
<u-notice-bar style="width:100%" :volume-icon="false" mode="horizontal" :list="notSupportFreightGoodsList"> <u-notice-bar
style="width: 100%"
:volume-icon="false"
mode="horizontal"
:list="notSupportFreightGoodsList"
>
</u-notice-bar> </u-notice-bar>
</div> </div>
@@ -179,11 +274,17 @@
<div class="tabbar-left"> <div class="tabbar-left">
<div v-if="!orderMessage.priceDetailDTO.payPoint" class="number"> <div v-if="!orderMessage.priceDetailDTO.payPoint" class="number">
<span>¥</span> <span>¥</span>
<span class="price">{{ formatPrice(orderMessage.priceDetailDTO.flowPrice)[0] }}</span> <span class="price">{{
<span>.{{formatPrice(orderMessage.priceDetailDTO.flowPrice)[1] }} </span> formatPrice(orderMessage.priceDetailDTO.flowPrice)[0]
}}</span>
<span>.{{ formatPrice(orderMessage.priceDetailDTO.flowPrice)[1] }} </span>
</div> </div>
<span v-else class="number"><span <span v-else class="number"
style="margin-right:10rpx;">{{orderMessage.priceDetailDTO.payPoint | unitPrice }}</span>积分</span> ><span style="margin-right: 10rpx">{{
orderMessage.priceDetailDTO.payPoint | unitPrice
}}</span
>积分</span
>
</div> </div>
<div class="navRiv" @click="createTradeFun()"> <div class="navRiv" @click="createTradeFun()">
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
@@ -192,7 +293,6 @@
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<div class="tabbar-right">微信支付</div> <div class="tabbar-right">微信支付</div>
<!-- #endif --> <!-- #endif -->
</div> </div>
</div> </div>
</div> </div>
@@ -348,9 +448,7 @@ export default {
this.navigateTo( this.navigateTo(
`/pages/mine/address/address?from=cart&way=${ `/pages/mine/address/address?from=cart&way=${
this.routerVal.way this.routerVal.way
}&parentOrder=${encodeURIComponent( }&parentOrder=${encodeURIComponent(JSON.stringify(this.routerVal.parentOrder))}`
JSON.stringify(this.routerVal.parentOrder)
)}`
); );
}, },
@@ -378,6 +476,18 @@ export default {
// 循环店铺id,商品id获取优惠券 // 循环店铺id,商品id获取优惠券
let store = []; let store = [];
let skus = []; let skus = [];
let selectedCoupon = [];
if (this.orderMessage.platformCoupon)
selectedCoupon.push(this.orderMessage.platformCoupon.memberCoupon.id);
if (
this.orderMessage.storeCoupons &&
Object.keys(this.orderMessage.storeCoupons)[0]
) {
let storeMemberCouponsId = Object.keys(this.orderMessage.storeCoupons)[0];
let storeCouponId = this.orderMessage.storeCoupons[storeMemberCouponsId]
.memberCoupon.id;
selectedCoupon.push(storeCouponId);
}
this.orderMessage.cartList.forEach((item) => { this.orderMessage.cartList.forEach((item) => {
item.skuList.forEach((sku) => { item.skuList.forEach((sku) => {
store.push(sku.storeId); store.push(sku.storeId);
@@ -391,7 +501,7 @@ export default {
data: this.orderMessage.priceDetailDTO.goodsPrice, data: this.orderMessage.priceDetailDTO.goodsPrice,
}); });
this.navigateTo( this.navigateTo(
`/pages/cart/coupon/index?way=${this.routerVal.way}&storeId=${store}&skuId=${skus}` `/pages/cart/coupon/index?way=${this.routerVal.way}&storeId=${store}&skuId=${skus}&selectedCoupon=${selectedCoupon}`
); );
}, },
@@ -498,8 +608,9 @@ export default {
// 如果没有商品选择地址的话 则选择 默认地址 // 如果没有商品选择地址的话 则选择 默认地址
API_Address.getAddressDefault().then((res) => { API_Address.getAddressDefault().then((res) => {
if (res.data.result) { if (res.data.result) {
res.data.result.consigneeAddressPath = res.data.result.consigneeAddressPath = res.data.result.consigneeAddressPath.split(
res.data.result.consigneeAddressPath.split(","); ","
);
this.address = res.data.result; this.address = res.data.result;
} }
}); });
@@ -507,8 +618,14 @@ export default {
// 获取结算参数 // 获取结算参数
getOrderList() { getOrderList() {
this.notSupportFreight = [];
// 获取结算参数 // 获取结算参数
API_Trade.getCheckoutParams(this.routerVal.way).then((res) => { API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
if (res.data.result.skuList.length <= 0) {
uni.redirectTo({
url: "/pages/order/myOrder?status=0",
});
}
res.data.result.cartList.forEach((item, index) => { res.data.result.cartList.forEach((item, index) => {
this.remarkVal[index] = { this.remarkVal[index] = {
remark: item.remark, remark: item.remark,
@@ -528,8 +645,9 @@ export default {
this.getUserAddress(); this.getUserAddress();
} else { } else {
this.address = res.data.result.memberAddress; this.address = res.data.result.memberAddress;
res.data.result.memberAddress.consigneeAddressPath = res.data.result.memberAddress.consigneeAddressPath = res.data.result.memberAddress.consigneeAddressPath.split(
res.data.result.memberAddress.consigneeAddressPath.split(","); ","
);
} }
if ( if (
@@ -575,7 +693,7 @@ page {
.nums { .nums {
flex: 2; flex: 2;
color: $light-color; color: $light-color;
text-align: center; text-align: center;
} }
.wait { .wait {
@@ -820,6 +938,7 @@ page {
border-radius: 8rpx; border-radius: 8rpx;
padding: 0rpx 12rpx; padding: 0rpx 12rpx;
color: #fff; color: #fff;
margin-right: 20rpx;
} }
.address-box { .address-box {
border-radius: 40rpx; border-radius: 40rpx;
@@ -830,9 +949,7 @@ page {
margin-bottom: 20rpx; margin-bottom: 20rpx;
color: #666; color: #666;
} }
.address-list {
margin-left: 20rpx;
}
.address-item { .address-item {
font-weight: normal; font-weight: normal;
letter-spacing: 1rpx; letter-spacing: 1rpx;

View File

@@ -57,7 +57,7 @@
<u-button ripple :customStyle="{'background':lightColor,'color':'#fff' }" shape="circle" class="pay-btn" size="mini" v-if="order.allowOperationVO.rog" @click="onRog(order.sn)"> <u-button ripple :customStyle="{'background':lightColor,'color':'#fff' }" shape="circle" class="pay-btn" size="mini" v-if="order.allowOperationVO.rog" @click="onRog(order.sn)">
确认收货 确认收货
</u-button> </u-button>
<u-button ripple shape="circle" class="cancel-btn" size="mini" v-if="order.groupAfterSaleStatus=='NOT_APPLIED'" @click="applyService(order)"> <u-button ripple shape="circle" class="cancel-btn" size="mini" v-if="order.groupAfterSaleStatus.includes('NOT_APPLIED')" @click="applyService(order)">
退款/售后 退款/售后
</u-button> </u-button>
<!-- TODO 后续完善 --> <!-- TODO 后续完善 -->

View File

@@ -155,7 +155,7 @@
<view class="invoice-info-view"> <view class="invoice-info-view">
<view class="ltitle">发票信息</view> <view class="ltitle">发票信息</view>
<view v-if="!order.needReceipt" class="value">无需发票</view> <view v-if="!order.needReceipt" class="value">无需发票</view>
<view v-else class="value" @click="onReceipt(order.receiptVO)">查看发票</view> <view v-else class="value" @click="onReceipt(orderDetail.receipt)">查看发票</view>
</view> </view>
</view> </view>
</view> </view>
@@ -324,7 +324,7 @@ export default {
}, },
gotoGoodsDetail(sku) { gotoGoodsDetail(sku) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${sku.id}&goodsId=${sku.goodsId}`, url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
}); });
}, },
onCopy(sn) { onCopy(sn) {

View File

@@ -1,250 +0,0 @@
<template>
<div class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<u-form-item class="cell" label-width="120" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item>
<u-form-item class="cell code" label-width="120" prop="code" label="验证码">
<div style="display:flex; width:100%;">
<u-input maxlength="6" v-model="codeForm.code" placeholder="请输入验证码" />
<u-verification-code keep-running unique-key="page-login" :seconds="seconds" @end="end" @start="start"
ref="uCode" @change="codeChange"></u-verification-code>
<view @tap="getCode" :style="{color:aiderLightColor}" class="text-tips">{{ tips }}</view>
</div>
</u-form-item>
<view class="submit bg-linear-gradient" @click="submit">登录</view>
<view :style="{color:aiderLightColor}" class="text-tips cell" @click="clickLogin">一键登录</view>
<myVerification v-if="codeFlag" @send="verification" class="verification" ref="verification" business="LOGIN" />
</u-form>
</div>
</template>
<script>
import { sendMobile, smsLogin } from "@/api/login";
import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js"; //缓存
import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
import myVerification from "@/components/verification/verification.vue"; //验证码模块
import uuid from "@/utils/uuid.modified.js"; // uuid
export default {
components: {
myVerification,
},
props: ["status"], //是否勾选 《用户隐私》和《隐私政策》
data() {
return {
aiderLightColor: this.$aiderLightColor,
uuid,
flage: false, //是否验证码验证
codeFlag: true, //验证开关,用于是否展示验证码
codeForm: {
mobile: "", //手机号
code: "", //验证码
},
tips: "", //提示,点击发送验证码和重新发送时赋值
clientType: "", // 客户端类型
seconds: 60, //默认验证码等待时间
// 二维码登录验证规则
codeRules: {
// 手机号验证
mobile: [
{
validator: (rule, value, callback) => {
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
trigger: ["blur"],
},
],
// 验证码验证
code: [
{
min: 4,
max: 6,
required: true,
message: "请输入验证码",
trigger: ["blur"],
},
],
},
};
},
// 必须要在onReady生命周期setRules因为onLoad生命周期组件可能尚未创建完毕
mounted() {
this.$refs.validateCodeForm.setRules(this.codeRules);
/**
* 条件编译判断当前客户端类型
*/
//#ifdef H5
this.clientType = "H5";
//#endif
//#ifdef APP-PLUS
this.clientType = "APP";
//#endif
},
watch: {
async flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
// 向后端请求验证码
uni.showLoading({
title: "正在获取验证码",
});
let res = await sendMobile(this.codeForm.mobile);
uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
}
} else {
this.$u.toast("请倒计时结束后再发送");
}
} else {
this.$refs.verification.hide();
}
},
},
methods: {
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
// 登录
submit() {
if (!this.status) {
/**
* 用户必须了解
* 用户协议以及隐私政策
*/
uni.showToast({
title: "请您阅读并同意用户协议以及隐私政策",
duration: 2000,
icon: "none",
});
return false;
}
let _this = this;
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
/**
* 清空当前账号信息
*/
storage.setHasLogin(false);
storage.setAccessToken("");
storage.setRefreshToken("");
storage.setUuid(this.uuid.v1());
storage.setUserInfo({});
/**
* 执行登录
*/
smsLogin(this.codeForm, _this.clientType).then((res) => {
if (res.data.success) {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
/**
* 登录成功后获取个人信息
*/
getUserInfo().then((user) => {
if (user.data.success) {
/**
* 个人信息存储到缓存userInfo中
*/
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
// 登录成功
uni.showToast({
title: "登录成功!",
icon: "none",
});
/**
* 计算出当前router路径
* 1.如果跳转的链接为登录页面或跳转的链接为空页面。则会重新跳转到首页
* 2.都不满足返回跳转页面
*/
whetherNavigate();
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
});
}
});
},
// 跳转到一键登录
clickLogin() {
this.$emit("open", "click");
},
/**点击验证码*/
codeChange(text) {
this.tips = text;
},
/** 结束验证码后执行 */
end() {},
/**获取验证码 */
getCode() {
if (this.tips == "重新获取") {
this.codeFlag = true;
uni.showLoading({
title: "加载中",
});
setTimeout(() => {
this.$refs.verification.hide();
uni.hideLoading();
}, 2000);
}
if (!this.$u.test.mobile(this.codeForm.mobile)) {
uni.showToast({
title: "请输入正确手机号",
icon: "none",
});
return false;
}
if (!this.flage) {
this.$refs.verification.error();
return false;
}
},
// 点击获取验证码
start() {
this.$u.toast("验证码已发送");
this.flage = false;
this.codeFlag = false;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("./login.scss");
// #ifdef MP-WEIXIN
@import url("./mp-codeLogin.scss");
// #endif
</style>

View File

@@ -1,68 +1,68 @@
.sub-title { .sub-title {
font-size: 24rpx; font-size: 24rpx;
color: #999; color: #999;
} }
.cell { .cell {
margin: 40rpx 0; margin: 40rpx 0;
} }
.login-ball { .login-ball {
border-bottom-left-radius: 300rpx; border-bottom-left-radius: 300rpx;
height: 400rpx; height: 400rpx;
position: relative; position: relative;
} }
/deep/ .u-form-item--right__content__slot { /deep/ .u-form-item--right__content__slot {
width: 100%; width: 100%;
display: block; display: block;
} }
.title { .title {
font-size: 48rpx; font-size: 48rpx;
color: #000; color: #000;
text-align: center; text-align: center;
} }
.privacy { .privacy {
font-size: 24upx; font-size: 24upx;
color: #999; color: #999;
text-align: center; text-align: center;
margin-top: 360rpx; margin-top: 360rpx;
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
span { span {
color: $aider-light-color; color: $aider-light-color;
} }
.form { .form {
padding: 0 72rpx; padding: 0 72rpx;
} }
.divider { .divider {
margin: 30rpx 0 !important; margin: 30rpx 0 !important;
} }
.submit { .submit {
height: 80rpx; height: 80rpx;
line-height: 80rpx; line-height: 80rpx;
color: #fff; color: #fff;
text-align: center; text-align: center;
font-size: 30rpx; font-size: 30rpx;
border-radius: 100px; border-radius: 100px;
} }
.logo { .logo {
margin-top: 20rpx; margin-top: 20rpx;
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
text-align: center; text-align: center;
} }
.logo-cell { .logo-cell {
text-align: center; text-align: center;
} }
.text-tips { .text-tips {
text-align: center; text-align: center;
} }
.tips { .tips {
position: absolute; position: absolute;
bottom: 10rpx; bottom: 10rpx;
width: 100%; width: 100%;
text-align: center; text-align: center;
} }

View File

@@ -1,45 +1,128 @@
<template> <template>
<view> <div class="wrapper">
<!-- --> <div v-if="!wechatLogin">
<view v-if="codeLogin"> <u-navbar :is-back="showBack" :border-bottom="false"></u-navbar>
<!-- 背景 --> <div>
<view class="login-ball bg-linear-gradient small"></view> <div class="title">{{loginTitleWay[current].title}}</div>
<div :class="current == 1 ? 'desc-light':'desc'">{{loginTitleWay[current].desc}}<span
<view class="logo-cell"> v-if="current == 1">{{mobile | secrecyMobile}}</span></div>
<image class="logo" :src="config.logo" mode="aspectFit"></image>
</view>
<view class="title">{{config.name}}</view>
<!-- 验证码登录 -->
<codeLogin @open="open" :status="value" v-if="login && loginData.code" />
<!-- 账号密码登录 -->
<onClickLogin @open="open" :status="value" v-if="login && loginData.click" />
<view class="form"> </view>
<!-- 隐私政策 -->
<div class="privacy">
<u-checkbox-group :icon-size="24" width="45rpx">
<u-checkbox v-model="value" :active-color="lightColor"></u-checkbox>
</u-checkbox-group>
同意<span @click="handleClick('user')">用户协议</span><span @click="handleClick('privacy')">隐私政策</span>
</div> </div>
</view> <!-- 手机号 -->
<view v-if="wechatLogin"> <div v-show="current==0">
<u-input :custom-style="inputStyle" :placeholder-style="placeholderStyle" placeholder="请输入手机号 (11位)"
class='mobile' focus v-model="mobile" type="number" maxlength="11" />
<div :class="!enabuleFetchCode ?'disable':'fetch'" @click="fetchCode" class=" btn">获取验证码</div>
<div class="flex">
<u-checkbox-group :icon-size="24" width="45rpx">
<u-checkbox shape="circle" v-model="enabulePrivacy" active-color="#FF5E00"></u-checkbox>
</u-checkbox-group>
<div class="tips">未注册的手机号验证后将自动创建用户账号登录即代表您已同意<span @click="navigateToPrivacy('privacy')">使用条款及隐私协议</span>
</div>
</div>
</div>
<!-- 输入验证码 -->
<div v-show="current==1" class="box-code">
<verifyCode type="bottom" @confirm="submit" boxActiveColor="#D8D8D8" v-model="code" isFocus
boxNormalColor="#D8D8D8" cursorColor="#D8D8D8" />
<div class="fetch-btn">
<u-verification-code change-text="验证码已发送x" end-text="重新获取验证码" unique-key="page-login"
:seconds="seconds" @end="end" @start="start" ref="uCode" @change="codeChange"></u-verification-code>
<span @tap="fetchCode" :style="{color:codeColor}"> {{tips}}</span>
</div>
</div>
<!-- 循环出当前可使用的第三方登录模式 -->
<div class="flex login-list">
<div v-if="item.code" :style="{background:item.color}" class="login-item" v-for="(item,index) in loginList" :key="index">
<u-icon v-if="item.title!='APPLE'" color="#fff" size="42" :name="item.icon" @click="navigateLogin(item)">
</u-icon>
<u-image v-else src="/static/appleidButton@2x.png" :lazy-load="false" @click="navigateLogin(item)" width="80"
height="80" />
</div>
</div>
<myVerification v-if="codeFlag" @send="verification" class="verification" ref="verification" business="LOGIN" />
</div>
<view v-else>
<wechatH5Login /> <wechatH5Login />
</view> </view>
</view> </div>
</template> </template>
<script> <script>
import codeLogin from "./codeLogin"; import { openIdLogin, loginCallback } from "@/api/connect.js";
import onClickLogin from "./onClickLogin"; import api from "@/config/api.js";
import { sendMobile, smsLogin } from "@/api/login";
import myVerification from "@/components/verification/verification.vue"; //验证码模块
import uuid from "@/utils/uuid.modified.js"; // uuid
import verifyCode from "@/components/verify-code/verify-code";
import { getUserInfo } from "@/api/members"; import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js"; import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
import { loginCallback } from "@/api/connect.js"; import storage from "@/utils/storage.js"; //缓存
import { webConnect } from "@/api/connect.js";
import config from "@/config/config";
import wechatH5Login from "./wechatH5Login.vue"; import wechatH5Login from "./wechatH5Login.vue";
import { webConnect } from "@/api/connect.js";
export default { export default {
components: { myVerification, verifyCode, wechatH5Login },
data() {
return {
uuid,
wechatLogin: false, //是否加载微信公众号登录
flage: false, //是否验证码验证
codeFlag: true, //验证开关,用于是否展示验证码
tips: "",
current: 0,
codeColor: "#999", //按钮验证码颜色
lightColor: this.$lightColor,
seconds: 60, //默认验证码等待时间
loginTitleWay: [
{
title: "欢迎登录",
desc: "登录后更精彩,美好生活即将开始",
},
{
title: "请输入验证码",
desc: "已经发送验证码至",
},
],
showBack: false,
enabuleFetchCode: false,
enabulePrivacy: false, //隐私政策
mobile: "", //手机号
code: "", //验证码
inputStyle: {
height: "104rpx",
"border-bottom": "1rpx solid #D8D8D8",
"letter-spacing": "1rpx",
"font-size": "40rpx",
"line-height": "40rpx",
color: "#333",
},
placeholderStyle: "font-size: 32rpx;line-height: 32rpx;color: #999999;",
loginList: [
//第三方登录集合
{
icon: "weixin-fill",
color: "#00a327",
title: "微信",
code: "WECHAT",
},
{
icon: "qq-fill",
color: "#38ace9",
title: "QQ",
code: "QQ",
},
{
icon: "apple-fill",
color: "#000000",
title: "Apple",
code: "APPLE",
},
],
};
},
onShow() { onShow() {
//#ifdef H5 //#ifdef H5
let isWXBrowser = /micromessenger/i.test(navigator.userAgent); let isWXBrowser = /micromessenger/i.test(navigator.userAgent);
@@ -53,26 +136,8 @@ export default {
} }
//#endif //#endif
}, },
data() {
return {
config,
lightColor: this.$lightColor,
wechatLogin: false, //是否加载微信公众号登录
codeLogin: false, //是否加载正常验证码登录
value: true, //隐私政策
loginData: {
code: true, //验证码登录
click: false,
},
login: true, //登录
};
},
watch: {},
components: {
codeLogin,
onClickLogin,
wechatH5Login,
},
mounted() { mounted() {
// #ifndef APP-PLUS // #ifndef APP-PLUS
//判断是否微信浏览器 //判断是否微信浏览器
@@ -80,34 +145,127 @@ export default {
if (ua.match(/MicroMessenger/i) == "micromessenger") { if (ua.match(/MicroMessenger/i) == "micromessenger") {
this.wechatLogin = true; this.wechatLogin = true;
return; return;
} else {
this.codeLogin = true;
} }
// #endif // #endif
// #ifdef APP-PLUS /**
this.codeLogin = true; * 条件编译判断当前客户端类型
*/
//#ifdef H5
this.clientType = "H5";
//#endif
//#ifdef APP-PLUS
this.clientType = "APP";
/**如果是app 加载支持的登录方式*/
let _this = this;
uni.getProvider({
service: "oauth",
success: (result) => {
_this.loginList = result.provider.map((value) => {
//展示title
let title = "";
//系统code
let code = "";
//颜色
let color = "#8b8b8b";
//图标
let icon = "";
//uni 联合登录 code
let appcode = "";
switch (value) {
case "weixin":
icon = "weixin-circle-fill";
color = "#00a327";
title = "微信";
code = "WECHAT";
break;
case "qq":
icon = "qq-circle-fill";
color = "#38ace9";
title = "QQ";
code = "QQ";
break;
case "apple":
icon = "apple-fill";
color = "#000000";
title = "Apple";
code = "APPLE";
break;
}
return {
title: title,
code: code,
color: color,
icon: icon,
appcode: value,
};
});
},
fail: (error) => {
uni.showToast({
title: "获取登录通道失败" + error,
duration: 2000,
icon: "none",
});
},
});
//#endif
//特殊平台,登录方式需要过滤
// #ifdef H5
this.methodFilter(["QQ"]);
// #endif
//微信小程序,只支持微信登录
// #ifdef MP-WEIXIN
this.methodFilter(["WECHAT"]);
// #endif // #endif
}, },
watch: {
current(val) {
val ? (this.showBack = true) : (this.showBack = false);
},
mobile: {
handler(val) {
if (val.length == 11) {
this.enabuleFetchCode = true;
}
},
},
async flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
// 向后端请求验证码
uni.showLoading({});
let res = await sendMobile(this.mobile);
uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.current = 1;
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
}
} else {
this.$u.toast("请倒计时结束后再发送");
}
} else {
this.$refs.verification.hide();
}
},
},
onLoad(options) { onLoad(options) {
if (options && options.state) { if (options && options.state) {
this.stateLogin(options.state); this.stateLogin(options.state);
} }
}, },
methods: { methods: {
handleClick(val) {
uni.navigateTo({
url: "/pages/mine/help/tips?type=" + val,
});
},
// open 开启另一个模板
open(val) {
Object.keys(this.loginData).forEach((item) => {
this.$set(this.loginData, item, false);
});
this.$set(this.loginData, val, true);
},
//联合信息返回登录 //联合信息返回登录
stateLogin(state) { stateLogin(state) {
loginCallback(state).then((res) => { loginCallback(state).then((res) => {
@@ -134,9 +292,363 @@ export default {
} }
}); });
}, },
/** 根据参数显示登录模块 */
methodFilter(code) {
let way = [];
this.loginList.forEach((item) => {
if (code.length != 0) {
code.forEach((val) => {
if (item.code == val) {
way.push(item);
}
});
} else {
uni.showToast({
title: "配置有误请联系管理员",
duration: 2000,
icon: "none",
});
}
});
this.loginList = way;
},
//非h5 获取openid
async nonH5OpenId(item) {
let _this = this;
//获取各个openid
await uni.login({
provider: item.appcode,
// #ifdef MP-ALIPAY
scopes: "auth_user", //支付宝小程序需设置授权类型
// #endif
success: function (res) {
uni.setStorageSync("type", item.code);
//微信小程序意外的其它方式直接在storage中写入openid
// #ifndef MP-WEIXIN
uni.setStorageSync("openid", res.authResult.openid);
// #endif
},
fail(e) {
uni.showToast({
title: "第三方登录暂不可用!",
icon: "none",
duration: 3000,
});
},
complete(e) {
//获取用户信息
uni.getUserInfo({
provider: item.appcode,
success: function (infoRes) {
//写入用户信息
uni.setStorageSync("nickname", infoRes.userInfo.nickName);
uni.setStorageSync("avatar", infoRes.userInfo.avatarUrl);
// #ifdef MP-WEIXIN
//微信小程序获取openid 需要特殊处理 如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id
_this.weixinMPOpenID(res).then((res) => {
//这里需要先行获得openid再使用openid登录小程序登录需要两步所以这里特殊编译
_this.goOpenidLogin("WECHAT_MP");
});
// #endif
// #ifndef MP-WEIXIN
_this.goOpenidLogin("APP");
//#endif
},
});
},
});
},
//openid 登录
goOpenidLogin(clientType) {
// 获取准备好的参数,进行登录系统
let params = {
uuid: uni.getStorageSync("openid"), //联合登陆id
source: uni.getStorageSync("type"), //联合登陆类型
nickname: uni.getStorageSync("nickname"), // 昵称
avatar: uni.getStorageSync("avatar"), // 头像
uniAccessToken: uni.getStorageSync("uni_access_token"), //第三方token
};
openIdLogin(params, clientType).then((res) => {
if (!res.data.success) {
let errormessage = "第三方登录暂不可用";
uni.showToast({
// title: '未绑定第三方账号',
title: errormessage,
icon: "none",
duration: 3000,
});
return;
} else {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
// 登录成功
uni.showToast({
title: "第三方登录成功!",
icon: "none",
});
// 执行登录
getUserInfo().then((user) => {
if (user.data.success) {
/**
* 个人信息存储到缓存userInfo中
*/
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
/**
* 计算出当前router路径
* 1.如果跳转的链接为登录页面或跳转的链接为空页面。则会重新跳转到首页
* 2.都不满足返回跳转页面
*/
whetherNavigate();
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
});
},
//微信小程序获取openid
async weixinMPOpenID(res) {
await miniProgramLogin(res.code).then((res) => {
uni.setStorageSync("openid", res.data);
});
},
/**跳转到登录页面 */
navigateLogin(connectLogin) {
// #ifdef H5
let code = connectLogin.code;
let buyer = api.buyer;
window.open(buyer + `/connect/login/web/` + code, "_self");
// #endif
// #ifdef APP-PLUS
this.nonH5OpenId(connectLogin);
// #endif
},
// 提交
submit() {
/**
* 清空当前账号信息
*/
storage.setHasLogin(false);
storage.setAccessToken("");
storage.setRefreshToken("");
storage.setUserInfo({});
/**
* 执行登录
*/
smsLogin({ mobile: this.mobile, code: this.code }, this.clientType).then(
(res) => {
if (res.data.success) {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
/**
* 登录成功后获取个人信息
*/
getUserInfo().then((user) => {
if (user.data.success) {
/**
* 个人信息存储到缓存userInfo中
*/
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
// 登录成功
uni.showToast({
title: "登录成功!",
icon: "none",
});
/**
* 计算出当前router路径
* 1.如果跳转的链接为登录页面或跳转的链接为空页面。则会重新跳转到首页
* 2.都不满足返回跳转页面
*/
whetherNavigate();
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
}
);
},
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
// 跳转
navigateToPrivacy(val) {
uni.navigateTo({
url: "/pages/mine/help/tips?type=" + val,
});
},
// 点击获取验证码
start() {
this.codeColor = "#999";
this.$u.toast("验证码已发送");
this.flage = false;
this.codeFlag = false;
this.$refs.verification.hide();
},
/**点击验证码*/
codeChange(text) {
this.tips = text;
},
/** 结束验证码后执行 */
end() {
this.codeColor = this.lightColor;
this.codeFlag = true;
console.log(this.codeColor);
},
// 发送验证码
fetchCode() {
if (!this.enabulePrivacy) {
uni.showToast({
title: "请同意用户隐私",
duration: 2000,
icon: "none",
});
return false;
}
if (!this.$u.test.mobile(this.mobile)) {
uni.showToast({
title: "请填写正确手机号",
duration: 2000,
icon: "none",
});
return false;
}
if (this.tips == "重新获取验证码") {
uni.showLoading({
title: "加载中",
});
if (!this.codeFlag) {
let timer = setInterval(() => {
if (this.$refs.verification) {
this.$refs.verification.error(); //发送
}
clearInterval(timer);
}, 100);
}
uni.hideLoading();
}
if (!this.flage) {
this.$refs.verification.error(); //发送
return false;
}
},
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style >
@import url("./login.scss"); page {
background: #fff;
}
</style> </style>
<style lang="scss" scoped>
.wrapper {
padding: 0 80rpx;
}
.title {
padding-top: calc(104rpx);
font-style: normal;
line-height: 1;
font-weight: 500;
font-size: 56rpx;
color: #333;
}
.box-code {
margin-top: 78rpx;
}
.desc,
.desc-light {
font-size: 32rpx;
line-height: 32rpx;
color: #333333;
margin-top: 40rpx;
}
.desc {
color: #333;
}
.desc-light {
color: #999999;
> span {
color: #333;
margin-left: 8rpx;
}
}
.mobile {
margin-top: 80rpx;
}
.disable {
background: linear-gradient(90deg, #ffdcba 2.21%, #ffcfb2 99.86%);
}
.fetch {
background: linear-gradient(57.72deg, #ff8a19 18.14%, #ff5e00 98.44%);
}
.btn {
border-radius: 100px;
width: 590rpx;
margin-top: 97rpx;
height: 80rpx;
font-size: 30rpx;
line-height: 80rpx;
text-align: center;
color: #ffffff;
}
.tips {
font-size: 12px;
line-height: 20px;
margin-top: 32rpx;
width: 546rpx;
> span {
color: $light-color;
}
}
.fetch-btn {
width: 370rpx;
height: 80rpx;
line-height: 80rpx;
text-align: center;
background: #f2f2f2;
border-radius: 100rpx;
font-size: 28rpx;
color: #999;
margin: 71rpx auto 0 auto;
}
.login-list {
display: flex;
width: 590rpx;
position: absolute;
bottom: 20px;
align-items: center;
justify-content: center;
}
.login-item {
width: 80rpx;
border-radius: 10rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
margin: 0 20rpx;
}
</style>

View File

@@ -1,8 +0,0 @@
/deep/ .u-form-item {
margin: 40rpx 0 !important;
padding: 40rpx 0 !important;
}
.submit {
margin-top: 40rpx;
}

View File

@@ -1,296 +0,0 @@
<template>
<div class="form">
<u-form ref="validateCodeForm">
<div class="login-list">
<!-- 循环出当前可使用的第三方登录模式 -->
<div :style="{background:item.color}" class="login-item" v-for="(item,index) in loginList" :key="index">
<u-icon v-if="item.title!='APPLE'" color="#fff" size="42" :name="item.icon" @click="navigateLogin(item)"></u-icon>
<u-image v-else src="/static/appleidButton@2x.png" :lazy-load="false" @click="navigateLogin(item)" width="80" height="80" />
</div>
</div>
<view :style="{color:aiderLightColor}" class="text-tips cell" @click="clickCodeLogin">账号密码登录</view>
</u-form>
</div>
</template>
<script>
import { openIdLogin } from "@/api/connect.js";
import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js";
import api from "@/config/api.js";
export default {
data() {
return {
aiderLightColor: this.$aiderLightColor,
loginList: [
{
icon: "weixin-fill",
color: "#00a327",
title: "微信",
code: "WECHAT",
},
{
icon: "qq-fill",
color: "#38ace9",
title: "QQ",
code: "QQ",
},
{
icon: "apple-fill",
color: "#000000",
title: "Apple",
code: "APPLE",
},
],
tips: "",
};
},
props: ["status"],
mounted() {
//#ifdef APP-PLUS
/**如果是app 加载支持的登录方式*/
let _this = this;
uni.getProvider({
service: "oauth",
success: (result) => {
_this.loginList = result.provider.map((value) => {
//展示title
let title = "";
//系统code
let code = "";
//颜色
let color = "#8b8b8b";
//图标
let icon = "";
//uni 联合登录 code
let appcode = "";
switch (value) {
case "weixin":
icon = "weixin-circle-fill";
color = "#00a327";
title = "微信";
code = "WECHAT";
break;
case "qq":
icon = "qq-circle-fill";
color = "#38ace9";
title = "QQ";
code = "QQ";
break;
case "apple":
icon = "apple-fill";
color = "#000000";
title = "Apple";
code = "APPLE";
break;
}
return {
title: title,
code: code,
color: color,
icon: icon,
appcode: value,
};
});
},
fail: (error) => {
uni.showToast({
title: "获取登录通道失败" + error,
duration: 2000,
icon: "none",
});
},
});
//#endif
//特殊平台,登录方式需要过滤
// #ifdef H5
this.methodFilter(["QQ"]);
// #endif
//微信小程序,只支持微信登录
// #ifdef MP-WEIXIN
this.methodFilter(["WECHAT"]);
// #endif
},
methods: {
/** 根据参数显示登录模块 */
methodFilter(code) {
let way = [];
this.loginList.forEach((item) => {
if (code.length != 0) {
code.forEach((val) => {
if (item.code == val) {
way.push(item);
}
});
} else {
uni.showToast({
title: "配置有误请联系管理员",
duration: 2000,
icon: "none",
});
}
});
this.loginList = way;
},
/**跳转到登录页面 */
navigateLogin(connectLogin) {
if (!this.status) {
uni.showToast({
title: "请您阅读并同意用户协议以及隐私政策",
duration: 2000,
icon: "none",
});
return false;
}
// #ifdef H5
let code = connectLogin.code;
let buyer = api.buyer;
window.open(buyer + `/connect/login/web/` + code, "_self");
// #endif
// #ifdef APP-PLUS
this.nonH5OpenId(connectLogin);
// #endif
},
// 跳转到一键登录
clickCodeLogin() {
this.$emit("open", "code");
},
//非h5 获取openid
async nonH5OpenId(item) {
let _this = this;
//获取各个openid
await uni.login({
provider: item.appcode,
// #ifdef MP-ALIPAY
scopes: "auth_user", //支付宝小程序需设置授权类型
// #endif
success: function (res) {
uni.setStorageSync("type", item.code);
//微信小程序意外的其它方式直接在storage中写入openid
// #ifndef MP-WEIXIN
uni.setStorageSync("openid", res.authResult.openid);
// #endif
},
fail(e) {
uni.showToast({
title: "第三方登录暂不可用!",
icon: "none",
duration: 3000,
});
},
complete(e) {
//获取用户信息
uni.getUserInfo({
provider: item.appcode,
success: function (infoRes) {
//写入用户信息
uni.setStorageSync("nickname", infoRes.userInfo.nickName);
uni.setStorageSync("avatar", infoRes.userInfo.avatarUrl);
// #ifdef MP-WEIXIN
//微信小程序获取openid 需要特殊处理 如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id
_this.weixinMPOpenID(res).then((res) => {
//这里需要先行获得openid再使用openid登录小程序登录需要两步所以这里特殊编译
_this.goOpenidLogin("WECHAT_MP");
});
// #endif
// #ifndef MP-WEIXIN
_this.goOpenidLogin("APP");
//#endif
},
});
},
});
},
//openid 登录
goOpenidLogin(clientType) {
let _this = this;
// 获取准备好的参数,进行登录系统
let params = {
uuid: uni.getStorageSync("openid"), //联合登陆id
source: uni.getStorageSync("type"), //联合登陆类型
nickname: uni.getStorageSync("nickname"), // 昵称
avatar: uni.getStorageSync("avatar"), // 头像
uniAccessToken: uni.getStorageSync("uni_access_token"), //第三方token
};
openIdLogin(params, clientType).then((res) => {
if (!res.data.success) {
let errormessage = "第三方登录暂不可用";
uni.showToast({
// title: '未绑定第三方账号',
title: errormessage,
icon: "none",
duration: 3000,
});
return;
} else {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
// 登录成功
uni.showToast({
title: "第三方登录成功!",
icon: "none",
});
// 执行登录
getUserInfo().then((user) => {
if (user.data.success) {
/**
* 个人信息存储到缓存userInfo中
*/
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
/**
* 计算出当前router路径
* 1.如果跳转的链接为登录页面或跳转的链接为空页面。则会重新跳转到首页
* 2.都不满足返回跳转页面
*/
whetherNavigate();
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
});
},
//微信小程序获取openid
async weixinMPOpenID(res) {
await miniProgramLogin(res.code).then((res) => {
uni.setStorageSync("openid", res.data);
});
},
},
};
</script>
<style lang="scss" scoped>
@import url("./login.scss");
.login-list {
margin: 140rpx 0;
display: flex;
align-items: center;
justify-content: space-around;
}
.login-item {
width: 80rpx;
border-radius: 10rpx;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
}
</style>

View File

@@ -1,31 +1,60 @@
<template> <template>
<div class="main-page"> <div class="main-page">
<!-- #ifdef APP-PLUS --> <!-- #ifdef APP-PLUS -->
<view class="status_bar"></view> <view class="status_bar"></view>
<!-- #endif --> <!-- #endif -->
<!-- 仅h5有效 打开App --> <!-- 仅h5有效 打开App -->
<!-- 分享 --> <!-- 分享 -->
<shares v-if="shareFlage && goodsDetail.id" :skuId="this.routerVal.id" :goodsId="this.routerVal.goodsId" <shares
:link="'/pages/product/goods?id='+this.routerVal.id+'&goodsId='+this.routerVal.goodsId" v-if="shareFlage && goodsDetail.id"
:thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods" @close="shareFlage = false" /> :skuId="this.routerVal.id"
<popups v-model="popupsSwitch" @tapPopup="handleNavbarList" :popData="navbarListData" :x="navbarListX" :goodsId="this.routerVal.goodsId"
:y="navbarListY" placement="top-start" /> :link="
'/pages/product/goods?id=' +
this.routerVal.id +
'&goodsId=' +
this.routerVal.goodsId
"
:thumbnail="goodsDetail.thumbnail"
:goodsName="goodsDetail.goodsName"
type="goods"
@close="shareFlage = false"
/>
<popups
v-model="popupsSwitch"
@tapPopup="handleNavbarList"
:popData="navbarListData"
:x="navbarListX"
:y="navbarListY"
placement="top-start"
/>
<view class="index"> <view class="index">
<!-- topBar --> <!-- topBar -->
<u-navbar :background="navbar" :is-back="false" :class="headerFlag ? 'header' : 'header bg-none scroll-hide'"> <u-navbar
:background="navbar"
:is-back="false"
:class="headerFlag ? 'header' : 'header bg-none scroll-hide'"
>
<div class="headerRow"> <div class="headerRow">
<div class="backs"> <div class="backs">
<u-icon @click="back()" name="arrow-left" class="icon-back"></u-icon> <u-icon @click="back()" name="arrow-left" class="icon-back"></u-icon>
<u-icon name="list" @click="popupsSwitch = !popupsSwitch" class="icon-list"></u-icon> <u-icon
name="list"
@click="popupsSwitch = !popupsSwitch"
class="icon-list"
></u-icon>
</div> </div>
<div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'"> <div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'">
<div class="headerRow"> <div class="headerRow">
<div class="nav-item" v-for="header in headerList" :key="header.id" <div
:class="{ cur: scrollId === header.id }" @click="headerTab(header.id)"> class="nav-item"
v-for="header in headerList"
:key="header.id"
:class="{ cur: scrollId === header.id }"
@click="headerTab(header.id)"
>
{{ header.text }} {{ header.text }}
</div> </div>
</div> </div>
@@ -33,44 +62,80 @@
</div> </div>
</u-navbar> </u-navbar>
<u-navbar :border-bottom="false" v-show="!headerFlag" class="header-only-back" :background="navbarOnlyBack" <u-navbar
:is-back="false"> :border-bottom="false"
v-show="!headerFlag"
class="header-only-back"
:background="navbarOnlyBack"
:is-back="false"
>
<div> <div>
<div class="bg-back"> <div class="bg-back">
<u-icon size="40" @click="back()" name="arrow-left" class="icon-back"></u-icon> <u-icon
<u-icon size="40" @click="popupsSwitch = !popupsSwitch" name="list" class="icon-list"></u-icon> size="40"
@click="back()"
name="arrow-left"
class="icon-back"
></u-icon>
<u-icon
size="40"
@click="popupsSwitch = !popupsSwitch"
name="list"
class="icon-list"
></u-icon>
</div> </div>
</div> </div>
</u-navbar> </u-navbar>
</view> </view>
<view class="product-container" :style="{ height: productRefHeight }" ref="productRef" id="productRef"> <view
<scroll-view scroll-anchoring enableBackToTop="true" scroll-with-animation scroll-y class="scroll-page" class="product-container"
:scroll-top="tabScrollTop" @scroll="pageScroll"> :style="{ height: productRefHeight }"
ref="productRef"
id="productRef"
>
<scroll-view
scroll-anchoring
enableBackToTop="true"
scroll-with-animation
scroll-y
class="scroll-page"
:scroll-top="tabScrollTop"
@scroll="pageScroll"
>
<view> <view>
<!-- 轮播图 --> <!-- 轮播图 -->
<GoodsSwiper id="main1" :res="imgList" /> <GoodsSwiper id="main1" :res="imgList" />
<!-- 促销活动条 --> <!-- 促销活动条 -->
<PromotionAssembleLayout v-if="PromotionList" :detail="goodsDetail" :res="PromotionList" /> <PromotionAssembleLayout
v-if="PromotionList"
:detail="goodsDetail"
:res="PromotionList"
/>
<view class="card-box top-radius-0" id="main2"> <view class="card-box top-radius-0" id="main2">
<!-- 活动不显示价钱 --> <!-- 活动不显示价钱 -->
<view v-if="!isPromotion" class="desc-bold -goods-msg"> <view v-if="!promotionFlag" class="desc-bold -goods-msg">
<view class="-goods-flex"> <view class="-goods-flex">
<view class="desc-bold"> <view class="desc-bold">
{{ goodsDetail.goodsName || "" }} {{ goodsDetail.goodsName || "" }}
</view> </view>
<view class="favorite" @click="clickFavorite(goodsDetail.id)"> <view class="favorite" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'"> <u-icon
size="30"
:color="favorite ? '#f2270c' : '#262626'"
:name="favorite ? 'heart-fill' : 'heart'"
>
</u-icon> </u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view> <view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{
favorite ? "已收藏" : "收藏"
}}</view>
</view> </view>
</view> </view>
<!-- 商品描述 --> <!-- 商品描述 -->
<view class="-goods-desc"> <view class="-goods-desc">
{{ goodsDetail.sellingPoint || '' }} {{ goodsDetail.sellingPoint || "" }}
</view> </view>
</view> </view>
<view v-else class="-goods-msg"> <view v-else class="-goods-msg">
@@ -79,31 +144,41 @@
<view class="-goods-flex"> <view class="-goods-flex">
<!-- 如果有积分显示积分 --> <!-- 如果有积分显示积分 -->
<view class="-goods-price" v-if="goodsDetail.price != undefined"> <view class="-goods-price" v-if="goodsDetail.price != undefined">
<span v-if="pointDetail.points"> <span class="price">{{pointDetail.points}}</span> <span v-if="pointDetail.points">
<span class="price">{{ pointDetail.points }}</span>
<span>积分</span> <span>积分</span>
</span> </span>
<span v-else> <span>¥</span><span class="price">{{ formatPrice(goodsDetail.price)[0] }}</span>.{{ <span v-else>
formatPrice(goodsDetail.price)[1] <span>¥</span
}} </span> ><span class="price">{{ formatPrice(goodsDetail.price)[0] }}</span
>.{{ formatPrice(goodsDetail.price)[1] }}
</span>
</view>
<view class="-goods-price" v-else>
¥<span class="price">0 </span>.00
</view> </view>
<view class="-goods-price" v-else> ¥<span class="price">0 </span>.00 </view>
<view class="icons share" @click="shareChange()"> <view class="icons share" @click="shareChange()">
<u-icon size="30" name="share-fill"></u-icon> <u-icon size="30" name="share-fill"></u-icon>
<view>分享</view> <view>分享</view>
</view> </view>
<view class="icons" @click="clickFavorite(goodsDetail.id)"> <view class="icons" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" <u-icon
:name="favorite ? 'heart-fill' : 'heart'"></u-icon> size="30"
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view> :color="favorite ? '#f2270c' : '#262626'"
:name="favorite ? 'heart-fill' : 'heart'"
></u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{
favorite ? "已收藏" : "收藏"
}}</view>
</view> </view>
</view> </view>
<view class="-goods-name desc-bold"> <view class="-goods-name desc-bold">
{{ goodsDetail.goodsName || "" }} {{ goodsDetail.goodsName || "" }}
</view> </view>
<view class="-goods-desc"> <view class="-goods-desc">
{{ goodsDetail.sellingPoint || '' }} {{ goodsDetail.sellingPoint || "" }}
</view> </view>
</view> </view>
</view> </view>
@@ -123,16 +198,22 @@
</view> </view>
<!-- 拼团用户列表 --> <!-- 拼团用户列表 -->
<PromotionAssembleListLayout v-if="isGroup" @to-assemble-buy-now="toAssembleBuyNow" :res="PromotionList" /> <PromotionAssembleListLayout
v-if="isGroup"
@to-assemble-buy-now="toAssembleBuyNow"
:res="PromotionList"
/>
<!-- 配置地址 如果是虚拟产品的时候不展示 --> <!-- 配置地址 如果是虚拟产品的时候不展示 -->
<view class="card-box" v-if="goodsDetail.goodsType !='VIRTUAL_GOODS'"> <view class="card-box" v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'">
<view class="card-flex" @click="shutMask(4)"> <view class="card-flex" @click="shutMask(4)">
<view class="card-title"> 已选 </view> <view class="card-title"> 已选 </view>
<view class="card-content"> <view class="card-content">
<span v-if="selectedGoods.spec">{{ selectedGoods.spec.specName }}-{{ <span v-if="selectedGoods.spec"
>{{ selectedGoods.spec.specName }}-{{
selectedGoods.spec.specValue selectedGoods.spec.specValue
}}</span> }}</span
>
<span v-else>默认</span> <span v-else>默认</span>
</view> </view>
<view class="card-bottom"> <view class="card-bottom">
@@ -140,7 +221,7 @@
</view> </view>
</view> </view>
<view class="card-flex" @click="shutMask(3)"> <view class="card-flex" @click="shutMask(3)">
<view class="card-title"> 送至 </view> <view class="card-title"> 送至</view>
<view class="card-content"> <view class="card-content">
<span v-if="delivery">{{ <span v-if="delivery">{{
delivery.consigneeAddressPath | clearStrComma delivery.consigneeAddressPath | clearStrComma
@@ -157,11 +238,21 @@
<Evaluation id="main5" :goodsDetail="goodsDetail" /> <Evaluation id="main5" :goodsDetail="goodsDetail" />
<!-- 店铺推荐 --> <!-- 店铺推荐 -->
<storeLayout id="main7" :storeDetail="storeDetail" :goodsDetail="goodsDetail" :res="recommendList" /> <storeLayout
id="main7"
:storeDetail="storeDetail"
:goodsDetail="goodsDetail"
:res="recommendList"
/>
<!-- 宝贝详情 --> <!-- 宝贝详情 -->
<GoodsIntro id="main9" :res="goodsDetail" :goodsParams="goodsParams" :goodsId="goodsDetail.goodsId" <GoodsIntro
v-if="goodsDetail.id" /> id="main9"
:res="goodsDetail"
:goodsParams="goodsParams"
:goodsId="goodsDetail.goodsId"
v-if="goodsDetail.id"
/>
<!-- 宝贝推荐 --> <!-- 宝贝推荐 -->
<GoodsRecommend id="main11" :res="likeGoodsList" /> <GoodsRecommend id="main11" :res="likeGoodsList" />
@@ -186,8 +277,13 @@
</view> </view>
<!-- 正常结算页面 --> <!-- 正常结算页面 -->
<view class="detail-btn" v-if="!isGroup"> <view class="detail-btn" v-if="!isGroup">
<view class="to-store-car to-store-btn" v-if="goodsDetail.goodsType!='VIRTUAL_GOODS'" @click="shutMask(4)"> <view
加入购物车</view> class="to-store-car to-store-btn"
v-if="goodsDetail.goodsType != 'VIRTUAL_GOODS'"
@click="shutMask(4)"
>
加入购物车</view
>
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view> <view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view> <view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
</view> </view>
@@ -204,33 +300,57 @@
</view> </view>
</view> </view>
<!-- 规格-模态层弹窗 --> <!-- 规格-模态层弹窗 -->
<view class="popup spec" @click="shutMask(false)" v-show="maskFlag"> <view class="spec">
<!-- 促销弹窗 --> <!-- 促销弹窗 -->
<view class="cuxiao mask" v-show="cuxiao"> <u-popup
<view ref="mask_title" class="title mask_title"> v-model="promotionShow"
优惠 :height="setup.height"
<span @click="shutMask(false)">×</span> :mode="setup.mode"
:border-radius="setup.radius"
@close="promotionShow = false"
:mask-close-able="setup.close"
closeable
>
<view class="header-title">优惠</view>
<view class="cuxiao">
<scroll-view class="scroll_mask" :scroll-y="true">
<view class="con-cuxiao">
<view class="cuxiao-title">促销活动</view>
<PromotionDetailsLayout :res="PromotionList" />
</view>
<view class="con-cuxiao coupons">
<view class="cuxiao-title">可领优惠券</view>
<PromotionCoupon @getCoupon="getCoupon" :res="PromotionList" />
</view>
</scroll-view>
</view> </view>
<scroll-view class="scroll_mask" :scroll-y="true"> </u-popup>
<view class="con-cuxiao">
<text>促销活动</text>
<PromotionDetailsLayout :res="PromotionList" />
</view>
<view class="con-cuxiao coupons">
<text>可领优惠券</text>
<PromotionCoupon @getCoupon="getCoupon" :res="PromotionList" />
</view>
</scroll-view>
</view>
<!-- 配送地址弹窗 --> <!-- 配送地址弹窗 -->
<popupAddress @closeAddress="closePopupAddress" @deliveryData="deliveryFun" v-if="goodsDetail.id" <popupAddress
:goodsId="goodsDetail.id" :addressFlag="addressFlag" /> @closeAddress="closePopupAddress"
@deliveryData="deliveryFun"
v-if="goodsDetail.id"
:goodsId="goodsDetail.id"
:addressFlag="addressFlag"
/>
<!-- 商品规格 商品详情以及默认参与活动的id--> <!-- 商品规格 商品详情以及默认参与活动的id-->
<popupGoods :addr="delivery" ref="popupGoods" @changed="changedGoods" @closeBuy="closePopupBuy" <popupGoods
@queryCart="cartCount()" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" :id="productId" :addr="delivery"
v-if="goodsDetail.id " :pointDetail="pointDetail" @handleClickSku="selectSku" :buyMask="buyMask" /> ref="popupGoods"
@changed="changedGoods"
@closeBuy="closePopupBuy"
@queryCart="cartCount()"
:goodsDetail="goodsDetail"
:goodsSpec="goodsSpec"
:isGroup="isGroup"
:id="productId"
v-if="goodsDetail.id"
:pointDetail="pointDetail"
@handleClickSku="selectSku"
:buyMask="buyMask"
/>
</view> </view>
</view> </view>
</div> </div>
@@ -238,15 +358,11 @@
<script> <script>
/************接口API***************/ /************接口API***************/
import { import { getGoods, getGoodsList, getMpScene, getGoodsDistribution } from "@/api/goods.js";
getGoods,
getGoodsList,
getMpScene,
getGoodsDistribution,
} from "@/api/goods.js";
import * as API_trade from "@/api/trade.js"; import * as API_trade from "@/api/trade.js";
import * as API_Members from "@/api/members.js"; import * as API_Members from "@/api/members.js";
import * as API_store from "@/api/store.js"; import * as API_store from "@/api/store.js";
import { getIMDetail } from "@/api/common";
import { modelNavigateTo } from "@/pages/tabbar/home/template/tpl.js"; import { modelNavigateTo } from "@/pages/tabbar/home/template/tpl.js";
/************请求存储***************/ /************请求存储***************/
import storage from "@/utils/storage.js"; import storage from "@/utils/storage.js";
@@ -262,10 +378,12 @@ import GoodsRecommend from "./product/goods/-goods-recommend"; //宝贝推荐
import storeLayout from "./product/shop/-shop"; //店铺组件 import storeLayout from "./product/shop/-shop"; //店铺组件
import Evaluation from "./product/evaluation/-evaluation"; //评价组件 import Evaluation from "./product/evaluation/-evaluation"; //评价组件
import GoodsSwiper from "./product/goods/-goods-swiper"; //轮播图组件 import GoodsSwiper from "./product/goods/-goods-swiper"; //轮播图组件
import popupGoods from "./product/popup/goods"; //购物车商品的模块 import popupGoods from "@/components/m-buy/goods"; //购物车商品的模块
import popupAddress from "./product/popup/address"; //地址选择模块 import popupAddress from "./product/popup/address"; //地址选择模块
import shares from "@/components/m-share/index"; //分享 import shares from "@/components/m-share/index"; //分享
import popups from "@/components/popups/popups"; //气泡框 import popups from "@/components/popups/popups"; //气泡框
import setup from "./product/popup/popup";
export default { export default {
components: { components: {
popups, popups,
@@ -285,6 +403,9 @@ export default {
}, },
data() { data() {
return { return {
setup,
promotionShow: false, //弹窗开关
promotionFlag: true, //活动开关
// #ifdef H5 // #ifdef H5
navbarListX: 110, //导航栏列表栏x轴 navbarListX: 110, //导航栏列表栏x轴
navbarListY: 80, //导航栏列表栏y轴 navbarListY: 80, //导航栏列表栏y轴
@@ -323,7 +444,6 @@ export default {
popupsSwitch: false, //导航栏列表栏开关 popupsSwitch: false, //导航栏列表栏开关
shareFlage: false, shareFlage: false,
selectedGoods: "", //选择的商品规格昵称 selectedGoods: "", //选择的商品规格昵称
isPromotion: true, //判断显示拼团活动文字
isGroup: false, // 是否是拼团活动 isGroup: false, // 是否是拼团活动
pointDetail: "", // 是否是积分商品 pointDetail: "", // 是否是积分商品
assemble: "", //拼团的sku assemble: "", //拼团的sku
@@ -373,8 +493,7 @@ export default {
imgList: [], //轮播图数据 imgList: [], //轮播图数据
favorite: false, //收藏与否flag favorite: false, //收藏与否flag
recommendList: [], //推荐列表 recommendList: [], //推荐列表
maskFlag: false, //模态显示与否 // maskFlag: false, //模态显示与否
cuxiao: false, //促销弹窗
goodsInfo: false, //商品介绍弹窗 goodsInfo: false, //商品介绍弹窗
addressFlag: false, //配送地址弹窗 addressFlag: false, //配送地址弹窗
buyMask: false, //添加购物车直接购买,查看已选 弹窗 buyMask: false, //添加购物车直接购买,查看已选 弹窗
@@ -404,19 +523,16 @@ export default {
startTimer: false, //未开启 是false startTimer: false, //未开启 是false
routerVal: "", routerVal: "",
IMLink: "", // IM地址
}; };
}, },
// #ifdef MP-WEIXNI
shareAppMessage() { computed: {
return { IM() {
title: this.goodsDetail.goodsName, return this.IMLink + this.storeDetail.merchantEuid;
type: 0, },
query: `id=${this.routerVal.id}&goodsId=${this.routerVal.goodsId}`,
path: `/pages/product/goods`,
imageUrl: this.goodsDetail.goodsGalleryList[0],
};
}, },
// #endif
watch: { watch: {
isGroup(val) { isGroup(val) {
if (val) { if (val) {
@@ -425,9 +541,9 @@ export default {
clearInterval(timer); clearInterval(timer);
}, 100); }, 100);
this.isPromotion = false; this.promotionFlag = false;
} else { } else {
this.isPromotion = true; this.promotionFlag = true;
this.$refs.popupGoods.buyType = ""; this.$refs.popupGoods.buyType = "";
} }
}, },
@@ -483,14 +599,22 @@ export default {
} }
}); });
} else { } else {
this.init( this.init(this.routerVal.id, this.routerVal.goodsId, this.routerVal.distributionId);
this.routerVal.id,
this.routerVal.goodsId,
this.routerVal.distributionId
);
} }
}, },
// #ifdef MP-WEIXIN
onShareAppMessage(res) {
return {
path: this.share(),
title: `[好友推荐]${this.goodsDetail.goodsName}`,
imageUrl: this.goodsDetail.goodsGalleryList[0],
};
},
// #endif
methods: { methods: {
share() {
return `/pages/product/goods?id=${this.routerVal.id}&goodsId=${this.routerVal.goodsId}`;
},
/** /**
* 导航栏列表栏 * 导航栏列表栏
*/ */
@@ -516,16 +640,17 @@ export default {
/** /**
* 初始化信息 * 初始化信息
*/ */
async init(id, goodsId, distributionId) { async init(id, goodsId, distributionId = "") {
this.isGroup = false; //初始化拼团 this.isGroup = false; //初始化拼团
this.productId = id; // skuId this.productId = id; // skuId
// 这里请求获取到页面数据 解析数据 // 这里请求获取到页面数据 解析数据
let response = await getGoods(id, goodsId); let response = await getGoods(id, goodsId);
if (!response.data.success) { if (!response.data.success) {
setTimeout(()=>{ setTimeout(() => {
uni.navigateBack(); uni.navigateBack();
},500) }, 500);
} }
// 这里是绑定分销员 // 这里是绑定分销员
if (distributionId || this.$store.state.distributionId) { if (distributionId || this.$store.state.distributionId) {
@@ -562,7 +687,7 @@ export default {
this.cartCount(); this.cartCount();
// 获取店铺推荐商品 // 获取店铺推荐商品
this.getstoreRecommend(); this.getStoreRecommend();
// 获取商品列表 // 获取商品列表
this.getOtherLikeGoods(); this.getOtherLikeGoods();
@@ -571,37 +696,52 @@ export default {
if (this.$options.filters.isLogin("auth")) { if (this.$options.filters.isLogin("auth")) {
this.getGoodsCollectionFun(this.goodsDetail.id); this.getGoodsCollectionFun(this.goodsDetail.id);
} }
// 获取IM 需要的话使用
// this.getIMDetailMethods();
}, },
linkMsgDetail() {
// 客服
// #ifdef MP-WEIXIN
const params = { async getIMDetailMethods() {
storeName: this.storeDetail.storeName, let res = await getIMDetail();
goodsName: this.goodsDetail.goodsName, if (res.data.success) {
goodsId: this.goodsDetail.goodsId, this.IMLink = res.data.result;
goodsImg: this.goodsDetail.thumbnail, }
price: this.goodsDetail.promotionPrice || this.goodsDetail.price, },
// originalPrice: this.goodsDetail.original || this.goodsDetail.price,
uuid: storage.getUuid(), linkMsgDetail() {
token: storage.getAccessToken(), if (this.storeDetail.merchantEuid) {
sign: this.storeDetail.yzfSign, uni.navigateTo({
mpSign: this.storeDetail.yzfMpSign, url: `/pages/tabbar/home/web-view?src=${this.IM}`,
}; });
uni.navigateTo({ } else {
url: // 客服
"/pages/product/customerservice/index?params=" + // #ifdef MP-WEIXIN
encodeURIComponent(JSON.stringify(params)), const params = {
}); storeName: this.storeDetail.storeName,
// #endif goodsName: this.goodsDetail.goodsName,
// #ifndef MP-WEIXIN goodsId: this.goodsDetail.goodsId,
const sign = this.storeDetail.yzfSign; goodsImg: this.goodsDetail.thumbnail,
uni.navigateTo({ price: this.goodsDetail.promotionPrice || this.goodsDetail.price,
url: // originalPrice: this.goodsDetail.original || this.goodsDetail.price,
"/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" + uuid: storage.getUuid(),
sign, token: storage.getAccessToken(),
}); sign: this.storeDetail.yzfSign,
// #endif mpSign: this.storeDetail.yzfMpSign,
};
uni.navigateTo({
url:
"/pages/product/customerservice/index?params=" +
encodeURIComponent(JSON.stringify(params)),
});
// #endif
// #ifndef MP-WEIXIN
const sign = this.storeDetail.yzfSign;
uni.navigateTo({
url:
"/pages/tabbar/home/web-view?src=https://yzf.qq.com/xv/web/static/chat/index.html?sign=" +
sign,
});
// #endif
}
}, },
// 格式化金钱 1999 --> [1999,00] // 格式化金钱 1999 --> [1999,00]
formatPrice(val) { formatPrice(val) {
@@ -625,14 +765,14 @@ export default {
*/ */
closePopupAddress(val) { closePopupAddress(val) {
this.addressFlag = val; this.addressFlag = val;
this.maskFlag = false; // this.maskFlag = false;
}, },
/** /**
* 商品规格子级关闭回调 * 商品规格子级关闭回调
*/ */
closePopupBuy(val) { closePopupBuy(val) {
this.buyMask = val; this.buyMask = val;
this.maskFlag = false; // this.maskFlag = false;
}, },
/** 参与拼团 创建拼团 */ /** 参与拼团 创建拼团 */
@@ -708,7 +848,7 @@ export default {
*/ */
getGoodsCollectionFun(goodsId) { getGoodsCollectionFun(goodsId) {
if (storage.getHasLogin()) { if (storage.getHasLogin()) {
API_Members.getGoodsIsCollect("GOODS",goodsId ).then((res) => { API_Members.getGoodsIsCollect("GOODS", goodsId).then((res) => {
this.favorite = res.data.result; this.favorite = res.data.result;
}); });
} }
@@ -717,7 +857,7 @@ export default {
/** /**
* 获取店铺推荐商品列表 * 获取店铺推荐商品列表
*/ */
getstoreRecommend() { getStoreRecommend() {
getGoodsList({ getGoodsList({
pageNumber: 1, pageNumber: 1,
pageSize: 6, pageSize: 6,
@@ -730,7 +870,7 @@ export default {
/** /**
* 获取相似商品列表 * 获取相似商品列表
* *
*/ */
getOtherLikeGoods() { getOtherLikeGoods() {
getGoodsList({ getGoodsList({
@@ -775,22 +915,21 @@ export default {
* 规格弹窗开关 * 规格弹窗开关
*/ */
shutMask(flag, buyFlag, type) { shutMask(flag, buyFlag, type) {
// type是指是否点击底部按钮 this.promotionShow = false;
this.buyMask = false;
this.addressFlag = false;
if (flag) { if (flag) {
switch (flag) { switch (flag) {
case 1: //优惠券弹窗 case 1: //优惠券弹窗
this.maskFlag = true; this.promotionShow = true;
this.cuxiao = true;
break; break;
case 3: case 3:
this.maskFlag = true;
this.addressFlag = true; this.addressFlag = true;
break; break;
case 4: //添加购物车直接购买,查看已选 弹窗 case 4: //添加购物车直接购买,查看已选 弹窗
// 判断是否是一个规格 // 判断是否是一个规格
this.maskFlag = true;
this.buyMask = true; this.buyMask = true;
if (buyFlag == "PINTUAN") { if (buyFlag == "PINTUAN") {
if (type.orderSn) { if (type.orderSn) {
@@ -804,10 +943,6 @@ export default {
break; break;
} }
} else {
this.maskFlag = false;
this.cuxiao = false;
this.buyMask = false;
} }
}, },
@@ -820,7 +955,7 @@ export default {
this.deleteGoodsCollectionFun(id); this.deleteGoodsCollectionFun(id);
return false; return false;
} }
API_Members.collectionGoods("GOODS",id ).then((res) => { API_Members.collectionGoods("GOODS", id).then((res) => {
if (res.data.success) { if (res.data.success) {
uni.showToast({ uni.showToast({
title: "收藏成功!", title: "收藏成功!",

View File

@@ -6,8 +6,19 @@
<div class="goods-detail-box"> <div class="goods-detail-box">
<div class="goods-detail-item goods-active">商品介绍</div> <div class="goods-detail-item goods-active">商品介绍</div>
</div> </div>
<u-empty class="empty" text="暂无商品介绍" mode="data" v-if="!res.intro"></u-empty> <u-empty
<u-parse class="vhtml" :lazy-load="true" :use-cache="true" :show-with-animation="true" :html="res.mobileIntro"></u-parse> class="empty"
text="暂无商品介绍"
mode="data"
v-if="!res.mobileIntro"
></u-empty>
<u-parse
class="vhtml"
:lazy-load="true"
:use-cache="true"
:show-with-animation="true"
:html="res.mobileIntro"
></u-parse>
</view> </view>
</view> </view>
</view> </view>
@@ -20,17 +31,27 @@
</div> </div>
<!-- <u-divider>商品参数</u-divider> --> <!-- <u-divider>商品参数</u-divider> -->
<div class="param-list" v-if="goodsParams.length == 0"> <div class="param-list" v-if="goodsParams.length == 0">
<u-empty text="暂无商品参数" mode="list"></u-empty> <u-empty text="暂无商品参数" mode="list"></u-empty>
</div>
<div
class="params-group"
v-for="(group, groupIndex) in goodsParams"
:key="groupIndex"
>
<view style="font-weight: bold; margin-left: 10px">{{
group.groupName
}}</view>
<div class="param-list">
<div
class="param-item"
v-for="(param, index) in group.goodsParamsItemDTOList"
:key="index"
>
<div class="param-left">{{ param.paramName }}</div>
<div class="param-right">{{ param.paramValue }}</div>
</div>
</div>
</div> </div>
<div class="params-group" v-for="(group,groupIndex) in goodsParams" :key="groupIndex">
<view style="font-weight: bold;margin-left: 10px;">{{group.groupName}}</view>
<div class="param-list">
<div class="param-item" v-for="(param,index) in group.goodsParamsItemDTOList" :key="index">
<div class="param-left">{{param.paramName}}</div>
<div class="param-right">{{param.paramValue}}</div>
</div>
</div>
</div>
</view> </view>
</view> </view>
</view> </view>
@@ -42,16 +63,14 @@ import { getGoodsMessage } from "@/api/goods";
export default { export default {
data() { data() {
return { return {
goodsDetail: "" goodsDetail: "",
}; };
}, },
props: ["res", "goodsId", "goodsParams"], props: ["res", "goodsId", "goodsParams"],
async mounted() { async mounted() {
console.log(this.res)
let res = await getGoodsMessage(this.goodsId); let res = await getGoodsMessage(this.goodsId);
if (res.data.success) { if (res.data.success) {
this.goodsDetail = res.data.result; this.goodsDetail = res.data.result;
} }
}, },
}; };
@@ -102,6 +121,11 @@ export default {
width: 100%; width: 100%;
} }
.vhtml {
/deep/ img {
display: block !important;
}
}
/deep/ img { /deep/ img {
width: 100%; width: 100%;

View File

@@ -1,5 +1,5 @@
<template> <template>
<u-popup class="popup" v-model="addressFlag" :height="setup.height" :mode="setup.mode" :border-radius="setup.radius" @close="closeAddress()" :mask-close-able="setup.close" :mask="false" closeable> <u-popup class="popup" v-model="addressFlag" :height="setup.height" :mode="setup.mode" :border-radius="setup.radius" @close="closeAddress()" closeable>
<view class="header-title">选择地址</view> <view class="header-title">选择地址</view>
<view class="view-box" v-if="addressDetail"> <view class="view-box" v-if="addressDetail">
<view class="view-item" v-for="(item, index) in addressDetail" :key="index" @click="clickAddress(item)"> <view class="view-item" v-for="(item, index) in addressDetail" :key="index" @click="clickAddress(item)">
@@ -27,7 +27,7 @@
</u-popup> </u-popup>
</template> </template>
<script> <script>
import setup from "./popup"; import setup from "@/components/m-buy/popup.js";
/************请求存储***************/ /************请求存储***************/
import * as API_Address from "@/api/address.js"; import * as API_Address from "@/api/address.js";
@@ -157,7 +157,7 @@ export default {
border-radius: 50%; border-radius: 50%;
border: 2rpx solid #ededed; border: 2rpx solid #ededed;
} }
@import "./popup.scss"; @import "@/components/m-buy/popup.scss";
.view-box { .view-box {
height: 810rpx; height: 810rpx;
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN

View File

@@ -1,411 +0,0 @@
<template>
<div class="wrapper">
<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode" :mask-close-able="isClose" :mask="isMask" :border-radius="setup.radius" @close="closeMask()">
<!-- 商品 -->
<view class="goods-box bottom">
<view class="goods-header">
<view class="goods-img">
<u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
</view>
<view class="goods-skus">
<!-- 有活动商品价格 -->
<view class="goods-price " v-if="goodsDetail.promotionPrice">
<span v-if="goodsDetail.promotionPrice && !pointDetail">
<span class="goods-price-promotionShow goods-price-bigshow">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span>
.{{ formatPrice(goodsDetail.promotionPrice)[1] }}
</span>
<span v-if="pointDetail.points">
<span class="goods-price-promotionShow goods-price-bigshow">{{ pointDetail.points }}</span>
积分
</span>
<div class="promotion-box">
<span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0]
}}</span>
.{{ formatPrice(goodsDetail.price)[1] }}
</div>
</view>
<!-- 正常商品的价格 -->
<view class="goods-price" v-else>
<span>
<span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0]
}}</span>
.{{ formatPrice(goodsDetail.price)[1] }}
</span>
</view>
<view class="goods-check-skus">
已选
<span class="goods-check-skus-name">
{{ selectName }}
<span>{{ num }}</span>
</span>
</view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-skus-box">
<!-- 规格 -->
<view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList">
<view class="skus-view-list">
<view class="view-class-title">{{ spec.name }}</view>
<view :class="{ active: spec_val.value == currentSelceted[specIndex] }" class="skus-view-item" v-for="(spec_val, spec_index) in spec.values" :key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view>
</view>
</view>
<!-- 数量 -->
<view class="goods-skus-number">
<view class="view-class-title">数量</view>
<u-number-box :bg-color="numberBox.bgColor" :max="200" :color="numberBox.color" :input-width="numberBox.width" :input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num">
</u-number-box>
</view>
</view>
<!-- 按钮 -->
<view class="btns">
<view class="box-btn card" v-if="buyType != 'PINTUAN' && goodsDetail.goodsType!='VIRTUAL_GOODS'" @click="addToCartOrBuy('cart')">加入购物车</view>
<view class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view>
</view>
</view>
</u-popup>
</div>
</template>
<script>
import * as API_trade from "@/api/trade.js";
import setup from "./popup";
export default {
data() {
return {
setup,
num: 1,
// 步进器的大小尺寸单位是 rpx
numberBox: {
width: "50",
height: "50",
size: "22",
color: "#333",
bgColor: "#fff",
},
selectName: "", //选中商品的昵称
selectSkuList: "", //选中商铺sku,
selectedSpecImg: "", //选中的图片路径
buyType: "", //用于存储促销,拼团等活动类型
parentOrder: "", //父级拼团活动的数据 - 如果是团员则有数据
formatList: [],
currentSelceted: [],
skuList: "",
isMask: false, //是否显示遮罩层
isClose: false, //是否可以点击遮罩关闭
};
},
props: [
"goodsDetail", //商品详情
"buyMask",
"selectedSku",
"goodsSpec",
"addr",
"pointDetail", // 积分详情
],
watch: {
buyType: {
handler(val) {
this.buyType = val;
},
immediate: true,
},
selectSkuList: {
handler(val, oldval) {
this.$emit("changed", val);
},
deep: true,
},
},
methods: {
// 格式化金钱 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
closeMask() {
this.$emit("closeBuy", false);
},
/**点击规格 */
handleClickSpec(val, index, specValue) {
this.$set(this.currentSelceted, index, specValue.value);
let selectedSkuId = this.goodsSpec.find((i) => {
let matched = true;
let specValues = i.specValues.filter((j) => j.specName !== "images");
for (let n = 0; n < specValues.length; n++) {
if (specValues[n].specValue !== this.currentSelceted[n]) {
matched = false;
return;
}
}
if (matched) {
return i;
}
});
this.selectSkuList = {
spec: {
specName: val.name,
specValue: specValue.value,
},
data: this.goodsDetail,
};
this.selectName = specValue.value;
this.$emit("handleClickSku", {skuId: selectedSkuId.skuId, goodsId: this.goodsDetail.goodsId});
},
/**
* 添加到购物车或购买
*/
addToCartOrBuy(val) {
if (!this.selectSkuList) {
uni.showToast({
title: "请选择规格商品",
icon: "none",
});
return;
}
let data = {
skuId: this.goodsDetail.id,
num: this.num,
};
if (val == "cart") {
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.showToast({
title: "商品已添加到购物车",
icon: "none",
});
this.$emit("queryCart");
this.closeMask();
}
});
} else {
// 判断是否拼团商品
if (this.buyType) {
data.cartType = "PINTUAN";
}
else if(this.goodsDetail.goodsType == 'VIRTUAL_GOODS'){
data.cartType = "VIRTUAL";
}
else {
data.cartType = "BUY_NOW";
}
API_trade.addToCart(data).then((res) => {
if (res.data.code == 200) {
uni.navigateTo({
url: `/pages/order/fillorder?way=${data.cartType}&addr=${
this.addr.id || ""
}&parentOrder=${encodeURIComponent(
JSON.stringify(this.parentOrder)
)}`,
});
}
});
}
},
formatSku(list) {
// 格式化数据
let arr = [{}];
list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => {
let name = spec.specName;
let values = {
value: spec.specValue,
quantity: item.quantity,
};
if (name === "images") {
return;
}
arr.forEach((arrItem, arrIndex) => {
if (
arrItem.name == name &&
arrItem.values &&
!arrItem.values.find((i) => i.value === values.value)
) {
arrItem.values.push(values);
}
let keys = arr.map((key) => {
return key.name;
});
if (!keys.includes(name)) {
arr.push({
name: name,
values: [values],
});
}
});
});
});
arr.shift();
this.formatList = arr;
list.forEach((item) => {
if (item.skuId === this.goodsDetail.id) {
item.specValues
.filter((i) => i.specName !== "images")
.forEach((value, _index) => {
this.currentSelceted[_index] = value.specValue;
this.selectName = value.specValue;
this.selectSkuList = {
spec: value,
data: this.goodsDetail,
};
});
}
});
this.skuList = list;
},
},
mounted() {
this.formatSku(this.goodsSpec);
console.log(this.goodsDetail);
},
};
</script>
<style lang="scss" scoped>
@import "./popup.scss";
.buy {
background-image: linear-gradient(135deg, #ffba0d, #ffc30d 69%, #ffcf0d);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
.card {
background-image: linear-gradient(135deg, #f2140c, #f2270c 70%, #f24d0c);
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
/deep/.u-icon-plus,
.u-icon-minus,
.u-icon-disabled {
height: 30rpx !important;
background: #fff !important;
}
.goods-skus-number {
justify-content: space-between;
display: flex;
}
/deep/ .uni-scroll-view {
overflow: hidden !important;
}
.active {
background: $price-light-color !important;
border: 2rpx solid $price-color;
font-weight: bold;
color: $price-color !important;
box-sizing: border-box;
}
.goods-skus-box {
overflow-y: auto;
height: 610rpx;
// #ifdef MP-WEIXIN
height: 570rpx;
// #endif
margin-bottom: 10rpx;
}
.goods-skus-view {
overflow: hidden;
.skus-view-list {
> .skus-view-item {
flex: 1;
padding: 0 36rpx;
overflow: hidden;
height: 60rpx;
line-height: 60rpx;
float: left;
text-align: center;
margin-left: 24rpx;
margin-bottom: 20rpx;
font-size: 22rpx;
color: #262626;
background: #f2f2f2;
border-radius: 30rpx;
}
}
}
.goods-header {
height: 200rpx;
display: flex;
align-items: center;
margin-bottom: 36rpx;
}
.goods-box {
padding: 50rpx 36rpx 0 36rpx;
}
.goods-skus {
padding: 0 20rpx;
}
.goods-price {
color: $price-color;
line-height: 80rpx;
display: flex;
}
.promotion-box {
line-height: 1;
display: flex;
align-items: center;
text-decoration: line-through;
color: #999;
margin-left: 10rpx;
/deep/ span {
font-size: 30rpx;
}
}
.promotion {
font-size: 30rpx;
}
.goods-price-promotionShow {
font-size: 48rpx;
}
.goods-check-skus {
font-size: 24rpx;
color: #999;
> .goods-check-skus-name {
margin-left: 4rpx;
}
> span {
color: #333;
}
}
</style>

View File

@@ -4,5 +4,5 @@ export default {
height:"1000rpx", //弹出层高度 height:"1000rpx", //弹出层高度
mode:"bottom", //弹出层位置 mode:"bottom", //弹出层位置
radius:"32", //圆角 rpx, radius:"32", //圆角 rpx,
close:false //能否点击遮罩退出 close:true //能否点击遮罩退出
} }

View File

@@ -1,37 +0,0 @@
.view-class-title {
font-size: 26rpx;
color: #262626;
font-weight: 700;
height: 80rpx;
line-height: 80rpx;
}
.confirmBtn {
width: 90%;
}
.confirmBtn,
.box-btn {
line-height: 80rpx;
height: 80rpx;
background: $price-color;
color: #fff;
border-radius: 200px;
text-align: center;
margin: 5rpx auto;
}
.btns {
display: flex;
width: 100%;
margin: 0 auto;
}
.goods-price-bigshow {
font-size: 48rpx;
font-weight: bold;
}
.box-btn {
flex: 1;
margin: 0 10rpx;
}

View File

@@ -34,14 +34,12 @@
height: 15px; height: 15px;
} }
} }
.scroll_mask{ .scroll_mask {
height: 555px; height: 868rpx;
// padding-bottom: 100rpx; // padding-bottom: 100rpx;
overflow-y: auto; overflow-y: auto;
} }
.coupons {
padding-bottom: 200rpx !important;
}
.mask { .mask {
height: 600px; height: 600px;
} }

View File

@@ -1,23 +1,23 @@
<template> <template>
<view class="group-list"> <view class="group-list">
<view class="group-name">拼购列表</view> <view class="group-name">拼购列表</view>
<view v-if="assembleOrder.length !=0"> <view v-if="assembleOrder.length != 0">
<view class="group-item" v-for="(order,index) in assembleOrder" :key="index"> <view class="group-item" v-for="(order, index) in assembleOrder" :key="index">
<view class="group-item-user"> <view class="group-item-user">
<u-image shape="circle" width="40px" height="40px" :src="order.face"></u-image> <u-image shape="circle" width="40px" height="40px" :src="order.face"></u-image>
<span class="group-item-name">{{order.nickName | noPassByName}}</span> <span class="group-item-name">{{ order.nickName | noPassByName }}</span>
</view> </view>
<view> <view>
<span class="group-item-name">还差{{ order.toBeGroupedNum}}人成团</span> <span class="group-item-name">还差{{ order.toBeGroupedNum }}人成团</span>
</view> </view>
<view> <view>
<u-button size="mini" :custom-style="customStyle" @click="buy(order)">去参团</u-button> <u-button size="mini" :custom-style="customStyle" @click="buy(order)"
>去参团</u-button
>
</view> </view>
</view> </view>
</view> </view>
<view v-else class="nomore"> <view v-else class="nomore">
<u-empty text="暂无拼团信息" mode="list"></u-empty> <u-empty text="暂无拼团信息" mode="list"></u-empty>
</view> </view>
</view> </view>

View File

@@ -1,61 +1,105 @@
<template> <template>
<view> <view>
<div v-for="(promotion, promotion_index) in res" :key="promotion_index"> <div v-for="(promotion, promotion_index) in res" :key="promotion_index">
<div class="showBox" v-if="promotion.__key == 'SECKILL' || promotion.__key =='GROUPBUY' || promotion.__key == 'PINTUAN'"> <div
class="showBox"
v-if="
promotion.__key == 'SECKILL' ||
promotion.__key == 'GROUPBUY' ||
promotion.__key == 'PINTUAN'
"
>
<view class="group-wrapper"> <view class="group-wrapper">
<div class="u-group-row"> <div class="u-group-row">
<view :span="8" class="showBox_L"> <view :span="8" class="showBox_L">
<view class="u-group-flex"> <view class="u-group-flex">
<!-- 限时抢购 --> <!-- 限时抢购 -->
<view class="u-group-flex-left" v-if="promotion.__key == 'SECKILL' "> <view class="u-group-flex-left" v-if="promotion.__key == 'SECKILL'">
<span
<span class="u-group-flex-left-span" v-if="detail.promotionPrice!=undefined"> class="u-group-flex-left-span"
<span class="flex-price"> {{ formatPrice(detail.promotionPrice)[0]}}.{{ formatPrice(detail.promotionPrice)[1]}}</span> v-if="detail.promotionPrice != undefined"
>
<span class="flex-price">
{{ formatPrice(detail.promotionPrice)[0] }}.{{
formatPrice(detail.promotionPrice)[1]
}}</span
>
</span> </span>
<view class="u-group-flex" v-if="detail.price!=undefined"> <view class="u-group-flex" v-if="detail.price != undefined">
<span class="old-price">{{ formatPrice(detail.price)[0]}}.{{ formatPrice(detail.price)[1]}}</span> <span class="old-price"
>¥{{ formatPrice(detail.price)[0] }}.{{
formatPrice(detail.price)[1]
}}</span
>
<view class="promotion">限时抢购</view> <view class="promotion">限时抢购</view>
</view> </view>
</view> </view>
<!-- 团购 --> <!-- 团购 -->
<view class="u-group-flex-left" v-if="promotion.__key == 'GROUPBUY' "> <view class="u-group-flex-left" v-if="promotion.__key == 'GROUPBUY'">
<span class="u-group-flex-left-span"> <span class="u-group-flex-left-span">
<span class="flex-price" <span
v-if="promotion.groupbuy_goods_vo.price !=undefined">{{ formatPrice(promotion.groupbuy_goods_vo.price )[0]}}.{{ formatPrice(promotion.groupbuy_goods_vo.price )[1]}}</span> class="flex-price"
v-if="promotion.groupbuy_goods_vo.price != undefined"
>¥{{ formatPrice(promotion.groupbuy_goods_vo.price)[0] }}.{{
formatPrice(promotion.groupbuy_goods_vo.price)[1]
}}</span
>
<!-- <span v-if="promotion.point">+{{promotion.point}}积分</span> --> <!-- <span v-if="promotion.point">+{{promotion.point}}积分</span> -->
</span> </span>
<view class="u-group-flex"> <view class="u-group-flex">
<span class="old-price" <span
v-if="promotion.groupbuy_goods_vo.original_price!=undefined">{{ formatPrice(promotion.groupbuy_goods_vo.original_price)[0]}}.{{ formatPrice(promotion.groupbuy_goods_vo.original_price)[1]}}</span> class="old-price"
v-if="promotion.groupbuy_goods_vo.original_price != undefined"
>¥{{
formatPrice(promotion.groupbuy_goods_vo.original_price)[0]
}}.{{
formatPrice(promotion.groupbuy_goods_vo.original_price)[1]
}}</span
>
<view class="promotion">团购活动</view> <view class="promotion">团购活动</view>
</view> </view>
</view> </view>
<view class="u-group-flex-left" v-if="promotion.__key == 'PINTUAN' "> <view class="u-group-flex-left" v-if="promotion.__key == 'PINTUAN'">
<span
<span class="u-group-flex-left-span" v-if="detail.promotionPrice != undefined"> class="u-group-flex-left-span"
<span class="flex-price"> {{ formatPrice(detail.promotionPrice)[0]}}.</span>{{ formatPrice(detail.promotionPrice)[1]}} v-if="detail.promotionPrice != undefined"
>
¥<span class="flex-price">
{{ formatPrice(detail.promotionPrice)[0] }}.</span
>{{ formatPrice(detail.promotionPrice)[1] }}
</span> </span>
<view class="u-group-flex" v-if="detail.price != undefined"> <view class="u-group-flex" v-if="detail.price != undefined">
<span class="old-price">{{ formatPrice(detail.price)[0]}}.{{ formatPrice(detail.price)[1]}}</span> <span class="old-price"
>¥{{ formatPrice(detail.price)[0] }}.{{
formatPrice(detail.price)[1]
}}</span
>
<view class="promotion">拼团活动</view> <view class="promotion">拼团活动</view>
</view> </view>
</view> </view>
<!-- 拼团右侧 --> <!-- 拼团右侧 -->
<view class="u-group-flex-right" v-if="promotion.__key == 'PINTUAN' "> <view class="u-group-flex-right" v-if="promotion.__key == 'PINTUAN'">
<span class="group-bag">{{promotion.requiredNum}}人拼团 </span> <span class="group-bag">{{ promotion.requiredNum }}人拼团 </span>
<span class="group-bag">限购{{promotion.limitNum}}</span> <span class="group-bag">限购{{ promotion.limitNum }}件</span>
</view> </view>
</view> </view>
</view> </view>
<view class="showBox_R" v-if="promotion && promotion.endTime"> <view class="showBox_R" v-if="promotion && promotion.endTime">
<u-tag :text="getIsTimer(promotion)" size="mini" type="error" /> <u-tag :text="getIsTimer(promotion)" size="mini" type="error" />
<u-count-down :hide-zero-day="true" font-size="25" color="#fff" bg-color="#f71471" separator-size="25" separator-color="#f71471" :show-hours="true" :show-minutes="true" <u-count-down
:timestamp="getCountDownTime(promotion.endTime)"></u-count-down> :hide-zero-day="true"
font-size="25"
color="#fff"
bg-color="#f71471"
separator-size="25"
separator-color="#f71471"
:show-hours="true"
:show-minutes="true"
:timestamp="getCountDownTime(promotion.endTime)"
></u-count-down>
</view> </view>
</div> </div>
</view> </view>
@@ -105,13 +149,12 @@ export default {
return val.toFixed(2).split("."); return val.toFixed(2).split(".");
}, },
getCountDownTime(val) { getCountDownTime(val) {
let date = new Date(val.replace(/-/g, "/")) let date = new Date(val);
let timeSimple = new Date(date).getTime() / 1000; let timeSimple = new Date(date).getTime() / 1000;
return timeSimple - new Date().getTime() / 1000; return timeSimple - new Date().getTime() / 1000;
}, },
getIsTimer(val) { getIsTimer(val) {
var timestamp = new Date().getTime(); var timestamp = new Date().getTime();
if (timestamp < val.start_time) { if (timestamp < val.start_time) {
this.startTimer = true; this.startTimer = true;

View File

@@ -1,33 +1,37 @@
<template> <template>
<view class="wrapper"> <view class="wrapper">
<div class="coupon-empty" v-if="!res">暂无优惠券</div> <div class="coupon-empty" v-if="!res">暂无优惠券</div>
<view class="coupon-List" v-if="res && item.__key=='COUPON'" v-for="(item, index) in res" :key="index"> <view class="coupon-List" v-for="(item, index) in couponRes" :key="index">
<view class="coupon-item"> <view class="coupon-item">
<view class="top"> <view class="top">
<div class="price"> <div class="price">
<span v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}</span> <span v-if="item.couponType == 'DISCOUNT'">{{ item.couponDiscount }}</span>
<span v-if="item.couponType == 'PRICE'">{{ item.price | unitPrice }}</span> <span v-if="item.couponType == 'PRICE'">{{ item.price | unitPrice }}</span>
</div> </div>
<view class="text"> <view class="text">
<div class="coupon-List-title"> <div class="coupon-List-title">
<view v-if="item.scopeType"> <view v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span> <span v-if="item.scopeType == 'ALL' && item.id == 'platform'"
>全平台</span
>
<span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span> <span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span>
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view> <view v-else
>{{
item.storeName == "platform" ? "全平台" : item.storeName + "店铺"
}}使用</view
>
</view> </view>
</div> </div>
<div>{{ item.consumeThreshold | unitPrice }}可用</div> <div>{{ item.consumeThreshold | unitPrice }}可用</div>
</view> </view>
<view class="lingqu-btn" @click="getCoupon(item)"> <view class="lingqu-btn" @click="getCoupon(item, index)">
<div :class="yhqFlag ? 'cur' : ''">{{ yhqFlag ? '已领取或领完' : '立即领取' }}</div> <div :class="yhqFlag[index] ? 'cur' : ''">
{{ yhqFlag[index] ? "已领取或领完" : "立即领取" }}
</div>
</view> </view>
</view> </view>
<view class="line"></view> <view class="line"></view>
<view class="time">{{ item.startTime }} - {{item.endTime }}</view> <view class="time">{{ item.startTime }} - {{ item.endTime }}</view>
</view> </view>
</view> </view>
</view> </view>
@@ -37,7 +41,8 @@
export default { export default {
data() { data() {
return { return {
yhqFlag: false, //获取优惠券判断是否点击 yhqFlag: [], //获取优惠券判断是否点击
couponRes: {},
}; };
}, },
props: { props: {
@@ -52,7 +57,9 @@ export default {
if (this.res && this.res.length != 0) { if (this.res && this.res.length != 0) {
Object.keys(this.res).forEach((item) => { Object.keys(this.res).forEach((item) => {
let key = item.split("-")[0]; let key = item.split("-")[0];
this.res[item].__key = key; if (key === "COUPON") {
this.couponRes[item] = this?.res[item];
}
}); });
} }
}, },
@@ -61,9 +68,8 @@ export default {
}, },
methods: { methods: {
// 提交优惠券 // 提交优惠券
getCoupon(item) { getCoupon(item, index) {
this.yhqFlag = true; this.yhqFlag[index] = true;
this.$emit("getCoupon", item); this.$emit("getCoupon", item);
}, },
}, },

View File

@@ -1,32 +1,45 @@
<template> <template>
<view class="wrapper" v-if="res"> <view class="wrapper" v-if="res">
<view v-for="(prom, index) in Object.keys(res)" :key="index"> <view v-for="(prom, index) in Object.keys(res)" :key="index">
<view> <view>
<view v-if="prom.split('-')[0] == 'FULL_DISCOUNT'"> <view v-if="prom.split('-')[0] == 'FULL_DISCOUNT'">
<div class="res_prom_item" v-if="res[prom].fullMinus"> <div class="res_prom_item" v-if="res[prom].fullMinus">
<u-tag text="满减" type="error"></u-tag> <u-tag text="满减" type="error"></u-tag>
<span class="proText">{{ res[prom].fullMoney }}立减现金 <span class="price">{{ res[prom].fullMinus}}</span></span> <!-- TODO 后续将优化为可点击的商品以及优惠券显示明细 -->
<span class="pro-text"
>{{ res[prom].fullMoney }} 立减现金
<span class="price">{{ res[prom].fullMinus }}</span>
<span v-if="res[prom].couponFlag"> 赠送<span>优惠券</span></span>
<span v-if="res[prom].pointFlag"> 赠送{{ res[prom].point }}积分</span>
<span v-if="res[prom].giftFlag"> 赠送商品</span>
<span v-if="res[prom].freeFreightFlag">赠送包邮服务</span>
</span>
</div> </div>
<div class="res_prom_item" v-if="res[prom].fullRate"> <div class="res_prom_item" v-if="res[prom].fullRate">
<u-tag text="打折" type="error"></u-tag> <u-tag text="打折" type="error"></u-tag>
<span class="proText">{{ res[prom].fullMoney }}立享<span class="price">{{ res[prom].fullRate }}</span>优惠</span> <span class="pro-text"
>{{ res[prom].fullMoney }}立享<span class="price"
>{{ res[prom].fullRate }}</span
>优惠</span
>
</div> </div>
</view> </view>
<view v-if="prom.split('-')[0] == 'PINTUAN'"> <view v-if="prom.split('-')[0] == 'PINTUAN'">
<div class="res_prom_item" v-if="res[prom].requiredNum"> <div class="res_prom_item" v-if="res[prom].requiredNum">
<u-tag text="拼团" type="error"></u-tag> <u-tag text="拼团" type="error"></u-tag>
<span class="proText">{{ res[prom].requiredNum }}人拼团 限购<span class="price">{{ res[prom].limitNum}}</span></span> <span class="pro-text"
>{{ res[prom].requiredNum }}人拼团 限购<span class="price"
>{{ res[prom].limitNum }}</span
></span
>
</div> </div>
</view> </view>
<view v-if="prom.split('-')[0] == 'SECKILL'"> <view v-if="prom.split('-')[0] == 'SECKILL'">
<div class="res_prom_item"> <div class="res_prom_item">
<u-tag text="限时抢购" type="error"></u-tag> <u-tag text="限时抢购" type="error"></u-tag>
<span class="proText">限时抢购</span> <span class="pro-text">限时抢购</span>
</div> </div>
</view> </view>
</view> </view>
@@ -68,13 +81,16 @@ export default {
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.proText { .pro-text {
font-size: 26rpx; font-size: 26rpx;
font-family: PingFang SC, PingFang SC-Regular; font-family: PingFang SC, PingFang SC-Regular;
font-weight: 400; font-weight: 400;
text-align: left; text-align: left;
color: #333333; color: #333333;
margin-left: 20rpx; margin-left: 20rpx;
> span {
margin-right: 15rpx;
}
} }
.wrapper { .wrapper {

View File

@@ -1,50 +1,65 @@
<template> <template>
<view> <view>
<view
<view v-for="(promotionItem,promotionIndex) in promotion" :key="promotionIndex" class="promotion_row" @click="shutMask(1)"> v-for="(promotionItem, promotionIndex) in promotion"
<view v-if="res!=null" v-for="(item, index) in Object.keys(res)" :key="index"> :key="promotionIndex"
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'FULL_DISCOUNT'"> class="promotion_row"
@click="shutMask(1)"
>
<view v-if="res != null" v-for="(item, index) in Object.keys(res)" :key="index">
<div
class="promotion_col"
v-if="
item.split('-')[0] == promotionItem.value &&
item.split('-')[0] == 'FULL_DISCOUNT'
"
>
<!-- 满减,折扣 --> <!-- 满减,折扣 -->
<div class="flex"> <div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view> <view class="deg_tag">{{ promotionItem.title }}</view>
<div class="text proText">满{{ res[item].fullMoney }}元,立享优惠</div> <div class="text proText">满{{ res[item].fullMoney }}元,立享优惠</div>
</div> </div>
</div> </div>
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'PINTUAN'"> <div
class="promotion_col"
v-if="
item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'PINTUAN'
"
>
<!-- 拼团 --> <!-- 拼团 -->
<div class="flex"> <div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view> <view class="deg_tag">{{ promotionItem.title }}</view>
<div class="text proText">{{ res[item].promotionName }}</div> <div class="text proText">{{ res[item].promotionName }}</div>
</div> </div>
</div> </div>
<div class="promotion_col" v-if="item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'SECKILL'"> <div
class="promotion_col"
v-if="
item.split('-')[0] == promotionItem.value && item.split('-')[0] == 'SECKILL'
"
>
<!-- 限时抢购 --> <!-- 限时抢购 -->
<div class="flex"> <div class="flex">
<view class="deg_tag">{{promotionItem.title}}</view> <view class="deg_tag">{{ promotionItem.title }}</view>
<div class="text proText">{{ res[item].promotionName }}</div> <div class="text proText">{{ res[item].promotionName }}</div>
</div> </div>
</div> </div>
</view> </view>
<view class="promotion_row" style="display:inline;"> <view class="promotion_row" style="display: inline">
<view> <view>
<div class="promotion_col coupon" v-if="couponList && promotionIndex ==1"> <div class="promotion_col coupon" v-if="couponList && promotionIndex == 1">
<!-- 优惠券 --> <!-- 优惠券 -->
<div> <div>
<view class="deg_tag">优惠券</view> <view class="deg_tag">优惠券</view>
</div> </div>
</div> </div>
</view> </view>
</view> </view>
</view> </view>
<view v-if=" this.res != null && Object.keys(res).length == 0"> <view v-if="this.res != null && Object.keys(res).length == 0"> 暂无促销信息 </view>
暂无促销信息
</view>
</view> </view>
</template> </template>
@@ -69,7 +84,6 @@ export default {
handler() { handler() {
if (this.res && this.res.length != 0 && this.res != null) { if (this.res && this.res.length != 0 && this.res != null) {
Object.keys(this.res).forEach((item) => { Object.keys(this.res).forEach((item) => {
let key = item.split("-")[0]; let key = item.split("-")[0];
this.res[item].__key = key; this.res[item].__key = key;

View File

@@ -16,7 +16,22 @@ page {
border-radius: 200px; border-radius: 200px;
line-height: 18rpx; line-height: 18rpx;
} }
.header-title{
font-weight: bold;
color: #333;
text-align: center;
height: 90rpx;
line-height: 90rpx;
font-size: 34rpx;
}
.cuxiao-title{
color: #999;
font-size: 24rpx;
}
.cuxiao{
padding:16rpx 32rpx;
}
.detail-btn { .detail-btn {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -56,7 +71,8 @@ page {
font-size: 32rpx; font-size: 32rpx;
} }
.-goods-desc { .-goods-desc {
padding: 36rpx 0 24rpx 0; padding: 36rpx 0 0 0;
margin-bottom: 24rpx;
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;
display: -webkit-box; display: -webkit-box;
@@ -326,50 +342,6 @@ page {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
/* 弹出层 */
.popup {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: -1px;
z-index: 9;
background: rgba(0, 0, 0, 0.5);
.mask {
position: absolute;
left: 0;
top: 30%;
right: 0;
bottom: 0;
background: #fff;
.title {
position: relative;
height: 90rpx;
line-height: 90rpx;
font-size: 32rpx;
text-align: center;
border-bottom: 1px solid #f2f2f2;
span {
position: absolute;
right: 30rpx;
font-size: 40rpx;
}
}
.con-cuxiao {
padding: 30rpx 30rpx 0 30rpx;
> text {
font-size: 26rpx;
color: #999;
}
}
}
}
} }
.u-mode-light-error { .u-mode-light-error {

163
pages/product/shopList.vue Normal file
View File

@@ -0,0 +1,163 @@
<template>
<div>
<u-navbar>
<u-search placeholder="请输入店铺名称" @search="search" @clear="search" @custom="search" v-model="params.storeName">
</u-search>
</u-navbar>
<div class="wrapper" v-if="storeList.length!=0">
<div class="store-item" @click="handleClickStore(item)" v-for="(item,index) in storeList" :key="index">
<div>
<u-image shape="circle" width="100" height="100" :src="item.storeLogo">
</u-image>
</div>
<div class="store-msg">
<div class="store-name">
{{item.storeName}}
</div>
<div class="goods-num">
商品 {{item.goodsNum}}
</div>
<div class="flex store-distance">
<div>
<span class="store-score">{{item.serviceScore | unitPrice}}</span>
<span class="line">|</span>
<span class="store-collection">收藏 {{item.collectionNum}}</span>
</div>
</div>
</div>
<!--
#TODO 后续将和后端补充从此处
<div class="flex store-goods">
<div class="store-goods-item" v-for="i in 3" :key="i">
<div>
<u-image src="https://picsum.photos/id/341/200/200" border-radius="20" width="215rpx" height="215rpx">
</u-image>
</div>
<div class="price">
<span>
<span class=" goods-price-bigshow">{{ formatPrice(16)[0] }}</span>
.{{ formatPrice(16)[1] }}
</span>
</div>
<div class="wes">test</div>
</div>
</div>
-->
</div>
</div>
<u-empty style="margin-top:20%;" text="暂无店铺信息" v-else></u-empty>
</div>
</template>
<script>
import { getStoreList } from "@/api/store";
export default {
data() {
return {
keyword: "",
params: {
pageNumber: 1,
pageSize: 10,
storeName: "",
},
storeList: [], // 店铺列表
};
},
onReachBottom() {
this.params.pageNumber++;
this.init();
},
mounted() {
this.init();
},
methods: {
handleClickStore(val){
uni.navigateTo({
url: `/pages/product/shopPage?id=${val.id}`
});
},
search() {
this.storeList = [];
this.init();
},
// 格式化金钱 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
async init() {
let res = await getStoreList(this.params);
if (res.data.success) {
let data = res.data.result;
this.storeList.push(...data.records);
}
},
},
};
</script>
<style lang="scss" scoped>
.wrapper {
padding: 0 16rpx;
}
.store-item {
display: flex;
background: #fff;
border-radius: 20rpx;
margin: 20rpx 0;
padding: 24rpx;
}
.store-msg {
margin-left: 20rpx;
}
.store-name {
font-weight: bold;
font-size: 30rpx;
}
.goods-num,
.store-collection {
color: #999;
font-size: 24rpx;
line-height: 1.5;
}
.store-goods {
margin: 20rpx 0;
}
.store-goods-item {
flex: 1;
overflow: hidden;
display: flex;
justify-content: flex-start;
flex-direction: column;
margin: 0 5rpx;
}
.wes {
margin: 10rpx 0;
width: 100%;
}
.store-score {
color: $light-color;
font-size: 24rpx;
font-weight: bold;
}
.line {
margin: 0 6rpx;
color: #999;
}
.store-distance {
justify-content: space-between;
}
.price {
margin-top: 10rpx;
color: $main-color;
}
.goods-price-bigshow {
font-size: 34rpx;
font-weight: bold;
}
</style>

View File

@@ -64,7 +64,7 @@
<u-image width="100%" height="330rpx" mode="aspectFit" :src="item.content.thumbnail"> <u-image width="100%" height="330rpx" mode="aspectFit" :src="item.content.thumbnail">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
</u-image> </u-image>
<div class="name">{{ item.content.goodsName }}</div> <div class="name wes-2">{{ item.content.goodsName }}</div>
<div class="price"> <div class="price">
<div>{{ item.content.price | unitPrice }}</div> <div>{{ item.content.price | unitPrice }}</div>
</div> </div>
@@ -126,7 +126,7 @@ export default {
}, },
watch: { watch: {
current(val) { current(val) {
val == 0 ? this.getGoodsData() : this.getCategoryData(); val == 0 ? ()=>{ this.goodsList = []; this.getGoodsData()} : this.getCategoryData();
}, },
}, },
@@ -135,22 +135,23 @@ export default {
*/ */
async onLoad(options) { async onLoad(options) {
this.storeId = options.id; this.storeId = options.id;
this.goodsParams.storeId = options.id;
this.couponParams.storeId = options.id;
}, },
onPageScroll(e) { onPageScroll(e) {
this.scrollTop = e.scrollTop; this.scrollTop = e.scrollTop;
}, },
onPullDownRefresh() { onPullDownRefresh() {
this.init();
this.init();
}, },
mounted() { mounted() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// 小程序默认分享 // 小程序默认分享
uni.showShareMenu({ withShareTicket: true }); uni.showShareMenu({ withShareTicket: true });
// #endif // #endif
this.init(); this.init();
}, },
// 下拉加载 // 下拉加载
onReachBottom() { onReachBottom() {
this.goodsParams.pageNumber++; this.goodsParams.pageNumber++;
@@ -420,8 +421,7 @@ export default {
color: #333; color: #333;
padding: 0 20rpx; padding: 0 20rpx;
margin-top: 20rpx; margin-top: 20rpx;
line-height: 1.4em; height: 80rpx;
max-height: 2.8em; //height是line-height的整数倍防止文字显示不全
overflow: hidden; overflow: hidden;
} }
.price { .price {

View File

@@ -13,7 +13,7 @@
<div>{{ item.content.price | unitPrice }}</div> <div>{{ item.content.price | unitPrice }}</div>
</div> </div>
<view class="buyCount"> <view class="buyCount">
<div>已售 {{ item.buyCount || "0" }}</div> <div>已售 {{ item.content.buyCount || "0" }}</div>
</view> </view>
</view> </view>
</div> </div>
@@ -32,8 +32,6 @@ export default {
params: { params: {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
order: "desc",
keyword: "", keyword: "",
storeCatId: "", storeCatId: "",
storeId: "", storeId: "",

View File

@@ -179,7 +179,7 @@ export default {
return { return {
path: this.share(), path: this.share(),
title: `请快来帮我砍一刀${this.bargainDetail.goodsName}`, title: `请快来帮我砍一刀${this.bargainDetail.goodsName}`,
imageUrl: this.thumbnail || config.logo, imageUrl: this.bargainDetail.thumbnail || config.logo,
}; };
}, },
// #endif // #endif
@@ -496,6 +496,11 @@ page {
> .user-name { > .user-name {
> div:nth-of-type(1) { > div:nth-of-type(1) {
font-size: 28rpx; font-size: 28rpx;
max-width: 300rpx;
overflow: hidden;
word-wrap: normal;
white-space: nowrap;
text-overflow: ellipsis;
} }
> div:nth-last-of-type(1) { > div:nth-last-of-type(1) {
font-size: 24rpx; font-size: 24rpx;

View File

@@ -26,7 +26,7 @@
<div v-if="groupBuy.length !=0"> <div v-if="groupBuy.length !=0">
<view class="view-item" v-for="(groupItem, groupIndex) in groupBuy" :key="groupIndex"> <view class="view-item" v-for="(groupItem, groupIndex) in groupBuy" :key="groupIndex">
<view class="view-left"> <view class="view-left">
<u-image border-radius="10" shape="square" :src="groupItem.goodsImage" width="186rpx" height="186rpx"> <u-image border-radius="10" shape="square" :src="groupItem.thumbnail" width="186rpx" height="186rpx">
<view slot="error" style="font-size: 24rpx;">加载失败</view> <view slot="error" style="font-size: 24rpx;">加载失败</view>
</u-image> </u-image>
@@ -42,7 +42,7 @@
{{groupItem.price | unitPrice }} {{groupItem.price | unitPrice }}
</view> </view>
<view class="view-content-original_price"> <view class="view-content-original_price">
{{ groupItem.originPrice | unitPrice }} {{ groupItem.originalPrice | unitPrice }}
</view> </view>
</view> </view>

View File

@@ -19,13 +19,13 @@
<view class="index-items"> <view class="index-items">
<view class="index-item" v-for="(item, key) in nav.goods" :key="key" @click="toGoods(item)"> <view class="index-item" v-for="(item, key) in nav.goods" :key="key" @click="toGoods(item)">
<view class="index-item-img"> <view class="index-item-img">
<u-image :src="item.goodsSku.thumbnail" mode="aspectFill"> <u-image :src="item.thumbnail" mode="aspectFill">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
</u-image> </u-image>
<view class="index-item-title">{{ item.goodsSku.goodsName }}</view> <view class="index-item-title">{{ item.goodsName }}</view>
<view class="index-item-price"> <view class="index-item-price">
{{ item.points }}积分 {{ item.points }}积分
<span class="tipsMkt">¥{{ item.goodsSku.price | unitPrice }}</span> <span class="tipsMkt">¥{{ item.originalPrice | unitPrice }}</span>
</view> </view>
</view> </view>
</view> </view>

View File

@@ -1,617 +0,0 @@
<template>
<view class="recommend" :style="styleWay">
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view class="prohibition" style="overscroll-behavior: unset;">
<view class="header" :style="'height:' + header.height + 'px;'">
<view class="left">
<u-icon @click="goMainPage" size="40" name="arrow-left"></u-icon>
</view>
{{ title }}
<view @click="goCart" class="right"><text class="alifont icon-gouwuche1" style="font-size: 40rpx;"></text></view>
</view>
</view>
<view class="recommend-head" :style="'margin-top:' + header.height + 'px;'">
<image src="/pages/floor/imgs/recommend/head-sample.png" mode="aspectFill"></image>
</view>
<view class="index-navs">
<ms-dropdown-item class="index-nav" :class="{ 'index-nav-active': nav == 1 }" v-model="sortType" @click.native="handledropdown(1)"
:hasSlot="true" :title="sortType || '综合排序'" ref="dropdownItem1">
<view class="dropdown-item-content">
<view class="dropdown-list" :class="{ 'dropdown-list-active': sortType == '综合排序' }" @click="setSortType('综合排序')">综合排序</view>
<view class="dropdown-list" :class="{ 'dropdown-list-active': sortType == '新品排序' }" @click="setSortType('新品排序')">新品排序</view>
</view>
</ms-dropdown-item>
<view class="index-nav-divider"></view>
<view class="index-nav" :class="{ 'index-nav-active': nav == 3 }" @click="setNav(3)">
销量
<view class="index-nav-arrows">
<view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-up-1.png" v-if="sale === 'asc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view>
<view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-down.png" v-if="sale === 'dec'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view>
</view>
</view>
<view class="index-nav-divider"></view>
<view class="index-nav" :class="{ 'index-nav-active': nav == 4 }" @click="setNav(4)">
价格
<view class="index-nav-arrows">
<view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-up-1.png" v-if="price === 'asc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view>
<view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-down.png" v-if="price === 'dec'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view>
</view>
</view>
<view class="index-nav-divider"></view>
<ms-dropdown-item class="index-nav" :class="{ 'index-nav-active': nav == 2 }" @click.native="handledropdown(2)"
v-model="current_tag" :hasSlot="true" :title="current_tag || '分类'" ref="dropdownItem2">
<view class="dropdown-tags">
<view class="dropdown-tag" :class="{ 'dropdown-tag-active': current_tag == item }" @click="setTags(item)" v-for="(item, index) in tags">{{ item }}</view>
<view class="dropdown-tag cancel-btn" @click="setTags('分类')">取消</view>
</view>
</ms-dropdown-item>
</view>
<view class="index-items">
<view class="index-item" v-for="(item, index) in goods" :key="index">
<view class="index-item-img" @click="toProduct(item.goods_id)">
<image :src="item.thumbnail" mode="aspectFill"></image>
<view class="index-item-title">{{ item.goodsName }}</view>
<view class="index-item-price">
¥{{ item.price | unitPrice }}
<!-- ¥{{ item.price | unitPrice }}{{ item.point ? '+' + item.point + '积分' : '' }} -->
<span class="tipsMkt">¥{{ item.mktprice }}</span>
</view>
<view class="index-item-title-desc">
<view>已售 {{ item.buy_count }}</view>
<view>好评率 {{ item.grade }}%</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import msDropdownItem from '@/components/ms-dropdown/dropdown-item.vue';
import {
getTagGoods
} from '@/api/goods.js';
import storage from '@/utils/storage.js';
export default {
components: {
msDropdownItem
},
data() {
return {
styleWay: {
'height': "100%",
'overflow': 'auto',
},
style_flag: false,
header: {
top: 0,
height: 40
},
originalGoods: [],
oldOriginalGoods: [],
// 分类的数据
sortData: [],
goods: [],
title: '',
mark: 'hot',
nav: 1,
sale: '',
price: '',
sortType: '',
tags: [],
current_tag: '',
typeSort1: true,
typeSort2: false,
};
},
async onLoad(options) {
if (options.title) {
this.title = options.title;
}
if (options.mark) {
this.mark = options.mark;
}
let response = await getTagGoods(-1, this.mark, 9999);
this.originalGoods = response.data;
this.reRank();
this.initCategory();
},
onNavigationBarButtonTap() {
uni.switchTab({
url: '/pages/tabbar/cart/cartList'
});
},
methods: {
handledropdown(val) {
if (!this.style_flag) {
this.styleWay = {
'overflow': "hidden",
'height': "100vh"
}
} else {
this.styleWay = {
'overflow': "auto",
'height': "100%"
}
}
this.style_flag = !this.style_flag
// 如果没有值的话就是全部关闭
if (!val) {
this.$refs.dropdownItem2.closePopup()
this.$refs.dropdownItem1.closePopup()
}
this.sale = '';
this.price = '';
// 如果等于1点击综合排序
if (val == 1) {
this.nav = 1
this.$refs.dropdownItem2.closePopup()
} else {
this.nav = 2
this.$refs.dropdownItem1.closePopup()
}
},
async getData() {
let response = await getTagGoods(-1, this.mark, 9999);
this.originalGoods = response.data;
this.reRank();
this.initCategory();
},
toProduct(goods_id) {
uni.navigateTo({
url: '/pages/product/goods?id=' + goods_id
});
},
goMainPage() {
uni.navigateBack()
},
goCart() {
let obj = {
from: 'recommend',
id: ''
};
storage.setCartBackbtn(obj);
uni.switchTab({
url: '/pages/tabbar/cart/cartList'
});
},
// 销量排序
saleSort(type) {
type == 'asc' ? this.originalGoods.sort(this.sortAsc('buy_count')) : this.originalGoods.sort(this.sortDec(
'buy_count'));
},
// 价格排序
priceSort(type) {
type == 'asc' ? this.originalGoods.sort(this.sortAsc('price')) : this.originalGoods.sort(this.sortDec('price'));
},
// 按照分类
cateSort(type) {
this.sortData = [];
// this.originalGoods =[]
for (let i = 0; i < this.originalGoods.length; i++) {
if (this.originalGoods[i].category_name == type) {
this.sortData.push(this.originalGoods[i]);
}
}
this.goods = this.sortData;
},
// 降序
sortDec(prop) {
return function(obj1, obj2) {
var val1 = obj1[prop];
var val2 = obj2[prop];
if (val1 < val2) {
return 1;
} else if (val1 > val2) {
return -1;
} else {
return 0;
}
};
},
// 升序
sortAsc(prop) {
return function(obj1, obj2) {
var val1 = obj1[prop];
var val2 = obj2[prop];
if (val1 < val2) {
return -1;
} else if (val1 > val2) {
return 1;
} else {
return 0;
}
};
},
setNav(type) {
this.handledropdown();
this.nav = type;
if (type == 3) {
// 销量 默认降序
this.typeSort1 ? this.setSort('sale', 'dec') : this.setSort('sale', 'asc');
this.typeSort1 = !this.typeSort1;
} else if (type == 4) {
// 价格 默认升序
this.typeSort2 ? this.setSort('price', 'asc') : this.setSort('price', 'dec');
this.typeSort2 = !this.typeSort2;
}
},
setSort(key, type) {
this.handledropdown();
if (key === 'sale') {
this.nav = 3;
this.saleSort(type);
this.$set(this, 'price', '');
}
if (key === 'price') {
this.nav = 4;
this.priceSort(type);
this.$set(this, 'sale', '');
}
if (this[key] === type) {
this.$set(this, key, '');
} else {
this.$set(this, key, type);
}
},
//
setSortType(value) {
this.nav = 1;
this.sortType = value;
// 新品排序
if (value == '新品排序') {
this.originalGoods.sort(this.sortDec('goods_id'));
} else {
this.getData();
}
this.$refs.dropdownItem1.closePopup();
},
setTags(value) {
this.current_tag = value;
this.$refs.dropdownItem2.closePopup();
if (value === '分类') {
this.nav = 1;
this.reRank();
} else {
this.nav = 2;
this.cateSort(value);
}
},
initCategory() {
let goods = this.goods;
let result = [];
for (var i = 0; i < goods.length; i++) {
result.push(goods[i].category_name);
}
this.tags = this.unique(result);
},
unique(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
//第一个等同于第二个splice方法删除第二个
arr.splice(j, 1);
j--;
}
}
}
return arr;
},
reRank() {
this.goods = this.originalGoods;
}
}
};
</script>
<style lang="less" scoped>
.index {
padding-top: var(--status-bar-height);
}
.prohibition {
position: fixed;
width: 100%;
z-index: 100;
top: var(--status-bar-height);
}
.status_bar {
position: fixed;
top: 0px;
height: var(--status-bar-height);
width: 100%;
background: #1abc9c;
z-index: 100;
}
.header {
background: #1abc9c;
position: relative;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
font-size: 34rpx;
height: 80rpx;
.left,
.right {
position: absolute;
width: max-content;
height: max-content;
top: 0;
bottom: 0;
margin: auto;
}
.left {
float: left;
top: 0;
bottom: 0;
left: 20rpx;
}
.right {
float: right;
right: 20rpx;
}
}
.tipsMkt {
float: right;
color: #c0c4cc;
text-decoration: line-through;
margin-right: 20rpx;
font-size: 24rpx;
line-height: 40rpx;
}
.img {
width: 13px !important;
height: 13px !important;
}
.recommend {
width: 100%;
padding-top: var(--status-bar-height);
}
.recommend-head {
image {
width: 3710 rpx;
height: 280 rpx;
}
}
.index-navs {
height: 80 rpx;
padding: 0 52 rpx;
background-color: #f7f7f7;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: space-between;
}
.index-nav {
color: #999;
font-size: 28 rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
&-active {
color: #1abc9c;
font-weight: 700;
.index-nav-desc {
color: #1abc9c;
}
}
}
.index-nav-desc {
margin-top: 8 rpx;
font-size: 22 rpx;
color: #999;
}
.index-nav-divider {
height: 64 rpx;
border-left: 1px solid #dddcdf;
}
.index-items {
margin-top: 20 rpx;
padding-left: 20 rpx;
background-color: #f7f7f7;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.index-item {
width: 346 rpx;
background-color: #fff;
margin: 0 18 rpx 20 rpx 0;
border-radius: 16 rpx;
box-sizing: border-box;
overflow: hidden;
}
.index-item-img {
image {
width: 346 rpx;
height: 320 rpx;
border-radius: 8rpx 8rpx 0 0;
}
}
.index-item-title {
font-size: 26 rpx;
color: #333333;
padding: 10 rpx 0 0 20 rpx;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.index-item-title-desc {
font-size: 25 rpx;
color: #c0c4cc;
margin: 10rpx 20rpx;
display: flex;
justify-content: space-between;
}
.index-item-price {
overflow: hidden;
font-size: 110 rpx;
color: #ff5a10;
padding: 20 rpx 0 0 20 rpx;
}
.index-nav-arrows {
margin-top: 4 rpx;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.index-nav-arrow {
image {
width: 32 rpx;
height: 32 rpx;
}
}
.index-nav-arrow:last-child {
margin-top: - 14 rpx;
}
.index-nav-arrow:first-child {
margin-bottom: - 14 rpx;
}
.dropdown-list {
width: 100%;
height: 88 rpx;
padding-left: 40 rpx;
font-size: 110 rpx;
color: #999;
font-weight: normal;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
&-active {
color: #1abc9c;
}
}
.dropdown-tags {
padding: 110 rpx;
box-sizing: border-box;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-wrap: wrap;
z-index: 9;
}
.dropdown-tag {
// width: 710 rpx;
padding: 10rpx 20rpx;
height: 60 rpx;
margin: 0 22 rpx 22 rpx 0;
border-radius: 60 rpx;
background-color: #f9f9f9;
font-size: 110 rpx;
color: #999;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
&-active {
background-color: #fff;
border: 1px solid #ed4743;
color: #ed4743;
}
}
.cancel-btn {
background-color: #e4e1e6;
}
</style>

View File

@@ -1,251 +0,0 @@
<template>
<view class="sale">
<view class="status_bar">
<!-- 这里是状态栏 -->
</view>
<view class="prohibition" :style="'overscroll-behavior: unset;height:' + header.height + 'px;'">
<view class="header">
<view class="left">
<u-icon @click="goMainPage()" size="40" name="arrow-left"></u-icon>
</view>
特惠推荐
<view @click="goCart" class="right"><text class="alifont icon-gouwuche1"
style="font-size: 40rpx;"></text></view>
</view>
</view>
<view class="sale-head">
<image :style="'margin-top:' + header.height + 'px;'" src="/pages/floor/imgs/recommend/head-sample.png"
mode="aspectFill"></image>
</view>
<view class="sale-title">
<view>今日特惠</view>
</view>
<view class="sale-items">
<view class="sale-item" v-for="item in goods" @click="navigateTo(item)">
<view class="sale-item-img">
<image :src="item.thumbnail" mode="aspectFill"></image>
</view>
<view class="sale-item-content">
<view class="sale-item-title">
{{ item.name }}
<view class="sale-item-title-desc">{{ item.category }}</view>
</view>
<view class="sale-item-price">
<text class="sale-item-price-now">¥{{ item.price | unitPrice }}
<!-- <text v-if="item.point">+{{ item.point || 0 }}积分</text> -->
</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import {
getPlateformTagGoods
} from '@/api/goods.js';
import storage from '@/utils/storage.js';
export default {
data() {
return {
header: {
top: 0,
height: 40
},
goods: [],
tag_id: 1,
loadStatus: 'more'
};
},
async onLoad(options) {
if (options.title) {
uni.setNavigationBarTitle({
title: options.title
});
}
let response = await getPlateformTagGoods(this.tag_id);
this.goods = response.data;
},
onBackPress() {
},
methods: {
// 跳转
navigateTo(item) {
uni.navigateTo({
url: '/pages/product/goods?id=' + item.goods_id
});
},
goCart() {
//跳转购物车
let obj = {
from: 'sale',
id: ''
};
storage.setCartBackbtn(obj);
uni.preloadPage({
url: '/pages/tabbar/cart/cartList'
});
},
goMainPage() {
//莫名其妙的,无法后退,尝试追加参数解决缓存问题
uni.switchTab({
url: '/pages/tabbar/home/index'
});
}
}
};
</script>
<style lang="less" scoped>
.sale {
width: 100%;
min-height: 100vh;
background-color: #f7f7f7;
}
.index {
padding-top: var(--status-bar-height);
}
.prohibition {
position: fixed;
width: 100%;
z-index: 100;
top: var(--status-bar-height);
}
.status_bar {
position: fixed;
top: 0px;
height: var(--status-bar-height);
width: 100%;
background: #1abc9c;
z-index: 100;
}
.header {
background: #1abc9c;
position: relative;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
font-size: 34rpx;
height: 80rpx;
.left,
.right {
position: absolute;
width: max-content;
height: max-content;
top: 0;
bottom: 0;
margin: auto;
}
.left {
float: left;
top: 0;
bottom: 0;
left: 20rpx;
}
.right {
float: right;
right: 20rpx;
}
}
.sale-head {
padding-top: var(--status-bar-height);
image {
width: 750 rpx;
height: 280 rpx;
border-radius: 0px;
}
margin-bottom: 20 rpx;
}
.sale-title {
width: 710 rpx;
height: 100 rpx;
margin: 0 auto;
font-size: 28 rpx;
color: #666;
border-radius: 14 rpx 14 rpx 0 0;
background-color: #f1f1f1;
display: -webkit-box;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
justify-content: start;
view {
margin-left: 40 rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 400;
}
}
.sale-items {
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
flex-direction: column;
margin: 0 20rpx;
background-color: #fff;
}
.sale-item {
width: 710 rpx;
padding: 0 20rpx;
height: 180 rpx;
border-bottom: 1px solid #eeeeee;
// position: relative;
display: -webkit-box;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: start;
}
.sale-item-img {
margin-right: 20 rpx;
image {
width: 124 rpx;
height: 124 rpx;
border-radius: 8 rpx;
}
}
.sale-item-content {
line-height: 1.5em;
}
.sale-item-title {
font-size: 28 rpx;
color: #333;
}
.sale-item-title-desc {
font-size: 25 rpx;
color: #ccc;
}
.sale-item-price-now {
font-size: 28 rpx;
color: #ff5a10;
margin: 0;
}
</style>

View File

@@ -1,6 +1,5 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<u-navbar :isBack="false" title="购物车"></u-navbar>
<!-- 空白页--> <!-- 空白页-->
<view v-if="cartDetail.cartList == '' || cartDetail.cartList == [] || !cartDetail" class="empty"> <view v-if="cartDetail.cartList == '' || cartDetail.cartList == [] || !cartDetail" class="empty">
<image src="/static/emptyCart.png" mode="aspectFit"></image> <image src="/static/emptyCart.png" mode="aspectFit"></image>
@@ -12,32 +11,37 @@
<!-- 店铺商品信息 --> <!-- 店铺商品信息 -->
<div class="content"> <div class="content">
<div class="box box2" :class="{ invalid: isInvalid(item) }" v-for="(item, index) in cartDetail.cartList" :key="index"> <div class="box box2" :class="{ invalid: isInvalid(item) }" v-for="(item, index) in cartDetail.cartList"
:key="index">
<view class="tab"> <view class="tab">
<view class="store-line"> <view class="store-line">
<u-checkbox-group class="store-line-check"> <u-checkbox-group class="store-line-check">
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
<u-checkbox shape="circle" :active-color="lightColor" v-model="item.checked" @change="checkboxChangeDP(item)"></u-checkbox> <u-checkbox shape="circle" :active-color="lightColor" v-model="item.checked"
@change="checkboxChangeDP(item)"></u-checkbox>
<!-- #endif --> <!-- #endif -->
<!-- 微信小程序这里 v-model出现问题改用:value --> <!-- 微信小程序这里 v-model出现问题改用:value -->
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<u-checkbox shape="circle" :active-color="lightColor" :value="item.checked" @change="checkboxChangeDP(item)"></u-checkbox> <u-checkbox shape="circle" :active-color="lightColor" :value="item.checked"
@change="checkboxChangeDP(item)"></u-checkbox>
<!-- #endif --> <!-- #endif -->
</u-checkbox-group> </u-checkbox-group>
<span class="storeName store-line-desc" @click.stop="navigateToStore(item)">{{ <span class="store-name store-line-desc" @click.stop="navigateToStore(item)">{{
item.storeName item.storeName
}}</span> }}</span>
<u-icon @click="navigateToStore(item)" size="24" style="margin-left:10rpx;" name="arrow-right"></u-icon>
</view> </view>
<view class="right_Col" @click="navigateToConpon(item)"> <view class="right-col" v-if="item.canReceiveCoupon" @click="navigateToConpon(item)">
<div class="right_Line"></div> <div class="right-line"></div>
<span>领劵</span> <span>领劵</span>
</view> </view>
</view> </view>
<u-swipe-action :show="skuItem.selected" @open="openAction(skuItem)" :options="options" bg-color="#fff" ref="swiperAction" class="cartItem" v-for="(skuItem, i) in item.skuList" :index="i" <u-swipe-action :show="skuItem.selected" @open="openAction(skuItem)" :options="options" bg-color="#fff"
:key="skuItem.goodsSku.id" @click="changeActionTab(skuItem)" @longpress="changeActionTab(skuItem)"> ref="swiperAction" class="cart-item" v-for="(skuItem, i) in item.skuList" :index="i" :key="skuItem.goodsSku.id"
@click="changeActionTab(skuItem)" @longpress="changeActionTab(skuItem)">
<!-- 满减活动 --> <!-- 满减活动 -->
<div v-if="skuItem.promotions" v-for="(fullDiscount,fullDiscountIndex) in skuItem.promotions" :key="fullDiscountIndex"> <div v-if="Object.keys(skuItem.promotionMap).length != 0">
<div v-if="fullDiscount.promotionType == 'FULL_DISCOUNT'"> <div v-if="getPromotion(skuItem).includes('FULL_DISCOUNT')">
<div class="promotion-notice" v-if="item.promotionNotice"> <div class="promotion-notice" v-if="item.promotionNotice">
<span class="tips">满减</span> <span class="tips">满减</span>
<span style="flex:10;">{{item.promotionNotice}}</span> <span style="flex:10;">{{item.promotionNotice}}</span>
@@ -49,16 +53,19 @@
<view> <view>
<u-checkbox-group v-if="skuItem.invalid == 0"> <u-checkbox-group v-if="skuItem.invalid == 0">
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
<u-checkbox shape="circle" :active-color="lightColor" class="c-left" v-model="skuItem.checked" @change="checkboxChange(skuItem)"></u-checkbox> <u-checkbox shape="circle" :active-color="lightColor" class="c-left" v-model="skuItem.checked"
@change="checkboxChange(skuItem)"></u-checkbox>
<!-- #endif --> <!-- #endif -->
<!-- 微信小程序这里 v-model出现问题改用:value --> <!-- 微信小程序这里 v-model出现问题改用:value -->
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<u-checkbox shape="circle" :active-color="lightColor" class="c-left" :value="skuItem.checked" @change="checkboxChange(skuItem)"></u-checkbox> <u-checkbox shape="circle" :active-color="lightColor" class="c-left" :value="skuItem.checked"
@change="checkboxChange(skuItem)"></u-checkbox>
<!-- #endif --> <!-- #endif -->
</u-checkbox-group> </u-checkbox-group>
<span class="invalid" v-else style="font-size: 24rpx">失效</span> <span class="invalid" v-else style="font-size: 24rpx">失效</span>
</view> </view>
<u-image border-radius="20" :fade="true" @click.native="navigateToGoods(skuItem)" width="200rpx" height="200rpx" :src="skuItem.goodsSku.thumbnail" @click="navigateToGoods(skuItem)" /> <u-image border-radius="10" :fade="true" @click="navigateToGoods(skuItem)" width="160rpx" height="160rpx"
:src="skuItem.goodsSku.thumbnail" />
</view> </view>
<view class="goods-content"> <view class="goods-content">
<!-- 商品名称 --> <!-- 商品名称 -->
@@ -69,33 +76,37 @@
<p class="sp-type">{{skuItem.goodsSku.simpleSpecs}}</p> <p class="sp-type">{{skuItem.goodsSku.simpleSpecs}}</p>
<p class="sp-number"> <p class="sp-number">
<view class="sp-price"> <view class="sp-price">
<div class="default-color" :class="{'theme-color':skuItem.promotions.length <=0 }"> <div class="default-color" :class="{'main-color':Object.keys(skuItem.promotionMap).length ==0 }">
<span>{{ formatPrice(skuItem.goodsSku.price)[0] }}</span> <span>{{ formatPrice(skuItem.goodsSku.price)[0] }}</span>
<span>.{{ formatPrice(skuItem.goodsSku.price)[1] }}</span> <span>.{{ formatPrice(skuItem.goodsSku.price)[1] }}</span>
</div> </div>
</view> </view>
<view> <view>
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
<u-number-box class="uNumber" :min="1" input-width="70" input-height="40" size="20" v-model="skuItem.num" @change="numChange(skuItem)"></u-number-box> <u-number-box class="uNumber" :min="1" input-width="70" input-height="40" size="20"
v-model="skuItem.num" @change="numChange(skuItem)"></u-number-box>
<!-- #endif --> <!-- #endif -->
<!-- #ifdef MP-WEIXIN --> <!-- #ifdef MP-WEIXIN -->
<u-number-box class="uNumber" :min="1" input-width="70" input-height="40" size="20" :value="skuItem.num" @plus="numChange(skuItem, '1')" @change="numChange_WEIXIN" :skuItem="skuItem" <u-number-box class="uNumber" :min="1" input-width="70" input-height="40" size="20"
:value="skuItem.num" @plus="numChange(skuItem, '1')" @change="numChange_WEIXIN" :skuItem="skuItem"
@minus="numChange(skuItem, '0')"></u-number-box> @minus="numChange(skuItem, '0')"></u-number-box>
<!-- #endif --> <!-- #endif -->
</view> </view>
<!-- 如果当有促销并且促销是 限时抢购 --> <!-- 如果当有促销并且促销是 限时抢购 -->
<!-- promotions --> <!-- promotions -->
<div class="promotions-list" v-if="skuItem.promotions" v-for="(seckill,seckillIndex) in skuItem.promotions" :key="seckillIndex"> <div class="promotions-list" v-if="Object.keys(skuItem.promotionMap).length != 0"
<div class="promotions-item-seckill" v-if="seckill.promotionType == 'SECKILL'"> >
距秒杀结束: <u-count-down show-border :hide-zero-day="true" :color="$mainColor" border-color="#ededed" font-size="24" :timestamp="getCountDownTime(seckill.endTime)"> <div class="promotions-item-seckill" v-if="getPromotion(skuItem).includes('SECKILL')">
距秒杀结束: <u-count-down show-border :hide-zero-day="true" :color="$mainColor" border-color="#ededed"
font-size="24" :timestamp="getCountDownTime(seckill.endTime)">
</u-count-down> </u-count-down>
</div> </div>
</div> </div>
<!-- 如果有活动 并且是选中的状态,显示预估到手价格 --> <!-- 如果有活动 并且是选中的状态,显示预估到手价格 -->
<div class="priceDetail-flowPrice" :class="{'theme-color':skuItem.priceDetailDTO}" <div class="priceDetail-flowPrice" :class="{'main-color':skuItem.priceDetailDTO}"
v-if="skuItem.priceDetailDTO && skuItem.invalid == 0 && skuItem.promotions.length!=0 && skuItem.checked && skuItem.checked"> v-if="skuItem.priceDetailDTO && skuItem.invalid == 0 && Object.keys(skuItem.promotionMap).length != 0 && skuItem.checked && skuItem.checked">
预估到手价 <span>{{ formatPrice(skuItem.priceDetailDTO.flowPrice)[0]}}</span> 预估到手价 <span>{{ formatPrice(skuItem.priceDetailDTO.flowPrice)[0]}}</span>
<span>.{{ formatPrice(skuItem.priceDetailDTO.flowPrice)[1] }} </span> <span>.{{ formatPrice(skuItem.priceDetailDTO.flowPrice)[1] }} </span>
</div> </div>
@@ -105,22 +116,28 @@
</u-swipe-action> </u-swipe-action>
</div> </div>
</div> </div>
<u-modal v-model="deleteShow" :confirm-style="{'color':lightColor}" @confirm="delectConfirm" show-cancel-button :content="deleteContent" :async-close="true"></u-modal> <u-modal v-model="deleteShow" :confirm-style="{'color':lightColor}" @confirm="delectConfirm" show-cancel-button
:content="deleteContent" :async-close="true"></u-modal>
<!-- 结账 --> <!-- 结账 -->
<div class="box box6"> <div class="box box6">
<view class="navL"> <view class="navL">
<u-checkbox shape="circle" :active-color="lightColor" v-model="checkout" @change="checkOut()" label-size="24">全选</u-checkbox> <u-checkbox shape="circle" :active-color="lightColor" v-model="checkout" @change="checkOut()" label-size="24">全选
</u-checkbox>
<span class="price"> <span class="price">
<div class="prices"> <div class="prices">
<div class="fullPrice"> <div class="fullPrice">
<span class="number" v-if="cartDetail && cartDetail.priceDetailDTO"> <span class="number" v-if="cartDetail && cartDetail.priceDetailDTO">
总计: <span>¥{{ formatPrice(cartDetail.priceDetailDTO.flowPrice)[0] }}</span>.<span>{{ formatPrice(cartDetail.priceDetailDTO.flowPrice)[1] }}</span> 总计:
<span>¥{{ formatPrice(cartDetail.priceDetailDTO.flowPrice)[0] }}</span>.<span>{{ formatPrice(cartDetail.priceDetailDTO.flowPrice)[1] }}</span>
</span> </span>
<span class="number" v-else>总计:0.00</span> <span class="number" v-else>总计:0.00</span>
</div> </div>
<div v-if="cartDetail.cartList && cartDetail.cartList.length!=0 && cartDetail.priceDetailDTO && cartDetail.priceDetailDTO.discountPrice!=0 " class="discountPrice"> <div
<span>优惠减:{{(cartDetail.priceDetailDTO.goodsPrice - cartDetail.priceDetailDTO.flowPrice) | unitPrice}} </span> v-if="cartDetail.cartList && cartDetail.cartList.length!=0 && cartDetail.priceDetailDTO && cartDetail.priceDetailDTO.discountPrice!=0 "
<span class="discountDetails" @click="discountDetails">优惠明细</span> class="discountPrice">
<span>优惠减:{{(cartDetail.priceDetailDTO.goodsPrice - cartDetail.priceDetailDTO.flowPrice) | unitPrice}}
</span>
<span class="discount-details" @click="discountDetails">优惠明细</span>
</div> </div>
</div> </div>
</span> </span>
@@ -187,16 +204,21 @@ export default {
cartDetail: "", //购物车详情 cartDetail: "", //购物车详情
goodsVal: "", //单个商品详情 goodsVal: "", //单个商品详情
isEdit: false, // 是否是编辑 isEdit: false, // 是否是编辑
checkout: true, //全选按钮 checkout: false, //全选按钮
WEIXIN_num: "", //购物车兼容微信步进器 WEIXIN_num: "", //购物车兼容微信步进器
}; };
}, },
mounted() { mounted() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// 小程序默认分享 // 小程序默认分享
uni.showShareMenu({ withShareTicket: true }); uni.showShareMenu({ withShareTicket: true });
// #endif // #endif
}, },
onPullDownRefresh(){
console.log("132")
this.getCardData();
},
/** /**
* 初始化信息 * 初始化信息
*/ */
@@ -316,7 +338,7 @@ export default {
*/ */
navigateToStore(val) { navigateToStore(val) {
uni.navigateTo({ uni.navigateTo({
url: "../product/shopPage?id=" + val.storeId, url: "/pages/product/shopPage?id=" + val.storeId,
}); });
}, },
@@ -379,6 +401,8 @@ export default {
* 验证是否选中商品 * 验证是否选中商品
*/ */
whetherChecked() { whetherChecked() {
this.$options.filters.forceLogin()
let canBuy = false; let canBuy = false;
this.cartDetail.cartList.forEach((item) => { this.cartDetail.cartList.forEach((item) => {
if (item.checked) { if (item.checked) {
@@ -472,6 +496,13 @@ export default {
}); });
}, },
// 数据去重一下
getPromotion(item) {
return Object.keys(item.promotionMap).map((child) => {
return child.split("-")[0]
});
},
/** /**
* 获取购物车数据 * 获取购物车数据
*/ */
@@ -482,26 +513,36 @@ export default {
}); });
API_Trade.getCarts() API_Trade.getCarts()
.then((result) => { .then((result) => {
uni.stopPullDownRefresh();
if (result.data.success) { if (result.data.success) {
this.cartDetail = result.data.result; this.cartDetail = result.data.result;
this.checkout = true; let checkouted = true;
for (let i = 0; i < this.cartDetail.cartList.length; i++) { for (let i = 0; i < this.cartDetail.cartList.length; i++) {
let item = this.cartDetail.cartList[i]; let item = this.cartDetail.cartList[i];
console.log(item);
// 循环出当前商品是否全选 // 循环出当前商品是否全选
if (item.checked == 0) { if (item.checked == 0) {
this.checkout = false; checkouted = false;
} }
// 如果有拼团活动顺便删除 // 如果有拼团活动顺便删除
item.skuList && item.skuList &&
item.skuList.forEach((sku) => { item.skuList.forEach((sku) => {
sku.promotions && if (sku.checked == 0) {
sku.promotions.forEach((pro, proIndex) => { checkouted = false;
if (pro.promotionType == "PINTUAN") { }
sku.promotions.splice(proIndex, 1); if(Object.keys(sku.promotionMap).length != 0)
{
Object.keys(sku.promotionMap).forEach((pro, proIndex) => {
pro = pro.split('-')[0]
if (pro == "PINTUAN" ) {
Object.keys(sku.promotionMap).splice(proIndex, 1);
} }
}); });
}
}); });
} }
this.checkout = checkouted;
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
} }
}) })
@@ -525,6 +566,11 @@ export default {
}; };
</script> </script>
<style lang="scss">
page {
background: #f2f2f2;
}
</style>
<style scoped lang="scss"> <style scoped lang="scss">
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
@import "./mp-carui.scss"; @import "./mp-carui.scss";
@@ -533,6 +579,7 @@ export default {
box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.05); box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.05);
} }
.promotion-notice { .promotion-notice {
margin-top: 10px;
margin-left: 68rpx; margin-left: 68rpx;
font-size: 24rpx; font-size: 24rpx;
color: #333; color: #333;
@@ -549,10 +596,9 @@ export default {
color: #fff; color: #fff;
} }
} }
.promotionNotice { .default-color {
font-size: 24rpx; color: #333;
} }
.goods-row { .goods-row {
padding: 30rpx 0; padding: 30rpx 0;
@@ -560,22 +606,19 @@ export default {
align-items: center; align-items: center;
} }
.storeName { .store-name {
font-weight: bold; font-weight: bold;
font-size: 28rpx;
} }
.invalid { .invalid {
filter: grayscale(1); filter: grayscale(1);
} }
.cartItem { .cart-item {
border-radius: 0.4em; border-radius: 0.4em;
transition: 0.35s; transition: 0.35s;
} }
.index {
padding-top: var(--status-bar-height);
}
/* 空白页 */ /* 空白页 */
/deep/ .u-number-input { /deep/ .u-number-input {
background: #fff !important; background: #fff !important;
@@ -598,7 +641,7 @@ export default {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
z-index: 99; z-index: 99;
padding-bottom: 100rpx; padding-bottom: var(--window-bottom);
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
@@ -648,16 +691,16 @@ export default {
} }
.box2 { .box2 {
border-radius: 30rpx; border-radius: 20rpx;
padding: 32rpx 40rpx 32rpx; padding: 0 16rpx 0;
margin: 0 16rpx 20rpx;
.u-checkbox { .u-checkbox {
display: flex; display: flex;
align-items: center; align-items: center;
text-align: center; text-align: center;
} }
background: #fff; background: #fff;
margin-bottom: 20rpx;
} }
.wrapper { .wrapper {
@@ -677,11 +720,6 @@ export default {
} }
} }
.allCheck {
// padding: 0 10rpx;
font-size: 24rpx;
}
.content { .content {
padding: 20rpx 0 20rpx 0; padding: 20rpx 0 20rpx 0;
margin-bottom: 80rpx; margin-bottom: 80rpx;
@@ -721,13 +759,10 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 30rpx 0; padding: 30rpx 0 0 0;
}
.couponIcon {
margin-left: 20rpx;
} }
.right_Col { .right-col {
color: $light-color; color: $light-color;
font-size: 26rpx; font-size: 26rpx;
@@ -736,7 +771,7 @@ export default {
} }
} }
.right_Line { .right-line {
width: 3px; width: 3px;
float: left; float: left;
height: 40rpx; height: 40rpx;
@@ -754,7 +789,7 @@ export default {
bottom: 0; bottom: 0;
// #endif // #endif
// #ifdef H5 // #ifdef H5
bottom: 100rpx; bottom: var(--window-bottom);
// #endif // #endif
left: 0; left: 0;
border-top: 1px solid #ededed; border-top: 1px solid #ededed;
@@ -773,16 +808,6 @@ export default {
} }
} }
.sp-name {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
font-size: 26rpx;
color: #333;
font-weight: bold;
}
.sp-type { .sp-type {
color: $u-light-color; color: $u-light-color;
padding: 10rpx 0; padding: 10rpx 0;
@@ -794,12 +819,7 @@ export default {
white-space: nowrap; white-space: nowrap;
} }
.default-color {
color: #333;
}
.theme-color {
color: $main-color;
}
.sp-number { .sp-number {
font-weight: bold; font-weight: bold;
@@ -833,7 +853,7 @@ export default {
color: rgb(201, 199, 199); color: rgb(201, 199, 199);
} }
} }
.discountDetails { .discount-details {
margin-left: 10px; margin-left: 10px;
color: #666; color: #666;
padding: 4rpx 10rpx; padding: 4rpx 10rpx;

View File

@@ -1,5 +1,6 @@
.box2 { .box2 {
padding: calc(32rpx) 40rpx 32rpx !important; padding: 0 16rpx 0;
margin: 0 16rpx 20rpx;
} }
.uNumber{ .uNumber{

View File

@@ -1,14 +1,13 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<!-- 楼层装修组件 --> <!-- 楼层装修组件 -->
<tpl /> <tpl ref="tpl" />
</div> </div>
</template> </template>
<script> <script>
import tpl from "@/pages/tabbar/home/views.vue"; import tpl from "@/pages/tabbar/home/views.vue";
export default { export default {
data() { data() {
return { return {
background: { background: {
@@ -16,13 +15,16 @@ export default {
}, },
}; };
}, },
onPullDownRefresh() {
this.$refs.tpl.init();
uni.stopPullDownRefresh();
},
components: { components: {
tpl, tpl,
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
</style> </style>

View File

@@ -3,7 +3,6 @@ export function modelNavigateTo(item) {
let val = item.url; let val = item.url;
switch (val.___type) { switch (val.___type) {
case "goods": case "goods":
uni.navigateTo({ uni.navigateTo({
url: "/pages/product/goods?id=" + val.id + "&goodsId=" + val.goodsId, url: "/pages/product/goods?id=" + val.id + "&goodsId=" + val.goodsId,
@@ -20,7 +19,7 @@ export function modelNavigateTo(item) {
}); });
} }
break; break;
case "stores": case "shops":
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/shopPage?id=${val.id}`, url: `/pages/product/shopPage?id=${val.id}`,
}); });
@@ -38,7 +37,6 @@ export function modelNavigateTo(item) {
break; break;
case "other": case "other":
switch (val.title) { switch (val.title) {
case "首页": case "首页":
uni.switchTab({ uni.switchTab({
url: `/pages/tabbar/home/index`, url: `/pages/tabbar/home/index`,
@@ -99,6 +97,11 @@ export function modelNavigateTo(item) {
url: `/pages/promotion/point/pointList`, url: `/pages/promotion/point/pointList`,
}); });
break; break;
case "店铺列表":
uni.navigateTo({
url: `/pages/product/shopList`,
});
break;
} }
break; break;

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="layout"> <div class="layout">
<u-sticky > <u-sticky>
<div class="goods-cell-title"> <div class="goods-cell-title">
<div class="goods-item-title" :class="{ 'selected-title': selected.index == index }" <div class="goods-item-title" :class="{ 'selected-title': selected.index == index }"
@click="handleClickTitle(title, index)" v-for="(title, index) in res.list[0].titleWay" :key="index"> @click="handleClickTitle(title, index)" v-for="(title, index) in res.list[0].titleWay" :key="index">
@@ -11,8 +11,9 @@
</div> </div>
</u-sticky> </u-sticky>
<div class="goods-list"> <div class="goods-list">
<div v-if="selected.val == item.type" @click="handleClick(item)" class="goods-item" <div v-if="item.___index != undefined ? (selected.index == item.___index) : ( selected.val == item.type)"
v-for="(item, item_index) in res.list[0].listWay" :key="item_index"> @click="handleClick(item)" class="goods-item" v-for="(item, item_index) in res.list[0].listWay"
:key="item_index">
<div class="goods-img"> <div class="goods-img">
<u-image :src="item.img" height="350rpx" mode="aspectFit" width="100%"> <u-image :src="item.img" height="350rpx" mode="aspectFit" width="100%">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
@@ -53,11 +54,7 @@ export default {
immediate: true, immediate: true,
}, },
}, },
mounted () { mounted() {},
this.$u.getRect('.goods-cell-title').then(res=>{
console.log(res)
})
},
methods: { methods: {
handleClick(item) { handleClick(item) {
uni.navigateTo({ uni.navigateTo({

View File

@@ -108,6 +108,7 @@ export default {
* 实例化首页数据楼层 * 实例化首页数据楼层
*/ */
init() { init() {
this.pageData = "";
getFloorData().then((res) => { getFloorData().then((res) => {
if (res.data.success) { if (res.data.success) {
this.pageData = JSON.parse(res.data.result.pageData); this.pageData = JSON.parse(res.data.result.pageData);
@@ -127,19 +128,28 @@ export default {
uni.scanCode({ uni.scanCode({
success: function (res) { success: function (res) {
let path = encodeURIComponent(res.result); let path = encodeURIComponent(res.result);
config.scanAuthNavigation.forEach((src) => {
if (res.result.indexOf(src) != -1) { // WX_CODE 为小程序码
uni.navigateTo({ if (res.scanType == "WX_CODE") {
url: `/${res.result.substring(src.length)}`, console.log(res)
}); uni.navigateTo({
} else { url: `/${res.path}`,
setTimeout(() => { });
} else {
config.scanAuthNavigation.forEach((src) => {
if (res.result.indexOf(src) != -1) {
uni.navigateTo({ uni.navigateTo({
url: "/pages/tabbar/home/web-view?src=" + path, url: `/${res.result.substring(src.length)}`,
}); });
}, 100); } else {
} setTimeout(() => {
}); uni.navigateTo({
url: "/pages/tabbar/home/web-view?src=" + path,
});
}, 100);
}
});
}
}, },
}); });
}, },

View File

@@ -61,7 +61,7 @@ $font-weight: 400;
color: $light-color; color: $light-color;
} }
.main-color { .main-color {
color: $main-color; color: $main-color !important;
} }
.bg-light-color { .bg-light-color {
background-color: $light-color !important; background-color: $light-color !important;

View File

@@ -105,6 +105,33 @@ export function isLogin(val) {
} }
} }
/**
* 验证是否登录如果没登录则去登录
* @param {*} val
* @returns
*/
export function forceLogin() {
let userInfo = storage.getUserInfo();
if (!userInfo.id) {
// #ifdef MP-WEIXIN
uni.navigateTo({
url: "/pages/passport/wechatMPLogin",
});
// #endif
// #ifndef MP-WEIXIN
uni.navigateTo({
url: "/pages/passport/login",
});
// #endif
}
}
/** /**
* 获取当前加载的页面对象 * 获取当前加载的页面对象
* @param val * @param val
@@ -168,6 +195,7 @@ export function orderStatusList(val) {
PAID: "已付款", PAID: "已付款",
DELIVERED: "已发货", DELIVERED: "已发货",
CANCELLED: "已取消", CANCELLED: "已取消",
COMPLETED: "已完成",
COMPLETE: "已完成", COMPLETE: "已完成",
TAKE: "待核验", TAKE: "待核验",
}; };

View File

@@ -4,62 +4,9 @@ import storage from "@/utils/storage.js";
import { md5 } from "@/utils/md5.js"; import { md5 } from "@/utils/md5.js";
import Foundation from "@/utils/Foundation.js"; import Foundation from "@/utils/Foundation.js";
import api from "@/config/api.js"; import api from "@/config/api.js";
import debounce from "@/uview-ui/libs/function/debounce.js";
import uuid from "@/utils/uuid.modified.js"; import uuid from "@/utils/uuid.modified.js";
/**
* 无痛刷新token思路如果不使用无痛刷新token,忽略此处注释)
* 看了很多,有个问题一直得不到解决----多个接口请求token失效如何让获取token只获取一遍
* 于是想到了闭包防抖......
* 本方案并不是最佳方案,只是给你们提供一种思路。如果你有完美解决方案,可以分享一下
*/
const expireToken = []; // 储存过期的token
// 防抖闭包来一波
function getTokenDebounce() {
let lock = false;
let success = false;
return async function () {
if (!lock) {
lock = true;
await refreshTokenFn(storage.getRefreshToken())
.then((res) => {
if (res.data.success) {
let { accessToken, refreshToken } = res.data.result;
storage.setAccessToken(accessToken);
storage.setRefreshToken(refreshToken);
success = true;
lock = false;
} else {
cleanStorage();
success = false;
lock = false;
}
})
.catch((error) => {
cleanStorage();
success = false;
lock = false;
});
}
return new Promise((resolve) => {
// XXX 我只能想到通过轮询来看获取新的token是否结束有好的方案可以说。一直看lock,直到请求失败或者成功
const timer = setInterval(() => {
if (!lock) {
clearInterval(timer);
if (success) {
resolve("success");
} else {
cleanStorage();
resolve("fail");
}
}
}, 100); // 轮询时间可以自己看改成多少合适
});
};
}
function cleanStorage() { function cleanStorage() {
uni.showToast({ uni.showToast({
title: "你的登录状态已过期,请重新登录", title: "你的登录状态已过期,请重新登录",
@@ -77,27 +24,28 @@ function cleanStorage() {
storage.setUuid(""); storage.setUuid("");
storage.setUserInfo({}); storage.setUserInfo({});
// 防抖处理跳转 // 防抖处理跳转
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
debounce(() => {
console.log("防抖"); uni.navigateTo({
uni.navigateTo({ url: "/pages/passport/wechatMPLogin",
url: "/pages/passport/wechatMPLogin", });
});
}, 500);
// #endif // #endif
// #ifndef MP-WEIXIN // #ifndef MP-WEIXIN
debounce(() => {
uni.navigateTo({ uni.navigateTo({
url: "/pages/passport/login", url: "/pages/passport/login",
}); });
}, 500);
// #endif // #endif
} }
let http = new Request(); let http = new Request();
const refreshToken = getTokenDebounce();
http.setConfig((config) => { http.setConfig((config) => {
// 没有uuid创建 // 没有uuid创建
@@ -136,26 +84,7 @@ http.interceptors.request.use(
config.params = params; config.params = params;
config.header.accessToken = accessToken; config.header.accessToken = accessToken;
/**
* jwt 因为安卓以及ios没有window的属性
* window.atob这个函数 base64编码的使用方法就是btoa而用于解码的使用方法是atob
* 所以使用手写 base-64 编码的字符串数据。
*/
const atob = (str) => Buffer.from(str, "base64").toString("binary");
// 判断如果过期时间小于我的当前时间在请求上重新刷新token
if (accessToken.split(".").length <= 1) {
refresh();
} else {
if (
JSON.parse(
atob(
accessToken.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")
)
).exp < Math.round(new Date() / 1000)
) {
refresh();
}
}
} }
config.header = { config.header = {
...config.header, ...config.header,
@@ -168,49 +97,59 @@ http.interceptors.request.use(
} }
); );
async function refresh() {
// 本地储存的是过期token了重新获取
const getTokenResult = await refreshToken();
if (getTokenResult === "success") {
// 获取新的token成功 刷新当前页面
let routes = getCurrentPages(); // 获取当前打开过的页面路由数组
let curRoute = routes[routes.length - 1].route; //获取当前页面路由
let curParam = routes[routes.length - 1].options; //获取路由参数
// 拼接参数
let param = "";
for (let key in curParam) {
param += "&" + key + "=" + curParam[key];
}
// 判断当前路径
if (curRoute.indexOf("pages/tabbar") == 1) {
uni.switchTab({
url: "/" + curRoute + param.replace("&", "?"),
});
}
uni.redirectTo({
url: "/" + curRoute + param.replace("&", "?"),
});
}
}
// 是否正在刷新的标记
let isRefreshing = false;
//重试队列
let requests = [];
// 必须使用异步函数,注意 // 必须使用异步函数,注意
http.interceptors.response.use( http.interceptors.response.use(
async (response) => { async (response) => {
/* 请求之后拦截器。可以使用async await 做异步操作 */ /* 请求之后拦截器。可以使用async await 做异步操作 */
// token存在并且token过期 // token存在并且token过期
if (isRefreshing && response.statusCode === 403) {
cleanStorage();
isRefreshing = false;
}
let token = storage.getAccessToken(); let token = storage.getAccessToken();
if ( if (
(token && response.statusCode === 403) || (token && response.statusCode === 403) ||
response.data.status === 403 response.data.status === 403
) { ) {
// jwt token 过期了 if (!isRefreshing) {
expireToken.push(token); // 把过期token 储存 isRefreshing = true;
const currentToken = storage.getAccessToken(); //调用刷新token的接口
if (expireToken.includes(currentToken)) { return refreshTokenFn(storage.getRefreshToken())
refresh(); .then((res) => {
let { accessToken, refreshToken } = res.data.result;
storage.setAccessToken(accessToken);
storage.setRefreshToken(refreshToken);
response.header.accessToken = `${accessToken}`;
// token 刷新后将数组的方法重新执行
requests.forEach((cb) => cb(accessToken));
requests = []; // 重新请求完清空
return http.request(response.config);
})
.catch((err) => {
cleanStorage();
return Promise.reject(err);
})
.finally(() => {
isRefreshing = false;
});
} else {
// 返回未执行 resolve 的 Promise
return new Promise((resolve) => {
// 用函数形式将 resolve 存入,等待刷新后再执行
requests.push((token) => {
response.header.accessToken = `${token}`;
resolve(http.request(response.config));
});
});
} }
// 如果当前返回没登录 // 如果当前返回没登录
} else if ( } else if (
(!token && response.statusCode === 403) || (!token && response.statusCode === 403) ||

View File

@@ -8,6 +8,7 @@ const USER_INFO = isDev ? "user_info_obj_dev" : "user_info_obj";
const FACE_LOGIN = isDev ? "face_login_dev" : "face_login"; const FACE_LOGIN = isDev ? "face_login_dev" : "face_login";
const FINGER_LOGIN = isDev ? "finger_login_dev" : "finger_login"; const FINGER_LOGIN = isDev ? "finger_login_dev" : "finger_login";
const CART_BACKBTN = isDev ? "cart_backbtn_dev" : "cart_backbtn"; const CART_BACKBTN = isDev ? "cart_backbtn_dev" : "cart_backbtn";
const AFTERSALE_DATA = isDev ? "aftersale_data_dev" : "aftersale_data";
export default { export default {
// 写入热门搜索时间戳 // 写入热门搜索时间戳
setHotWords(val) { setHotWords(val) {
@@ -91,4 +92,16 @@ export default {
removeRefreshToken() { removeRefreshToken() {
uni.removeStorageSync(REFRESH_TOKEN); uni.removeStorageSync(REFRESH_TOKEN);
}, },
// 写入刷新token
setAfterSaleData(val) {
uni.setStorageSync(AFTERSALE_DATA, val);
},
// 获取刷新token
getAfterSaleData() {
return uni.getStorageSync(AFTERSALE_DATA);
},
// 删除token
removeAfterSaleData() {
uni.removeStorageSync(AFTERSALE_DATA);
},
}; };