mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2025-12-19 17:05:55 +08:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d1089b756 | ||
|
|
6c8102aecd | ||
|
|
56fdb2c2f0 | ||
|
|
7c85460fbb | ||
|
|
47b58c290a | ||
|
|
cdf57806d6 | ||
|
|
9671d60555 | ||
|
|
f8b388c968 | ||
|
|
91cc98e853 | ||
|
|
58484f1b61 | ||
|
|
d65ad6c5fd | ||
|
|
68bc1d6974 | ||
|
|
b1c518c3a8 | ||
|
|
48c7030c0e | ||
|
|
13c9d521f9 | ||
|
|
375653eb78 | ||
|
|
8c72cdcb0a | ||
|
|
cfb88d798b | ||
|
|
ebf32a18b0 | ||
|
|
5f6c1adf91 | ||
|
|
44648e9971 | ||
|
|
fd37087c43 | ||
|
|
4c47a1249f | ||
|
|
ea3563e4e9 | ||
|
|
c98c5b64e1 | ||
|
|
3b9b2e8ba2 | ||
|
|
cebde87682 | ||
|
|
0b2bf1faf1 | ||
|
|
73560e8366 | ||
|
|
afabfdd1d5 | ||
|
|
dadce33d74 |
253
README.md
253
README.md
@@ -1,110 +1,138 @@
|
|||||||
## Lilishop B2B2C商城系统
|
## 🔥 Lilishop B2B2C商城系统
|
||||||
|
|
||||||
|
##### 🌹 开源不易,如有帮助请点Star
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 欢迎交流需求,交流业务,交流技术(基础问题自行解决,进群先看文档后提问)
|
||||||
|
|
||||||
|
##### 交流 qq 1群 961316482(已满)
|
||||||
|
|
||||||
|
##### 交流 qq 2群 875294241
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### 商城 公众号/小程序体验,扫描二维码
|
||||||
|
|
||||||
##### 官方公众号 & 开源不易,如有帮助请点Star
|
|
||||||

|

|
||||||
|
|
||||||
[](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
|
[](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
### 介绍
|
### 🔥 商城介绍
|
||||||
**官网**: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
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 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 |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 功能列表
|
### ⚾️ 功能列表
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 平台功能
|
#### 🥎 商城平台功能
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 商家端功能
|
#### 🥎 商城卖家功能
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -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%;" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 管理端
|
#### ⚽️ 商城管理端
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
### 技术选型
|
### 商城技术选型
|
||||||
|
|
||||||
#### 架构图
|
#### 🥅 架构图
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
##### 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
|
||||||
|
|
||||||
|
|||||||
@@ -65,3 +65,12 @@ export function refreshTokenFn(refresh_token) {
|
|||||||
method: "GET",
|
method: "GET",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取密码状态
|
||||||
|
export function logout () {
|
||||||
|
return http.request({
|
||||||
|
url: '/members/logout',
|
||||||
|
method: "POST",
|
||||||
|
needToken: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode"
|
<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()">
|
:border-radius="setup.radius" @close="closeMask()">
|
||||||
<!-- 商品 -->
|
<!-- 商品 -->
|
||||||
<view class="goods-box bottom">
|
<view class="goods-box bottom">
|
||||||
<view class="goods-header">
|
<view class="goods-header">
|
||||||
@@ -10,14 +10,18 @@
|
|||||||
:src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
|
: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">
|
||||||
<span>
|
<span v-if="goodsDetail.promotionPrice && !pointDetail">
|
||||||
¥
|
¥
|
||||||
<span class="goods-price-promotionShow goods-price-bigshow"
|
<span
|
||||||
v-if="goodsDetail.promotionPrice">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span>
|
class="goods-price-promotionShow goods-price-bigshow">{{ 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">
|
||||||
¥
|
¥
|
||||||
@@ -36,6 +40,7 @@
|
|||||||
formatPrice(goodsDetail.price)[0]
|
formatPrice(goodsDetail.price)[0]
|
||||||
}}</span>
|
}}</span>
|
||||||
.{{ formatPrice(goodsDetail.price)[1] }}
|
.{{ formatPrice(goodsDetail.price)[1] }}
|
||||||
|
|
||||||
</span>
|
</span>
|
||||||
</view>
|
</view>
|
||||||
<view class="goods-check-skus">
|
<view class="goods-check-skus">
|
||||||
@@ -48,24 +53,33 @@
|
|||||||
</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"
|
|
||||||
|
|
||||||
|
<!-- 正常逻辑 循环出sku -->
|
||||||
|
<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"
|
v-for="(spec_val, spec_index) in spec.values" :key="spec_index"
|
||||||
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view>
|
@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 :bg-color="numberBox.bgColor" :max="200" :color="numberBox.color"
|
||||||
:input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num">
|
: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">
|
||||||
|
|
||||||
@@ -80,6 +94,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,17 +116,35 @@ 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",
|
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) {
|
||||||
@@ -120,7 +153,7 @@ export default {
|
|||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
selectSkuList: {
|
selectSkuList: {
|
||||||
handler(val) {
|
handler(val, oldval) {
|
||||||
this.$emit("changed", val);
|
this.$emit("changed", val);
|
||||||
},
|
},
|
||||||
deep: true,
|
deep: true,
|
||||||
@@ -128,6 +161,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
|
||||||
// 格式化金钱 1999 --> [1999,00]
|
// 格式化金钱 1999 --> [1999,00]
|
||||||
formatPrice(val) {
|
formatPrice(val) {
|
||||||
if (typeof val == "undefined") {
|
if (typeof val == "undefined") {
|
||||||
@@ -142,7 +177,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,21 +191,48 @@ 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)
|
||||||
|
)}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加到购物车或购买
|
* 添加到购物车或购买
|
||||||
*/
|
*/
|
||||||
@@ -222,27 +284,9 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 直接购买
|
|
||||||
*/
|
|
||||||
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;
|
console.log(list);
|
||||||
let arr = [{}];
|
let arr = [{}];
|
||||||
list.forEach((item, index) => {
|
list.forEach((item, index) => {
|
||||||
item.specValues.forEach((spec, specIndex) => {
|
item.specValues.forEach((spec, specIndex) => {
|
||||||
@@ -250,6 +294,7 @@ export default {
|
|||||||
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 +304,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);
|
||||||
}
|
}
|
||||||
@@ -268,6 +315,7 @@ export default {
|
|||||||
return key.name;
|
return key.name;
|
||||||
});
|
});
|
||||||
if (!keys.includes(name)) {
|
if (!keys.includes(name)) {
|
||||||
|
console.log(name, values);
|
||||||
arr.push({
|
arr.push({
|
||||||
name: name,
|
name: name,
|
||||||
values: [values],
|
values: [values],
|
||||||
@@ -276,16 +324,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 +347,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>
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -132,7 +117,6 @@ export default {
|
|||||||
//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 {
|
||||||
|
|||||||
@@ -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"></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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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
@@ -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>
|
|
||||||
278
components/verify-code/verify-code.vue
Normal file
278
components/verify-code/verify-code.vue
Normal 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>
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
"name" : "lili商城",
|
"name" : "lili商城",
|
||||||
"appid" : "__UNI__C100675",
|
"appid" : "__UNI__C100675",
|
||||||
"description" : "",
|
"description" : "",
|
||||||
"versionName" : "4.0.42",
|
"versionName" : "4.0.47",
|
||||||
"versionCode" : 4000042,
|
"versionCode" : 4000047,
|
||||||
"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"
|
||||||
},
|
},
|
||||||
|
|||||||
30
pages.json
30
pages.json
@@ -10,7 +10,8 @@
|
|||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "首页",
|
"navigationBarTitleText": "首页",
|
||||||
"navigationStyle": "custom", // 隐藏系统导航栏
|
"navigationStyle": "custom", // 隐藏系统导航栏
|
||||||
"navigationBarTextStyle": "black"
|
"navigationBarTextStyle": "black",
|
||||||
|
"enablePullDownRefresh":true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -18,8 +19,6 @@
|
|||||||
"path": "pages/tabbar/cart/cartList",
|
"path": "pages/tabbar/cart/cartList",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "购物车",
|
"navigationBarTitleText": "购物车",
|
||||||
"navigationStyle": "custom",
|
|
||||||
|
|
||||||
"navigationBarBackgroundColor": "#fff"
|
"navigationBarBackgroundColor": "#fff"
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -42,9 +41,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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
@@ -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": "限时抢购",
|
||||||
@@ -475,13 +474,6 @@
|
|||||||
"bounce": "none"
|
"bounce": "none"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
"path": "recommend",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "人气推荐",
|
|
||||||
"navigationStyle": "custom"
|
|
||||||
|
|
||||||
}
|
|
||||||
},{
|
},{
|
||||||
"path": "lives",
|
"path": "lives",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -69,6 +69,10 @@ 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);
|
||||||
@@ -114,10 +118,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 +209,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;
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -13,7 +14,8 @@
|
|||||||
<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,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
|
this.navList[this.tabCurrentIndex].dataList = [];
|
||||||
this.getData();
|
this.getData();
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -158,7 +161,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();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export default {
|
|
||||||
height:"1000rpx", //弹出层高度
|
|
||||||
mode:"bottom", //弹出层位置
|
|
||||||
radius:"32", //圆角 rpx,
|
|
||||||
close:false //能否点击遮罩退出
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
<view class="myTracks">
|
<view class="myTracks">
|
||||||
<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>
|
||||||
@@ -33,7 +34,8 @@
|
|||||||
<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>
|
||||||
@@ -79,6 +81,10 @@ export default {
|
|||||||
onLoad() {
|
onLoad() {
|
||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
|
onPullDownRefresh() {
|
||||||
|
this.trackList = [];
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
/**
|
||||||
* 导航到店铺
|
* 导航到店铺
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 || "", //生日
|
||||||
|
|||||||
@@ -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");
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,6 +353,7 @@ 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;
|
||||||
}
|
}
|
||||||
if (this.routerVal.keyword) {
|
if (this.routerVal.keyword) {
|
||||||
@@ -383,6 +382,12 @@ export default {
|
|||||||
this.defaultKeyword = "请输入搜索商品";
|
this.defaultKeyword = "请输入搜索商品";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
sortPopup(val) {
|
||||||
|
if (val) {
|
||||||
|
this.selectedWay = { brand: [], categoryId: [], prop: [] };
|
||||||
|
console.log(this.selectedWay);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
onReachBottom() {
|
onReachBottom() {
|
||||||
@@ -458,19 +463,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 +503,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 +562,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();
|
||||||
|
|||||||
@@ -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,31 +42,38 @@
|
|||||||
<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>
|
||||||
<view class="after-line">
|
<view class="after-line">
|
||||||
<!-- 售后申请 -->
|
<!-- 售后申请 -->
|
||||||
<view v-if="
|
<view v-if="
|
||||||
current === 0 && order.groupAfterSaleStatus=='NOT_APPLIED'
|
current === 0 && order.groupAfterSaleStatus.includes('NOT_APPLIED')
|
||||||
" @click="applyService(sku.sn, order, sku)" class="rebuy-btn">
|
" @click="applyService(sku.sn, order, sku)" class="rebuy-btn">
|
||||||
申请售后
|
申请售后
|
||||||
</view>
|
</view>
|
||||||
@@ -276,10 +285,19 @@ export default {
|
|||||||
/**
|
/**
|
||||||
* 查看详情
|
* 查看详情
|
||||||
*/
|
*/
|
||||||
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
|
||||||
|
}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -462,7 +469,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 +490,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>
|
||||||
|
|||||||
@@ -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,8 @@
|
|||||||
</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";
|
||||||
export default {
|
export default {
|
||||||
components: {
|
|
||||||
UniIcons,
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
sn: "",
|
sn: "",
|
||||||
|
|||||||
@@ -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,13 @@
|
|||||||
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"
|
<image :src="img" @click="preview(serviceDetail.afterSaleImage.split(','), index)"
|
||||||
|
v-for="(img, index) in serviceDetail.afterSaleImage.split(',')" :key="index"
|
||||||
style="width: 50px; height: 50px; margin: 0px 5px"></image>
|
style="width: 50px; height: 50px; margin: 0px 5px"></image>
|
||||||
</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 +105,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
|
||||||
@@ -197,12 +201,7 @@ import {
|
|||||||
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: "", //申请原因
|
||||||
@@ -339,9 +338,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 +364,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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@
|
|||||||
<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 :span="3" textAlign="right" v-if=" orderMessage.priceDetailDTO.couponPrice">
|
||||||
-¥{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</u-col>
|
<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>
|
||||||
@@ -507,6 +507,7 @@ export default {
|
|||||||
|
|
||||||
// 获取结算参数
|
// 获取结算参数
|
||||||
getOrderList() {
|
getOrderList() {
|
||||||
|
this.notSupportFreight = []
|
||||||
// 获取结算参数
|
// 获取结算参数
|
||||||
API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
|
API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
|
||||||
res.data.result.cartList.forEach((item, index) => {
|
res.data.result.cartList.forEach((item, index) => {
|
||||||
@@ -820,6 +821,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 +832,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;
|
||||||
|
|||||||
@@ -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 后续完善 -->
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -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 :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,360 @@ 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.setUuid(this.uuid.v1());
|
||||||
|
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 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: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-item {
|
||||||
|
width: 80rpx;
|
||||||
|
|
||||||
|
border-radius: 10rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
|
|
||||||
/deep/ .u-form-item {
|
|
||||||
margin: 40rpx 0 !important;
|
|
||||||
padding: 40rpx 0 !important;
|
|
||||||
}
|
|
||||||
.submit {
|
|
||||||
margin-top: 40rpx;
|
|
||||||
}
|
|
||||||
@@ -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>
|
|
||||||
@@ -204,24 +204,25 @@
|
|||||||
</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 v-model="promotionFlag" :height="setup.height" :mode="setup.mode" :border-radius="setup.radius"
|
||||||
<view ref="mask_title" class="title mask_title">
|
@close="promotionFlag=false" :mask-close-able="setup.close" closeable>
|
||||||
优惠
|
<view class="header-title">优惠</view>
|
||||||
<span @click="shutMask(false)">×</span>
|
<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 @closeAddress="closePopupAddress" @deliveryData="deliveryFun" v-if="goodsDetail.id"
|
||||||
@@ -262,10 +263,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 +288,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
setup,
|
||||||
|
promotionFlag: false,
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
navbarListX: 110, //导航栏列表栏x轴
|
navbarListX: 110, //导航栏列表栏x轴
|
||||||
navbarListY: 80, //导航栏列表栏y轴
|
navbarListY: 80, //导航栏列表栏y轴
|
||||||
@@ -373,8 +378,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, //添加购物车直接购买,查看已选 弹窗
|
||||||
@@ -406,17 +410,7 @@ export default {
|
|||||||
routerVal: "",
|
routerVal: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// #ifdef MP-WEIXNI
|
|
||||||
shareAppMessage() {
|
|
||||||
return {
|
|
||||||
title: this.goodsDetail.goodsName,
|
|
||||||
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) {
|
||||||
@@ -479,6 +473,7 @@ export default {
|
|||||||
getMpScene(this.routerVal.scene).then((res) => {
|
getMpScene(this.routerVal.scene).then((res) => {
|
||||||
if (res.data.success) {
|
if (res.data.success) {
|
||||||
let data = res.data.result.split(","); // skuId,goodsId,distributionId
|
let data = res.data.result.split(","); // skuId,goodsId,distributionId
|
||||||
|
console.warn(data);
|
||||||
this.init(data[0], data[1], data[2]);
|
this.init(data[0], data[1], data[2]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -490,7 +485,19 @@ export default {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// #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,21 +523,24 @@ 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);
|
||||||
|
|
||||||
|
console.log(response);
|
||||||
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) {
|
||||||
let disResult = await getGoodsDistribution(distributionId);
|
let disResult = await getGoodsDistribution(distributionId);
|
||||||
if (!disResult.data.success || disResult.statusCode == 403) {
|
if (!disResult.data.success || disResult.statusCode == 403) {
|
||||||
|
console.log("绑定成功!");
|
||||||
this.$store.state.distributionId = distributionId;
|
this.$store.state.distributionId = distributionId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -625,14 +635,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 +718,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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -739,6 +749,7 @@ export default {
|
|||||||
category: this.goodsDetail.categoryId,
|
category: this.goodsDetail.categoryId,
|
||||||
keyword: this.goodsDetail.name,
|
keyword: this.goodsDetail.name,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
console.warn(this.likeGoodsList )
|
||||||
this.likeGoodsList = res.data.result.content;
|
this.likeGoodsList = res.data.result.content;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -775,22 +786,21 @@ export default {
|
|||||||
* 规格弹窗开关
|
* 规格弹窗开关
|
||||||
*/
|
*/
|
||||||
shutMask(flag, buyFlag, type) {
|
shutMask(flag, buyFlag, type) {
|
||||||
// type是指是否点击底部按钮
|
this.promotionFlag = false;
|
||||||
|
this.buyMask = false;
|
||||||
|
this.addressFlag = false;
|
||||||
if (flag) {
|
if (flag) {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case 1: //优惠券弹窗
|
case 1: //优惠券弹窗
|
||||||
this.maskFlag = true;
|
this.promotionFlag = 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 +814,6 @@ export default {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
this.maskFlag = false;
|
|
||||||
this.cuxiao = false;
|
|
||||||
this.buyMask = false;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -820,7 +826,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: "收藏成功!",
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
<view class="goods-detail">
|
<view class="goods-detail">
|
||||||
<view class="detail_padding">
|
<view class="detail_padding">
|
||||||
<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 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>
|
<u-parse class="vhtml" :lazy-load="true" :use-cache="true" :show-with-animation="true" :html="res.mobileIntro"></u-parse>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -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()" :mask-close-able="setup.close" 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
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -4,5 +4,5 @@ export default {
|
|||||||
height:"1000rpx", //弹出层高度
|
height:"1000rpx", //弹出层高度
|
||||||
mode:"bottom", //弹出层位置
|
mode:"bottom", //弹出层位置
|
||||||
radius:"32", //圆角 rpx,
|
radius:"32", //圆角 rpx,
|
||||||
close:false //能否点击遮罩退出
|
close:true //能否点击遮罩退出
|
||||||
}
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,19 @@
|
|||||||
<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].isCoupon"> 赠送<span>优惠券</span></span>
|
||||||
|
<span v-if="res[prom].isPoint"> 赠送{{res[prom].point}}积分</span>
|
||||||
|
<span v-if="res[prom].isGift"> 赠送商品</span>
|
||||||
|
<span v-if="res[prom].isFreeFreight">赠送包邮服务</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>
|
||||||
|
|
||||||
@@ -19,14 +27,15 @@
|
|||||||
|
|
||||||
<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 +77,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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -135,16 +135,17 @@ 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
|
||||||
|
|||||||
@@ -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: "",
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
|
||||||
@@ -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>
|
|
||||||
@@ -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,31 +11,36 @@
|
|||||||
|
|
||||||
<!-- 店铺商品信息 -->
|
<!-- 店铺商品信息 -->
|
||||||
<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>
|
||||||
</view>
|
</view>
|
||||||
<view class="right_Col" @click="navigateToConpon(item)">
|
<view class="right-col" @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="skuItem.promotions" v-for="(fullDiscount,fullDiscountIndex) in skuItem.promotions"
|
||||||
|
:key="fullDiscountIndex">
|
||||||
<div v-if="fullDiscount.promotionType == 'FULL_DISCOUNT'">
|
<div v-if="fullDiscount.promotionType == '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>
|
||||||
@@ -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,32 +76,36 @@
|
|||||||
<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':skuItem.promotions.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="skuItem.promotions"
|
||||||
|
v-for="(seckill,seckillIndex) in skuItem.promotions" :key="seckillIndex">
|
||||||
<div class="promotions-item-seckill" v-if="seckill.promotionType == 'SECKILL'">
|
<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)">
|
距秒杀结束: <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 && skuItem.promotions.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>
|
||||||
@@ -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>
|
||||||
@@ -191,6 +208,7 @@ export default {
|
|||||||
WEIXIN_num: "", //购物车兼容微信步进器
|
WEIXIN_num: "", //购物车兼容微信步进器
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
// 小程序默认分享
|
// 小程序默认分享
|
||||||
@@ -525,6 +543,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";
|
||||||
@@ -549,10 +572,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 +582,18 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.storeName {
|
.store-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.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 +616,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 +666,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 +695,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 +734,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 +746,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.right_Line {
|
.right-line {
|
||||||
width: 3px;
|
width: 3px;
|
||||||
float: left;
|
float: left;
|
||||||
height: 40rpx;
|
height: 40rpx;
|
||||||
@@ -754,7 +764,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 +783,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 +794,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 +828,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;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
.box2 {
|
.box2 {
|
||||||
padding: calc(32rpx) 40rpx 32rpx !important;
|
padding: 0 16rpx 0;
|
||||||
|
margin: 0 16rpx 20rpx;
|
||||||
|
|
||||||
}
|
}
|
||||||
.uNumber{
|
.uNumber{
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -20,7 +20,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}`,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
2
uni.scss
2
uni.scss
@@ -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;
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ export function orderStatusList(val) {
|
|||||||
PAID: "已付款",
|
PAID: "已付款",
|
||||||
DELIVERED: "已发货",
|
DELIVERED: "已发货",
|
||||||
CANCELLED: "已取消",
|
CANCELLED: "已取消",
|
||||||
|
COMPLETED:"已完成",
|
||||||
COMPLETE: "已完成",
|
COMPLETE: "已完成",
|
||||||
TAKE: "待核验",
|
TAKE: "待核验",
|
||||||
};
|
};
|
||||||
|
|||||||
168
utils/request.js
168
utils/request.js
@@ -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,33 +97,11 @@ 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) => {
|
||||||
@@ -205,12 +112,39 @@ http.interceptors.response.use(
|
|||||||
(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) ||
|
||||||
|
|||||||
Reference in New Issue
Block a user