74 Commits

Author SHA1 Message Date
lemon橪
3d1089b756 优化我的评价 2021-11-17 16:30:04 +08:00
lemon橪
6c8102aecd 新增我的评价中订单评论状态 2021-11-16 17:43:09 +08:00
lemon橪
56fdb2c2f0 退出登录 2021-11-16 11:11:54 +08:00
lemon橪
7c85460fbb Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-11-15 16:19:55 +08:00
lemon橪
47b58c290a 删除冗余选择器优化代码 2021-11-15 16:19:53 +08:00
paulGao
cdf57806d6 add logout 2021-11-11 18:46:26 +08:00
lemon橪
9671d60555 修改商品搜索样式 以及es中删除部分字段 2021-11-11 18:15:12 +08:00
lemon橪
f8b388c968 优化筛选 2021-11-11 16:42:41 +08:00
lemon橪
91cc98e853 修改筛选逻辑判断 2021-11-10 10:22:37 +08:00
lemon橪
58484f1b61 筛选中可能出现的问题 2021-11-09 19:04:38 +08:00
lemon橪
d65ad6c5fd 修改登录中可能存在的验证码bug 2021-11-08 11:21:19 +08:00
lemon橪
68bc1d6974 优化商品筛选楼层装修判断 2021-11-04 10:53:52 +08:00
lemon橪
b1c518c3a8 合并Master 2021-11-03 11:55:24 +08:00
lemon橪
48c7030c0e 修改部分页面判断问题 2021-11-03 11:54:38 +08:00
chopper711
13c9d521f9 update README.md. 2021-11-02 08:03:59 +00:00
lemon橪
375653eb78 更新微信公众号登录 2021-10-29 16:34:41 +08:00
lemon橪
8c72cdcb0a 修改我的优惠券中bug 2021-10-29 11:19:27 +08:00
lemon橪
cfb88d798b 提交上次更改多余删除部分 2021-10-26 15:45:30 +08:00
lemon橪
ebf32a18b0 1.修改商品规格中可能出现的sku判断,优化选择商品规格上下滑动。2.优化登录页面样式。3.优化购物车样式 2021-10-26 15:27:13 +08:00
lemon橪
5f6c1adf91 优化无痛刷新token 修改分销扫码bug 2021-10-22 18:03:41 +08:00
lemon橪
44648e9971 首页下拉刷新,优化商品促销界面 2021-10-15 18:01:54 +08:00
lemon橪
fd37087c43 删除冗余组件,修改搜索商品样式 2021-10-13 18:01:09 +08:00
lemon橪
4c47a1249f 优化售后方面 2021-10-12 16:31:03 +08:00
lemon橪
ea3563e4e9 解决商品详情中商品介绍判断bug 2021-10-06 16:46:47 +08:00
lemon橪
c98c5b64e1 修改部分已知的代码问题 2021-09-28 17:56:21 +08:00
lemon橪
3b9b2e8ba2 优化订单,组件页面下拉刷新,修改评论bug 2021-09-27 19:58:18 +08:00
lemon橪
cebde87682 修改小程序使用优惠券bug 2021-09-26 10:30:28 +08:00
lemon橪
0b2bf1faf1 优化购物车在微信公众号中样式问题 2021-09-22 11:31:37 +08:00
lemon橪
73560e8366 修改筛选不赋值categoryId问题 2021-09-18 10:11:29 +08:00
lemon橪
afabfdd1d5 修改发现的 商品搜索已售问题 2021-09-18 09:59:47 +08:00
lemon橪
dadce33d74 解决筛选bug 和已知的坐标问题 2021-09-17 18:08:08 +08:00
lemon橪
fe0d888da0 优化微信网页登录 2021-09-10 10:45:37 +08:00
lemon橪
58f33b05dd 优化微信公众号中h5登录 2021-09-09 17:53:57 +08:00
lemon橪
ba3034e5cb 提交补交 2021-09-09 15:05:19 +08:00
lemon橪
4c7663d671 修改地址中逻辑错误bug 2021-09-09 15:02:44 +08:00
lemon橪
a78dca1a0c 修改第三方登录时 苹果审核不同过原因 2021-09-09 14:50:51 +08:00
lemon橪
c529688932 优化移动端已知的问题 2021-09-09 11:21:28 +08:00
lemon橪
0cfb5d42c0 优化部分样式 2021-09-08 09:52:04 +08:00
lemon橪
13f3971f2a 修改收藏bug 2021-09-03 16:46:55 +08:00
lemon橪
075399d329 修改收藏bug 2021-09-03 16:33:32 +08:00
lemon橪
90d9fa9671 修改搜索问题,优化签到页面 2021-09-03 09:48:35 +08:00
lemon橪
6ca01d2c71 解决后端更新之后es中与前端不匹配bug,优化部分代码复用性 2021-09-02 16:08:35 +08:00
lemon橪
275d76c0dd 优化提交页面样式,优化商品默认为第一个热词进行搜索,修复分销商铺bug 2021-09-01 17:30:54 +08:00
lemon橪
c53af2fcc3 防抖登录,砍价优化,新增砍价记录,优化积分信息,优化组件复用。 2021-08-27 17:54:52 +08:00
lemon橪
c45a378665 未提交的api修改 2021-08-27 14:24:16 +08:00
lemon橪
cb982c2883 砍价活动修改bug 2021-08-27 14:11:06 +08:00
lemon橪
52e6c57f70 解决签到问题 以及优惠券,砍价等问题 2021-08-26 18:08:16 +08:00
lemon橪
9a91e58f2c 优化修改密码部分 2021-08-26 09:48:32 +08:00
lemon橪
25fb26b7d0 优化拼团时选择地址bug,优化其他问题 2021-08-26 09:31:57 +08:00
lemon橪
8f5f44022b 优化app中订单时间问题 2021-08-23 11:54:27 +08:00
lemon橪
a2994454aa 修复优惠券微信小程序中出现的bug,以及拼团分享规格问题 2021-08-23 10:56:56 +08:00
lemon橪
915aee9143 微信支付成功订阅进行优化 2021-08-23 10:09:12 +08:00
lemon橪
224eb05703 修改部分scss类名,新增部分注释以及登录颜色化配置:) 2021-08-19 16:20:21 +08:00
lemon橪
775bf3055d 修改第三方登录可能出现的bug 2021-08-17 17:10:19 +08:00
lemon橪
d76bab4b71 优化小程序登录跳转部分代码.新增全局条件编译跳转方法 2021-08-17 11:53:56 +08:00
lemon橪
3d1e175194 修改楼层装修中商品装修出现的默认不显示bug 2021-08-16 11:34:15 +08:00
lemon橪
885ccb5006 配置微信小程序返回首页按钮 2021-08-16 10:35:12 +08:00
lemon橪
eb11f9dbae 修改收藏店铺bug 2021-08-12 17:05:01 +08:00
lemon橪
415dd15dd1 删除没有的components组件 2021-08-12 16:48:06 +08:00
lemon橪
3f19fc8c15 新增店铺营业执照 2021-08-11 17:09:37 +08:00
lemon橪
464379178d 优化部分代码冗余 2021-08-11 10:28:04 +08:00
lemon橪
1fbb43c848 修改店铺页面店铺显示问题 2021-08-11 09:49:09 +08:00
lemon橪
b93395d0dc 添加店铺联系客服功能 2021-08-10 09:57:48 +08:00
lemon橪
1141923407 修改店铺样式,优化部分代码 2021-08-09 18:44:03 +08:00
lemon橪
209060fd76 优化部分代码,修改店铺ui以及功能 2021-08-09 18:40:06 +08:00
lemon橪
e02fa75274 店铺页面有些bug 已处理 2021-08-05 19:01:31 +08:00
lemon橪
4ca71d0987 优化移动端登录样式按钮样式问题 2021-08-04 18:14:31 +08:00
lemon橪
123127d977 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2021-07-30 16:29:17 +08:00
lemon橪
d19b02a97d 优化热门搜索方案,如果更新了后端最新代码,请pull下更新 2021-07-30 16:29:05 +08:00
mabo
aad083970e no message 2021-07-30 08:02:13 +08:00
lemon橪
436dd56e54 积分商品展示的部分问题 2021-07-28 09:53:41 +08:00
lemon橪
a9db24d1ad 新增积分商品功能 以及 在微信公众号优化部分逻辑 2021-07-27 18:14:53 +08:00
lemon橪
a6fec5cf70 优化部分商品评价无id,以及投诉详情页面展示错误问题 2021-07-22 17:32:33 +08:00
lemon橪
0ea121e59e 积分商品,以及完善砍价商品 2021-07-20 18:05:50 +08:00
146 changed files with 4213 additions and 9006 deletions

View File

@@ -2,10 +2,23 @@
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数 // launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version": "0.0", "version": "0.0",
"configurations": [{ "configurations": [{
"type": "uniCloud", "app-plus" :
"default": { {
"launchtype": "remote" "launchtype" : "remote"
} },
} "default" :
{
"launchtype" : "remote"
},
"h5" :
{
"launchtype" : "remote"
},
"mp-weixin" :
{
"launchtype" : "remote"
},
"type" : "uniCloud"
}
] ]
} }

View File

@@ -195,7 +195,7 @@ export default {
<style lang="scss"> <style lang="scss">
@import "uview-ui/index.scss"; @import "uview-ui/index.scss";
@import "./static/font/iconfont/iconfont.css";
// -------适配底部安全区 苹果x系列刘海屏 // -------适配底部安全区 苹果x系列刘海屏
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN

253
README.md
View File

@@ -1,110 +1,138 @@
## Lilishop B2B2C商城系统 ## 🔥 Lilishop B2B2C商城系统
##### 🌹 开源不易如有帮助请点Star
#### 欢迎交流需求,交流业务,交流技术(基础问题自行解决,进群先看文档后提问)
##### 交流 qq 1群 961316482已满
##### 交流 qq 2群 875294241
##### 商城 公众号/小程序体验,扫描二维码
##### 官方公众号 & 开源不易如有帮助请点Star
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png) ![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
[![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers) [![star](https://gitee.com/beijing_hongye_huicheng/lilishop/badge/star.svg?theme=dark)](https://gitee.com/beijing_hongye_huicheng/lilishop/stargazers)
&nbsp;&nbsp;![github](https://img.shields.io/github/stars/hongyehuicheng/lilishop.svg?style=social&logo=#181717)
### 介绍 ### 🔥 商城介绍
**官网**https://pickmall.cn **官网**https://pickmall.cn
Lilishop 是一款Java开发基于SpringBoot研发B2B2C多用户商城前端使用 Vue、uniapp开发 **系统全端全部代码开源** Lilishop 商城系统 基于SpringBoot 研发B2B2C多用户商城系统,前端使用 Vue、uniapp开发 **系统全端全部代码开源**
产品前后端分离、支持分布式部署 业务兼容O2O商城/B2B商城/B2B2C商城/F2B2C商城/S2B2C商城。支持小程序商城、H5商城、APP商城、 PC商城
商城展示端包含 PC、H5、微信小程序、APP。
商城前后端分离、支持分布式部署。
商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块 商城包含 会员模块、**第三方登录模块**、**第三方支付模块**、**楼层装修模块**、订单模块、分销模块、文章模块、系统设置模块、流量分析模块
系统包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等支持Docker支持k8s。是一款高性能支持高并发商城系统。 商城包含各种中间件、搜索引擎、多级缓存、分布式事务、分布式任务调度等支持Docker支持k8s。是一款高性能支持高并发商城系统。
开箱即用,简单配置即可部署一套属于您的系统。 ##### 商城 API/消费者 聚合版
api不需要单独部署只需启动一个jar包就可以正常运转 如有需要可以点击跳转https://gitee.com/beijing_hongye_huicheng/lilishop-simplify
### 文档 ### ☃️ 商城 开发/使用/常见问题 帮助文档
**产品文档**(需求、架构、使用、部署、开发):https://docs.pickmall.cn https://docs.pickmall.cn
### 💧 开源商城项目地址(gitee)
**API商城所有API**https://gitee.com/beijing_hongye_huicheng/lilishop.git
**UI商城管理端/商家端/买家PC端** https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
**uniapp商城移动端支持小程序/APP/H5**https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
**docker一键部署商城部署脚本**https://gitee.com/beijing_hongye_huicheng/docker.git
### 💧 开源商城项目地址(github)
**API商城所有API**https://github.com/hongyehuicheng/lilishop.git
**UI商城管理端/商家端/买家PC端** https://github.com/hongyehuicheng/lilishop-ui.git
**uniapp商城移动端支持小程序/APP/H5**https://github.com/hongyehuicheng/lilishop-uniapp.git
**docker一键部署商城部署脚本**https://github.com/hongyehuicheng/docker.git
### 项目链接(gitee) ☃️ UI 项目下3个文件夹 buyer买家PC端seller商家端manager后台管理端
**Java后台**https://gitee.com/beijing_hongye_huicheng/lilishop.git
**Vue后台前端** https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git ### 💧 演示地址(手机验证码为 111111)
**Uni-app**https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git **商城管理端**https://admin-b2b2c.pickmall.cn 账号admin/123456
**docker一键部署**https://gitee.com/beijing_hongye_huicheng/docker.git **商城店铺后台**https://store-b2b2c.pickmall.cn 账号13011111111/111111
### 项目链接(github) **商城PC页面**https://pc-b2b2c.pickmall.cn
**Java后台**https://github.com/hongyehuicheng/lilishop.git **商城移动端(请使浏览器手机模式,或者用手机浏览器打开)**https://m-b2b2c.pickmall.cn
**Vue后台前端** https://github.com/hongyehuicheng/lilishop-ui.git **小程序/公众号**:扫描二维码
**Uni-app**https://github.com/hongyehuicheng/lilishop-uniapp.git
**docker一键部署**https://github.com/hongyehuicheng/docker.git
### 演示地址
**运营后台**https://admin-b2b2c.pickmall.cn 账号admin/123456
**店铺后台**https://store-b2b2c.pickmall.cn 账号13011111111/111111
**用户前台**https://pc-b2b2c.pickmall.cn
**移动端**https://m-b2b2c.pickmall.cn
![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png) ![image-20210511171611793](https://pickmall.cn/assets/imgs/h5-qrcode.png)
### 3行命令搭建本地环境 ### 🚙 3行命令搭建本地商城(注:只能本机访问,如需调整,请自行操作镜像)
温馨提示由于服务较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。 温馨提示:由于服务中间件较多如果笔记本环境启动内存没有32g可能无法启动成功macbookpro 2020 16g内存启动无法成功台式机在16g内存、AMD 3700x 的ubuntu系统成功运行。
##### 下载docker脚本
##### docker环境安装 [点击跳转](https://docs.pickmall.cn/deploy/%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%E5%87%86%E5%A4%87.html)
##### 下载docker-compose脚本
`git clone https://gitee.com/beijing_hongye_huicheng/docker.git ` `git clone https://gitee.com/beijing_hongye_huicheng/docker.git `
##### 部署基础环境
##### 部署商城所需中间件
`docker-compose up -d` `docker-compose up -d`
##### 部署应用 ##### 部署商城应用
`docker-compose -f docker-compose-application.yml up -d` `docker-compose -f docker-compose-application.yml up -d`
PS:单独部署的话,数据库文件访问这里:https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql PS:商城数据库单独部署 https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql 这里有与tag版本一致的sql根据tag获取sql如果使用master代码则需要在lilishop项目根目录的DB目录中获取对应的升级sql。
##### 各个地址 ##### 商城 API/UI 地址
| API | 地址 | | API | 地址 |
| -------------- | --------------- | | -------------- | --------------- |
| 买家API | http://127.0.0.1:8888 | | 商城买家API | http://127.0.0.1:8888 |
| 商家API | http://127.0.0.1:8889 | | 商城商家API | http://127.0.0.1:8889 |
| 管理端API | http://127.0.0.1:8887 | | 商城管理端API | http://127.0.0.1:8887 |
| 通用API | http://127.0.0.1:8890 | | 商城基础API | http://127.0.0.1:8890 |
| 前端演示 | 地址 | | 前端演示 | 地址 |
| -------------- | --------------- | | -------------- | --------------- |
| PC | http://127.0.0.1:10000 | | 商城PC端 | http://127.0.0.1:10000 |
| WAP | http://127.0.0.1:10001 | | 商城WAP | http://127.0.0.1:10001 |
| 商 | http://127.0.0.1:10002 | | 商城卖家端 | http://127.0.0.1:10002 |
| 管理端 | http://127.0.0.1:10003 | | 商城管理端 | http://127.0.0.1:10003 |
### 功能列表 ### ⚾️ 功能列表
#### 平台功能 #### 🥎 商城平台功能
![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg) ![平台功能](https://pickmall.cn/assets/imgs/other/managerList.jpg)
#### 商家端功能 #### 🥎 商城卖家功能
![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg) ![商家端功能](https://pickmall.cn/assets/imgs/other/storeList.jpg)
@@ -112,30 +140,28 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
### 功能展示 ### 🧩 商城前端功能展示
#### 移动端 #### ⚽️ 商城移动端
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="管理端功能展示" style="zoom:50%;" />
<img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" /> <img src="https://pickmall.cn/assets/imgs/other/app.gif" alt="移动端功能展示" style="zoom:50%;" />
#### 管理端 #### ⚽️ 商城管理端
![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif) ![管理端功能展示](https://pickmall.cn/assets/imgs/other/manager.gif)
### 技术选型 ### 商城技术选型
#### 架构图 #### 🥅 架构图
![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png) ![架构](https://lili-system.oss-cn-beijing.aliyuncs.com/docs/%E6%9E%B6%E6%9E%84.png)
##### Java后台 ##### 🕹 后台技术选型
| 说明 | 框架 | 说明 | | | 说明 | 框架 | 说明 | |
| -------------- | --------------- | -------------- | ------------- | | -------------- | --------------- | -------------- | ------------- |
@@ -149,7 +175,7 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 短信 | 阿里云短信 | 认证 | JWT | | 短信 | 阿里云短信 | 认证 | JWT |
| 日志处理 | Log4j | 接口规范 | RESTful | | 日志处理 | Log4j | 接口规范 | RESTful |
##### 前端-运营后台、店铺后台 ##### 🖥 前端-运营后台、店铺后台
| 说明 | 框架 | 说明 | 框架 | | 说明 | 框架 | 说明 | 框架 |
| ---------- | ---------- | ---------- | ------- | | ---------- | ---------- | ---------- | ------- |
@@ -159,119 +185,34 @@ PS:单独部署的话数据库文件访问这里https://gitee.com/beijing_
| 基础UI库 | iView | UI界面基于 | iView | | 基础UI库 | iView | UI界面基于 | iView |
| 网络请求 | axios | | | | 网络请求 | axios | | |
##### 前端-移动端 ##### 📱前端-移动端
| 说明 | 架构 | 说明 | 架构 | | 说明 | 架构 | 说明 | 架构 |
| --------- | ------- | -------- | ------- | | --------- | ------- | -------- | ------- |
| 基础UI库 | uViewui | 基础框架 | uni-app | | 基础UI库 | uViewui | 基础框架 | uni-app |
| CSS预处理 | scss | 地图引擎 | amap | | CSS预处理 | scss | 地图引擎 | amap |
### 升级计划 ### 🌟 版本升级
#### 计划每个月发布一个版本,具体时间可能有出入
时间2021年6月15日
``` ```
新增功能: 商城后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
1.微信小程序直播
2.优惠券活动
3.新人赠券
4.准确发券
5.用户等级
6.数据导出
7.订单批量
8.APP版本升级检测
9.积分商城
功能优化:
1.优惠券有效期增加类型:设置领取后*内有效。
2.秒杀活动设置为每天开启,需设置秒杀活动开启时间。
3.店铺配送模板,配送地区如果选择省份则下方的市级地址不展示。
4.店铺配送模板支持,店铺包邮。
5.普通商品设置去除卖家承担运费。
后续会考虑推出微服务商城系统/商城中台等
``` ```
时间2021年7月15日
``` ### ⚠️ 开源须知
新增功能:
1.会员权益
2.支持用户升级会员
3.供求单
4.IM腾讯云智服
5.服务商品
6.店铺支持订单核销
7.店铺自提点
功能优化:
1.用户分享商城、关注店铺、邀请新用户可获取积分、经验值。
```
时间2021年8月16日
```
新增功能:
1.微淘功能
2.店铺移动端
3.店铺发货单
```
时间2021年9月15日
```
新增功能:
增加供应商功能
```
### 版本升级
```
后续会持续版本升级修复bug完善功能覆盖更多业务场景 o2o/b2b/s2b2b2c/跨境电商
后续会考虑推出微服务/中台等 企业级版本
```
### 技术亮点
1.后端框架基于Springboot构建基于maven持久层使用MyBatisPlus。使用elasticsearch、redis、mongodb、rocketmq 等各种中间健。都是主流架构,轻松应对各种环境。
2.支持集群、分布式支持docker 轻松部署,解决各种复杂场景!
3.代码模块清晰主要分为三端api买家、卖家、管理各端API互相隔离自己鉴权自己操作业务。
4.使用阿里开源的RocketMQ基于mq解决各种并发场景解决事务一致性解决搞并发延迟场景问题。
5.项目使用多级缓存应用不同场景redis缓存业务数据、mongodb缓存关系型多对多关系问题、nginx缓存高频访问低频修改的页面。
6.支持各种联合登陆,支持各种客户端的支付问题,灵活配置灵活开启。
7.内置完善的楼层装修机制,各种拖拉拽,维护跳转页面或外网,即便是一个什么都不懂的运营也可以轻松掌握。
8.内置阿里短信接口可以在线申请短信模版。内置阿里oss系统可以对文件执行各种操作。oss商家端资源相互隔离。
10.强大的统计报表,统计效果,可以实现各个场景,包含在线人数,历史在线人数,活跃人数等信息。
11.标准Api接口、提供swagger文档快速二开。
12.分布式调度任务中心,解决分布式定时任务多次执行问题。
13.代码注释完善,快速上手。
14.非移动端采用IView框架各种自定义插件、选择器实现。移动端采用uniapp一次编写全端使用
15.已经对接好各种第三方插件,支持各种复杂等联合登陆,联合支付等场景。
### 开源须知
1.仅允许用于个人学习研究使用. 1.仅允许用于个人学习研究使用.
2.禁止将本开源的代码和资源进行任何形式任何名义的出售. 2.禁止将本开源的代码和资源进行任何形式任何名义的出售.
3.限制商用如果需要商业使用请联系我们。QQ3409056806. 3.软件受国家计算机软件著作权保护登记号2021SR0805085
### 交流群 4.限制商用如果需要商业使用请联系我们。QQ3409056806.
**QQ群**961316482
### 🐧 交流群
##### 官方qq 1群 961316482已满
##### 官方qq 2群 875294241

View File

@@ -19,6 +19,7 @@ export function getAddressList(pageNumber, pageSize) {
}); });
} }
/** /**
* 获取物流公司 * 获取物流公司
*/ */

View File

@@ -118,17 +118,6 @@ export function getCategoryList(id) {
}); });
} }
/**
* 获取商品分类
* @param parent_id
*/
export function getCategory(parent_id = 0) {
return http.request({
url: `goods/categories/${parent_id}/children`,
method: Method.GET,
loading: false,
});
}
@@ -167,20 +156,23 @@ export function cash(params) {
/** /**
* 分销商提现历史 * 分销商提现历史
*/ */
export function cashLog() { export function cashLog(params) {
return http.request({ return http.request({
url: `/distribution/cash`, url: `/distribution/cash`,
method: Method.GET, method: Method.GET,
params
}); });
} }
/** /**
* 获取分销商分页订单列表 * 获取分销商分页订单列表
*/ */
export function distributionOrderList() { export function distributionOrderList(params) {
return http.request({ return http.request({
url: `/distribution/distributionOrder`, url: `/distribution/distributionOrder`,
method: Method.GET, method: Method.GET,
params
}); });
} }

View File

@@ -30,12 +30,12 @@ export function getCategory(parent_id = 0) {
* 获取热门关键词 * 获取热门关键词
* @param num * @param num
*/ */
export function getHotKeywords(start = 0, end = 10) { export function getHotKeywords(count) {
return http.request({ return http.request({
url: "/goods/hot-words", url: "/goods/hot-words",
method: Method.GET, method: Method.GET,
loading: false, loading: false,
params: { start, end }, params: { count },
}); });
} }

View File

@@ -18,9 +18,9 @@ export function resetByMobile(params) {
* 发送验证码 * 发送验证码
* @param mobile * @param mobile
*/ */
export function sendMobile(mobile) { export function sendMobile(mobile,type='LOGIN') {
return http.request({ return http.request({
url: `${api.common}/sms/LOGIN/${mobile}`, url: `${api.common}/sms/${type}/${mobile}`,
method: "GET", method: "GET",
}); });
} }
@@ -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,
})
}

View File

@@ -206,7 +206,7 @@ export function getGoodsCollection(params, type) {
* 收藏商品 * 收藏商品
* @returns {AxiosPromise} * @returns {AxiosPromise}
*/ */
export function collectionGoods(id, type) { export function collectionGoods(type, id) {
return http.request({ return http.request({
url: `/member/collection/add/${type}/${id}`, url: `/member/collection/add/${type}/${id}`,
method: Method.POST, method: Method.POST,
@@ -230,11 +230,23 @@ export function deleteGoodsCollection(ids) {
}); });
} }
/**
* 删除店铺收藏
* @param store_id
*/
export function deleteStoreCollection(store_id) {
return http.request({
url: `/member/collection/delete/STORE/${store_id}`,
method: Method.DELETE,
needToken: true,
});
}
/** /**
* 获取商品是否被收藏 * 获取商品是否被收藏
* @param good_id * @param good_id
*/ */
export function getGoodsIsCollect(good_id, type) { export function getGoodsIsCollect(type, good_id) {
return http.request({ return http.request({
url: `/member/collection/isCollection/${type}/${good_id}`, url: `/member/collection/isCollection/${type}/${good_id}`,
method: Method.GET, method: Method.GET,
@@ -257,18 +269,6 @@ export function collectionStore(store_id) {
}); });
} }
/**
* 删除店铺收藏
* @param store_id
*/
export function deleteStoreCollection(store_id) {
return http.request({
url: `members/collection/store/${store_id}`,
method: Method.DELETE,
needToken: true,
});
}
/** /**
* 获取当前登录的用户信息 * 获取当前登录的用户信息
* @returns {AxiosPromise} * @returns {AxiosPromise}

View File

@@ -51,13 +51,25 @@ export function getPointsCategory() {
* 获取积分商城商品 * 获取积分商城商品
* @param params * @param params
*/ */
export function getPointsGoods(params) { export function getPointsGoods(params) {
return http.request({ return http.request({
url: "/promotion/pointsGoods", url: "/promotion/pointsGoods",
method: Method.GET, method: Method.GET,
params, params,
}); });
} }
/**
* 获取积分商城商品详情
* @param params
*/
export function getPointsGoodsDetail(id) {
return http.request({
url: "/promotion/pointsGoods/"+id,
method: Method.GET,
});
}
/** /**
* 获取限时抢购时间线 当天限时抢购信息 * 获取限时抢购时间线 当天限时抢购信息
@@ -151,12 +163,26 @@ export function getBargainLog(params) {
}); });
} }
/** /**
* 分页获取砍价活动-帮砍记录 * 分页获取砍价活动-帮砍记录
*/ */
export function helpBargain(kanJiaActivityId) { export function helpBargain(kanJiaActivityId) {
return http.request({ return http.request({
url: `promotion/kanjiaGoods/help/${kanJiaActivityId}`, url: `promotion/kanjiaGoods/help/${kanJiaActivityId}`,
method: Method.POST, method: Method.POST,
}); });
} }
/**
* 分页获取已参与的砍价活动
*/
export function getMineBargainLog(params) {
return http.request({
url: `/promotion/kanjiaGoods/kanjiaActivity/mine/`,
method: Method.GET,
params
});
}

View File

@@ -20,10 +20,37 @@ export function getstoreList(params) {
* 获取店铺基本信息 * 获取店铺基本信息
* @param storeId * @param storeId
*/ */
export function getstoreBaseInfo(storeId) { export function getStoreBaseInfo(storeId) {
return http.request({ return http.request({
url: `/store/get/detail/${storeId}`, url: `/store/get/detail/${storeId}`,
method: Method.GET, method: Method.GET,
loading: false, loading: false,
}); });
} }
/**
* 获取店铺分类
* @param id
*/
export function getStoreCategory(id) {
return http.request({
url: `/store/label/get/${id}`,
method: Method.GET,
});
}
/**
* 营业执照
* @param id
*/
export function getLicencePhoto(id) {
return http.request({
url: `/store/get/licencePhoto/${id}`,
method: Method.GET,
});
}

View File

@@ -0,0 +1,3 @@
## 购买组件
1.本组件是砍价,积分购买,参团等复用组
2.后续会将此组件和商品购买组件合并,文档后续再出

View File

@@ -1,11 +1,13 @@
<template> <template>
<div class="wrapper"> <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()"> <u-popup class="popup" v-model="buyMask" :height="setup.height" closeable :mode="setup.mode"
:border-radius="setup.radius" @close="closeMask()">
<!-- 商品 --> <!-- 商品 -->
<view class="goods-box bottom"> <view class="goods-box bottom">
<view class="goods-header"> <view class="goods-header">
<view class="goods-img"> <view class="goods-img">
<u-image width="200rpx" border-radius="20" class="uimage" height="200rpx" :src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image> <u-image width="200rpx" border-radius="20" class="uimage" height="200rpx"
:src="selectedSpecImg ? selectedSpecImg : goodsDetail.thumbnail"></u-image>
</view> </view>
<view class="goods-skus"> <view class="goods-skus">
@@ -13,11 +15,11 @@
<view class="goods-price " v-if="goodsDetail.promotionPrice"> <view class="goods-price " v-if="goodsDetail.promotionPrice">
<span v-if="goodsDetail.promotionPrice && !pointDetail"> <span v-if="goodsDetail.promotionPrice && !pointDetail">
<span class="goods-price-promotionShow goods-price-bigshow">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span> <span
class="goods-price-promotionShow goods-price-bigshow">{{ formatPrice(goodsDetail.promotionPrice)[0] }}</span>
.{{ formatPrice(goodsDetail.promotionPrice)[1] }} .{{ formatPrice(goodsDetail.promotionPrice)[1] }}
</span> </span>
<span v-if="pointDetail.points"> <span v-if="pointDetail.points">
<span class="goods-price-promotionShow goods-price-bigshow">{{ pointDetail.points }}</span> <span class="goods-price-promotionShow goods-price-bigshow">{{ pointDetail.points }}</span>
积分 积分
</span> </span>
@@ -51,26 +53,38 @@
</view> </view>
</view> </view>
<!-- 商品信息 --> <!-- 商品信息 -->
<view class="goods-skus-box"> <scroll-view class="goods-skus-box" :scroll-y="true">
<!-- 规格 --> <!-- 规格 -->
<view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList"> <view class="goods-skus-view" :key="specIndex" v-for="(spec, specIndex) in formatList">
<view class="skus-view-list"> <view class="skus-view-list">
<view class="view-class-title">{{ spec.name }}</view> <view class="view-class-title">{{ spec.name }}</view>
<view :class="{ active: spec_val.value == currentSelceted[specIndex] }" class="skus-view-item" v-for="(spec_val, spec_index) in spec.values" :key="spec_index"
@click="handleClickSpec(spec, specIndex, spec_val)">{{ spec_val.value }}</view>
<!-- 正常逻辑 循环出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"
@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" :input-height="numberBox.height" :size="numberBox.size" :min="1" v-model="num"> <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> </u-number-box>
</view> </view>
</view> </scroll-view>
<!-- 按钮 --> <!-- 按钮 -->
<view class="btns"> <view class="btns">
<view class="box-btn card" v-if="buyType != 'PINTUAN' && goodsDetail.goodsType!='VIRTUAL_GOODS'" @click="addToCartOrBuy('cart')">加入购物车</view> <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 class="box-btn buy" @click="addToCartOrBuy('buy')">立即购买</view>
</view> </view>
</view> </view>
@@ -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,18 +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: {
"pointDetail", // 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) {
@@ -145,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");
@@ -159,18 +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", {skuId: selectedSkuId.skuId, goodsId: this.goodsDetail.goodsId}); this.$emit("handleClickSku", {
skuId: selectedSkuId.skuId,
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)
)}`,
});
}
});
},
/** /**
* 添加到购物车或购买 * 添加到购物车或购买
*/ */
@@ -203,11 +265,9 @@ export default {
// //
if (this.buyType) { if (this.buyType) {
data.cartType = "PINTUAN"; data.cartType = "PINTUAN";
} } else if (this.goodsDetail.goodsType == "VIRTUAL_GOODS") {
else if(this.goodsDetail.goodsType == 'VIRTUAL_GOODS'){ data.cartType = "VIRTUAL";
data.cartType = "VIRTUAL"; } else {
}
else {
data.cartType = "BUY_NOW"; data.cartType = "BUY_NOW";
} }
@@ -226,7 +286,7 @@ export default {
}, },
formatSku(list) { formatSku(list) {
// //
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) => {
@@ -234,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;
@@ -243,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);
} }
@@ -252,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],
@@ -265,6 +329,7 @@ export default {
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")
@@ -282,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>
@@ -322,10 +386,10 @@ export default {
} }
.active { .active {
background: $jd-light-color !important; background: $price-light-color !important;
border: 2rpx solid $jd-color; border: 2rpx solid $price-color;
font-weight: bold; font-weight: bold;
color: $jd-color !important; color: $price-color !important;
box-sizing: border-box; box-sizing: border-box;
} }
@@ -377,7 +441,7 @@ export default {
} }
.goods-price { .goods-price {
color: $jd-color; color: $price-color;
line-height: 80rpx; line-height: 80rpx;
display: flex; display: flex;
} }

View File

@@ -14,7 +14,7 @@
line-height: 80rpx; line-height: 80rpx;
height: 80rpx; height: 80rpx;
background: $jd-color; background: $price-color;
color: #fff; color: #fff;
border-radius: 200px; border-radius: 200px;
text-align: center; text-align: center;

View File

@@ -4,16 +4,16 @@
<div class="goods-list"> <div class="goods-list">
<div @click="handleClick(item)" class="goods-item" v-for="(item, item_index) in goodsList" :key="item_index"> <div @click="handleClick(item)" class="goods-item" v-for="(item, item_index) in goodsList" :key="item_index">
<div class="goods-img"> <div class="goods-img">
<u-image :src="item.thumbnail" mode="aspectFill" height="350rpx" width="100%"> <u-image :src="item.content.thumbnail" mode="aspectFill" height="350rpx" width="100%">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
</u-image> </u-image>
</div> </div>
<div class="goods-desc"> <div class="goods-desc">
<div class="goods-title"> <div class="goods-title">
{{ item.goodsName }} {{ item.content.goodsName }}
</div> </div>
<div class="goods-bottom"> <div class="goods-bottom">
<div class="goods-price">{{ item.price | unitPrice }}</div> <div class="goods-price">{{ item.content.price | unitPrice }}</div>
</div> </div>
</div> </div>
</div> </div>
@@ -73,13 +73,12 @@ export default {
delete submit[key]; delete submit[key];
} }
}); });
let goodsList = await getGoodsList(submit); let goodsList = await getGoodsList(submit);
this.goodsList.push(...goodsList.data.result.content); this.goodsList.push(...goodsList.data.result.content);
}, },
handleClick(item) { handleClick(item) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${item.id}&goodsId=${item.goodsId}`, url: `/pages/product/goods?id=${item.content.id}&goodsId=${item.content.goodsId}`,
}); });
}, },
}, },

View File

@@ -1,20 +1,21 @@
<template> <template>
<view class="serach"> <view class="serach">
<view class="left-box" @tap="onClickLeft"> <view class="left-box" @tap="onClickLeft">
<uni-icons style="line-height:70rpx" type="back" size="24" /> <u-icon name="arrow-left" size="40" color="#666"></u-icon>
</view> </view>
<view class="content" :style="{ 'border-radius': radius + 'px' }"> <view class="content" :style="{ 'border-radius': radius + 'px' }">
<!-- HM修改 增加进入输入状态的点击范围 --> <!-- HM修改 增加进入输入状态的点击范围 -->
<view class="content-box" :class="{ center: mode === 2 }"> <view class="content-box" :class="{ center: mode === 2 }">
<u-icon name="search" size="32" style="padding:0 15rpx;"></u-icon> <u-icon name="search" size="32" style="padding:0 15rpx;"></u-icon>
<!-- HM修改 增加placeholder input confirm-type confirm--> <!-- HM修改 增加placeholder input confirm-type confirm-->
<input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color" @input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input" <input style="width:100%; " :placeholder="placeholder" placeholder-class="placeholder-color"
@input="inputChange" confirm-type="search" @confirm="triggerConfirm" class="input"
:class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" /> :class="{ center: !active && mode === 2 }" :focus="isFocus" v-model="inputVal" @focus="focus" @blur="blur" />
<u-icon name="close" v-if="isDelShow" style="padding:0 30rpx;" @click="clear"></u-icon> <u-icon name="close" v-if="isDelShow" style="padding:0 30rpx;" @click="clear"></u-icon>
</view> </view>
<view v-show="(active && show && button === 'inside') || (isDelShow && button === 'inside')" class="serachBtn" @click="search">搜索</view>
</view> </view>
<view v-if="button === 'outside'" class="button" :class="{ active: show || active }"> <view class="button active" >
<view v-if="isShowSeachGoods !=true" class="button-item"> <view v-if="isShowSeachGoods !=true" class="button-item">
<div @click="out()">取消</div> <div @click="out()">取消</div>
</view> </view>
@@ -28,14 +29,7 @@
</template> </template>
<script> <script>
import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
import uniIcons from "../uni-icons/uni-icons.vue";
export default { export default {
components: {
uniStatusBar,
uniIcons,
},
props: { props: {
mode: { mode: {
value: Number, value: Number,
@@ -50,15 +44,6 @@ export default {
type: String, type: String,
default: "", default: "",
}, },
button: {
value: String,
default: "outside",
},
//
show: {
value: Boolean,
default: true,
},
// 默认半径为60 // 默认半径为60
radius: { radius: {
value: String, value: String,
@@ -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 {

View File

@@ -58,13 +58,6 @@ export default {
// 图片缩略图、 商品名称 、 typegoods,shop,pintuan) 拼团商品分享以及店铺分享 // 图片缩略图、 商品名称 、 typegoods,shop,pintuan) 拼团商品分享以及店铺分享
props: ["thumbnail", "goodsName", "type", "goodsId", "link"], props: ["thumbnail", "goodsName", "type", "goodsId", "link"],
// #ifdef MP-WEIXIN
onShareAppMessage(res) {
return {
imageUrl: this.thumbnail || require("@/static/logo.png"),
};
},
// #endif
methods: { methods: {
close() { close() {
this.$emit("close"); this.$emit("close");
@@ -97,21 +90,24 @@ export default {
}, },
// #endif // #endif
shareTitle() {
let shareTitle;
if (this.type == "goods") {
shareTitle = `我发现了一个${this.goodsName}商品快来跟我一起看看吧`;
} else if (this.type == "shops") {
shareTitle = `我发现了一个${this.goodsName}店铺快来跟我一起看看吧`;
} else if (this.type == "pintuan") {
shareTitle = `我拼了一个${this.goodsName}快来跟我一起抢购吧!`;
} else if (this.type == "kanjia") {
shareTitle = `请快来帮我砍一刀${this.goodsName}`;
}
return shareTitle;
},
// #ifdef APP-PLUS // #ifdef APP-PLUS
handleShare(val) { handleShare(val) {
console.log("12312312")
if (val.type <= 1) { if (val.type <= 1) {
let shareTitle;
if (this.type == "goods") {
shareTitle = `我发现了一个${this.goodsName}商品快来跟我一起看看吧`;
} else if (this.type == "shops") {
shareTitle = `我发现了一个${this.goodsName}店铺快来跟我一起看看吧`;
} else if (this.type == "pintuan") {
shareTitle = `我拼了一个${this.goodsName}快来跟我一起抢购吧!`;
} else if (this.type == "kanjia") {
shareTitle = `请快来帮我砍一刀${this.goodsName}`;
}
let scene; // "WXSenceTimeline 朋友圈 WXSceneSession 微信好友" let scene; // "WXSenceTimeline 朋友圈 WXSceneSession 微信好友"
val.type == 1 val.type == 1
? (scene = "WXSenceTimeline") ? (scene = "WXSenceTimeline")
@@ -123,7 +119,7 @@ export default {
imageUrl: this.thumbnail, imageUrl: this.thumbnail,
type: 0, type: 0,
summary: this.goodsName, summary: this.goodsName,
title: shareTitle, title: this.shareTitle(),
success: function (res) { success: function (res) {
uni.showToast({ uni.showToast({
title: "分享成功!", title: "分享成功!",

View File

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

View File

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

View File

@@ -1,151 +0,0 @@
<template>
<text v-if="text" :class="inverted ? 'uni-badge--' + type + ' uni-badge--' + size + ' uni-badge--' + type + '-inverted' : 'uni-badge--' + type + ' uni-badge--' + size"
:style="badgeStyle" class="uni-badge" @click="onClick()">{{ text }}</text>
</template>
<script>
/**
* Badge 数字角标
* @description 数字角标一般和其它控件列表、9宫格等配合使用用于进行数量提示默认为实心灰色背景
* @tutorial https://ext.dcloud.net.cn/plugin?id=21
* @property {String} text 角标内容
* @property {String} type = [default|primary|success|warning|error] 颜色类型
* @value default 灰色
* @value primary 蓝色
* @value success 绿色
* @value warning 黄色
* @value error 红色
* @property {String} size = [normal|small] Badge 大小
* @value normal 一般尺寸
* @value small 小尺寸
* @property {String} inverted = [true|false] 是否无需背景颜色
* @event {Function} click 点击 Badge 触发事件
* @example <uni-badge text="1"></uni-badge>
*/
export default {
name: 'UniBadge',
props: {
type: {
type: String,
default: 'default'
},
inverted: {
type: Boolean,
default: false
},
text: {
type: [String, Number],
default: ''
},
size: {
type: String,
default: 'normal'
}
},
data() {
return {
badgeStyle: ''
};
},
watch: {
text() {
this.setStyle()
}
},
mounted() {
this.setStyle()
},
methods: {
setStyle() {
this.badgeStyle = `width: ${String(this.text).length * 8 + 12}px`
},
onClick() {
this.$emit('click');
}
}
};
</script>
<style lang="scss" scoped>
$bage-size: 12px;
$bage-small: scale(0.8);
$bage-height: 20px;
.uni-badge {
/* #ifndef APP-PLUS */
display: flex;
/* #endif */
justify-content: center;
flex-direction: row;
height: $bage-height;
line-height: $bage-height;
color: $uni-text-color;
border-radius: 100px;
background-color: $uni-bg-color-hover;
background-color: transparent;
text-align: center;
font-family: 'Helvetica Neue', Helvetica, sans-serif;
font-size: $bage-size;
padding: 0px 6px;
}
.uni-badge--inverted {
padding: 0 5px 0 0;
color: $uni-bg-color-hover;
}
.uni-badge--default {
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-badge--default-inverted {
color: $uni-text-color-grey;
background-color: transparent;
}
.uni-badge--primary {
color: $uni-text-color-inverse;
background-color: $uni-color-primary;
}
.uni-badge--primary-inverted {
color: $uni-color-primary;
background-color: transparent;
}
.uni-badge--success {
color: $uni-text-color-inverse;
background-color: $uni-color-success;
}
.uni-badge--success-inverted {
color: $uni-color-success;
background-color: transparent;
}
.uni-badge--warning {
color: $uni-text-color-inverse;
background-color: $uni-color-warning;
}
.uni-badge--warning-inverted {
color: $uni-color-warning;
background-color: transparent;
}
.uni-badge--error {
color: $uni-text-color-inverse;
background-color: $uni-color-error;
}
.uni-badge--error-inverted {
color: $uni-color-error;
background-color: transparent;
}
.uni-badge--small {
transform: $bage-small;
transform-origin: center center;
}
</style>

View File

@@ -1,170 +0,0 @@
<template>
<view v-if="visibleSync" :class="{ 'uni-drawer--visible': showDrawer }" class="uni-drawer" @touchmove.stop.prevent="clear">
<view class="uni-drawer__mask" :class="{ 'uni-drawer__mask--visible': showDrawer && mask }" @tap="close('mask')" />
<view class="uni-drawer__content" :class="{'uni-drawer--right': rightMode,'uni-drawer--left': !rightMode, 'uni-drawer__content--visible': showDrawer}" :style="{width:drawerWidth+'px'}">
<slot />
</view>
</view>
</template>
<script>
/**
* Drawer 抽屉
* @description 抽屉侧滑菜单
* @tutorial https://ext.dcloud.net.cn/plugin?id=26
* @property {Boolean} mask = [true | false] 是否显示遮罩
* @property {Boolean} maskClick = [true | false] 点击遮罩是否关闭
* @property {Boolean} mode = [left | right] Drawer 滑出位置
* @value left 从左侧滑出
* @value right 从右侧侧滑出
* @property {Number} width 抽屉的宽度 ,仅 vue 页面生效
* @event {Function} close 组件关闭时触发事件
*/
export default {
name: 'UniDrawer',
props: {
/**
* 显示模式(左、右),只在初始化生效
*/
mode: {
type: String,
default: ''
},
/**
* 蒙层显示状态
*/
mask: {
type: Boolean,
default: true
},
/**
* 遮罩是否可点击关闭
*/
maskClick:{
type: Boolean,
default: true
},
/**
* 抽屉宽度
*/
width: {
type: Number,
default: 220
}
},
data() {
return {
visibleSync: false,
showDrawer: false,
rightMode: false,
watchTimer: null,
drawerWidth: 220
}
},
created() {
// #ifndef APP-NVUE
this.drawerWidth = this.width
// #endif
this.rightMode = this.mode === 'right'
},
methods: {
clear(){},
close(type) {
// fixed by mehaotian 抽屉尚未完全关闭或遮罩禁止点击时不触发以下逻辑
if((type === 'mask' && !this.maskClick) || !this.visibleSync) return
this._change('showDrawer', 'visibleSync', false)
},
open() {
// fixed by mehaotian 处理重复点击打开的事件
if(this.visibleSync) return
this._change('visibleSync', 'showDrawer', true)
},
_change(param1, param2, status) {
this[param1] = status
if (this.watchTimer) {
clearTimeout(this.watchTimer)
}
this.watchTimer = setTimeout(() => {
this[param2] = status
this.$emit('change',status)
}, status ? 50 : 300)
}
}
}
</script>
<style lang="scss" scoped>
// 抽屉宽度
$drawer-width: 220px;
.uni-drawer {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
z-index: 999;
}
.uni-drawer__content {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
top: 0;
width: $drawer-width;
bottom: 0;
background-color: $uni-bg-color;
transition: transform 0.3s ease;
}
.uni-drawer--left {
left: 0;
/* #ifdef APP-NVUE */
transform: translateX(-$drawer-width);
/* #endif */
/* #ifndef APP-NVUE */
transform: translateX(-100%);
/* #endif */
}
.uni-drawer--right {
right: 0;
/* #ifdef APP-NVUE */
transform: translateX($drawer-width);
/* #endif */
/* #ifndef APP-NVUE */
transform: translateX(100%);
/* #endif */
}
.uni-drawer__content--visible {
transform: translateX(0px);
}
.uni-drawer__mask {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
opacity: 0;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition: opacity 0.3s;
}
.uni-drawer__mask--visible {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
opacity: 1;
}
</style>

View File

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

File diff suppressed because one or more lines are too long

View File

@@ -1,269 +0,0 @@
<template>
<!-- #ifdef APP-NVUE -->
<cell>
<!-- #endif -->
<view :class="disabled ? 'uni-list-item--disabled' : ''" :hover-class="disabled || showSwitch ? '' : 'uni-list-item--hover'" class="uni-list-item" @click="onClick">
<view class="uni-list-item__container" :class="{ 'uni-list-item--first': isFirstChild }">
<view v-if="thumb" class="uni-list-item__icon"><image :src="thumb" class="uni-list-item__icon-img" /></view>
<view v-else-if="showExtraIcon" class="uni-list-item__icon">
<uni-icons :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" class="uni-icon-wrapper" />
</view>
<view class="uni-list-item__content">
<slot name="left"></slot>
<text class="uni-list-item__content-title">{{ title }}</text>
<text v-if="note" class="uni-list-item__content-note">{{ note }}</text>
</view>
<view class="uni-list-item__extra">
<text v-if="rightText" class="uni-list-item__extra-text">{{ rightText }}</text>
<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" />
<switch v-if="showSwitch" :disabled="disabled" :checked="switchChecked" @change="onSwitchChange" />
<slot name="right"></slot>
<uni-icons v-if="showArrow" :size="20" class="uni-icon-wrapper" color="#bbb" type="arrowright" />
</view>
</view>
</view>
<!-- #ifdef APP-NVUE -->
</cell>
<!-- #endif -->
</template>
<script>
import uniIcons from '../uni-icons/uni-icons.vue';
import uniBadge from '../uni-badge/uni-badge.vue';
/**
* ListItem 列表子组件
* @description 列表子组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
* @property {String} title 标题
* @property {String} note 描述
* @property {String} thumb 左侧缩略图若thumb有值则不会显示扩展图标
* @property {String} badgeText 数字角标内容
* @property {String} badgeType 数字角标类型,参考[uni-icons](https://ext.dcloud.net.cn/plugin?id=21)
* @property {String} rightText 右侧文字内容
* @property {Boolean} disabled = [true|false]是否禁用
* @property {Boolean} showArrow = [true|false] 是否显示箭头图标
* @property {Boolean} showBadge = [true|false] 是否显示数字角标
* @property {Boolean} showSwitch = [true|false] 是否显示Switch
* @property {Boolean} switchChecked = [true|false] Switch是否被选中
* @property {Boolean} showExtraIcon = [true|false] 左侧是否显示扩展图标
* @property {Boolean} scrollY = [true|false] 允许纵向滚动,需要显式的设置其宽高
* @property {Object} extraIcon 扩展图标参数,格式为 {color: '#4cd964',size: '22',type: 'spinner'}
* @event {Function} click 点击 uniListItem 触发事件
* @event {Function} switchChange 点击切换 Switch 时触发
*/
export default {
name: 'UniListItem',
components: {
uniIcons,
uniBadge
},
props: {
title: {
type: String,
default: ''
}, // 列表标题
note: {
type: String,
default: ''
}, // 列表描述
disabled: {
// 是否禁用
type: [Boolean, String],
default: false
},
showArrow: {
// 是否显示箭头
type: [Boolean, String],
default: true
},
showBadge: {
// 是否显示数字角标
type: [Boolean, String],
default: false
},
showSwitch: {
// 是否显示Switch
type: [Boolean, String],
default: false
},
switchChecked: {
// Switch是否被选中
type: [Boolean, String],
default: false
},
badgeText: {
// badge内容
type: String,
default: ''
},
badgeType: {
// badge类型
type: String,
default: 'success'
},
rightText: {
// 右侧文字内容
type: String,
default: ''
},
thumb: {
// 缩略图
type: String,
default: ''
},
showExtraIcon: {
// 是否显示扩展图标
type: [Boolean, String],
default: false
},
extraIcon: {
type: Object,
default() {
return {
type: 'contact',
color: '#000000',
size: 20
};
}
}
},
inject: ['list'],
data() {
return {
isFirstChild: false
};
},
mounted() {
if (!this.list.firstChildAppend) {
this.list.firstChildAppend = true;
this.isFirstChild = true;
}
},
methods: {
onClick() {
this.$emit('click');
},
onSwitchChange(e) {
this.$emit('switchChange', e.detail);
}
}
};
</script>
<style lang="scss" scoped>
$list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg;
.uni-list-item {
font-size: $uni-font-size-lg;
position: relative;
flex-direction: column;
justify-content: space-between;
}
.uni-list-item--disabled {
opacity: 0.3;
}
.uni-list-item--hover {
background-color: $uni-bg-color-hover;
}
.uni-list-item__container {
line-height: 48rpx;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: $list-item-pd;
padding-left: 0;
flex: 1;
position: relative;
justify-content: space-between;
align-items: center;
/* #ifdef APP-PLUS */
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 0.5px;
/* #endif */
}
.uni-list-item--first {
border-top-width: 0px;
}
/* #ifndef APP-NVUE */
.uni-list-item__container:after {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
background-color: $uni-border-color;
}
.uni-list-item--first:after {
height: 0px;
}
/* #endif */
.uni-list-item__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
overflow: hidden;
flex-direction: column;
color: #3b4144;
}
.uni-list-item__content-title {
font-size: $uni-font-size-base;
color: #3b4144;
overflow: hidden;
}
.uni-list-item__content-note {
margin-top: 6rpx;
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
overflow: hidden;
}
.uni-list-item__extra {
// width: 25%;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.uni-list-item__icon {
display: flex;
margin-right: 18rpx;
flex-direction: row;
justify-content: center;
align-items: center;
margin-left: 20rpx;
}
.uni-list-item__icon-img {
// height: $uni-img-size-base;
// width: $uni-img-size-base;
height: 38rpx;
width: 38rpx;
}
.uni-list-item__extra-text {
color: $uni-text-color-grey;
font-size: $uni-font-size-sm;
}
</style>

View File

@@ -1,75 +0,0 @@
<template>
<!-- #ifndef APP-NVUE -->
<view class="uni-list">
<slot />
</view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<list class="uni-list" :enableBackToTop="enableBackToTop" loadmoreoffset="15" :scroll-y="scrollY" @loadmore="loadMore">
<slot />
</list>
<!-- #endif -->
</template>
<script>
/**
* List 列表
* @description 列表组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=24
*/
export default {
name: 'UniList',
'mp-weixin': {
options: {
multipleSlots: false
}
},
props: {
enableBackToTop: {
type: [Boolean, String],
default: false
},
scrollY: {
type: [Boolean, String],
default: false
}
},
provide() {
return {
list: this
}
},
created() {
this.firstChildAppend = false
},
methods: {
loadMore(e) {
this.$emit("scrolltolower");
}
}
}
</script>
<style lang="scss" scoped>
.uni-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
background-color: $uni-bg-color;
position: relative;
flex-direction: column;
// border-bottom-color: $uni-border-color;
// border-bottom-style: solid;
// border-bottom-width: 1px;
}
/* #ifndef APP-NVUE */
.uni-list:before {
height: 0;
}
.uni-list:after {
height: 0;
}
/* #endif */
</style>

View File

@@ -1,65 +0,0 @@
<template>
<!-- #ifdef APP-NVUE -->
<refresh :display="display" @refresh="onrefresh" @pullingdown="onpullingdown">
<slot />
</refresh>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<view ref="uni-refresh" class="uni-refresh" v-show="isShow">
<slot />
</view>
<!-- #endif -->
</template>
<script>
export default {
name: 'UniRefresh',
props: {
display: {
type: [String],
default: "hide"
}
},
data() {
return {
pulling: false
}
},
computed: {
isShow() {
if (this.display === "show" || this.pulling === true) {
return true;
}
return false;
}
},
created() {},
methods: {
onchange(value) {
this.pulling = value;
},
onrefresh(e) {
this.$emit("refresh", e);
},
onpullingdown(e) {
// #ifdef APP-NVUE
this.$emit("pullingdown", e);
// #endif
// #ifndef APP-NVUE
var detail = {
viewHeight: 90,
pullingDistance: e.height
}
this.$emit("pullingdown", detail);
// #endif
}
}
}
</script>
<style>
.uni-refresh {
height: 0;
overflow: hidden;
}
</style>

View File

@@ -1,87 +0,0 @@
var pullDown = {
threshold: 95,
maxHeight: 200,
callRefresh: 'onrefresh',
callPullingDown: 'onpullingdown',
refreshSelector: '.uni-refresh'
};
function ready(newValue, oldValue, ownerInstance, instance) {
var state = instance.getState()
state.canPullDown = newValue;
// console.log(newValue);
}
function touchStart(e, instance) {
var state = instance.getState();
state.refreshInstance = instance.selectComponent(pullDown.refreshSelector);
state.canPullDown = (state.refreshInstance != null && state.refreshInstance != undefined);
if (!state.canPullDown) {
return
}
// console.log("touchStart");
state.height = 0;
state.touchStartY = e.touches[0].pageY || e.changedTouches[0].pageY;
state.refreshInstance.setStyle({
'height': 0
});
state.refreshInstance.callMethod("onchange", true);
}
function touchMove(e, ownerInstance) {
var instance = e.instance;
var state = instance.getState();
if (!state.canPullDown) {
return
}
var oldHeight = state.height;
var endY = e.touches[0].pageY || e.changedTouches[0].pageY;
var height = endY - state.touchStartY;
if (height > pullDown.maxHeight) {
return;
}
var refreshInstance = state.refreshInstance;
refreshInstance.setStyle({
'height': height + 'px'
});
height = height < pullDown.maxHeight ? height : pullDown.maxHeight;
state.height = height;
refreshInstance.callMethod(pullDown.callPullingDown, {
height: height
});
}
function touchEnd(e, ownerInstance) {
var state = e.instance.getState();
if (!state.canPullDown) {
return
}
state.refreshInstance.callMethod("onchange", false);
var refreshInstance = state.refreshInstance;
if (state.height > pullDown.threshold) {
refreshInstance.callMethod(pullDown.callRefresh);
return;
}
refreshInstance.setStyle({
'height': 0
});
}
function propObserver(newValue, oldValue, instance) {
pullDown = newValue;
}
module.exports = {
touchmove: touchMove,
touchstart: touchStart,
touchend: touchEnd,
propObserver: propObserver
}

View File

@@ -1,395 +0,0 @@
<template>
<view v-if="show" class="uni-noticebar" :style="{ backgroundColor: backgroundColor }" @click="onClick">
<!-- #ifdef MP-ALIPAY -->
<view v-if="showClose === true || showClose === 'true'" class="uni-noticebar-close" @click="close">
<uni-icons type="closeempty" :color="color" size="12" />
</view>
<view v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon">
<uni-icons type="sound" :color="color" size="14" />
</view>
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<uni-icons v-if="showClose === true || showClose === 'true'" class="uni-noticebar-close" type="closeempty" :color="color"
size="12" @click="close" />
<uni-icons v-if="showIcon === true || showIcon === 'true'" class="uni-noticebar-icon" type="sound" :color="color"
size="14" />
<!-- #endif -->
<view ref="textBox" class="uni-noticebar__content-wrapper" :class="{'uni-noticebar__content-wrapper--scrollable':scrollable, 'uni-noticebar__content-wrapper--single':!scrollable && (single || moreText)}">
<view :id="elIdBox" class="uni-noticebar__content" :class="{'uni-noticebar__content--scrollable':scrollable, 'uni-noticebar__content--single':!scrollable && (single || moreText)}">
<text :id="elId" ref="animationEle" class="uni-noticebar__content-text" :class="{'uni-noticebar__content-text--scrollable':scrollable,'uni-noticebar__content-text--single':!scrollable && (single || moreText)}"
:style="{color:color, width:wrapWidth+'px', 'animationDuration': animationDuration, '-webkit-animationDuration': animationDuration ,animationPlayState: webviewHide?'paused':animationPlayState,'-webkit-animationPlayState':webviewHide?'paused':animationPlayState, animationDelay: animationDelay, '-webkit-animationDelay':animationDelay}">{{text}}</text>
</view>
</view>
<view v-if="showGetMore === true || showGetMore === 'true'" class="uni-noticebar__more" @click="clickMore">
<text v-if="moreText" :style="{ color: moreColor }" class="uni-noticebar__more-text">{{ moreText }}</text>
<uni-icons type="arrowright" :color="moreColor" size="14" />
</view>
</view>
</template>
<script>
import uniIcons from '../uni-icons/uni-icons.vue'
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
const animation = weex.requireModule('animation');
// #endif
/**
* NoticeBar 自定义导航栏
* @description 通告栏组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=30
* @property {Number} speed 文字滚动的速度默认100px/秒
* @property {String} text 显示文字
* @property {String} backgroundColor 背景颜色
* @property {String} color 文字颜色
* @property {String} moreColor 查看更多文字的颜色
* @property {String} moreText 设置“查看更多”的文本
* @property {Boolean} single = [true|false] 是否单行
* @property {Boolean} scrollable = [true|false] 是否滚动为true时NoticeBar为单行
* @property {Boolean} showIcon = [true|false] 是否显示左侧喇叭图标
* @property {Boolean} showClose = [true|false] 是否显示左侧关闭按钮
* @property {Boolean} showGetMore = [true|false] 是否显示右侧查看更多图标为true时NoticeBar为单行
* @event {Function} click 点击 NoticeBar 触发事件
* @event {Function} close 关闭 NoticeBar 触发事件
* @event {Function} getmore 点击”查看更多“时触发事件
*/
export default {
name: 'UniNoticeBar',
components: {
uniIcons
},
props: {
text: {
type: String,
default: ''
},
moreText: {
type: String,
default: ''
},
backgroundColor: {
type: String,
default: '#fffbe8'
},
speed: {
// 默认1s滚动100px
type: Number,
default: 100
},
color: {
type: String,
default: '#de8c17'
},
moreColor: {
type: String,
default: '#999999'
},
single: {
// 是否单行
type: [Boolean, String],
default: false
},
scrollable: {
// 是否滚动,添加后控制单行效果取消
type: [Boolean, String],
default: false
},
showIcon: {
// 是否显示左侧icon
type: [Boolean, String],
default: false
},
showGetMore: {
// 是否显示右侧查看更多
type: [Boolean, String],
default: false
},
showClose: {
// 是否显示左侧关闭按钮
type: [Boolean, String],
default: false
}
},
data() {
const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
const elIdBox = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
return {
textWidth: 0,
boxWidth: 0,
wrapWidth: '',
webviewHide: false,
// #ifdef APP-NVUE
stopAnimation: false,
// #endif
elId: elId,
elIdBox: elIdBox,
show: true,
animationDuration: 'none',
animationPlayState: 'paused',
animationDelay: '0s'
}
},
mounted() {
// #ifdef APP-PLUS
var pages = getCurrentPages();
var page = pages[pages.length - 1];
var currentWebview = page.$getAppWebview();
currentWebview.addEventListener('hide',()=>{
this.webviewHide = true
})
currentWebview.addEventListener('show',()=>{
this.webviewHide = false
})
// #endif
this.$nextTick(() => {
this.initSize()
})
},
// #ifdef APP-NVUE
beforeDestroy() {
this.stopAnimation = true
},
// #endif
methods: {
initSize() {
if (this.scrollable) {
// #ifndef APP-NVUE
let query = [],
boxWidth = 0,
textWidth = 0;
let textQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elId}`)
.boundingClientRect()
.exec(ret => {
this.textWidth = ret[0].width
resolve()
})
})
let boxQuery = new Promise((resolve, reject) => {
uni.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
.select(`#${this.elIdBox}`)
.boundingClientRect()
.exec(ret => {
this.boxWidth = ret[0].width
resolve()
})
})
query.push(textQuery)
query.push(boxQuery)
Promise.all(query).then(() => {
this.animationDuration = `${this.textWidth / this.speed}s`
this.animationDelay = `-${this.boxWidth / this.speed}s`
setTimeout(() => {
this.animationPlayState = 'running'
}, 1000)
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['animationEle'], (res) => {
let winWidth = uni.getSystemInfoSync().windowWidth
this.textWidth = res.size.width
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateY(-${winWidth}px)`
},
duration: 0,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateY(-${this.textWidth}px)`
},
timingFunction: 'linear',
duration: (this.textWidth - winWidth) / this.speed * 1000,
delay: 1000
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
})
// #endif
}
// #ifdef APP-NVUE
if (!this.scrollable && (this.single || this.moreText)) {
dom.getComponentRect(this.$refs['textBox'], (res) => {
this.wrapWidth = res.size.width
})
}
// #endif
},
loopAnimation() {
// #ifdef APP-NVUE
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateY(0px)`
},
duration: 0
}, () => {
if (!this.stopAnimation) {
animation.transition(this.$refs['animationEle'], {
styles: {
transform: `translateY(-${this.textWidth}px)`
},
duration: this.textWidth / this.speed * 1000,
timingFunction: 'linear',
delay: 0
}, () => {
if (!this.stopAnimation) {
this.loopAnimation()
}
});
}
});
// #endif
},
clickMore() {
this.$emit('getmore')
},
close() {
this.show = false;
this.$emit('close')
},
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
.uni-noticebar {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
box-sizing: border-box;
/* #endif */
flex-direction: row;
align-items: center;
padding: 6px 12px;
margin-bottom: 10px;
}
.uni-noticebar-close {
margin-right: 5px;
}
.uni-noticebar-icon {
margin-right: 5px;
}
.uni-noticebar__content-wrapper {
flex: 1;
flex-direction: column;
overflow: hidden;
}
.uni-noticebar__content-wrapper--single {
/* #ifndef APP-NVUE */
line-height: 18px;
/* #endif */
}
.uni-noticebar__content-wrapper--single,
.uni-noticebar__content-wrapper--scrollable {
flex-direction: row;
}
/* #ifndef APP-NVUE */
.uni-noticebar__content-wrapper--scrollable {
position: relative;
height: 18px;
}
/* #endif */
.uni-noticebar__content--scrollable {
/* #ifdef APP-NVUE */
flex: 0;
/* #endif */
/* #ifndef APP-NVUE */
flex: 1;
display: block;
overflow: hidden;
/* #endif */
}
.uni-noticebar__content--single {
/* #ifndef APP-NVUE */
display: flex;
flex: none;
width: 100%;
justify-content: center;
/* #endif */
}
.uni-noticebar__content-text {
font-size: 14px;
line-height: 18px;
/* #ifndef APP-NVUE */
word-break: break-all;
/* #endif */
}
.uni-noticebar__content-text--single {
/* #ifdef APP-NVUE */
lines: 1;
/* #endif */
/* #ifndef APP-NVUE */
display: block;
width: 100%;
white-space: nowrap;
/* #endif */
overflow: hidden;
text-overflow: ellipsis;
}
.uni-noticebar__content-text--scrollable {
/* #ifdef APP-NVUE */
lines: 1;
padding-left: 750rpx;
/* #endif */
/* #ifndef APP-NVUE */
position: absolute;
display: block;
height: 18px;
line-height: 18px;
white-space: nowrap;
padding-left: 100%;
animation: notice 10s 0s linear infinite both;
animation-play-state: paused;
/* #endif */
}
.uni-noticebar__more {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
padding-left: 5px;
}
.uni-noticebar__more-text {
font-size: 14px;
}
@keyframes notice {
100% {
transform: translate3d(-100%, 0, 0);
}
}
</style>

View File

@@ -1,29 +0,0 @@
export default {
created() {
if (this.type === 'message') {
// 获取自组件对象
this.maskShow = false
this.children = null
}
},
created() {
if (this.type === 'message') {
// 不显示遮罩
this.maskShow = false
// 获取子组件对象
this.childrenMsg = null
}
},
methods: {
customOpen() {
if (this.childrenMsg) {
this.childrenMsg.open()
}
},
customClose() {
if (this.childrenMsg) {
this.childrenMsg.close()
}
}
}
}

View File

@@ -1,24 +0,0 @@
import message from './message.js';
// 定义 type 类型:弹出类型top/bottom/center
const config = {
// 顶部弹出
top:'top',
// 底部弹出
bottom:'bottom',
// 居中弹出
center:'center',
// 消息提示
message:'top',
// 对话框
dialog:'center',
// 分享
share:'bottom',
}
export default {
data(){
return {
config:config
}
},
mixins: [message],
}

View File

@@ -1,243 +0,0 @@
<template>
<view class="uni-popup-dialog">
<view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text>
</view>
<view class="uni-dialog-content">
<text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text>
<input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus" >
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button" @click="close">
<text class="uni-dialog-button-text">取消</text>
</view>
<view class="uni-dialog-button uni-border-left" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">确定</text>
</view>
</view>
</view>
</template>
<script>
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式、
* @value base 基础对话框
* @value input 可输入对话框
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
props: {
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: [String, Number],
default: '请输入内容'
},
/**
* 对话框主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'error'
},
/**
* 对话框模式 base/input
*/
mode: {
type: String,
default: 'base'
},
/**
* 对话框标题
*/
title: {
type: String,
default: '提示'
},
/**
* 对话框内容
*/
content: {
type: String,
default: ''
},
/**
* 拦截取消事件 如果拦截取消事件必须监听close事件执行 done()
*/
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
dialogType: 'error',
focus: false,
val: ""
}
},
inject: ['popup'],
watch: {
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
this.val = val
}
},
created() {
// 对话框遮罩不可点击
this.popup.mkclick = false
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value
} else {
this.dialogType = this.type
}
},
mounted() {
this.focus = true
},
methods: {
/**
* 点击确认按钮
*/
onOk() {
this.$emit('confirm', () => {
this.popup.close()
if (this.mode === 'input') this.val = this.value
}, this.mode === 'input' ? this.val : '')
},
/**
* 点击取消按钮
*/
close() {
if (this.beforeClose) {
this.$emit('close', () => {
this.popup.close()
})
return
}
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-dialog {
width: 300px;
border-radius: 15px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
}
.uni-dialog-title-text {
font-size: 16px;
font-weight: 500;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 5px 15px 15px 15px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6e6e6e;
}
.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-size: 14px;
}
.uni-button-color {
color: $uni-color-primary;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
}
.uni-popup__success {
color: $uni-color-success;
}
.uni-popup__warn {
color: $uni-color-warning;
}
.uni-popup__error {
color: $uni-color-error;
}
.uni-popup__info {
color: #909399;
}
</style>

View File

@@ -1,116 +0,0 @@
<template>
<view class="uni-popup-message" :class="'uni-popup__'+[type]">
<text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text>
</view>
</template>
<script>
/**
* PopUp 弹出层-消息提示
* @description 弹出层-消息提示
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} message 消息提示文字
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
*/
export default {
name: 'UniPopupMessage',
props: {
/**
* 主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'success'
},
/**
* 消息文字
*/
message: {
type: String,
default: ''
},
/**
* 显示时间,设置为 0 则不会自动关闭
*/
duration: {
type: Number,
default: 3000
}
},
inject: ['popup'],
data() {
return {}
},
created() {
this.popup.childrenMsg = this
},
methods: {
open() {
if (this.duration === 0) return
clearTimeout(this.popuptimer)
this.popuptimer = setTimeout(() => {
this.popup.close()
}, this.duration)
},
close() {
clearTimeout(this.popuptimer)
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-message {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
background-color: #e1f3d8;
padding: 10px 15px;
border-color: #eee;
border-style: solid;
border-width: 1px;
}
.uni-popup-message-text {
font-size: 14px;
padding: 0;
}
.uni-popup__success {
background-color: #e1f3d8;
}
.uni-popup__success-text {
color: #67C23A;
}
.uni-popup__warn {
background-color: #faecd8;
}
.uni-popup__warn-text {
color: #E6A23C;
}
.uni-popup__error {
background-color: #fde2e2;
}
.uni-popup__error-text {
color: #F56C6C;
}
.uni-popup__info {
background-color: #F2F6FC;
}
.uni-popup__info-text {
color: #909399;
}
</style>

View File

@@ -1,165 +0,0 @@
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">取消</button>
</view>
</view>
</template>
<script>
export default {
name: 'UniPopupShare',
props: {
title: {
type: String,
default: '分享到'
}
},
inject: ['popup'],
data() {
return {
bottomData: [{
text: '微信',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-2.png',
name: 'wx'
},
{
text: '支付宝',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-8.png',
name: 'wx'
},
{
text: 'QQ',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/gird-3.png',
name: 'qq'
},
{
text: '新浪',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-1.png',
name: 'sina'
},
{
text: '百度',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-7.png',
name: 'copy'
},
{
text: '其他',
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uni-ui/grid-5.png',
name: 'more'
}
]
}
},
created() {},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
}, () => {
this.popup.close()
})
},
/**
* 关闭窗口
*/
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-share {
background-color: #fff;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>

View File

@@ -1,294 +0,0 @@
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
<uni-transition v-if="maskShow" :mode-class="['fade']" :styles="maskClass" :duration="duration" :show="showTrans"
@click="onTap" />
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</uni-transition>
</view>
</template>
<script>
import uniTransition from '../uni-transition/uni-transition.vue'
import popup from './popup.js'
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [ture|false] 是否开启动画
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
* @event {Function} change 打开关闭弹窗触发e={show: false}
*/
export default {
name: 'UniPopup',
components: {
uniTransition
},
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型可选值top: 顶部弹出层bottom底部弹出层center全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: 'center'
},
// maskClick
maskClick: {
type: Boolean,
default: true
}
},
provide() {
return {
popup: this
}
},
mixins: [popup],
watch: {
/**
* 监听type类型
*/
type: {
handler: function(newVal) {
this[this.config[newVal]]()
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick(val) {
this.mkclick = val
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
transClass: {
'position': 'fixed',
'left': 0,
'right': 0,
},
maskShow: true,
mkclick: true,
popupstyle: 'top'
}
},
created() {
this.mkclick = this.maskClick
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation()
},
open() {
this.showPopup = true
this.$nextTick(() => {
new Promise(resolve => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.showTrans = true
// fixed by mehaotian 兼容 app 端
this.$nextTick(() => {
resolve();
})
}, 50);
}).then(res => {
// 自定义打开事件
clearTimeout(this.msgtimer)
this.msgtimer = setTimeout(() => {
this.customOpen && this.customOpen()
}, 100)
this.$emit('change', {
show: true,
type: this.type
})
})
})
},
close(type) {
this.showTrans = false
this.$nextTick(() => {
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// 自定义关闭事件
this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
})
},
onTap() {
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top() {
this.popupstyle = 'top'
this.ani = ['slide-top']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
}
},
/**
* 底部弹出样式处理
*/
bottom() {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0
}
},
/**
* 中间弹出样式处理
*/
center() {
this.popupstyle = 'center'
this.ani = ['zoom-out', 'fade']
this.transClass = {
'position': 'fixed',
/* #ifndef APP-NVUE */
'display': 'flex',
'flexDirection': 'column',
/* #endif */
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.bottom {
bottom: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>

View File

@@ -1,135 +0,0 @@
<template>
<view class="uni-section" nvue>
<view v-if="type" class="uni-section__head">
<view :class="type" class="uni-section__head-tag" />
</view>
<view class="uni-section__content">
<text :class="{'distraction':!subTitle}" class="uni-section__content-title">{{ title }}</text>
<text v-if="subTitle" class="uni-section__content-sub">{{ subTitle }}</text>
</view>
<slot />
</view>
</template>
<script>
/**
* Section 标题栏
* @description 标题栏
* @property {String} type = [line|circle] 标题装饰类型
* @value line 竖线
* @value circle 圆形
* @property {String} title 主标题
* @property {String} subTitle 副标题
*/
export default {
name: 'UniTitle',
props: {
type: {
type: String,
default: ''
},
title: {
type: String,
default: ''
},
subTitle: {
type: String,
default: ''
}
},
data() {
return {}
},
watch: {
title(newVal) {
if (uni.report && newVal !== '') {
uni.report('title', newVal)
}
}
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" scoped>
.uni-section {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
margin-top: 10px;
flex-direction: row;
align-items: center;
padding: 0 10px;
height: 50px;
background-color: $uni-bg-color-grey;
/* #ifdef APP-NVUE */
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 0.5px;
/* #endif */
font-weight: normal;
}
/* #ifndef APP-NVUE */
.uni-section:after {
position: absolute;
bottom: 0;
right: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: $uni-border-color;
}
/* #endif */
.uni-section__head {
flex-direction: row;
justify-content: center;
align-items: center;
margin-right: 10px;
}
.line {
height: 15px;
background-color: $uni-text-color-disable;
border-radius: 5px;
width: 3px;
}
.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
background-color: $uni-text-color-disable;
}
.uni-section__content {
flex: 1;
color: $uni-text-color;
}
.uni-section__content-title {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.distraction {
flex-direction: row;
align-items: center;
}
.uni-section__content-sub {
font-size: $uni-font-size-sm;
color: $uni-text-color-grey;
}
</style>

View File

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

View File

@@ -1,253 +0,0 @@
<template>
<view class="uni-steps">
<view :class="[direction==='column'?'uni-steps__column':'uni-steps__row']">
<view :class="[direction==='column'?'uni-steps__column-text-container':'uni-steps__row-text-container']">
<view v-for="(item,index) in options" :key="index" :class="[direction==='column'?'uni-steps__column-text':'uni-steps__row-text']">
<text :style="{color:index<=active?activeColor:deactiveColor}" :class="[direction==='column'?'uni-steps__column-title':'uni-steps__row-title']">{{item.title}}</text>
<text v-if="direction=='column'" :style="{color:index<=active?activeColor:deactiveColor}" :class="[direction==='column'?'uni-steps__column-desc':'uni-steps__row-desc']">{{item.desc}}</text>
</view>
</view>
<view :class="[direction==='column'?'uni-steps__column-container':'uni-steps__row-container']">
<view :class="[direction==='column'?'uni-steps__column-line-item':'uni-steps__row-line-item']" v-for="(item,index) in options"
:key="index">
<view :class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--before':'uni-steps__row-line--before']"
:style="{backgroundColor:index<=active&&index!==0?activeColor:index===0?'transparent':deactiveColor}"></view>
<view :class="[direction==='column'?'uni-steps__column-check':'uni-steps__row-check']" v-if="index === active">
<uni-icons :color="activeColor" type="checkbox-filled" size="14"></uni-icons>
</view>
<view :class="[direction==='column'?'uni-steps__column-circle':'uni-steps__row-circle']" v-else :style="{backgroundColor:index<active?activeColor:deactiveColor}"></view>
<view :class="[direction==='column'?'uni-steps__column-line':'uni-steps__row-line',direction==='column'?'uni-steps__column-line--after':'uni-steps__row-line--after']"
:style="{backgroundColor:index<active&&index!==options.length-1?activeColor:index===options.length-1?'transparent':deactiveColor}"></view>
<!-- <view v-if="index==0 && direction!='column'" class="address">北京市</view>
<view v-if="options.length-1 == index && direction!='column'" class="address">太原市</view> -->
</view>
</view>
</view>
</view>
</template>
<script>
import uniIcons from '../uni-icons/uni-icons.vue'
export default {
name: 'UniSteps',
components: {
uniIcons
},
props: {
direction: {
// 排列方向 row column
type: String,
default: 'row'
},
activeColor: {
// 激活状态颜色
type: String,
default: '#1aad19'
},
deactiveColor: {
// 未激活状态颜色
type: String,
default: '#999999'
},
active: {
// 当前步骤
type: Number,
default: 0
},
options: {
type: Array,
default () {
return []
}
} // 数据
},
data() {
return {}
}
}
</script>
<style lang="scss" scoped>
.uni-steps {
/* #ifndef APP-NVUE */
display: flex;
width: 100%;
/* #endif */
/* #ifdef APP-NVUE */
flex: 1;
/* #endif */
flex-direction: column;
}
.uni-steps__row {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-steps__column {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row-reverse;
}
.uni-steps__row-text-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-steps__column-text-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
}
.uni-steps__row-text {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex: 1;
flex-direction: column;
}
.uni-steps__column-text {
padding: 6px 0px;
// border-bottom-style: solid;
// border-bottom-width: 1px;
// border-bottom-color: $uni-border-color;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-steps__row-title {
font-size: 24rpx;
line-height: 16px;
text-align: center;
}
.uni-steps__column-title {
font-size: 24rpx;
text-align: left;
line-height: 18px;
}
.uni-steps__row-desc {
font-size: 12px;
line-height: 14px;
text-align: center;
}
.uni-steps__column-desc {
font-size: $uni-font-size-sm;
text-align: left;
line-height: 18px;
}
.uni-steps__row-container {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-steps__column-container {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
width: 30px;
flex-direction: column;
}
.uni-steps__row-line-item {
/* #ifndef APP-NVUE */
display: inline-flex;
/* #endif */
flex-direction: row;
flex: 1;
height: 14px;
line-height: 14px;
align-items: center;
justify-content: center;
position: relative;
.address{
position: absolute;
top: 40rpx;
left: 60rpx;
color: #999;
font-size: 24rpx;
}
}
.uni-steps__column-line-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
align-items: center;
justify-content: center;
}
.uni-steps__row-line {
flex: 1;
height: 1px;
background-color: $uni-text-color-grey;
}
.uni-steps__column-line {
width: 1px;
background-color: $uni-text-color-grey;
}
.uni-steps__row-line--after {
transform: translateX(1px);
}
.uni-steps__column-line--after {
flex: 1;
transform: translate(0px, 1px);
}
.uni-steps__row-line--before {
transform: translateX(-1px);
}
.uni-steps__column-line--before {
height: 6px;
transform: translate(0px, -1px);
}
.uni-steps__row-circle {
width: 5px;
height: 5px;
border-radius: 100px;
background-color: $uni-text-color-grey;
margin: 0px 3px;
}
.uni-steps__column-circle {
width: 5px;
height: 5px;
border-radius: 100px;
background-color: $uni-text-color-grey;
margin: 4px 0px 5px 0px;
}
.uni-steps__row-check {
margin: 0px 6px;
}
.uni-steps__column-check {
height: 14px;
line-height: 14px;
margin: 2px 0px;
}
</style>

View File

@@ -1,184 +0,0 @@
<template>
<view class="uni-swiper__warp">
<slot />
<view v-if="mode === 'default'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='default'>
<view v-for="(item,index) in info" :style="{
'width': (index === current? dots.width*2:dots.width ) + 'px','height':dots.width/3 +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border-radius':'0px'}"
:key="index" class="uni-swiper__dots-item uni-swiper__dots-bar" />
</view>
<view v-if="mode === 'dot'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='dot'>
<view v-for="(item,index) in info" :style="{
'width': dots.width + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
:key="index" class="uni-swiper__dots-item" />
</view>
<view v-if="mode === 'round'" :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box" key='round'>
<view v-for="(item,index) in info" :class="[index === current&&'uni-swiper__dots-long']" :style="{
'width':(index === current? dots.width*3:dots.width ) + 'px','height':dots.height +'px' ,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
:key="index" class="uni-swiper__dots-item " />
</view>
<view v-if="mode === 'nav'" key='nav' :style="{'background-color':dotsStyles.backgroundColor,'bottom':'0'}" class="uni-swiper__dots-box uni-swiper__dots-nav">
<text :style="{'color':dotsStyles.color}" class="uni-swiper__dots-nav-item">{{ (current+1)+"/"+info.length +' ' +info[current][field] }}</text>
</view>
<view v-if="mode === 'indexes'" key='indexes' :style="{'bottom':dots.bottom + 'px'}" class="uni-swiper__dots-box">
<view v-for="(item,index) in info" :style="{
'width':dots.width + 'px','height':dots.height +'px' ,'color':index === current?dots.selectedColor:dots.color,'background-color':index !== current?dots.backgroundColor:dots.selectedBackgroundColor,'border':index !==current ? dots.border:dots.selectedBorder}"
:key="index" class="uni-swiper__dots-item uni-swiper__dots-indexes"><text class="uni-swiper__dots-indexes-text">{{ index+1 }}</text></view>
</view>
</view>
</template>
<script>
export default {
name: 'UniSwiperDot',
props: {
info: {
type: Array,
default () {
return []
}
},
current: {
type: Number,
default: 0
},
dotsStyles: {
type: Object,
default () {
return {}
}
},
// 类型 default(默认) indexes long nav
mode: {
type: String,
default: 'default'
},
// 只在 nav 模式下生效,变量名称
field: {
type: String,
default: ''
}
},
data() {
return {
dots: {
width: 8,
height: 8,
bottom: 10,
color: '#fff',
backgroundColor: 'rgba(0, 0, 0, .3)',
border: '1px rgba(0, 0, 0, .3) solid',
selectedBackgroundColor: '#333',
selectedBorder: '1px rgba(0, 0, 0, .9) solid'
}
}
},
watch: {
dotsStyles(newVal) {
this.dots = Object.assign(this.dots, this.dotsStyles)
},
mode(newVal) {
if (newVal === 'indexes') {
this.dots.width = 20
this.dots.height = 20
} else {
this.dots.width = 8
this.dots.height = 8
}
}
},
created() {
if (this.mode === 'indexes') {
this.dots.width = 20
this.dots.height = 20
}
this.dots = Object.assign(this.dots, this.dotsStyles)
}
}
</script>
<style lang="scss" scoped>
.uni-swiper__warp {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: column;
position: relative;
overflow: hidden;
}
.uni-swiper__dots-box {
position: absolute;
bottom: 10px;
left: 0;
right: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
}
.uni-swiper__dots-item {
width: 8px;
border-radius: 100px;
margin-left: 6px;
background-color: $uni-bg-color-mask;
// transition: width 0.2s linear; 不要取消注释,不然会不能变色
}
.uni-swiper__dots-item:first-child {
margin: 0;
}
.uni-swiper__dots-default {
border-radius: 100px;
}
.uni-swiper__dots-long {
border-radius: 50px;
}
.uni-swiper__dots-bar {
border-radius: 50px;
}
.uni-swiper__dots-nav {
bottom: 0px;
height: 40px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: flex-start;
align-items: center;
background-color: rgba(0, 0, 0, 0.2);
}
.uni-swiper__dots-nav-item {
/* overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; */
font-size: $uni-font-size-base;
color: #fff;
margin: 0 15px;
}
.uni-swiper__dots-indexes {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
// flex: 1;
justify-content: center;
align-items: center;
}
.uni-swiper__dots-indexes-text {
color: #fff;
font-size: $uni-font-size-sm;
}
</style>

View File

@@ -1,230 +0,0 @@
<template>
<view :class="[
'uni-tag--' + type,
disabled === true || disabled === 'true' ? 'uni-tag--disabled' : '',
inverted === true || inverted === 'true' ? type + '-uni-tag--inverted' : '',
circle === true || circle === 'true' ? 'uni-tag--circle' : '',
mark === true || mark === 'true' ? 'uni-tag--mark' : '',
'uni-tag--' + size
]"
@click="onClick()" class="uni-tag" v-if="text">
<text :class="[type === 'default' ? 'uni-tag--default':'uni-tag-text',inverted === true || inverted === 'true' ? 'uni-tag-text--'+type : '',size === 'small' ? 'uni-tag-text--small':'' ]">{{ text }}</text>
</view>
</template>
<script>
/**
* Tag 标签
* @description 用于展示1个或多个文字标签可点击切换选中、不选中的状态
* @tutorial https://ext.dcloud.net.cn/plugin?id=35
* @property {String} text 标签内容
* @property {String} size = [normal|small] 大小尺寸
* @value normal 正常
* @value small 小尺寸
* @property {String} type = [default|primary|successwarningerrorroyal] 颜色类型
* @value default 灰色
* @value primary 蓝色
* @value success 绿色
* @value warning 黄色
* @value error 红色
* @value royal 紫色
* @property {Boolean} disabled = [true|false] 是否为禁用状态
* @property {Boolean} inverted = [true|false] 是否无需背景颜色(空心标签)
* @property {Boolean} circle = [true|false] 是否为圆角
* @event {Function} click 点击 Tag 触发事件
*/
export default {
name: "UniTag",
props: {
type: {
// 标签类型default、primary、success、warning、error、royal
type: String,
default: "default"
},
size: {
// 标签大小 normal, small
type: String,
default: "normal"
},
// 标签内容
text: {
type: String,
default: ""
},
disabled: {
// 是否为禁用状态
type: [Boolean, String],
default: false
},
inverted: {
// 是否为空心
type: [Boolean, String],
default: false
},
circle: {
// 是否为圆角样式
type: [Boolean, String],
default: false
},
mark: {
// 是否为标记样式
type: [Boolean, String],
default: false
}
},
methods: {
onClick() {
if (this.disabled === true || this.disabled === "true") {
return;
}
this.$emit("click");
}
}
};
</script>
<style lang="scss" scoped>
$tag-pd: 0px 16px;
$tag-small-pd: 0px 8px;
.uni-tag {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
padding: $tag-pd;
height: 30px;
line-height: 30px;
justify-content: center;
color: $uni-text-color;
border-radius: $uni-border-radius-base;
background-color: $uni-bg-color-grey;
border-width: 1rpx;
border-style: solid;
border-color: $uni-bg-color-grey;
}
.uni-tag--circle {
border-radius: 15px;
}
.uni-tag--mark {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
}
.uni-tag--disabled {
opacity: 0.5;
}
.uni-tag--small {
height: 20px;
padding: $tag-small-pd;
line-height: 20px;
font-size: $uni-font-size-sm;
}
.uni-tag--default {
color: $uni-text-color;
font-size: $uni-font-size-base;
}
.uni-tag-text--small {
font-size: $uni-font-size-sm !important;
}
.uni-tag-text {
color: $uni-text-color-inverse;
font-size: $uni-font-size-base;
}
.uni-tag-text--primary {
color: $uni-color-primary !important;
}
.uni-tag-text--success {
color: $uni-color-success !important;
}
.uni-tag-text--warning {
color: $uni-color-warning !important;
}
.uni-tag-text--error {
color: $uni-color-error !important;
}
.uni-tag--primary {
color: $uni-text-color-inverse;
background-color: $uni-color-primary;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-primary;
}
.primary-uni-tag--inverted {
color: $uni-color-primary;
background-color: $uni-bg-color;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-primary;
}
.uni-tag--success {
color: $uni-text-color-inverse;
background-color: $uni-color-success;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-success;
}
.success-uni-tag--inverted {
color: $uni-color-success;
background-color: $uni-bg-color;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-success;
}
.uni-tag--warning {
color: $uni-text-color-inverse;
background-color: $uni-color-warning;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-warning;
}
.warning-uni-tag--inverted {
color: $uni-color-warning;
background-color: $uni-bg-color;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-warning;
}
.uni-tag--error {
color: $uni-text-color-inverse;
background-color: $uni-color-error;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-error;
}
.error-uni-tag--inverted {
color: $uni-color-error;
background-color: $uni-bg-color;
border-width: 1rpx;
border-style: solid;
border-color: $uni-color-error;
}
.uni-tag--inverted {
color: $uni-text-color;
background-color: $uni-bg-color;
border-width: 1rpx;
border-style: solid;
border-color: $uni-bg-color-grey;
}
</style>

View File

@@ -1,279 +0,0 @@
<template>
<view v-if="isShow" ref="ani" class="uni-transition" :class="[ani.in]" :style="'transform:' +transform+';'+stylesObject"
@click="change">
<slot></slot>
</view>
</template>
<script>
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
/**
* Transition 过渡动画
* @description 简单过渡动画组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
* @property {Array} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
* @value fade 渐隐渐出过渡
* @value slide-top 由上至下过渡
* @value slide-right 由右至左过渡
* @value slide-bottom 由下至上过渡
* @value slide-left 由左至右过渡
* @value zoom-in 由小到大过渡
* @value zoom-out 由大到小过渡
* @property {Number} duration 过渡动画持续时间
* @property {Object} styles 组件样式,同 css 样式,注意带’-‘连接符的属性需要使用小驼峰写法如:`backgroundColor:red`
*/
export default {
name: 'uniTransition',
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: Array,
default () {
return []
}
},
duration: {
type: Number,
default: 300
},
styles: {
type: Object,
default () {
return {}
}
}
},
data() {
return {
isShow: false,
transform: '',
ani: { in: '',
active: ''
}
};
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
this.close()
}
},
immediate: true
}
},
computed: {
stylesObject() {
let styles = {
...this.styles,
'transition-duration': this.duration / 1000 + 's'
}
let transfrom = ''
for (let i in styles) {
let line = this.toLine(i)
transfrom += line + ':' + styles[i] + ';'
}
return transfrom
}
},
created() {
// this.timer = null
// this.nextTick = (time = 50) => new Promise(resolve => {
// clearTimeout(this.timer)
// this.timer = setTimeout(resolve, time)
// return this.timer
// });
},
methods: {
change() {
this.$emit('click', {
detail: this.isShow
})
},
open() {
clearTimeout(this.timer)
this.isShow = true
this.transform = ''
this.ani.in = ''
for (let i in this.getTranfrom(false)) {
if (i === 'opacity') {
this.ani.in = 'fade-in'
} else {
this.transform += `${this.getTranfrom(false)[i]} `
}
}
this.$nextTick(() => {
setTimeout(() => {
this._animation(true)
}, 50)
})
},
close(type) {
clearTimeout(this.timer)
this._animation(false)
},
_animation(type) {
let styles = this.getTranfrom(type)
// #ifdef APP-NVUE
if(!this.$refs['ani']) return
animation.transition(this.$refs['ani'].ref, {
styles,
duration: this.duration, //ms
timingFunction: 'ease',
needLayout: false,
delay: 0 //ms
}, () => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
})
})
// #endif
// #ifndef APP-NVUE
this.transform = ''
for (let i in styles) {
if (i === 'opacity') {
this.ani.in = `fade-${type?'out':'in'}`
} else {
this.transform += `${styles[i]} `
}
}
this.timer = setTimeout(() => {
if (!type) {
this.isShow = false
}
this.$emit('change', {
detail: this.isShow
})
}, this.duration)
// #endif
},
getTranfrom(type) {
let styles = {
transform: ''
}
this.modeClass.forEach((mode) => {
switch (mode) {
case 'fade':
styles.opacity = type ? 1 : 0
break;
case 'slide-top':
styles.transform += `translateY(${type?'0':'-100%'}) `
break;
case 'slide-right':
styles.transform += `translateX(${type?'0':'100%'}) `
break;
case 'slide-bottom':
styles.transform += `translateY(${type?'0':'100%'}) `
break;
case 'slide-left':
styles.transform += `translateX(${type?'0':'-100%'}) `
break;
case 'zoom-in':
styles.transform += `scale(${type?1:0.8}) `
break;
case 'zoom-out':
styles.transform += `scale(${type?1:1.2}) `
break;
}
})
return styles
},
_modeClassArr(type) {
let mode = this.modeClass
if (typeof(mode) !== "string") {
let modestr = ''
mode.forEach((item) => {
modestr += (item + '-' + type + ',')
})
return modestr.substr(0, modestr.length - 1)
} else {
return mode + '-' + type
}
},
// getEl(el) {
// console.log(el || el.ref || null);
// return el || el.ref || null
// },
toLine(name) {
return name.replace(/([A-Z])/g, "-$1").toLowerCase();
}
}
}
</script>
<style>
.uni-transition {
transition-timing-function: ease;
transition-duration: 0.3s;
transition-property: transform, opacity;
}
.fade-in {
opacity: 0;
}
.fade-active {
opacity: 1;
}
.slide-top-in {
/* transition-property: transform, opacity; */
transform: translateY(-100%);
}
.slide-top-active {
transform: translateY(0);
/* opacity: 1; */
}
.slide-right-in {
transform: translateX(100%);
}
.slide-right-active {
transform: translateX(0);
}
.slide-bottom-in {
transform: translateY(100%);
}
.slide-bottom-active {
transform: translateY(0);
}
.slide-left-in {
transform: translateX(-100%);
}
.slide-left-active {
transform: translateX(0);
opacity: 1;
}
.zoom-in-in {
transform: scale(0.8);
}
.zoom-out-active {
transform: scale(1);
}
.zoom-out-in {
transform: scale(1.2);
}
</style>

View File

@@ -65,7 +65,6 @@ export default {
// 可自行调整 // 可自行调整
this.scHight = phone.screenHeight / 2 - 200 + "px"; this.scHight = phone.screenHeight / 2 - 200 + "px";
this.getCode(); this.getCode();
}, },
props: { props: {
height: { height: {
@@ -315,30 +314,6 @@ export default {
width: 750rpx; width: 750rpx;
} }
.border-bom {
border-bottom: 0.5rpx solid #dddddd;
}
.border-red {
border-bottom: 1rpx solid #d33e18;
}
.border-bom-big {
border-bottom: 8rpx solid #dddddd;
}
.border-bom-white {
border-bottom: 2rpx solid #ffffff;
}
.border-bom-green {
border-bottom: 4rpx solid #f8f9bd;
}
.border-bom-index {
border-bottom: 4rpx solid #27d9b3;
}
.padding-left { .padding-left {
padding-left: 20rpx; padding-left: 20rpx;
} }

View File

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

View File

@@ -1,7 +1,8 @@
const name = "lilishop"; const name = "lilishop"; //全局商城name
const schemeName = 'lilishop' //唤醒app需要的schemeName
export default { export default {
name: name, name: name,
schemeLink: `${name}://`, //唤起app地址 schemeLink: `${schemeName}://`, //唤起app地址
downloadLink: "https://pickmall.cn/download-page/index.html", //下载地址下载app的地址 downloadLink: "https://pickmall.cn/download-page/index.html", //下载地址下载app的地址
shareLink: "https://m-b2b2c.pickmall.cn", //分享地址也就是在h5中默认的复制地址 shareLink: "https://m-b2b2c.pickmall.cn", //分享地址也就是在h5中默认的复制地址
appid: "wx6f10f29075dc1b0b", //小程序唯一凭证,即 AppID可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态) appid: "wx6f10f29075dc1b0b", //小程序唯一凭证,即 AppID可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
@@ -9,5 +10,7 @@ export default {
aMapKey: "d649892b3937a5ad20b76dacb2bcb5bd", //在高德中申请web端key aMapKey: "d649892b3937a5ad20b76dacb2bcb5bd", //在高德中申请web端key
scanAuthNavigation:['https://m-b2b2c.pickmall.cn/'], //扫码认证跳转域名配置 会根据此处配置的路由进行跳转 scanAuthNavigation:['https://m-b2b2c.pickmall.cn/'], //扫码认证跳转域名配置 会根据此处配置的路由进行跳转
iosAppId:"id1564638363", //AppStore的应用地址id 具体在分享->拷贝链接中查看 iosAppId:"id1564638363", //AppStore的应用地址id 具体在分享->拷贝链接中查看
logo:"https://lilishop-oss.oss-cn-beijing.aliyuncs.com/4c864e133c2944efad1f7282ac8a3b9e.png" //logo地址 logo:"https://lilishop-oss.oss-cn-beijing.aliyuncs.com/4c864e133c2944efad1f7282ac8a3b9e.png", //logo地址
customerServiceMobile:"13161366885", //客服电话
customerServiceEmail:"lili@lili.com" //客服邮箱
}; };

View File

@@ -1,7 +1,18 @@
/**
* 微信小程序支付
* 此处针对于微信小程序开发的支付插件
* 第一次支付成功后会跳出订阅的消息 如果用户拒绝或同意都会跳转到支付成功页面
* 如果点击订阅 会将状态写进缓存 之后不再提醒。
*
* @param {sn,price}
*/
import { initiatePay } from "@/api/trade"; import { initiatePay } from "@/api/trade";
import { getWeChatMpMessage } from "@/api/message.js";
class LiLiWXPay { class LiLiWXPay {
constructor(...payList) { constructor(...payList) {
this.data = payList[0]; this.data = payList[0];
console.log(payList);
// 调用支付 // 调用支付
this.pay = () => { this.pay = () => {
uni.showLoading({ uni.showLoading({
@@ -32,13 +43,7 @@ class LiLiWXPay {
icon: "none", icon: "none",
title: "支付成功!", title: "支付成功!",
}); });
// 之后成功后跳转到支付成功页面 sendMessage(payList[0].price);
uni.redirectTo({
url:
"/pages/cart/payment/success?paymentMethod=WECHAT" +
"&payPrice=" +
this.data.price,
});
}, },
fail: (e) => { fail: (e) => {
this.exception = e; this.exception = e;
@@ -59,4 +64,53 @@ class LiLiWXPay {
} }
} }
function sendMessage(price) {
//判断用户是否已经进行了订阅
if (!uni.getStorageSync("acceptSubscribeMessage")) {
//订阅消息
getWeChatMpMessage().then((res) => {
var message = res.data.result;
var templateid = message.map((item) => item.code);
uni.requestSubscribeMessage({
tmplIds: templateid,
success: (res) => {
for (let key in res) {
// 表示用户拒绝订阅该信息
if (res[key] == "reject") {
this.checked = false;
} else {
uni.setStorageSync("acceptSubscribeMessage", res);
}
}
},
fail: (res) => {
uni.removeStorageSync("acceptSubscribeMessage");
this.checked = false;
},
complete: () => {
/**
* 已经支付成功
*/
uni.redirectTo({
url:
"/pages/cart/payment/success?paymentMethod=WECHAT" +
"&payPrice=" +
price,
});
},
});
});
} else {
/**
* 已经支付成功
*/
uni.redirectTo({
url:
"/pages/cart/payment/success?paymentMethod=WECHAT" +
"&payPrice=" +
price,
});
}
}
export default LiLiWXPay; export default LiLiWXPay;

View File

@@ -1,274 +0,0 @@
/**
* 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
*/
var isIos;
// #ifdef APP-PLUS
isIos = plus.os.name == "iOS";
// #endif
// 判断推送权限是否开启
function judgeIosPermissionPush() {
var result = false;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
console.log("推送权限没有开启");
} else {
result = true;
console.log("已经开启推送功能!");
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
console.log("推送权限没有开启!");
} else {
result = true;
console.log("已经开启推送功能!");
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
// 判断定位权限是否开启
function judgeIosPermissionLocation() {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var status = cllocationManger.authorizationStatus();
result = status != 2;
console.log("定位权限开启:" + result);
// 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
console.log("enable:" + enable);
console.log("status:" + status);
if (enable && status != 2) {
result = true;
console.log("手机定位服务已开启且已授予定位权限");
} else {
console.log("手机系统的定位没有打开或未给予定位权限");
}
plus.ios.deleteObject(cllocationManger);
return result;
}
// 判断麦克风权限是否开启
function judgeIosPermissionRecord() {
var result = false;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var permissionStatus = avaudio.recordPermission();
console.log("permissionStatus:" + permissionStatus);
if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
console.log("麦克风权限没有开启");
} else {
result = true;
console.log("麦克风权限已经开启");
}
plus.ios.deleteObject(avaudiosession);
return result;
}
// 判断相机权限是否开启
function judgeIosPermissionCamera() {
var result = false;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType("vide");
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相机权限已经开启");
} else {
console.log("相机权限没有开启");
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
// 判断相册权限是否开启
function judgeIosPermissionPhotoLibrary() {
var result = false;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
console.log("authStatus:" + authStatus);
if (authStatus == 3) {
result = true;
console.log("相册权限已经开启");
} else {
console.log("相册权限没有开启");
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
// 判断通讯录权限是否开启
function judgeIosPermissionContact() {
var result = false;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus == 3) {
result = true;
console.log("通讯录权限已经开启");
} else {
console.log("通讯录权限没有开启");
}
plus.ios.deleteObject(CNContactStore);
return result;
}
// 判断日历权限是否开启
function judgeIosPermissionCalendar() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = true;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// 判断备忘录权限是否开启
function judgeIosPermissionMemo() {
var result = false;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = true;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
// Android权限查询
function requestAndroidPermission(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
function (resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log("已获取的权限:" + grantedPermission);
result = 1;
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log("拒绝本次申请的权限:" + deniedPresentPermission);
result = 0;
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log("永久拒绝申请的权限:" + deniedAlwaysPermission);
result = -1;
}
resolve(result);
// 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
// if (result != 1) {
// gotoAppPermissionSetting()
// }
},
function (error) {
console.log("申请权限错误:" + error.code + " = " + error.message);
resolve({
code: error.code,
message: error.message,
});
}
);
});
}
// 使用一个方法,根据参数判断权限
function judgeIosPermission(permissionID) {
if (permissionID == "location") {
return judgeIosPermissionLocation();
} else if (permissionID == "camera") {
return judgeIosPermissionCamera();
} else if (permissionID == "photoLibrary") {
return judgeIosPermissionPhotoLibrary();
} else if (permissionID == "record") {
return judgeIosPermissionRecord();
} else if (permissionID == "push") {
return judgeIosPermissionPush();
} else if (permissionID == "contact") {
return judgeIosPermissionContact();
} else if (permissionID == "calendar") {
return judgeIosPermissionCalendar();
} else if (permissionID == "memo") {
return judgeIosPermissionMemo();
}
return false;
}
// 跳转到**应用**的权限页面
function gotoAppPermissionSetting() {
if (isIos) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
// 检查系统的设备服务是否开启
// var checkSystemEnableLocation = async function () {
function checkSystemEnableLocation() {
if (isIos) {
var result = false;
var cllocationManger = plus.ios.import("CLLocationManager");
var result = cllocationManger.locationServicesEnabled();
console.log("系统定位开启:" + result);
plus.ios.deleteObject(cllocationManger);
return result;
} else {
var context = plus.android.importClass("android.content.Context");
var locationManager = plus.android.importClass(
"android.location.LocationManager"
);
var main = plus.android.runtimeMainActivity();
var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
console.log("系统定位开启:" + result);
return result;
}
}
module.exports = {
judgeIosPermission: judgeIosPermission,
requestAndroidPermission: requestAndroidPermission,
checkSystemEnableLocation: checkSystemEnableLocation,
gotoAppPermissionSetting: gotoAppPermissionSetting,
};

37
main.js
View File

@@ -4,41 +4,46 @@ import * as filters from "./utils/filters.js"; // global filter
import uView from "uview-ui"; import uView from "uview-ui";
import store from "./store"; import store from "./store";
/**
* 仅在h5中显示唤醒app功能
* 在h5页面手动挂载
*
*/
// #ifdef H5 // #ifdef H5
// 在h5页面手动挂载 h5唤醒app插件
import airBtn from "@/components/m-airbtn/index.vue"; import airBtn from "@/components/m-airbtn/index.vue";
let btn = Vue.component("airBtn", airBtn); //全局注册 let btn = Vue.component("airBtn", airBtn); //全局注册
document.body.appendChild(new btn().$mount().$el); document.body.appendChild(new btn().$mount().$el);
// #endif // #endif
/**
* 全局filters
*/
Object.keys(filters).forEach((key) => { Object.keys(filters).forEach((key) => {
Vue.filter(key, filters[key]); Vue.filter(key, filters[key]);
}); });
const msg = (title, duration = 1500, mask = false, icon = "none") => { // 引入Vuex
//统一提示方便全局修改
if (Boolean(title) === false) {
return;
}
uni.showToast({
title,
duration,
mask,
icon,
});
};
// 引入vuex
Vue.prototype.$store = store; Vue.prototype.$store = store;
Vue.use(uView); Vue.use(uView);
Vue.config.productionTip = false; Vue.config.productionTip = false;
/**
* 注意!
* 此处将常用的颜色嵌入到原型链上面
* 颜色使用驼峰命名对应 uni.scss中全局颜色变量名
* 如需更换主题请修改此处以及uni.scss中的全局颜色
*/
// 主题色 // 主题色
Vue.prototype.$mainColor = "#ff3c2a"; Vue.prototype.$mainColor = "#ff3c2a";
// 高亮主题色 // 高亮主题色
Vue.prototype.$lightColor = "#ff6b35"; Vue.prototype.$lightColor = "#ff6b35";
// 可直接 this.$api调用 // 辅助高亮颜色
Vue.prototype.$api = { msg }; Vue.prototype.$aiderLightColor = "#ff9f28";
App.mpType = "app"; App.mpType = "app";

View File

@@ -2,8 +2,8 @@
"name" : "lili商城", "name" : "lili商城",
"appid" : "__UNI__C100675", "appid" : "__UNI__C100675",
"description" : "", "description" : "",
"versionName" : "4.0.23", "versionName" : "4.0.47",
"versionCode" : 4000023, "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"
}, },
@@ -178,7 +179,7 @@
"mp-weixin" : { "mp-weixin" : {
/* */ /* */
"usingComponents" : true, "usingComponents" : true,
"appid" : "", "appid" : "wx6f10f29075dc1b0b",
"optimization" : { "optimization" : {
"subPackages" : true "subPackages" : true
}, },

42
package-lock.json generated
View File

@@ -1,42 +0,0 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"async-validator": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.12.2.tgz",
"integrity": "sha512-57EETfCPFiB7M4QscvQzWSGNsmtkjjzZv318SK1CBlstk+hycV72ocjriMOOM48HjvmoAoJGpJNjC7Z76RlnZA=="
},
"core-js": {
"version": "2.6.11",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
"integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg=="
},
"deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
"integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
},
"popper.js": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-0.6.4.tgz",
"integrity": "sha1-GDfEdgr1TSuyC2b5wJuSmT2Exik="
},
"uview": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/uview/-/uview-0.1.0.tgz",
"integrity": "sha1-tASc8q1kE1430huAdCtjeoLl7yo=",
"requires": {
"async-validator": "^1.7.1",
"core-js": "^2.4.1",
"deepmerge": "^1.5.0",
"popper.js": "^0.6.4"
}
},
"xmldom": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.3.0.tgz",
"integrity": "sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g=="
}
}
}

View File

@@ -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"
} }
@@ -36,21 +35,22 @@
} }
}, },
{
"path": "pages/navigation/point/point-mall",
"style": {
"navigationBarTitleText": "积分商城",
"enablePullDownRefresh": true
}
},
{ {
"path": "pages/navigation/search/searchPage", "path": "pages/navigation/search/searchPage",
"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"
}
} }
} }
}, { }, {
@@ -341,12 +341,23 @@
{ {
"root": "pages/product", "root": "pages/product",
"pages": [{ "pages": [{
"path": "shopPage", "path": "shopPage",
"style": { "style": {
"navigationBarTitleText": "详情展示", "navigationBarTitleText": "",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },{
"path": "licencePhoto",
"style": {
"navigationBarTitleText": "营业执照"
}
},{
"path": "shopPageGoods",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
},
{ {
"path": "goods", "path": "goods",
"style": { "style": {
@@ -440,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": "限时抢购",
@@ -470,13 +474,6 @@
"bounce": "none" "bounce": "none"
} }
} }
}, {
"path": "recommend",
"style": {
"navigationBarTitleText": "人气推荐",
"navigationStyle": "custom"
}
},{ },{
"path": "lives", "path": "lives",
"style": { "style": {
@@ -497,6 +494,25 @@
"navigationStyle": "custom", "navigationStyle": "custom",
"navigationBarTextStyle": "white" "navigationBarTextStyle": "white"
}
},{
"path": "bargain/log",
"style": {
"navigationBarTitleText": "砍价记录"
}
},{
"path": "point/detail",
"style": {
"navigationStyle": "custom",
"navigationBarTextStyle": "white"
}
},{
"path": "point/pointList",
"style": {
"navigationBarTitleText": "积分商城"
} }
} }
@@ -510,16 +526,8 @@
"style": { "style": {
"navigationBarTitleText": "我的优惠券", "navigationBarTitleText": "我的优惠券",
"app-plus": { "app-plus": {
"bounce": "coupon/none", "bounce": "coupon/none"
"titleNView": {
"padding-right": "12",
"buttons": [{
"fontSrc": "/static/font/iconfont/iconfont.ttf",
"text": "\ue608",
"fontSize": "20",
"color": "#FFFFFF"
}]
}
} }
} }
}, },
@@ -540,19 +548,8 @@
"path": "coupon/couponCenter", "path": "coupon/couponCenter",
"style": { "style": {
"navigationBarTitleText": "领券中心", "navigationBarTitleText": "领券中心",
"enablePullDownRefresh": true, "enablePullDownRefresh": true
"app-plus": {
"bounce": "none",
"titleNView": {
"padding-right": "12",
"buttons": [{
"fontSrc": "/static/font/iconfont/iconfont.ttf",
"text": "\ue608",
"fontSize": "20",
"color": "#FFFFFF"
}]
}
}
} }
}, },
{ {
@@ -746,12 +743,6 @@
"text": "分类" "text": "分类"
}, },
// {
// "pagePath": "pages/navigation/point/point-mall",
// "iconPath": "static/tabbar/point-mall.png",
// "selectedIconPath": "static/tabbar/point-mall-s.png",
// "text": "积分商城"
// },
{ {
"pagePath": "pages/tabbar/cart/cartList", "pagePath": "pages/tabbar/cart/cartList",
"iconPath": "static/tabbar/cart.png", "iconPath": "static/tabbar/cart.png",

View File

@@ -1,9 +1,12 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<u-tabs :list="list" :is-scroll="false" :active-color="lightColor" :current="current" @change="(i)=>{current = i}">
</u-tabs>
<div class="empty" v-if="couponsList.length <= 0"> <div class="empty" v-if="couponsList.length <= 0">
<u-empty text="暂无优惠券" mode="coupon"></u-empty> <u-empty text="暂无优惠券" mode="coupon"></u-empty>
</div> </div>
<view class="coupon-item" v-for="(item, index) in couponsList" :key="index" v-if="item.memberCouponStatus == 'NEW'"> <view class="coupon-item" v-for="(item, index) in couponsList" :key="index" >
<view class="left"> <view class="left">
<view class="wave-line"> <view class="wave-line">
<view class="wave" v-for="(item, index) in 12" :key="index"></view> <view class="wave" v-for="(item, index) in 12" :key="index"></view>
@@ -19,29 +22,40 @@
<view class="circle circle-bottom"></view> <view class="circle circle-bottom"></view>
</view> </view>
<view class="right"> <view class="right">
<view> <view class="desc">
<view v-if="item.scopeType"> <view v-if="item.scopeType">
<span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span> <span v-if="item.scopeType == 'ALL' && item.id == 'platform'">全平台</span>
<span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span> <span v-if="item.scopeType == 'PORTION_CATEGORY'">仅限品类</span>
<view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view> <view v-else>{{ item.storeName == 'platform' ? '全平台' :item.storeName+'店铺' }}使用</view>
</view> </view>
<view>有效期至{{item.endTime}}</view> <view class="reason" v-if="item.reason">{{item.reason}}</view>
<view class="end-time">有效期至:{{item.endTime}}</view>
</view> </view>
<view class="receive" @click="clickWay(item)"> <view class="receive" v-if="current ==0" @click="clickWay(item)">
<text>立即</text><br /> <text>立即</text><br />
<text>使用</text> <text>使用</text>
</view> </view>
<view class="bg-quan"> </view> <view class="bg-quan"></view>
</view> </view>
</view> </view>
</div> </div>
</template> </template>
<script> <script>
import { useCoupon, getMemberCanUse } from "@/api/trade.js"; import { useCoupon } from "@/api/trade.js";
export default { export default {
data() { data() {
return { return {
lightColor: this.$lightColor,
current: 0,
list: [
{
name: "可用优惠券",
},
{
name: "不可用优惠券",
},
],
couponsList: [], //优惠券集合 couponsList: [], //优惠券集合
params: { params: {
//传参 //传参
@@ -55,36 +69,30 @@ export default {
routerVal: "", //上级传参 routerVal: "", //上级传参
}; };
}, },
/** onLoad(options){
* 赋值 this.routerVal = options
*/
onLoad(val) {
this.routerVal = val;
this.params.scopeId = val.skuId;
this.params.storeId = val.storeId;
}, },
watch: {
current(val) {
console.log(this.$store.state.cantUseCoupons);
val == 0
? (this.couponsList = this.$store.state.canUseCoupons)
: (this.couponsList = this.$store.state.cantUseCoupons);
},
},
mounted() { mounted() {
uni.getStorage({ this.init();
key: "totalPrice",
success: (res) => {
this.params.totalPrice = res.data;
this.getCoupons();
},
});
}, },
methods: { methods: {
/** /**
* 取优惠券数量 * 从vuex中拿取优惠券信息
*/ */
getCoupons() { init() {
getMemberCanUse(this.params).then((res) => { this.couponsList = this.$store.state.canUseCoupons;
if (res.data.success) {
this.couponsList = res.data.result.records;
}
});
}, },
/** /**
* 领取优惠券 * 领取优惠券
*/ */
@@ -109,6 +117,20 @@ export default {
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.desc {
height: 220rpx;
flex: 2;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.end-time,
.reason {
color: #999;
line-height: 1.5;
font-size: 24rpx;
}
.empty { .empty {
margin-top: 20px; margin-top: 20px;
text-align: center; text-align: center;
@@ -187,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;

View File

@@ -2,7 +2,8 @@
<view class="b-content"> <view class="b-content">
<view class="navbar"> <view class="navbar">
<!-- 循环出头部tab栏 --> <!-- 循环出头部tab栏 -->
<view v-for="(item, index) in navList" :key="index" class="nav-item" @click="handleTabClick(index)"><text :class="{ current: tabCurrentIndex === index }">{{ <view v-for="(item, index) in navList" :key="index" class="nav-item" @click="handleTabClick(index)"><text
:class="{ current: tabCurrentIndex === index }">{{
item.text item.text
}}</text></view> }}</text></view>
</view> </view>
@@ -11,8 +12,10 @@
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData"> <scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadData">
<!-- 空白页 --> <!-- 空白页 -->
<u-empty mode="coupon" text="暂无优惠券了" v-if="navItem.wheterEmpty"></u-empty> <u-empty mode="coupon" text="暂无优惠券了" v-if="navItem.wheterEmpty"></u-empty>
<!-- 数据 --> <!-- 数据 -->
<view v-if="navItem.dataList && coupon" class="coupon-item" :class="{ 'coupon-used': navIndex != 0 }" v-for="(coupon, index) in navItem.dataList" :key="index"> <view v-if="navItem.dataList && coupon" class="coupon-item" :class="{ 'coupon-used': navIndex != 0 }"
v-for="(coupon, index) in navItem.dataList" :key="index">
<view class="left"> <view class="left">
<view class="wave-line"> <view class="wave-line">
<view class="wave" v-for="(item, index) in 12" :key="index"></view> <view class="wave" v-for="(item, index) in 12" :key="index"></view>
@@ -47,7 +50,7 @@
<text class="text-2" v-if="coupon.used_status == 1">将过期</text> <text class="text-2" v-if="coupon.used_status == 1">将过期</text>
</view> </view>
<image class="no-icon" v-if="navIndex == 1" src="@/static/img/used.png"></image> <image class="no-icon" v-if="navIndex == 1" src="@/static/img/used.png"></image>
<image class="no-icon" v-if="navIndex == 2" src="@/pages/floor/imgs/overdue.png"></image> <image class="no-icon" v-if="navIndex == 2" src="@/static/img/overdue.png"></image>
<view class="receive" v-if="navIndex == 0" @click="useItNow(coupon)"> <view class="receive" v-if="navIndex == 0" @click="useItNow(coupon)">
<text>立即</text><br /> <text>立即</text><br />
<text>使用</text> <text>使用</text>
@@ -112,7 +115,8 @@ export default {
}; };
}, },
onLoad() { onShow() {
this.navList[this.tabCurrentIndex].dataList = [];
this.getData(); this.getData();
}, },
@@ -142,7 +146,7 @@ export default {
let index = this.tabCurrentIndex; let index = this.tabCurrentIndex;
getMemberCoupons(this.navList[index].params).then((res) => { getMemberCoupons(this.navList[index].params).then((res) => {
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
if (res.statusCode == 200) { if (res.data.success) {
let data = res.data.result.records; let data = res.data.result.records;
if (data.length == 0) { if (data.length == 0) {
if (res.data.pageNumber == 1) { if (res.data.pageNumber == 1) {
@@ -220,7 +224,7 @@ $item-color: #fff;
} }
.swiper-box { .swiper-box {
height: calc(100% - 40px); height: calc(100vh - 40px);
} }
.list-scroll-content { .list-scroll-content {

View File

@@ -1,47 +1,46 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div class="box"> <div class="box">
<div class="block block-1"> <div class="block block-1">
<image class="img" src="@/pages/cart/static/pay.png" /> <image class="img" src="@/pages/cart/static/pay.png" />
<p class="ptips">收银台</p> <p class="ptips">收银台</p>
<p class="ptips">剩余支付时间 <p class="ptips">剩余支付时间
<u-count-down :show-days="false" :show-border="true" font-size="28" color="#008ffa" <u-count-down :show-days="false" :show-border="true" font-size="28" color="#008ffa" border-color="#008ffa" ref="uCountDown" :timestamp="autoCancel"></u-count-down>
border-color="#008ffa" ref="uCountDown" :timestamp="autoCancel"></u-count-down> </p>
</p> <p class="ptips">
<p class="ptips"> 支付金额
支付金额 <span>¥{{ cashierParams.price | unitPrice }}</span>
<span>¥{{ cashierParams.price | unitPrice }}</span> </p>
</p> </div>
</div> </div>
</div> <div class="__pay_form__">
<div class="__pay_form__"> </div>
</div> <div class="block-4" v-if="cashierParams.price > 0">
<div class="block-4" v-if="cashierParams.price > 0"> <div class="payItem">支付方式</div>
<div class="payItem">支付方式</div> <div class="payItem" v-for="(item, index) in payList" :key="index">
<div class="payItem" v-for="(item, index) in payList" :key="index"> <u-row class="row">
<u-row class="row"> <div class="col1" @click="awaitPay(item, index)" size="100" style="text-align:left;">
<div class="col1" @click="awaitPay(item, index)" size="100" style="text-align:left;"> <div v-if="item == 'ALIPAY'">
<div v-if="item == 'ALIPAY'"> <u-icon class="method_icon" name="zhifubao-circle-fill" color="#008ffa" size="80"></u-icon>
<u-icon class="method_icon" name="zhifubao-circle-fill" color="#008ffa" size="80"></u-icon> <span class="method_name">支付宝</span>
<span class="method_name">支付宝</span> </div>
</div> <div v-if="item == 'WECHAT'">
<div v-if="item == 'WECHAT'"> <u-icon class="method_icon" name="weixin-circle-fill" color="#00c98b" size="80"></u-icon>
<u-icon class="method_icon" name="weixin-circle-fill" color="#00c98b" size="80"></u-icon> <span class="method_name">微信</span>
<span class="method_name">微信</span> </div>
</div> <div v-if="item == 'WALLET'">
<div v-if="item == 'WALLET'"> <u-icon class="method_icon" name="red-packet-fill" color="#dd6161" size="80"></u-icon>
<u-icon class="method_icon" name="red-packet-fill" color="#dd6161" size="80"></u-icon> <span class="method_name">余额支付(当前余额¥{{ walletValue | unitPrice }})</span>
<span class="method_name">余额支付(当前余额¥{{ walletValue | unitPrice }})</span> </div>
</div> </div>
</div> <div class="col3" @click="awaitPay(item)" textAlign="right">
<div class="col3" @click="awaitPay(item)" textAlign="right"> <u-icon size="26" color="#b1b1b1" name="arrow-right"></u-icon>
<u-icon size="26" color="#b1b1b1" name="arrow-right"></u-icon> </div>
</div> </u-row>
</u-row> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import * as API_Trade from "@/api/trade"; import * as API_Trade from "@/api/trade";
@@ -152,6 +151,8 @@
parms.clientType = this.paymentType; parms.clientType = this.paymentType;
API_Trade.getCashierData(parms).then((res) => { API_Trade.getCashierData(parms).then((res) => {
if(res.data.success){
this.cashierParams = res.data.result; this.cashierParams = res.data.result;
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
@@ -160,8 +161,6 @@
}); });
// #endif // #endif
// #ifndef MP-WEIXIN // #ifndef MP-WEIXIN
if(this.routerVal.recharge_sn){ if(this.routerVal.recharge_sn){
this.payList = res.data.result.support.filter((item) => { this.payList = res.data.result.support.filter((item) => {
@@ -171,11 +170,33 @@
else{ else{
this.payList = res.data.result.support; this.payList = res.data.result.support;
} }
// #ifndef APP-PLUS
//判断是否微信浏览器
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == 'micromessenger') {
this.payList = res.data.result.support.filter((item) => {
return item != "ALIPAY";
});
}
// #endif
// #endif // #endif
this.walletValue = res.data.result.walletValue; this.walletValue = res.data.result.walletValue;
this.autoCancel = this.autoCancel =
(res.data.result.autoCancel - new Date().getTime()) / 1000; (res.data.result.autoCancel - new Date().getTime()) / 1000;
}
else if(res.data.code == 32000){
setTimeout(()=>{
uni.redirectTo({
url: `/pages/order/myOrder?status=0`
});
},500)
}
}); });
}, },
@@ -239,7 +260,7 @@
}, },
fail: (e) => { fail: (e) => {
console.log(e); console.log(this);
this.exception = e; this.exception = e;
uni.showModal({ uni.showModal({
content: "支付失败,如果您已支付,请勿反复支付", content: "支付失败,如果您已支付,请勿反复支付",
@@ -277,7 +298,7 @@
WeixinJSBridge.invoke( WeixinJSBridge.invoke(
"getBrandWCPayRequest", "getBrandWCPayRequest",
response.result, response.result,
function(res) { (res) => {
if (res.err_msg == "get_brand_wcpay_request:ok") { if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示: // 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok但并不保证它绝对可靠。 //res.err_msg将在用户支付成功后返回ok但并不保证它绝对可靠。
@@ -376,108 +397,108 @@
}; };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.method_icon { .method_icon {
vertical-align: middle; vertical-align: middle;
} }
.method_name { .method_name {
font-size: 28rpx; font-size: 28rpx;
color: #999; color: #999;
padding-left: 24rpx; padding-left: 24rpx;
} }
.row { .row {
display: flex; display: flex;
width: 100%; width: 100%;
} }
/deep/ .u-row { /deep/ .u-row {
width: 100% !important; width: 100% !important;
display: flex; display: flex;
justify-content: space-between !important; justify-content: space-between !important;
} }
.method_name, .method_name,
.col1 { .col1 {
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.col1 { .col1 {
text-align: center; text-align: center;
flex: 99; flex: 99;
} }
.col3 { .col3 {
text-align: right; text-align: right;
flex: 1; flex: 1;
} }
.payItem { .payItem {
padding: 13px 25rpx; padding: 13px 25rpx;
border-top: 1px solid #f9f9f9; border-top: 1px solid #f9f9f9;
line-height: 100rpx; line-height: 100rpx;
font-size: 36rpx; font-size: 36rpx;
color: #333; color: #333;
} }
.ptips { .ptips {
font-size: 32rpx; font-size: 32rpx;
margin: 20rpx 0; margin: 20rpx 0;
color: #333; color: #333;
>span { > span {
font-size: 40rpx; font-size: 40rpx;
color: #df5a52; color: #df5a52;
margin-left: 10rpx; margin-left: 10rpx;
} }
} }
.img { .img {
width: 392rpx !important; width: 392rpx !important;
height: 296rpx !important; height: 296rpx !important;
} }
.wrapper { .wrapper {
min-height: 100vh; min-height: 100vh;
height: auto; height: auto;
background: #f9f9f9; background: #f9f9f9;
} }
.block-4 { .block-4 {
background: #fff; background: #fff;
color: $u-tips-color; color: $u-tips-color;
>p { > p {
padding: 8rpx; padding: 8rpx;
} }
} }
.box { .box {
background: #fff; background: #fff;
padding: 40rpx 0; padding: 40rpx 0;
// justify-content: center; //这个是X轴居中 // justify-content: center; //这个是X轴居中
// align-items: center; //这个是 Y轴居中 // align-items: center; //这个是 Y轴居中
} }
.block { .block {
text-align: center; text-align: center;
display: block; display: block;
width: 100%; width: 100%;
image { image {
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
} }
} }
.block-1 { .block-1 {
margin-top: 80rpx; margin-top: 80rpx;
} }
.btns { .btns {
margin: 0 20rpx; margin: 0 20rpx;
} }
</style> </style>

View File

@@ -1,410 +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] }}
<span></span>
</div>
</view>
<!-- 正常商品的价格 -->
<view class="goods-price" v-else>
<span class="goods-price-bigshow">{{
formatPrice(goodsDetail.price)[0]
}}</span>
.{{ formatPrice(goodsDetail.price)[1] }}
<span></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.id == 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'" @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.id);
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].specValueId !== 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", selectedSkuId.skuId, this.goodsDetail.id);
},
/**
* 直接购买
*/
buy(data) {
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)
)}`,
});
}
});
},
/**
* 添加到购物车或购买
*/
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 {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
return false;
}
});
} else {
// 判断是否拼团商品
if (this.buyType) {
data.cartType = "PINTUAN";
} else {
data.cartType = "BUY_NOW";
}
this.buy(data);
}
},
formatSku(list) {
// 格式化数据
let arr = [{}];
list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => {
let id = spec.specNameId;
let name = spec.specName;
let values = {
id: spec.specValueId,
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.id === values.id)
) {
arrItem.values.push(values);
}
let keys = arr.map((key) => {
return key.name;
});
if (!keys.includes(name)) {
arr.push({
id: id,
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.specValueId;
this.selectName = value.specValue;
this.selectSkuList = {
spec: value,
data: this.goodsDetail,
};
});
}
});
this.skuList = list;
},
},
mounted() {
this.formatSku(this.goodsSpec);
},
};
</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: $jd-light-color !important;
border: 2rpx solid $jd-color;
font-weight: bold;
color: $jd-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: $jd-color;
line-height: 80rpx;
display: flex;
}
.promotion-box {
line-height: 1;
display: flex;
align-items: center;
text-decoration: line-through;
color: #999;
margin-left: 10rpx;
/deep/ span {
font-size: 30rpx;
}
}
.promotion {
font-size: 30rpx;
}
.goods-price-promotionShow {
font-size: 48rpx;
}
.goods-check-skus {
font-size: 24rpx;
color: #999;
> .goods-check-skus-name {
margin-left: 4rpx;
}
> span {
color: #333;
}
}
</style>

View File

@@ -67,12 +67,12 @@ import { getGoods } from "@/api/goods.js";
import { getPinTuanShare } from "@/api/order"; import { getPinTuanShare } from "@/api/order";
import shares from "@/components/m-share/index"; import shares from "@/components/m-share/index";
import storage from "@/utils/storage.js"; import storage from "@/utils/storage.js";
import popupGoods from "./popup/goods"; //购物车商品的模块 import popupGoods from "@/components/m-buy/goods"; //购物车商品的模块
export default { export default {
data() { data() {
return { return {
flage:false, //判断接口是否正常请求 flage: false, //判断接口是否正常请求
addr: { addr: {
id: "", id: "",
}, },
@@ -140,7 +140,7 @@ export default {
async init(sn, sku) { async init(sn, sku) {
let res = await getPinTuanShare(sn, sku); let res = await getPinTuanShare(sn, sku);
if (res.data.success && res.data.result.promotionGoods) { if (res.data.success && res.data.result.promotionGoods) {
this.flage = true this.flage = true;
this.data = res.data.result; this.data = res.data.result;
this.selectedGoods = res.data.result.promotionGoods; this.selectedGoods = res.data.result.promotionGoods;
let endTime = Date.parse( let endTime = Date.parse(
@@ -172,7 +172,10 @@ export default {
} else { } else {
this.isMaster = false; this.isMaster = false;
// 获取商品详情 // 获取商品详情
this.getGoodsDetail(this.routers.sku, this.routers.goodsId); this.getGoodsDetail({
id: this.routers.sku,
goodsId: this.routers.goodsId,
});
} }
// 获取当前商品是否已经购买 // 获取当前商品是否已经购买
@@ -183,15 +186,16 @@ export default {
isBuy.length != 0 ? (this.isBuy = true) : (this.isBuy = false); isBuy.length != 0 ? (this.isBuy = true) : (this.isBuy = false);
} }
} else { } else {
uni.showToast({ uni.showToast({
title: '当前拼团单有误!请联系管理员重试', title: "当前拼团单有误!请联系管理员重试",
duration: 2000, duration: 2000,
icon:"none" icon: "none",
}); });
} }
}, },
// 获取商品详情 // 获取商品详情
getGoodsDetail(id, goodsId) { getGoodsDetail(val) {
let { id, goodsId } = val;
uni.showLoading({ uni.showLoading({
title: "加载中", title: "加载中",
mask: true, mask: true,

View File

@@ -7,36 +7,24 @@
<div class="pay-btns"> <div class="pay-btns">
<div v-show="!from" @click="checkOrder">查看{{this.orderType == "RECHARGE" ? '余额' : '订单'}}</div> <div v-show="!from" @click="checkOrder">查看{{this.orderType == "RECHARGE" ? '余额' : '订单'}}</div>
<div @click="navigateTo('/pages/tabbar/home/index', 'switch')">回到首页</div> <div @click="navigateTo('/pages/tabbar/home/index', 'switch')">回到首页</div>
</div> </div>
</div> </div>
<div class="pay-box"> <div class="pay-box">
<div class="pay-tag-box"> <div class="pay-tag-box">
<h2>订单支付成功!</h2> <h2>订单支付成功!</h2>
<div class="pay-item"> <div class="pay-item">
<div> <div>
支付方式 支付方式
</div> </div>
<div>{{paymentMethod | paymentTypeFilter}}</div> <div>{{paymentMethod | paymentTypeFilter}}</div>
</div> </div>
</div> </div>
<!-- #ifdef MP-WEIXIN -->
<div class="subscribe flex">
<div>订阅订单状态</div>
<div>
<u-switch size="50" :disabled="checked" :active-color="activeColor" @change="changeStatus" v-model="checked"></u-switch>
</div>
</div>
<!-- #endif -->
</div> </div>
<goodsRecommend /> <goodsRecommend />
</div> </div>
</template> </template>
<script> <script>
import { getWeChatMpMessage } from "@/api/message.js";
import goodsRecommend from "@/components/m-goods-recommend"; import goodsRecommend from "@/components/m-goods-recommend";
export default { export default {
data() { data() {
@@ -48,7 +36,6 @@ export default {
payPrice: 0, payPrice: 0,
goodsList: [], goodsList: [],
activeColor: this.$mainColor, activeColor: this.$mainColor,
}; };
}, },
components: { components: {
@@ -73,6 +60,7 @@ export default {
this.from = options.from || ""; this.from = options.from || "";
this.payPrice = options.payPrice || 0; this.payPrice = options.payPrice || 0;
this.orderType = options.orderType; this.orderType = options.orderType;
// this.sendMessage()
}, },
methods: { methods: {
checkOrder() { checkOrder() {
@@ -95,30 +83,6 @@ export default {
} }
}, },
sendMessage() {
//订阅消息
//#ifdef MP-WEIXIN
getWeChatMpMessage().then((res) => {
var message = res.data.result;
var templateid = message.map((item) => item.code);
uni.requestSubscribeMessage({
tmplIds: templateid,
success: (res) => {
for (let key in res) {
if (res[key] == "reject") {
this.checked = false;
}
}
},
fail: (res) => {
uni.removeStorageSync("acceptSubscribeMessage");
this.checked = false;
},
});
});
//#endif
},
navigateTo(url, type) { navigateTo(url, type) {
if (type === "switch") { if (type === "switch") {
uni.switchTab({ uni.switchTab({

View File

@@ -28,7 +28,8 @@
<div class="saveBtn" @click="save">保存</div> <div class="saveBtn" @click="save">保存</div>
</u-form> </u-form>
<m-city :provinceData="list" headTitle="区域选择" ref="cityPicker" @funcValue="getpickerParentValue" pickerSize="4"></m-city> <m-city :provinceData="list" headTitle="区域选择" ref="cityPicker" @funcValue="getpickerParentValue" pickerSize="4">
</m-city>
<uniMap v-if="mapFlage" @close="closeMap" @callback="callBackAddress" /> <uniMap v-if="mapFlage" @close="closeMap" @callback="callBackAddress" />
</div> </div>
@@ -149,15 +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) {
if (this.routerVal.type == "order") { uni.navigateBack();
uni.redirectTo({
url: `/pages/mine/address/address?way=${this.routerVal.way}`,
});
} else {
uni.redirectTo({
url: `/pages/mine/address/addressManage`,
});
}
} }
}); });
} else { } else {
@@ -198,8 +191,8 @@ export default {
return _child.id == item.id; return _child.id == item.id;
}); });
this.form.lat = _town[0].center.split(",")[0]; this.form.lat = _town[0].center.split(",")[1];
this.form.lon = _town[0].center.split(",")[1]; this.form.lon = _town[0].center.split(",")[0];
} }
}); });
}, },

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="address"> <view class="address">
<u-empty class="empty" v-if="empty" text="暂无收货地址" mode="address"></u-empty> <u-empty class="empty" v-if="addressList.length == 0" text="暂无收货地址" mode="address"></u-empty>
<view class="list" v-else> <view class="list" v-else>
<view class="item c-content" v-for="(item, index) in addressList" :key="index"> <view class="item c-content" v-for="(item, index) in addressList" :key="index">
<view class="basic" @click="selectAddressData(item)"> <view class="basic" @click="selectAddressData(item)">
@@ -50,7 +50,6 @@ export default {
return { return {
addressList: [], //地址列表 addressList: [], //地址列表
showAction: false, //是否显示下栏框 showAction: false, //是否显示下栏框
empty: false, //是否为空
removeList: [ removeList: [
{ {
text: "确定", text: "确定",
@@ -67,7 +66,11 @@ export default {
}, },
}; };
}, },
onPullDownRefresh() {
//下拉刷新
this.addressList = [];
this.getAddressList();
},
onLoad: function (val) { onLoad: function (val) {
this.routerVal = val; this.routerVal = val;
}, },
@@ -76,19 +79,12 @@ export default {
this.getAddressList(); this.getAddressList();
}, },
onHide() {}, onHide() {},
onBackPress(e) {
uni.redirectTo({
url: "/pages/order/fillorder?way=" + this.routerVal.way,
});
return true;
},
methods: { methods: {
async selectAddressData(val) { async selectAddressData(val) {
await API_Trade.setAddressId(val.id, this.routerVal.way); await API_Trade.setAddressId(val.id, this.routerVal.way);
uni.redirectTo({ uni.navigateBack({
url: `/pages/order/fillorder?way=${this.routerVal.way}`, delta: 1,
}); });
}, },
//获取地址列表 //获取地址列表
@@ -99,18 +95,11 @@ export default {
this.params.pageNumber, this.params.pageNumber,
this.params.pageSize this.params.pageSize
).then((res) => { ).then((res) => {
res.data.result.records.forEach((item) => {
if (res.data.result.records.length == 0) { item.consigneeAddressPath = item.consigneeAddressPath.split(",");
this.empty = true; });
} else { this.addressList = res.data.result.records;
res.data.result.records.forEach((item) => { console.log(this.addressList);
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
});
this.$set(this, "addressList", res.data.result.records);
}
uni.hideLoading(); uni.hideLoading();
}); });
@@ -139,7 +128,6 @@ export default {
}, },
//新建。编辑地址 //新建。编辑地址
addAddress(id) { addAddress(id) {
if (id) { if (id) {
uni.navigateTo({ uni.navigateTo({
url: url:
@@ -177,5 +165,5 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './address.scss'; @import "./address.scss";
</style> </style>

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="address"> <view class="address">
<u-empty class="empty" v-if="empty" text="暂无收货地址" mode="address"></u-empty> <u-empty class="empty" v-if="this.addressList == 0" text="暂无收货地址" mode="address"></u-empty>
<view class="list" v-else> <view class="list" >
<view class="item c-content" v-for="(item, index) in addressList" :key="index"> <view class="item c-content" v-for="(item, index) in addressList" :key="index">
<view class="basic"> <view class="basic">
<text>{{ item.name }}</text> <text>{{ item.name }}</text>
@@ -50,7 +50,7 @@ export default {
return { return {
addressList: [], //地址列表 addressList: [], //地址列表
showAction: false, //是否显示下栏框 showAction: false, //是否显示下栏框
empty: false, //是否为空
removeList: [ removeList: [
{ {
text: "确定", text: "确定",
@@ -77,10 +77,16 @@ export default {
onLoad: function (val) { onLoad: function (val) {
this.routerVal = val; this.routerVal = val;
}, },
onPullDownRefresh() {
//下拉刷新
this.addressList = [];
this.getAddressList();
},
/** /**
* 进入页面检测当前账户是否登录 * 进入页面检测当前账户是否登录
*/ */
onShow() { onShow() {
let that = this;
if (this.$options.filters.isLogin("auth")) { if (this.$options.filters.isLogin("auth")) {
this.getAddressList(); this.getAddressList();
} else { } else {
@@ -90,9 +96,7 @@ export default {
confirmColor: this.$lightColor, confirmColor: this.$lightColor,
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) {
uni.navigateTo({ that.$options.filters.navigateToLogin();
url: "/pages/passport/login",
});
} else if (res.cancel) { } else if (res.cancel) {
uni.navigateBack(); uni.navigateBack();
} }
@@ -108,14 +112,11 @@ export default {
this.params.pageNumber, this.params.pageNumber,
this.params.pageSize this.params.pageSize
).then((res) => { ).then((res) => {
if (res.data.result.records.length == 0) { res.data.result.records.forEach((item) => {
this.empty = true; item.consigneeAddressPath = item.consigneeAddressPath.split(",");
} else { });
res.data.result.records.forEach((item) => { this.addressList = res.data.result.records;
item.consigneeAddressPath = item.consigneeAddressPath.split(",");
});
this.addressList = res.data.result.records;
}
uni.hideLoading(); uni.hideLoading();
}); });
}, },
@@ -169,5 +170,5 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './address.scss'; @import "./address.scss";
</style> </style>

View File

@@ -26,7 +26,7 @@ export default {
walletNum: 0, walletNum: 0,
}; };
}, },
async mounted() { async onShow() {
if (this.$options.filters.isLogin("auth")) { if (this.$options.filters.isLogin("auth")) {
let result = await getUserWallet(); //预存款 let result = await getUserWallet(); //预存款
this.walletNum = result.data.result.memberWallet; this.walletNum = result.data.result.memberWallet;
@@ -36,9 +36,8 @@ export default {
duration: 3000, duration: 3000,
title: "请先登录!", title: "请先登录!",
}); });
uni.redirectTo({
url: "/pages/passport/login", this.$options.filters.navigateToLogin("redirectTo");
});
} }
}, },
methods: { methods: {

View File

@@ -12,6 +12,10 @@
<view @click="handleAll" :style="{ color: $mainColor }">全部</view> <view @click="handleAll" :style="{ color: $mainColor }">全部</view>
<view style="font-size: 24rpx; color: #999">可提现金额<span>{{ walletNum | unitPrice }}</span></view> <view style="font-size: 24rpx; color: #999">可提现金额<span>{{ walletNum | unitPrice }}</span></view>
</view> </view>
</view>
<view class="tips">
最低提现金额为1.00
</view> </view>
</view> </view>
@@ -19,7 +23,7 @@
</view> </view>
</template> </template>
<script> <script>
import { getUserWallet,withdrawalApply } from "@/api/members"; import { getUserWallet, withdrawalApply } from "@/api/members";
export default { export default {
data() { data() {
return { return {
@@ -67,4 +71,8 @@ export default {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import "./style.scss"; @import "./style.scss";
.tips {
font-size: 24rpx;
color: #999;
}
</style> </style>

View File

@@ -56,9 +56,6 @@ export default {
type: 0, type: 0,
routers: "", routers: "",
achParams: { achParams: {
distributionId: (this.routers && this.routers.id) || "", //分销商id
distributionName: (this.routers && this.routers.name) || "", //分销商名称
distributionOrderStatus: "", //分销商订单状态
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
}, },
@@ -72,15 +69,14 @@ export default {
title: title, //这是修改后的导航栏文字 title: title, //这是修改后的导航栏文字
}); });
this.routers = option; this.routers = option;
this.type = option.type;
option.type == 0 ? this.achievement() : this.history(); option.type == 0 ? this.achievement() : this.history();
}, },
mounted() {}, mounted() {},
onReachBottom() { onReachBottom() {
this.status = "loading"; this.status = "loading";
this.params.pageNumber++; this.type == 0 ? this.achParams.pageNumber++ : this.params.pageNumber++;
this.type == 0 ? this.achievement() : this.history();
this.type == 1 ? this.history() : this.achievement();
}, },
methods: { methods: {
// 业绩 // 业绩

View File

@@ -174,9 +174,7 @@ export default {
onLoad(options) { onLoad(options) {
this.routers = options; this.routers = options;
}, },
watch: { watch: {},
showFlag(val) {},
},
onShow() { onShow() {
this.goodsList = []; this.goodsList = [];
this.init(); this.init();
@@ -224,7 +222,7 @@ export default {
*/ */
handleNavgationGoods(val) { handleNavgationGoods(val) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.id}`, url: `/pages/product/goods?id=${val.skuId}&goodsId=${val.goodsId}`,
}); });
}, },
@@ -273,12 +271,7 @@ export default {
// 选择商品 // 选择商品
handleClickGoods(val) { handleClickGoods(val) {
uni.showLoading({
title: "加载中",
mask: true,
});
checkedDistributionGoods({ id: val.id, checked: true }).then((res) => { checkedDistributionGoods({ id: val.id, checked: true }).then((res) => {
uni.hideLoading();
if (res.data.success) { if (res.data.success) {
uni.showToast({ uni.showToast({
title: "已添加到我的选品库", title: "已添加到我的选品库",
@@ -295,12 +288,7 @@ export default {
}, },
init() { init() {
uni.showLoading({
title: "加载中",
});
distributionGoods(this.params).then((res) => { distributionGoods(this.params).then((res) => {
uni.hideLoading();
if (res.data.success && res.data.result.records.length >= 1) { if (res.data.success && res.data.result.records.length >= 1) {
res.data.result.records.forEach((item) => { res.data.result.records.forEach((item) => {
this.$set(item, "___selected", false); this.$set(item, "___selected", false);
@@ -466,7 +454,7 @@ export default {
overflow: hidden; overflow: hidden;
} }
> .-item-price { > .-item-price {
color: $jd-color; color: $price-color;
> span { > span {
font-size: 36rpx; font-size: 36rpx;
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<div v-html="res.content"></div> <u-parse v-html="res.content"></u-parse>
</div> </div>
</template> </template>

View File

@@ -30,11 +30,8 @@
</template> </template>
<script> <script>
import uniSteps from "@/components/uni-steps/uni-steps.vue";
import { getExpress } from "@/api/trade.js"; import { getExpress } from "@/api/trade.js";
export default { export default {
components: { uniSteps },
data() { data() {
return { return {
express: "", express: "",

View File

@@ -11,10 +11,11 @@
<view v-if="tabCurrentIndex == 0" class="tab-content"> <view v-if="tabCurrentIndex == 0" class="tab-content">
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore"> <scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore">
<!-- 空白页 --> <!-- 空白页 -->
<u-empty text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty> <u-empty style="margin-top:40rpx;" text="暂无收藏商品数据" mode="favor" v-if="goodsEmpty"></u-empty>
<!-- 商品展示数据 --> <!-- 商品展示数据 -->
<u-swipe-action @open="openLeftChange(item,index,'goods')" :show="item.selected" btn-width="180" :options="LeftOptions" v-else v-for="(item,index) in goodList" <u-swipe-action @open="openLeftChange(item,index,'goods')" :show="item.selected" btn-width="180"
@click="clickGoodsSwiperAction(item,index)" :index="index" :key="index"> :options="LeftOptions" v-else v-for="(item,index) in goodList" @click="clickGoodsSwiperAction(item,index)"
:index="index" :key="index">
<view class="goods" @click="goGoodsDetail(item)"> <view class="goods" @click="goGoodsDetail(item)">
<u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit"> <u-image width="131rpx" height="131rpx" :src="item.image" mode="aspectFit">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
@@ -34,20 +35,22 @@
<view v-else class="tab-content"> <view v-else class="tab-content">
<scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore"> <scroll-view class="list-scroll-content" scroll-y @scrolltolower="loadMore">
<!-- 空白页 --> <!-- 空白页 -->
<u-empty text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty> <u-empty style="margin-top:40rpx;" text="暂无收藏店铺数据" mode="favor" v-if="storeEmpty"></u-empty>
<!-- 店铺展示数据 --> <!-- 店铺展示数据 -->
<u-swipe-action @open="openLeftChange(item,'store')" :show="item.selected" btn-width="180" :options="LeftOptions" v-else v-for="(item,index) in storeList" :key="index" <u-swipe-action @open="openLeftChange(item,'store')" :show="item.selected" btn-width="180"
:options="LeftOptions" v-else v-for="(item,index) in storeList" :key="index"
@click="clickstoreSwiperAction(item)"> @click="clickstoreSwiperAction(item)">
<view class="store" @click="gostoreMainPage(item.storeId)"> <view class="store" @click="gostoreMainPage(item.id)">
<view class="intro"> <view class="intro">
<view class="store-logo"> <view class="store-logo">
<u-image width="102rpx" height="102rpx" :src="item.logo" :alt="item.storeName" mode="aspectFit"> <u-image width="102rpx" height="102rpx" :src="item.storeLogo" :alt="item.storeName" mode="aspectFit">
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
</u-image> </u-image>
</view> </view>
<view class="store-name"> <view class="store-name">
<view>{{item.storeName}}</view> <view>{{item.storeName}}</view>
<u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated" text="自营" mode="plain" shape="circle" /> <u-tag size="mini" type="error" :color="$mainColor" v-if="item.selfOperated" text="自营" mode="plain"
shape="circle" />
</view> </view>
<view class="store-collect"> <view class="store-collect">
<view>进店逛逛</view> <view>进店逛逛</view>
@@ -133,7 +136,6 @@ export default {
*/ */
clickGoodsSwiperAction(val) { clickGoodsSwiperAction(val) {
deleteGoodsCollection(val.skuId).then((res) => { deleteGoodsCollection(val.skuId).then((res) => {
if (res.statusCode == 200) { if (res.statusCode == 200) {
this.storeList = []; this.storeList = [];
this.goodList = []; this.goodList = [];
@@ -159,7 +161,6 @@ export default {
*/ */
tabClick(index) { tabClick(index) {
this.tabCurrentIndex = index; this.tabCurrentIndex = index;
}, },
/** /**

View File

@@ -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: {
/** /**
* 导航到店铺 * 导航到店铺

View File

@@ -4,7 +4,7 @@
<image src="/static/pointTrade/point_bg_1.png" mode=""></image> <image src="/static/pointTrade/point_bg_1.png" mode=""></image>
<image class="point-img" src="/static/pointTrade/tradehall.png" /> <image class="point-img" src="/static/pointTrade/tradehall.png" />
<view class="position-point"> <view class="position-point">
<view class="apply-point" @click="goIntro"><text>积分介绍</text></view>
</view> </view>
</view> </view>
@@ -25,7 +25,7 @@
<view>{{ item.content }}</view> <view>{{ item.content }}</view>
<view>{{ item.createTime}}</view> <view>{{ item.createTime}}</view>
</view> </view>
<view><span>{{item.pointType == "1" ? '+' : '-'}}</span>{{ item.variablePoint }}</view> <view><span>{{item.pointType == "INCREASE" ? '+' : '-'}}</span>{{ item.variablePoint }}</view>
</view> </view>
<uni-load-more :status="count.loadStatus"></uni-load-more> <uni-load-more :status="count.loadStatus"></uni-load-more>
</div> </div>

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="edition-intro"> <view class="edition-intro">
<image src="https://lilishop-oss.oss-cn-beijing.aliyuncs.com/4c864e133c2944efad1f7282ac8a3b9e.png" class="logo" /> <image :src="config.logo" class="logo" />
<h1> {{config.name}}</h1> <h1> {{config.name}}</h1>
<view class='version'> <view class='version'>
<!-- #ifdef APP-PLUS --> <!-- #ifdef APP-PLUS -->
@@ -24,11 +24,11 @@
</u-cell-group> </u-cell-group>
<view class="intro"> <view class="intro">
<view>客服热线13161366885</view> <view>{{config.customerServiceMobile ? `客服热线:${config.customerServiceMobile}` : ``}}</view>
<view style="margin:20rpx 0 0 0;">客服邮箱lili@lili.com</view> <view style="margin:20rpx 0 0 0;">{{config.customerServiceEmail ? `客服邮箱:${config.customerServiceEmail}` : ``}}</view>
<view> <view>
<view style="margin:20rpx 0; color:#003a8c;" @click="navigateTo('/pages/mine/help/tips?type=user')">lili商城用户协议</view> <view style="margin:20rpx 0; color:#003a8c;" @click="navigateTo('/pages/mine/help/tips?type=user')">{{config.name}}用户协议</view>
<view>CopyRight @{{config.name}} </view> <view>CopyRight @{{config.name}} </view>
</view> </view>
</view> </view>
@@ -54,6 +54,7 @@ export default {
}; };
}, },
onLoad() { onLoad() {
// #ifdef APP-PLUS
const platform = uni.getSystemInfoSync().platform; const platform = uni.getSystemInfoSync().platform;
/** /**
* 获取是否是安卓 * 获取是否是安卓
@@ -72,6 +73,7 @@ export default {
version: inf.version, version: inf.version,
}; };
}); });
// #endif
}, },
methods: { methods: {

View File

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

View File

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

View File

@@ -9,17 +9,17 @@
<u-form :model="codeForm" class="form" ref="validateCodeForm"> <u-form :model="codeForm" class="form" ref="validateCodeForm">
<view v-if="!validateFlage"> <view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile"> <u-form-item label-width="120" label="手机号" prop="mobile">
<u-input v-model="codeForm.mobile" placeholder="请输入您的手机号" /> <u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item> </u-form-item>
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码"> <u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
<u-input v-model="codeForm.code" placeholder="请输入验证码" /> <u-input v-model="codeForm.code" placeholder="请输入验证码" />
<u-verification-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start" ref="uCode" @change="codeChange"></u-verification-code> <u-verification-code unique-key="page-edit" :seconds="seconds" @end="end" @start="start" ref="uCode" @change="codeChange"></u-verification-code>
<view @tap="getCode" class="text-tips">{{ tips }}</view> <view @tap="getCode" class="text-tips">{{ tips }}</view>
</u-form-item> </u-form-item>
<view class="submit" @click="validatePhone">验证</view> <view class="submit" @click="validatePhone">验证</view>
<myVerification keep-running @send="verification" class="verification" ref="verification" business="LOGIN" /> <myVerification keep-running @send="verification" class="verification" ref="verification" business="FIND_USER" />
</view> </view>
<view v-if="validateFlage"> <view v-if="validateFlage">
<u-form-item label-width="120" label="旧密码"> <u-form-item label-width="120" label="旧密码">
@@ -40,7 +40,7 @@
<script> <script>
import { sendMobile, resetByMobile, modifyPass } from "@/api/login"; import { sendMobile, resetByMobile, modifyPass } from "@/api/login";
import storage from "@/utils/storage.js";
import { md5 } from "@/utils/md5.js"; // md5 import { md5 } from "@/utils/md5.js"; // md5
import myVerification from "@/components/verification/verification.vue"; //验证 import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js"; import uuid from "@/utils/uuid.modified.js";
@@ -108,7 +108,7 @@ export default {
uni.showLoading({ uni.showLoading({
title: "正在获取验证码", title: "正在获取验证码",
}); });
sendMobile(this.codeForm.mobile).then((res) => { sendMobile(this.codeForm.mobile, "FIND_USER").then((res) => {
uni.hideLoading(); uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖 // 这里此提示会被this.start()方法中的提示覆盖
if (res.data.code == 200) { if (res.data.code == 200) {
@@ -161,8 +161,7 @@ export default {
if (valid) { if (valid) {
resetByMobile(this.codeForm).then((res) => { resetByMobile(this.codeForm).then((res) => {
if (res.data.success) { if (res.data.success) {
storage.setAccessToken(res.data.result.accessToken); this.validateFlage = !this.validateFlage;
storage.setRefreshToken(res.data.result.refreshToken);
// 登录成功 // 登录成功
uni.showToast({ uni.showToast({
title: "验证成功!", title: "验证成功!",
@@ -238,6 +237,9 @@ page {
padding: 80rpx 0; padding: 80rpx 0;
border-radius: 20rpx; border-radius: 20rpx;
} }
.submit {
background: $light-color;
}
.box-tips { .box-tips {
margin: 0 72rpx; margin: 0 72rpx;
} }

View File

@@ -17,13 +17,10 @@ export default {
methods: { methods: {
navigateTo(url) { navigateTo(url) {
uni.navigateTo({ uni.navigateTo({
url: url + `?mobile=${this.mobile}`, url: url,
}); });
}, },
}, },
onLoad(option) {
this.mobile = option.mobile;
},
}; };
</script> </script>

View File

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

View File

@@ -1,26 +1,30 @@
<template> <template>
<view class="sign-in"> <view class="sign-in">
<view class="signin-btn-con"> <view class="date-card">
<div class="circle-box"> <div class="box">
<div class="cricle" @click="signIn()"> <div class="circle-box">
<span v-if="!ifSign" :class="{ active: signFlag || ifSign }">签到</span> <div class="cricle" @click="signIn()">
<span v-else :class="{ active: signFlag || ifSign }" :style="ifSign ? 'transform: rotateY(0deg);' : ''">已签</span> <span v-if="!ifSign" :class="{ active: signFlag || ifSign }">签到</span>
<span v-else :class="{ active: signFlag || ifSign }"
:style="ifSign ? 'transform: rotateY(0deg);' : ''">已签</span>
</div>
</div> </div>
<text class="tips">坚持每天连续签到可以获多重奖励哦</text>
</div> </div>
<text class="tips">坚持每天连续签到可以获多重奖励哦</text>
</view> </view>
<div class="date-card"> <div class="date-card">
<view class="date-con"> <view class="date-con">
<view class="date-tit"> <view class="date-tit">
<u-row style="width: 100%; justify-content: center;"> <div class="current-month">
<div style="text-align: center; " class="text">{{ currentMonth }} {{ currentYear }}</div> <div class="day">每日记录<span> ({{ currentMonth }})</span></div>
</u-row> </div>
</view> </view>
<view class="week"> <view class="week">
<text v-for="item in weekArr" :key="item.id">{{ item }}</text> <text v-for="item in weekArr" :key="item.id">{{ item }}</text>
</view> </view>
<view class="date" v-for="obj in dataObj" :key="obj.id"> <view class="date" v-for="obj in dataObj" :key="obj.id">
<view class="item" v-for="item in obj" :key="item.id" :class="item == '' ? 'hide' : ''" :animation="item == currentDay ? animationData : ''"> <view class="item" v-for="item in obj" :key="item.id" :class="item == '' ? 'hide' : ''"
:animation="item == currentDay ? animationData : ''">
<view class="just" :class="signArr.indexOf(item) != -1 ? 'active' : ''"> <view class="just" :class="signArr.indexOf(item) != -1 ? 'active' : ''">
<view class="top">{{ item }} </view> <view class="top">{{ item }} </view>
<view class="bottom"> <view class="bottom">
@@ -36,7 +40,7 @@
"> ">
<view class="top">{{ item }}</view> <view class="top">{{ item }}</view>
<view class="bottom"> <view class="bottom">
<u-icon name="checkmark" color="#ff9f28"></u-icon> <u-icon name="checkmark" :color="aiderLightColor"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -50,16 +54,7 @@
<text class="close" @click="close">×</text> <text class="close" @click="close">×</text>
</view> </view>
<view class="mask-con"> <view class="mask-con">
<view class="keep-sign"> <u-icon size="120" style="margin: 50rpx 0" :color="aiderLightColor" name="checkmark"></u-icon>
本月已连续签到
<text>{{ continuity }}</text>
</view>
<u-icon size="120" style="margin: 50rpx 0" color="#ff9f28" name="checkmark"></u-icon>
<view class="mark">
<view>获得积分</view>
<text>{{ continuityPoint }}</text>
</view>
<text class="text">连续签到可获得额外奖励哦</text> <text class="text">连续签到可获得额外奖励哦</text>
</view> </view>
</view> </view>
@@ -71,8 +66,7 @@ import { sign, signTime } from "@/api/point.js";
export default { export default {
data() { data() {
return { return {
continuity: 1, //本月连续签到天数 aiderLightColor:this.$aiderLightColor,
continuityPoint: 2, //获得的积分
signFlag: false, signFlag: false,
animationData: {}, animationData: {},
maskFlag: false, // maskFlag: false, //
@@ -115,7 +109,6 @@ export default {
this.getDate(); this.getDate();
}, },
methods: { methods: {
/** /**
* 补0 * 补0
*/ */
@@ -215,7 +208,6 @@ export default {
Number(itemVal[1]) === Number(this.currentMonthIndex) Number(itemVal[1]) === Number(this.currentMonthIndex)
) { ) {
this.signArr.push(Number(itemVal[2])); this.signArr.push(Number(itemVal[2]));
} }
if ( if (
Number(itemVal[0]) === Number(date.getFullYear()) && Number(itemVal[0]) === Number(date.getFullYear()) &&
@@ -295,70 +287,79 @@ export default {
}, },
}; };
</script> </script>
<style scoped>
page {
background: #f7f7f7;
}
</style>
<style lang="scss" scoped> <style lang="scss" scoped>
.date-card { .date-card {
padding: 0 40rpx; padding: 0 32rpx;
margin: 32rpx 0;
box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1);
} }
.tips { .tips {
margin-top: 34rpx; margin-top: 54rpx;
color: #999;
font-size: 24rpx;
letter-spacing: 1rpx;
} }
.circle-box { .circle-box {
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
border-radius: 50%; border-radius: 50%;
margin-top: 60rpx; background: $aider-light-color;
background: #ff9f28; box-shadow: 0 4rpx 24rpx 0 rgba($color: $aider-light-color, $alpha: 1);
display: flex; display: flex;
justify-content: center; //这个是X轴居中 justify-content: center; //这个是X轴居中
align-items: center; //这个是 Y轴居中 align-items: center; //这个是 Y轴居中
} }
.cricle { .cricle {
width: 160rpx; width: 160rpx;
height: 160rpx; height: 160rpx;
border-radius: 50%; border-radius: 50%;
background: #ff9f28; background: $aider-light-color;
text-align: center; text-align: center;
line-height: 160rpx; line-height: 160rpx;
color: #fff; color: #fff;
font-size: 40rpx; font-size: 40rpx;
} }
.current-month {
page { width: 100%;
background: #fff; margin: 20rpx 0;
}
.box {
display: flex;
flex-direction: column;
align-items: center;
padding:64rpx 32rpx;
background: #fff;
border-radius: 20rpx;
} }
.sign-in { .sign-in {
color: #333; color: #333;
.signin-btn-con {
width: 100%;
height: 670rpx;
background-image: linear-gradient(180deg, #ff6b35, #ff9f28, #ffcc03);
display: flex;
flex-direction: column;
align-items: center;
text {
color: #fff;
font-size: 28rpx;
font-weight: 400;
}
}
.date-con { .date-con {
background: #fff; background: #fff;
min-height: 730rpx; min-height: 730rpx;
border-radius: 0.8em; border-radius: 20rpx;
border: 1px solid #ededed;
padding: 0 28rpx; padding: 0 28rpx;
transform: translateY(-320rpx);
box-shadow: (1px 3px 5px rgba(0, 0, 0, 0.2));
} }
.day {
font-size: 36rpx;
> span {
font-size: 30rpx;
color: #999;
margin-left: 20rpx;
}
}
.date-tit { .date-tit {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: 30rpx 0; margin: 0 0 30rpx 0;
} }
.week { .week {
@@ -429,7 +430,7 @@ page {
} }
.top { .top {
color: #ff9f28; color: $aider-light-color;
} }
} }
@@ -471,7 +472,7 @@ page {
width: 540rpx; width: 540rpx;
height: 130rpx; height: 130rpx;
line-height: 130rpx; line-height: 130rpx;
background: #ff9f28; background: $aider-light-color;
color: #fff; color: #fff;
font-size: 40rpx; font-size: 40rpx;
font-weight: 500; font-weight: 500;
@@ -488,7 +489,7 @@ page {
.mask-con { .mask-con {
width: 540rpx; width: 540rpx;
height: 460rpx; height: 380rpx;
background: #fff; background: #fff;
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

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

View File

@@ -1,10 +1,9 @@
<template> <template>
<view class="content"> <view class="content">
<u-navbar :background="navObj" :is-back="false"> <u-navbar :background="navObj" :is-back="false">
<!-- mSearch组件 如果使用原样式删除组件元素--> <mSearch ref="mSearch" class="mSearch-input-box" @clickLeft="back" :mode="2" :placeholder="defaultKeyword"
@search="doSearch(false)" @confirm="doSearch(false)" @SwitchType="doSearchSwitch()" v-model="keyword"
<mSearch ref="mSearch" class="mSearch-input-box" @clickLeft="back" :mode="2" :placeholder="defaultKeyword" @search="doSearch(false)" @input="inputChange" @confirm="doSearch(false)" :isFocusVal="!isShowSeachGoods"></mSearch>
@SwitchType="doSearchSwitch()" v-model="keyword" :isFocusVal="!isShowSeachGoods"></mSearch>
</u-navbar> </u-navbar>
<view class="search-keyword" v-if="!isShowSeachGoods"> <view class="search-keyword" v-if="!isShowSeachGoods">
@@ -23,22 +22,19 @@
<view class="u-tips">热门搜索</view> <view class="u-tips">热门搜索</view>
</view> </view>
<view class="keyword keywordBox"> <view class="keyword keywordBox">
<view class="wes" v-for="(keyword, index) in hotKeywordList" @tap="doSearch(keyword)" :key="index">{{ keyword }}</view> <view class="wes" v-for="(keyword, index) in hotKeywordList" @tap="doSearch(keyword)" :key="index">
{{ keyword }}</view>
</view> </view>
</view> </view>
<view class="keyword-block" v-if="oldKeywordList.length > 0"> <view class="keyword-block" v-if="oldKeywordList.length > 0">
<view class="keyword-list-header"> <view class="keyword-list-header">
<view class="u-tips">搜索历史</view> <view class="u-tips">搜索历史</view>
</view> </view>
<div class="oldKeyList"> <div class="oldKeyList">
<div class="oldKeyItem" v-if="keyword" v-for="(keyword, index) in oldKeywordList" :key="index"
<div class="oldKeyItem" v-if="keyword" v-for="(keyword, index) in oldKeywordList" :key="index" @click="doSearch(keyword)"> @click="doSearch(keyword)">
<span>{{ keyword }} </span> <span>{{ keyword }} </span>
</div> </div>
<div @click="showMore" v-if=" oldKeywordIndex > loadIndex" class="oldKeyItem">展示更多</div> <div @click="showMore" v-if=" oldKeywordIndex > loadIndex" class="oldKeyItem">展示更多</div>
</div> </div>
</view> </view>
@@ -54,11 +50,13 @@
<text>销量</text> <text>销量</text>
<view class="p-box"> <view class="p-box">
<view class="index-nav-arrow"> <view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-up-1.png" v-if="params.sort === 'buyCount' && params.order === 'asc'" mode="aspectFit"></image> <image class="img" src="/static/index/arrow-up-1.png"
v-if="params.sort === 'buyCount' && params.order === 'asc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image> <image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view> </view>
<view class="index-nav-arrow"> <view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-down.png" v-if="params.sort === 'buyCount' && params.order === 'desc'" mode="aspectFit"></image> <image class="img" src="/static/index/arrow-down.png"
v-if="params.sort === 'buyCount' && params.order === 'desc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image> <image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view> </view>
</view> </view>
@@ -67,11 +65,13 @@
<text>价格</text> <text>价格</text>
<view class="p-box"> <view class="p-box">
<view class="index-nav-arrow"> <view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-up-1.png" v-if="params.sort === 'price' && params.order === 'asc'" mode="aspectFit"></image> <image class="img" src="/static/index/arrow-up-1.png"
v-if="params.sort === 'price' && params.order === 'asc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image> <image class="img" src="/static/index/arrow-up.png" v-else mode="aspectFit"></image>
</view> </view>
<view class="index-nav-arrow"> <view class="index-nav-arrow">
<image class="img" src="/static/index/arrow-down.png" v-if="params.sort === 'price' && params.order === 'desc'" mode="aspectFit"></image> <image class="img" src="/static/index/arrow-down.png"
v-if="params.sort === 'price' && params.order === 'desc'" mode="aspectFit"></image>
<image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image> <image class="img" src="/static/index/arrow-down-1.png" v-else mode="aspectFit"></image>
</view> </view>
</view> </view>
@@ -80,53 +80,51 @@
</view> </view>
<!-- 一行一个商品展示 --> <!-- 一行一个商品展示 -->
<div v-if="isSWitch"> <div v-if="isSWitch">
<scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250" @scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page"> <scroll-view :style="{ height: goodsHeight }" enableBackToTop="true" lower-threshold="250"
<div class="goodsClass"> @scrolltolower="loadmore()" scroll-with-animation scroll-y class="scoll-page">
<u-row v-for="(item, index) in goodsList" :key="index" class="goodsRow"> <div class="goods-class">
<u-col :span="4" @click.native="navigateToDetailPage(item)" class="switchType1"> <div v-for="(item, index) in goodsList" :key="index" class="goods-row">
<u-image width="182rpx" height="200rpx" class="imgGoods" :src="item.thumbnail"> <div class="flex goods-col">
<u-loading slot="loading"></u-loading> <div class="goods-img" @click="navigateToDetailPage(item)">
</u-image> <u-image width="230rpx" height="230rpx" :src="item.content.thumbnail">
</u-col> <u-loading slot="loading"></u-loading>
<u-col :span="8" @click.native="navigateToDetailPage(item)" class="switchType2"> </u-image>
<div class="title clamp3" style="">{{ item.goodsName }}</div> </div>
<view class="price-box"> <div class="goods-detail">
<div class="price" v-if="item.price!=undefined"> <div class="title clamp3" @click="navigateToDetailPage(item)">{{ item.content.goodsName }}</div>
¥<span>{{ formatPrice(item.price )[0] }} </span>.{{ <view class="price-box" @click="navigateToDetailPage(item)">
formatPrice(item.price )[1] <div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
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>
@@ -148,39 +146,39 @@
!isSWitch && !isSWitch &&
!(goodsList == [] || goodsList == '' || goodsList == null) !(goodsList == [] || goodsList == '' || goodsList == null)
"> ">
<scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true" @scrolltolower="loadmore()" scroll-with-animation scroll-y lower-threshold="250" class="scoll-page"> <scroll-view :style="{ height: goodsHeight }" scroll-anchoring enableBackToTop="true"
@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" @click="navigateToDetailPage(item)"> <view v-for="(item, index) in goodsList" :key="index" class="goods-item">
<view class="image-wrapper"> <view class="image-wrapper" @click="navigateToDetailPage(item)">
<image :src="item.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.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.price!=undefined"> <div class="price" v-if="item.content.price!=undefined">
¥<span>{{ formatPrice(item.content.price )[0] }} </span>.{{
¥<span>{{ formatPrice(item.price )[0] }} </span>.{{ formatPrice(item.content.price )[1]
formatPrice(item.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="自营" type="error" /> <u-tag style="margin-right: 10rpx" size="mini" mode="dark" v-if="item.selfOperated" text="自营"
<span>{{ item.storeName || "暂无" }}</span> type="error" />
<span>{{ item.content.storeName || "暂无" }}</span>
</div> </div>
<span> <span>
<u-icon name="arrow-right"></u-icon> <u-icon name="arrow-right"></u-icon>
@@ -201,7 +199,8 @@
<view class="sort-item"> <view class="sort-item">
<view class="sort-title"> 品牌 </view> <view class="sort-title"> 品牌 </view>
<view class="flex" v-if="sortData.brands"> <view class="flex" v-if="sortData.brands">
<view class="sort-brand-item" :key="brandsIndex" v-for="(brand, brandsIndex) in sortData.brands" @click="handleSort(brand, brandsIndex, 'brand')"> <view class="sort-brand-item" :key="brandsIndex" v-for="(brand, brandsIndex) in sortData.brands"
@click="handleSort(brand, brandsIndex, 'brand')">
<view class="sort-radius" :class="{ <view class="sort-radius" :class="{
'sort-active': brand.__selected, 'sort-active': brand.__selected,
}"> }">
@@ -214,7 +213,9 @@
<view class="sort-item"> <view class="sort-item">
<view class="sort-title"> 全部分类 </view> <view class="sort-title"> 全部分类 </view>
<view class="flex" style="flex-wrap: wrap;" v-if="sortData.categories"> <view class="flex" style="flex-wrap: wrap;" v-if="sortData.categories">
<view class="sort-brand-item" :key="categoriesIndex" v-for="(categoryId, categoriesIndex) in sortData.categories" @click="handleSort(categoryId, categoriesIndex, 'categoryId')"> <view class="sort-brand-item" :key="categoriesIndex"
v-for="(categoryId, categoriesIndex) in sortData.categories"
@click="handleSort(categoryId, categoriesIndex, 'categoryId')">
<view class="sort-radius" :class="{ <view class="sort-radius" :class="{
'sort-active': categoryId.__selected, 'sort-active': categoryId.__selected,
}"> }">
@@ -248,7 +249,8 @@
<view class="sort-item" :key="paramIndex" v-for="(param, paramIndex) in sortData.paramOptions"> <view class="sort-item" :key="paramIndex" v-for="(param, paramIndex) in sortData.paramOptions">
<view class="sort-title"> {{ param.key }} </view> <view class="sort-title"> {{ param.key }} </view>
<view class="flex" style="flex-warp:warp" v-if="param.values"> <view class="flex" style="flex-warp:warp" v-if="param.values">
<view class="sort-brand-item" :key="i" v-for="(value, i) in param.values" @click="handleSort(value, i, 'prop', param)"> <view class="sort-brand-item" :key="i" v-for="(value, i) in param.values"
@click="handleSort(value, i, 'prop', param)">
<view class="sort-radius" :class="{ <view class="sort-radius" :class="{
'sort-active': value.__selected, 'sort-active': value.__selected,
}"> }">
@@ -266,6 +268,7 @@
</view> </view>
</view> </view>
</u-popup> </u-popup>
<u-back-top :scroll-top="scrollTop"></u-back-top>
</view> </view>
</template> </template>
@@ -274,10 +277,11 @@ import { getGoodsList, getGoodsRelated } from "@/api/goods.js";
import { getHotKeywords } from "@/api/home.js"; import { getHotKeywords } from "@/api/home.js";
import mSearch from "@/components/m-search-revision/m-search-revision.vue"; import mSearch from "@/components/m-search-revision/m-search-revision.vue";
import storage from "@/utils/storage";
export default { export default {
data() { data() {
return { return {
scrollTop: 0,
loadIndex: 10, loadIndex: 10,
oldKeywordIndex: "", oldKeywordIndex: "",
selectedWay: { selectedWay: {
@@ -317,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: "",
@@ -336,10 +339,13 @@ export default {
routerVal: "", routerVal: "",
}; };
}, },
onPageScroll(e) {
console.log(e);
this.scrollTop = e.scrollTop;
},
onLoad(val) { onLoad(val) {
// return false
this.init(); this.init();
this.initSortGoods(); // this.initSortGoods();
// 接收分类的数据 // 接收分类的数据
this.routerVal = val; this.routerVal = val;
@@ -347,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) {
@@ -360,9 +367,28 @@ export default {
this.loadData(); this.loadData();
}, },
components: { components: {
//引用mSearch组件如不需要删除即可
mSearch, mSearch,
}, },
watch: {
/**
* 将搜索的字和热词进行匹配,如果为热词则不改商品搜索关键字
*/
keyword(val) {
if (val) {
if (val) {
this.defaultKeyword = val;
}
} else {
this.defaultKeyword = "请输入搜索商品";
}
},
sortPopup(val) {
if (val) {
this.selectedWay = { brand: [], categoryId: [], prop: [] };
console.log(this.selectedWay);
}
},
},
onReachBottom() { onReachBottom() {
this.params.pageNumber++; this.params.pageNumber++;
@@ -437,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}`);
@@ -464,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();
}, },
@@ -497,8 +549,9 @@ export default {
}, },
init() { init() {
this.loadDefaultKeyword(); // 加载搜索记录
this.loadOldKeyword(this.loadIndex); this.loadOldKeyword(this.loadIndex);
// 加载热词
this.loadHotKeyword(); this.loadHotKeyword();
}, },
blur() { blur() {
@@ -509,9 +562,16 @@ export default {
delta: 1, delta: 1,
}); });
}, },
// 跳转到商品详情
navigateToDetailPage(item) { navigateToDetailPage(item) {
uni.navigateTo({ uni.navigateTo({
url: `/pages/product/goods?id=${item.id}&goodsId=${item.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() {
@@ -577,8 +637,16 @@ export default {
}, },
//加载默认搜索关键字 //加载默认搜索关键字
loadDefaultKeyword() { loadDefaultKeyword() {
//定义默认搜索关键字可以自己实现ajax请求数据再赋值,用户未输入时,以水印方式显示在输入框,直接不输入内容搜索会搜索默认关键字 /**
this.defaultKeyword = "请输入搜索商品"; * 定义默认搜索关键字会根据当前热门搜索来进行显示
* 如果当前热门搜索没有的话,则会显示默认关键字
*/
if (this.hotKeywordList.length != 0) {
//
this.defaultKeyword = this.hotKeywordList[0];
} else {
this.defaultKeyword = "请输入搜索商品";
}
}, },
//加载历史搜索,自动读取本地Storage //加载历史搜索,自动读取本地Storage
loadOldKeyword(index) { loadOldKeyword(index) {
@@ -594,15 +662,39 @@ export default {
}, },
}); });
}, },
//加载热门搜索
/**
* 加载热门搜索
* 1.5分钟之后更新缓存
* 2.如果有缓存热门关键字则去请求缓存
*/
async loadHotKeyword() { async loadHotKeyword() {
this.hotKeywordList = []; this.hotKeywordList = [];
let res = await getHotKeywords(); if (
let keywords = res.data.result; !storage.getHotWords().time ||
storage.getHotWords().time <= new Date().getTime() / 1000
) {
// 没有缓存或者第一次进入请求接口保存缓存
let res = await getHotKeywords(10);
let keywords = res.data.result;
keywords.forEach((item) => { keywords.forEach((item) => {
this.hotKeywordList.push(item); this.hotKeywordList.push(item);
}); });
let hotData = {
time: new Date().getTime() / 1000 + 30 * 5,
keywords: keywords,
};
storage.setHotWords(hotData);
} else {
let keywords = storage.getHotWords().keywords;
keywords.forEach((item) => {
this.hotKeywordList.push(item);
});
}
this.loadDefaultKeyword();
}, },
//加载商品 ,带下拉刷新和上滑加载 //加载商品 ,带下拉刷新和上滑加载
async loadData(type, loading) { async loadData(type, loading) {
@@ -610,7 +702,7 @@ export default {
if (type == "refresh") { if (type == "refresh") {
this.goodsList = []; this.goodsList = [];
} }
//没有更多直接返回 //没有更多直接返回 #TODO
let goodsList = await getGoodsList(this.params); let goodsList = await getGoodsList(this.params);
if (goodsList.data.result.content.length < 10) { if (goodsList.data.result.content.length < 10) {
@@ -620,19 +712,7 @@ export default {
this.initSortGoods(); this.initSortGoods();
uni.hideLoading(); uni.hideLoading();
}, },
//监听输入
inputChange(event) {
//兼容引入组件时传入参数情况
var keyword = event.detail ? event.detail.value : event;
if (!keyword) {
this.keywordList = [];
this.isShowKeywordList = false;
return;
}
this.isShowKeywordList = true;
this.getKeywordNumFun(keyword);
},
//高亮关键字 //高亮关键字
drawCorrelativeKeyword(keywords, keyword) { drawCorrelativeKeyword(keywords, keyword) {
var len = keywords.length, var len = keywords.length,
@@ -663,7 +743,6 @@ export default {
content: "确定清除历史搜索记录?", content: "确定清除历史搜索记录?",
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
this.oldKeywordList = []; this.oldKeywordList = [];
uni.removeStorage({ uni.removeStorage({
key: "OldKeys", key: "OldKeys",
@@ -674,27 +753,39 @@ export default {
}, },
// 样式修改布局 // 样式修改布局
doSearchSwitch(val) { doSearchSwitch() {
this.isSWitch = !this.isSWitch; this.isSWitch = !this.isSWitch;
this.isShowSeachGoods = true; this.isShowSeachGoods = true;
}, },
//执行搜索 /**
* 执行搜索
*/
doSearch(keyword) { doSearch(keyword) {
// 用户自行搜索/热门搜索/搜索历史
keyword = keyword === false ? this.keyword : keyword; keyword = keyword === false ? this.keyword : keyword;
this.keyword = keyword;
if (!keyword) {
/**
* 进行空搜索
* 第一次搜索如果没有关键词会将热门搜索中第一个热词进行判定
* 如果没有热词则会展示一个空词搜索
*/
keyword = (this.hotKeywordList.length && this.hotKeywordList[0]) || "";
}
this.defaultKeyword == "请输入搜索商品" ? (keyword = "") : "";
// this.keyword = keyword;
keyword ? (this.keyword = keyword) : "";
this.saveKeyword(keyword); //保存为历史 this.saveKeyword(keyword); //保存为历史
this.isShowSeachGoods = true; this.isShowSeachGoods = true;
this.$refs.mSearch.isShowSeachGoods = true; this.$refs.mSearch.isShowSeachGoods = true;
this.params.keyword = keyword; this.params.keyword = this.keyword;
this.params.pageNumber = 1; this.params.pageNumber = 1;
this.$set(this.sortParams, "keyword", keyword); this.$set(this.sortParams, "keyword", keyword);
this.loadData("refresh", 1); this.loadData("refresh", 1);
}, },
//保存关键字到历史记录 //保存关键字到历史记录
saveKeyword(keyword) { saveKeyword(keyword) {
if (!keyword) return false; if (!keyword) return false;
uni.getStorage({ uni.getStorage({
key: "OldKeys", key: "OldKeys",
@@ -715,7 +806,6 @@ export default {
data: JSON.stringify(OldKeys), data: JSON.stringify(OldKeys),
}); });
this.oldKeywordList = OldKeys; //更新历史搜索 this.oldKeywordList = OldKeys; //更新历史搜索
}, },
fail: (e) => { fail: (e) => {
var OldKeys = [keyword]; var OldKeys = [keyword];
@@ -727,12 +817,6 @@ export default {
}, },
}); });
}, },
// 搜索关键字
getKeywordNumFun(keywords) {
this.params.keyword = keywords;
this.$set(this.sortParams, "keyword", keywords);
},
}, },
}; };
</script> </script>

View File

@@ -1,10 +1,12 @@
<template> <template>
<view class="content"> <view class="content">
<view class="u-tabs-box"> <view class="u-tabs-box">
<u-tabs bg-color="#fff" :list="list" :is-scroll="false" :current="current" @change="change" :active-color="$lightColor"></u-tabs> <u-tabs bg-color="#fff" :list="list" :is-scroll="false" :current="current" @change="change"
:active-color="$lightColor"></u-tabs>
</view> </view>
<div class="u-tabs-search"> <div class="u-tabs-search">
<u-search placeholder="请输入订单编号" @search="handleGetOrderList(current)" @clear="handleGetOrderList(current)" @custom="handleGetOrderList(current)" v-model="params.orderSn"></u-search> <u-search placeholder="请输入订单编号" @search="handleGetOrderList(current)" @clear="handleGetOrderList(current)"
@custom="handleGetOrderList(current)" v-model="params.orderSn"></u-search>
</div> </div>
<scroll-view class="body-view" scroll-y @scrolltolower="renderDate"> <scroll-view class="body-view" scroll-y @scrolltolower="renderDate">
<view class="seller-view" v-for="(order, orderIndex) in orderList" :key="orderIndex"> <view class="seller-view" v-for="(order, orderIndex) in orderList" :key="orderIndex">
@@ -21,7 +23,7 @@
<view class="order-sn">{{ order.serviceType_text }}</view> <view class="order-sn">{{ order.serviceType_text }}</view>
</view> </view>
<view v-for="(sku, goodsIndex) in order.orderItems" :key="goodsIndex"> <view v-for="(sku, goodsIndex) in order.orderItems" :key="goodsIndex">
<view class="goods-item-view" @click="onDetail(sku)"> <view class="goods-item-view" @click="onDetail(order,sku)">
<view class="goods-img"> <view class="goods-img">
<u-image border-radius="6" width="100%" height="100%" :src="sku.image"></u-image> <u-image border-radius="6" width="100%" height="100%" :src="sku.image"></u-image>
</view> </view>
@@ -40,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>
@@ -129,8 +138,8 @@ export default {
params: { params: {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
sort: 'createTime', sort: "createTime",
order: 'desc' order: "desc",
}, },
logParams: { logParams: {
@@ -171,6 +180,8 @@ export default {
this.logParams = { this.logParams = {
pageNumber: 1, pageNumber: 1,
pageSize: 10, pageSize: 10,
sort: "createTime",
order: "desc",
}; };
if (index === 1) { if (index === 1) {
this.logParams.serviceStatus = "APPLY"; this.logParams.serviceStatus = "APPLY";
@@ -274,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
}`,
}); });
} }
}, },

View File

@@ -10,7 +10,8 @@
</view> </view>
</view> </view>
<view> <view>
<view class="goods-item-view" v-for="(item,index) in sku.orderItems" v-if="item.sn == sn" @click="gotoGoodsDetail(sku.goods_id)"> <view class="goods-item-view" v-for="(item,index) in sku.orderItems" v-if="item.sn == sn"
@click="gotoGoodsDetail(sku.goods_id)">
<view class="goods-img"> <view class="goods-img">
<u-image border-radius="6" width="131rpx" height="131rpx" :src="item.image"></u-image> <u-image border-radius="6" width="131rpx" height="131rpx" :src="item.image"></u-image>
</view> </view>
@@ -27,7 +28,8 @@
<view class="after-num"> <view class="after-num">
<view>申请数量</view> <view>申请数量</view>
<view> <view>
<u-number-box :value="parseInt(form.num)" disabled-input :min="1" :max="parseInt(sku.num)" bg-color="#fff" @change="valChange"></u-number-box> <u-number-box :value="parseInt(form.num)" disabled-input :min="1" :max="parseInt(sku.num)" bg-color="#fff"
@change="valChange"></u-number-box>
</view> </view>
</view> </view>
</view> </view>
@@ -36,7 +38,8 @@
<!-- 退款原因 --> <!-- 退款原因 -->
<view class="opt-view"> <view class="opt-view">
<u-form-item label="申请原因" :label-width="150"> <u-form-item label="申请原因" :label-width="150">
<u-input v-model="form.reason" type="select" input-align="right" :select-open="reasonSelectShow" @click="reasonSelectShow = true" placeholder="请选择申请原因" /> <u-input v-model="form.reason" type="select" input-align="right" :select-open="reasonSelectShow"
@click="reasonSelectShow = true" placeholder="请选择申请原因" />
</u-form-item> </u-form-item>
<u-form-item label="申请说明" :label-width="150"> <u-form-item label="申请说明" :label-width="150">
<u-input input-align="right" type="textarea" v-model="form.problemDesc" placeholder="请描述申请售后的说明" /> <u-input input-align="right" type="textarea" v-model="form.problemDesc" placeholder="请描述申请售后的说明" />
@@ -47,7 +50,8 @@
<view class="opt-view"> <view class="opt-view">
<view class="img-title">上传凭证最多5张</view> <view class="img-title">上传凭证最多5张</view>
<view class="images-view"> <view class="images-view">
<u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150" @on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload> <u-upload :header=" { accessToken: storage.getAccessToken() }" :action="action" width="150"
@on-uploaded="onUploaded" :max-count="5" :show-progress="false"></u-upload>
</view> </view>
</view> </view>
@@ -81,11 +85,14 @@
</u-form> </u-form>
<view class="submit-view"> <view class="submit-view">
<u-button type="primary" ripple shape="circle" v-if="applyInfo.refundWay" :custom-style="customStyle" @click="onSubmit">提交申请</u-button> <u-button type="primary" ripple shape="circle" v-if="applyInfo.refundWay" :custom-style="customStyle"
@click="onSubmit">提交申请</u-button>
</view> </view>
<u-select mode="single-column" :list="reasonList" v-model="reasonSelectShow" @confirm="reasonSelectConfirm"></u-select> <u-select mode="single-column" :list="reasonList" v-model="reasonSelectShow" @confirm="reasonSelectConfirm">
</u-select>
<u-select mode="single-column" :list="typeList" v-model="typeSelectShow" @confirm="typeSelectConfirm"></u-select> <u-select mode="single-column" :list="typeList" v-model="typeSelectShow" @confirm="typeSelectConfirm"></u-select>
<u-select mode="single-column" :list="returnList" v-model="returnSelectShow" @confirm="returnSelectConfirm"></u-select> <u-select mode="single-column" :list="returnList" v-model="returnSelectShow" @confirm="returnSelectConfirm">
</u-select>
<u-toast ref="uToast" /> <u-toast ref="uToast" />
</view> </view>
</template> </template>
@@ -462,7 +469,6 @@ page,
align-items: center; align-items: center;
} }
.images-view { .images-view {
padding: 20rpx;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
@@ -484,7 +490,11 @@ page,
background-color: #ffffff; background-color: #ffffff;
height: 100rpx; height: 100rpx;
width: 750rpx; width: 750rpx;
justify-content: flex-end;
display: flex;
align-items: center; align-items: center;
padding: 0rpx 20rpx; width: 100%;
padding-right: 32rpx;
} }
</style> </style>

View File

@@ -34,7 +34,7 @@
<view class="select-title">退货</view> <view class="select-title">退货</view>
<view class="select-sub-title"> <view class="select-sub-title">
退回收到的商品 退回收到的商品
<uni-icons color="#BABABA" type="arrowright"></uni-icons> <u-icon name="arrow-right" color="#bababa"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -46,7 +46,7 @@
<view class="select-title">退款</view> <view class="select-title">退款</view>
<view class="select-sub-title"> <view class="select-sub-title">
退款商品返还金额 退款商品返还金额
<uni-icons color="#BABABA" type="arrowright"></uni-icons> <u-icon name="arrow-right" color="#bababa"></u-icon>
</view> </view>
</view> </view>
</view> </view>
@@ -55,13 +55,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: "",

View File

@@ -28,7 +28,7 @@
logs[0].message logs[0].message
}}</view> }}</view>
</view> </view>
<uni-icons type="arrowright" style="margin-right: 5px"></uni-icons> <u-icon name="arrow-right" style="margin-right: 5px" size="30" color="#999"></u-icon>
</view> </view>
</view> </view>
<view class="goods-info"> <view class="goods-info">
@@ -75,7 +75,7 @@
</view> </view>
<view class="detail-item"> <view class="detail-item">
<view class="title">申请原因:</view> <view class="title">申请原因:</view>
<view class="value">{{ serviceDetail.reason }}</view> <view class="value">{{ reason }}</view>
</view> </view>
<!-- <view class="detail-item" v-if="serviceDetail.apply_vouchers"> <!-- <view class="detail-item" v-if="serviceDetail.apply_vouchers">
<view class="title">申请凭证:</view> <view class="title">申请凭证:</view>
@@ -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
@@ -195,15 +199,12 @@ import {
getServiceDetail, getServiceDetail,
getstoreAfterSaleAddress, getstoreAfterSaleAddress,
getAfterSaleLog, getAfterSaleLog,
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: "", //申请原因
serviceTypeList: { serviceTypeList: {
// 售后类型 // 售后类型
CANCEL: "取消", CANCEL: "取消",
@@ -330,6 +331,18 @@ export default {
}); });
}, },
/**
* 获取申请原因
*/
getReasonList(serviceType) {
getAfterSaleReason(serviceType).then((res) => {
if (res.data.success) {
// 1357583466371219456
this.reason = this.serviceDetail.reason;
}
});
},
/** /**
* 初始化详情 * 初始化详情
*/ */
@@ -340,7 +353,10 @@ export default {
getServiceDetail(this.sn).then((res) => { getServiceDetail(this.sn).then((res) => {
uni.hideLoading(); uni.hideLoading();
this.serviceDetail = res.data.result; this.serviceDetail = res.data.result;
if (this.serviceDetail.serviceType == "RETURN_GOODS") { if (
this.serviceDetail.serviceType == "RETURN_GOODS" ||
this.serviceDetail.serviceType === "RETURN_MONEY"
) {
this.refundShow = true; this.refundShow = true;
} }
@@ -348,11 +364,15 @@ 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_GOODS" || this.serviceDetail.accountType === "BANK_TRANSFER" &&
this.serviceDetail.serviceType === "ORDER_CANCEL") &&
this.serviceDetail.refundWay === "OFFLINE" && this.serviceDetail.refundWay === "OFFLINE" &&
this.serviceDetail.accountType === "BANK_TRANSFER"; ((this.serviceDetail.serviceType === "RETURN_GOODS") |
(this.serviceDetail.serviceType === "ORDER_CANCEL") ||
this.serviceDetail.serviceType === "RETURN_MONEY");
this.getReasonList(this.serviceDetail.serviceType);
}); });
}, },

View File

@@ -103,7 +103,9 @@ export default {
.row { .row {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
padding: 26rpx 32rpx;
} }
.speak-msg { .speak-msg {
padding: 26rpx 32rpx; padding: 26rpx 32rpx;
> span { > span {
@@ -120,6 +122,6 @@ export default {
padding: 16rpx; padding: 16rpx;
} }
.tips { .tips {
margin: 40rpx 0; margin: 40rpx 32rpx;
} }
</style> </style>

View File

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

View File

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

View File

@@ -1,48 +1,38 @@
<template> <template>
<div class="wrapper"> <div class="wrapper">
<!-- 选择地址 --> <!-- 选择地址 -->
<div class="box1 box"> <div class="address-box" @click="clickToAddress()">
<u-row style="margin-top: 32rpx"> <div class="user-box flex">
<u-col style="padding: 0 !important" :offset="0" :span="11" @click.native="clickToAddress()"> <div class="flex-8">
<div v-if="!address.id">请选择地址</div> <div v-if="!address.id">请选择地址</div>
<div v-else> <div v-else>
<div class="userClass"> <div class="user-address">
{{ address.name }} <!-- 省市区 -->
<span> <div class="flex flex-a-c">
{{ address.mobile | secrecyMobile }} <span class="default" v-if="address.isDefault">默认</span>
<u-tag v-if="address.isDefault" text="默认" style="margin-left: 24rpx" mode="plain" type="error" size="mini" /> <div class="address-list" v-if="address.consigneeAddressPath.length != 0">
</span> <span class="address-item" v-for="(item,index) in address.consigneeAddressPath" :key="index">
</div> {{item}}
<div class="userAdress"> </span>
<span v-if="address.consigneeAddressPath[0]">{{ </div>
address.consigneeAddressPath[0] </div>
}}</span> <!-- 详细地址 -->
<div class="user-address-detail wes-2">
<span v-if="address.consigneeAddressPath[1]">{{
address.consigneeAddressPath[1]
}}</span>
<span v-if="address.consigneeAddressPath[2]">{{
address.consigneeAddressPath[2]
}}</span>
<span v-if="address.consigneeAddressPath[3]">{{
address.consigneeAddressPath[3]
}}</span>
<span>
{{ address.detail }} {{ address.detail }}
</span> </div>
<!-- 姓名 手机号 -->
<div>
<span>{{ address.name }}</span>
<span class="mobile">{{ address.mobile | secrecyMobile }}</span>
</div>
</div> </div>
</div> </div>
</u-col> </div>
<u-col :span="1" @click.native=" <u-icon name="arrow-right" style="color: #bababa"></u-icon>
navigateTo('/pages/mine/address/address?way=' + routerVal.way) </div>
" style="text-align: right"> <!-- 背景 -->
<u-icon name="arrow-right" style="color: #bababa"></u-icon> <div class="bar"></div>
</u-col>
</u-row>
</div> </div>
<!-- 背景 -->
<div class="bar"></div>
<!-- 开团信息 --> <!-- 开团信息 -->
<view class="group-box" v-if="isAssemble"> <view class="group-box" v-if="isAssemble">
@@ -52,17 +42,19 @@
</view> </view>
<view class="group"> <view class="group">
<view> <view>
<u-image borderRadius="50%" shape="square" class="head-img" width="81rpx" height="81rpx" :src="masterWay.face || '/static/missing-face.png'"></u-image> <u-image borderRadius="50%" shape="square" class="head-img" width="81rpx" height="81rpx"
:src="masterWay.face || '/static/missing-face.png'"></u-image>
<view class="btn-one">团长</view> <view class="btn-one">团长</view>
</view> </view>
<view class="line"> </view> <view class="line"> </view>
<view> <view>
<!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 --> <!-- 如果有最后一名显示最后一名没有最后一名显示等待参团 -->
<u-image class="head-img" v-if="endWay.face" :src="endWay.face" borderRadius="50%" shape="square" width="81rpx" height="81rpx"> <u-image class="head-img" v-if="endWay.face" :src="endWay.face" borderRadius="50%" shape="square"
width="81rpx" height="81rpx">
<view slot="loading"></view> <view slot="loading"></view>
</u-image> </u-image>
<u-image class="head-img" borderRadius="50%" shape="square" v-else width="81rpx" height="81rpx"
<u-image class="head-img" borderRadius="50%" shape="square" v-else width="81rpx" height="81rpx" :src="endWay.face || '/static/missing-face.png'"></u-image> :src="endWay.face || '/static/missing-face.png'"></u-image>
<view class="wait">{{ endWay.nickname || "等待参团" }}</view> <view class="wait">{{ endWay.nickname || "等待参团" }}</view>
</view> </view>
@@ -71,38 +63,30 @@
<!-- 店铺商品信息 --> <!-- 店铺商品信息 -->
<div class="box box2" v-for="(item, index) in orderMessage.cartList" :key="index"> <div class="box box2" v-for="(item, index) in orderMessage.cartList" :key="index">
<u-row class="tab1" @click="navigateToStore(item)"> <div @click="navigateToStore(item)">
<u-col :offset="0"> <div class="store-name">
<span class="ybname">{{ item.storeName }}</span> <span>{{ item.storeName }}</span>
</u-col> </div>
</u-row> </div>
<div class="promotionNotice">{{ item.promotionNotice }}</div> <div class="promotionNotice">{{ item.promotionNotice || '' }}</div>
<u-row class="goodsBorder" v-for="(val, i) in item.skuList" :key="i"> <div class="flex goods-item" v-for="(val, i) in item.skuList" :key="i">
<u-col class="tabL" :offset="0" @click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)" :span="3"> <div class="goods-image"
<u-image borderRadius="10rpx" :src="val.goodsSku.thumbnail" alt /> @click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)" :span="3">
</u-col> <u-image borderRadius="10rpx" width="200rpx" height="200rpx" :src="val.goodsSku.thumbnail" alt />
<u-col :span="9" @click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)" class="tabC"> </div>
<div style="overflow: hidden"> <div @click="navigateTo('/pages/product/goods?id=' + val.goodsSku.id+'&goodsId='+val.goodsSku.goodsId)"
<p class="sp_name">{{ val.goodsSku.goodsName }}</p> class="goods-detail">
<p class="sp_promotion" v-if="val.promotion_tags"> <div class="flex">
<view class="sp_tag sp_tag_plain" v-for="(promotion_item, promotion_index) in val.promotion_tags" :key="promotion_index">{{ promotion_item }}</view> <p class="goods-name">{{ val.goodsSku.goodsName }}</p>
</p>
<span class="nums">x{{ val.num }}</span> <span class="nums">x{{ val.num }}</span>
</div> </div>
<p class="goods-prices">
<p class="sp_number">{{ val.goodsSku.price | unitPrice }}</p> <span></span>
</u-col> <span class="goods-price">{{formatPrice(val.goodsSku.price)[0]}}</span>
</u-row> <span>.{{formatPrice(val.goodsSku.price)[1] }}</span>
</p>
<u-row> </div>
<u-col :offset="0" :span="4" class="tl" style="text-align: left">备注信息</u-col> </div>
<u-col :span="8" textAlign="right">
<u-input style="text-align:right;" class="uinput" v-model="remarkVal[index].remark" />
</u-col>
</u-row>
</div>
<!-- 订单信息 -->
<div class="box box3">
<u-row> <u-row>
<u-col :offset="0" :span="4">发票信息</u-col> <u-col :offset="0" :span="4">发票信息</u-col>
<u-col :span="8" class="tipsColor" textAlign="right" @click.native="invoice()"> <u-col :span="8" class="tipsColor" textAlign="right" @click.native="invoice()">
@@ -110,35 +94,25 @@
<span v-else>不开发票</span> <span v-else>不开发票</span>
</u-col> </u-col>
</u-row> </u-row>
<u-row>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :offset="0" :span="9" @click="shippingFlag = true">配送
</u-col>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="3" textAlign="right" @click="shippingFlag = true">
{{shippingMethod.find(e=>{ return e.value == shippingText; }).label }}
</u-col>
</u-row>
<u-row>
<u-col :offset="0" :span="4" class="tl" style="text-align: left">备注信息</u-col>
<u-col :span="8" textAlign="right">
<u-input style="text-align:right;" class="uinput" v-model="remarkVal[index].remark" />
</u-col>
</u-row>
</div> </div>
<!-- 发票信息 --> <!-- 发票信息 -->
<invoices :res="receiptList" @callbackInvoice="callbackInvoice" v-if="invoiceFlag" /> <invoices :res="receiptList" @callbackInvoice="callbackInvoice" v-if="invoiceFlag" />
<u-select v-model="shippingFlag" :list="shippingMethod"></u-select> <u-select v-model="shippingFlag" :list="shippingMethod"></u-select>
<!-- 优惠券 -->
<div class="box box4">
<u-row>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :offset="0" :span="9" @click="shippingFlag = true">配送方式</u-col>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="3" textAlign="right" @click="shippingFlag = true">
{{ shippingMethod.find(e=>{ return e.value == shippingText; }).label }}
</u-col>
</u-row>
<u-row>
<u-col :offset="0" :span="9" @click="GET_Discount()">优惠券</u-col>
<u-col :span="3" v-if="orderMessage.priceDetailDTO && orderMessage.priceDetailDTO.couponPrice" textAlign="right" @click="GET_Discount()">
<span class="main-color">-{{orderMessage.priceDetailDTO.couponPrice | unitPrice}}</span>
</u-col>
<!-- orderMessage.priceDetailDTO.couponPrice | unitPrice -->
<u-col :span="3" v-else textAlign="right" @click="GET_Discount()">
{{ couponNums || "0" }}张可用
<u-icon name="arrow-right"></u-icon>
</u-col>
</u-row>
</div>
<div class="box box5" v-if="orderMessage.priceDetailDTO"> <div class="box box5" v-if="orderMessage.priceDetailDTO">
<div> <div>
<u-row> <u-row>
@@ -152,47 +126,64 @@
<u-row> <u-row>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7">运费</u-col> <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="7">运费</u-col>
<u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="5" class="tr tipsColor" textAlign="right"> <u-col v-if="orderMessage.cartTypeEnum != 'VIRTUAL'" :span="5" class="tr tipsColor" textAlign="right">
<u-tag v-if="orderMessage.priceDetailDTO.freightPrice == 0" style="margin-right: 20rpx" color="#FF6262" text="包邮" type="warning" size="mini" mode="plain" shape="circle" /> <span v-if="orderMessage.priceDetailDTO.freightPrice == 0">包邮</span>
<span>{{ <span v-else>{{
orderMessage.priceDetailDTO.freightPrice | unitPrice orderMessage.priceDetailDTO.freightPrice | unitPrice
}}</span> }}</span>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
<u-row>
<u-col :offset="0" :span="9" @click="GET_Discount()">优惠券</u-col>
<u-col :span="3" v-if="orderMessage.priceDetailDTO && orderMessage.priceDetailDTO.couponPrice" textAlign="right"
@click="GET_Discount()">
<span class="main-color">-{{orderMessage.priceDetailDTO.couponPrice | unitPrice}}</span>
</u-col>
<!-- orderMessage.priceDetailDTO.couponPrice | unitPrice -->
<u-col :span="3" v-else textAlign="right" @click="GET_Discount()">
{{ orderMessage.canUseCoupons.length || "0" }} 张可用
<u-icon name="arrow-right"></u-icon>
</u-col>
</u-row>
<div> <div>
<u-row> <u-row>
<u-col :span="9">优惠金额</u-col> <u-col :span="9">优惠金额</u-col>
<u-col :span="3" textAlign="right">-{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</u-col> <u-col :span="3" textAlign="right" v-if=" orderMessage.priceDetailDTO.couponPrice">
<span class="main-color"> -{{ orderMessage.priceDetailDTO.couponPrice | unitPrice }}</span></u-col>
<u-col :span="3" textAlign="right" v-else>0.00</u-col>
</u-row> </u-row>
</div> </div>
<div> <div>
<u-row> <u-row>
<u-col :span="6">活动优惠</u-col> <u-col :span="6">活动优惠</u-col>
<u-col :span="6" class="tr tipsColor" textAlign="right"> <u-col :span="6" class="tr tipsColor" textAlign="right">
<u-tag style="margin-right: 20rpx" v-if="orderMessage.priceDetailDTO.discountPrice != 0" color="#FF6262" :text="`优惠 ${orderMessage.priceDetailDTO.discountPrice} 元`" type="warning" <span
size="mini" mode="plain" shape="circle" /> v-if="orderMessage.priceDetailDTO.discountPrice">-{{orderMessage.priceDetailDTO.discountPrice | unitPrice}}</span>
<span>{{ <span v-else>0.00</span>
orderMessage.priceDetailDTO.discountPrice | unitPrice
}}</span>
</u-col> </u-col>
</u-row> </u-row>
</div> </div>
</div> </div>
<!-- 配送地区没有提示 --> <!-- 配送地区没有提示 -->
<div class="notSupportFreight" v-if="notSupportFreight.length !=0"> <div class="notSupportFreight" v-if="notSupportFreight.length !=0">
<u-notice-bar style="width:100%" :volume-icon="false" mode="horizontal" :list="notSupportFreightGoodsList"></u-notice-bar> <u-notice-bar style="width:100%" :volume-icon="false" mode="horizontal" :list="notSupportFreightGoodsList">
</u-notice-bar>
</div> </div>
<!-- 结账 --> <!-- 结账 -->
<div class="box6 mp-iphonex-bottom" v-if="orderMessage.priceDetailDTO"> <div class="box6 mp-iphonex-bottom" v-if="orderMessage.priceDetailDTO">
<div class="tabbar-left"> <div class="tabbar-left">
合计 <div v-if="!orderMessage.priceDetailDTO.payPoint" class="number">
<span class="number"> <span>¥</span>
¥ <span class="price">{{ formatPrice(orderMessage.priceDetailDTO.flowPrice)[0] }}</span>
<span>{{ orderMessage.priceDetailDTO.billPrice | unitPrice }}</span> <span>.{{formatPrice(orderMessage.priceDetailDTO.flowPrice)[1] }} </span>
</span> </div>
<span v-else class="number"><span
style="margin-right:10rpx;">{{orderMessage.priceDetailDTO.payPoint | unitPrice }}</span>积分</span>
</div> </div>
<div class="navRiv" @click="createTradeFun()"> <div class="navRiv" @click="createTradeFun()">
<!-- #ifndef MP-WEIXIN --> <!-- #ifndef MP-WEIXIN -->
@@ -322,6 +313,13 @@ export default {
mounted() {}, mounted() {},
methods: { methods: {
// 格式化金钱 1999 --> [1999,00]
formatPrice(val) {
if (typeof val == "undefined") {
return val;
}
return val.toFixed(2).split(".");
},
//发票回调 选择发票之后刷新购物车 //发票回调 选择发票之后刷新购物车
async callbackInvoice(val) { async callbackInvoice(val) {
this.invoiceFlag = false; this.invoiceFlag = false;
@@ -509,8 +507,7 @@ export default {
// 获取结算参数 // 获取结算参数
getOrderList() { getOrderList() {
// 获取购物车可用优惠券 this.notSupportFreight = []
this.getCartsCouponNums();
// 获取结算参数 // 获取结算参数
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) => {
@@ -520,6 +517,12 @@ export default {
}; };
}); });
this.orderMessage = res.data.result; this.orderMessage = res.data.result;
/**
* 为了避免路径传值在h5中超出限制问题
* 这块将可用的优惠券以及不可用的优惠券放入到vuex里面进行存储
*/
this.$store.state.canUseCoupons = res.data.result.canUseCoupons;
this.$store.state.cantUseCoupons = res.data.result.cantUseCoupons;
if (!res.data.result.memberAddress.id) { if (!res.data.result.memberAddress.id) {
// 获取会员默认地址 // 获取会员默认地址
@@ -543,20 +546,20 @@ export default {
}); });
}, },
/**购物车可用优惠券 */
getCartsCouponNums() {
API_Trade.getCartCouponNum(this.routerVal.way).then((res) => {
if (res.data.success) {
this.couponNums = res.data.result;
}
});
},
// //
}, },
}; };
</script> </script>
<style scoped>
page {
background: #ededed !important;
}
</style>
<style scoped lang="scss"> <style scoped lang="scss">
.flex-8 {
flex: 8;
}
.main-color { .main-color {
font-weight: bold; font-weight: bold;
} }
@@ -567,12 +570,13 @@ export default {
} }
.promotionNotice { .promotionNotice {
font-size: 24rpx; font-size: 24rpx;
margin: 20rpx 0;
color: $aider-light-color; color: $aider-light-color;
} }
.nums { .nums {
flex: 2;
color: $light-color; color: $light-color;
float: right;
width: 15%;
text-align: center; text-align: center;
} }
.wait { .wait {
@@ -621,11 +625,8 @@ export default {
.group-title { .group-title {
text-align: center; text-align: center;
font-size: 28rpx; font-size: 28rpx;
font-family: PingFang SC, PingFang SC-Regular;
font-weight: 400; font-weight: 400;
color: $light-color; color: $light-color;
} }
@@ -641,7 +642,6 @@ export default {
.group { .group {
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -662,15 +662,7 @@ export default {
height: 4rpx; height: 4rpx;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
background: url("/pages/floor/imgs/line.png") no-repeat; background: url("@/pages/order/imgs/line.png") no-repeat;
}
.tabC {
> p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
} }
.box2 { .box2 {
@@ -699,21 +691,6 @@ export default {
width: 100% !important; width: 100% !important;
} }
.userClass {
font-weight: bold;
font-size: 32rpx;
color: $u-content-color;
> span {
margin-left: 20rpx;
}
}
.userAdress {
margin: 20rpx 0;
color: $u-tips-color;
font-size: 26rpx;
}
.box6 { .box6 {
position: fixed; position: fixed;
bottom: 0; bottom: 0;
@@ -752,7 +729,7 @@ export default {
border-radius: 0.4em; border-radius: 0.4em;
} }
.sp_promotion { .goods-promotion {
float: left; float: left;
width: 75%; width: 75%;
margin: 4rpx 0; margin: 4rpx 0;
@@ -772,15 +749,9 @@ export default {
margin-left: 0; margin-left: 0;
} }
.sp_name { .goods-name {
float: left; flex: 8;
width: 75%;
font-size: 28rpx; font-size: 28rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.sp_type { .sp_type {
@@ -792,28 +763,21 @@ export default {
.number { .number {
color: $main-color; color: $main-color;
font-size: 26rpx; font-size: 26rpx;
margin-left: 10rpx; font-weight: bold;
> span { > span {
font-size: 36rpx; font-size: 36rpx;
} }
} }
.sp_number { .goods-prices {
color: $light-color; margin: 10rpx 0;
color: $main-color;
font-size: 28rpx; font-size: 28rpx;
} font-weight: bold;
> .goods-price {
.box1 { font-size: 38rpx;
background: #f6f6f6 !important; padding: 0 2rpx;
min-height: 166rpx;
// height: 200rpx;
/deep/ .u-row {
border: none;
} }
margin-bottom: 0 !important;
} }
.box { .box {
@@ -821,18 +785,19 @@ export default {
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
margin-bottom: 20rpx; margin-bottom: 20rpx;
color: #666;
padding: 0 32rpx; padding: 0 32rpx;
} }
.wrapper { .wrapper {
background: #f9f9f9;
height: auto; height: auto;
background: #f7f7f7;
padding-bottom: 200rpx; padding-bottom: 200rpx;
overflow: auto !important; overflow: auto !important;
} }
.ybname { .store-name {
margin-left: 20rpx; margin-top: 32rpx;
font-weight: 400; font-weight: 400;
color: #333333; color: #333333;
} }
@@ -843,18 +808,66 @@ export default {
/deep/ .u-col-3, /deep/ .u-col-3,
.tipsColor { .tipsColor {
color: $u-tips-color; color: #333;
} }
.tabL { .goods-image {
text-align: left; text-align: left;
overflow: hidden; overflow: hidden;
}
.default {
background: $main-color;
font-size: 24rpx;
border-radius: 8rpx;
padding: 0rpx 12rpx;
color: #fff;
margin-right: 20rpx;
}
.address-box {
border-radius: 40rpx;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
overflow: hidden;
background: #fff;
margin-bottom: 20rpx;
color: #666;
}
/deep/ .u-image, .address-item {
.u-image__image { font-weight: normal;
width: 132rpx !important; letter-spacing: 1rpx;
height: 132rpx !important; }
border-radius: 0.4em !important; .user-box {
padding: 32rpx;
}
.user-address-detail {
color: #333;
font-size: 38rpx;
font-weight: bold;
margin: 20rpx 0;
letter-spacing: 1rpx;
}
.mobile {
margin-left: 20rpx;
}
.price {
font-size: 50rpx !important;
margin: 0 2rpx;
}
.goods-detail {
display: flex;
flex-direction: column;
justify-content: center;
flex: 8;
margin-left: 20rpx !important;
> p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
} }
.goods-item {
margin: 20rpx 0;
}
</style> </style>

View File

Before

Width:  |  Height:  |  Size: 367 B

After

Width:  |  Height:  |  Size: 367 B

View File

@@ -79,7 +79,11 @@ export default {
}, },
}); });
} else { } else {
this.$api.msg("暂无发票可预览"); uni.showToast({
title: "暂无发票可预览",
duration: 2000,
icon: "none",
});
} }
}, },
download() { download() {
@@ -95,7 +99,11 @@ export default {
uni.saveFile({ uni.saveFile({
tempFilePath: tempFilePath, tempFilePath: tempFilePath,
success: function (res) { success: function (res) {
_this.$api.msg("发票已下载到" + res.savedFilePath); uni.showToast({
title: "发票已下载到" + res.savedFilePath,
duration: 2000,
icon: "none",
});
}, },
}); });
} }
@@ -103,7 +111,11 @@ export default {
}); });
}); });
} else { } else {
this.$api.msg("暂无发票可下载"); uni.showToast({
title: "暂无发票可下载",
duration: 2000,
icon: "none",
});
} }
}, },
}, },
@@ -193,13 +205,6 @@ export default {
} }
} }
.btn {
font-size: 34rpx;
margin: 60rpx 20rpx;
&::after {
border: none;
}
}
.u-cell { .u-cell {
padding: 35rpx 20rpx; padding: 35rpx 20rpx;
height: 110rpx; height: 110rpx;

View File

@@ -57,7 +57,7 @@
<u-button ripple :customStyle="{'background':lightColor,'color':'#fff' }" shape="circle" class="pay-btn" size="mini" v-if="order.allowOperationVO.rog" @click="onRog(order.sn)"> <u-button ripple :customStyle="{'background':lightColor,'color':'#fff' }" shape="circle" class="pay-btn" size="mini" v-if="order.allowOperationVO.rog" @click="onRog(order.sn)">
确认收货 确认收货
</u-button> </u-button>
<u-button ripple shape="circle" class="cancel-btn" size="mini" v-if="order.groupAfterSaleStatus=='NOT_APPLIED'" @click="applyService(order)"> <u-button ripple shape="circle" class="cancel-btn" size="mini" v-if="order.groupAfterSaleStatus.includes('NOT_APPLIED')" @click="applyService(order)">
退款/售后 退款/售后
</u-button> </u-button>
<!-- TODO 后续完善 --> <!-- TODO 后续完善 -->
@@ -219,6 +219,7 @@ export default {
if (status == 0) { if (status == 0) {
this.loadData(status); this.loadData(status);
} }
}, },
watch: { watch: {
@@ -504,6 +505,9 @@ page,
.swiper-box { .swiper-box {
height: calc(100vh - 40px); height: calc(100vh - 40px);
// #ifdef H5
height: calc(100vh - 40px - 44px);
// #endif
} }
.list-scroll-content { .list-scroll-content {

View File

@@ -155,7 +155,7 @@
<view class="invoice-info-view"> <view class="invoice-info-view">
<view class="ltitle">发票信息</view> <view class="ltitle">发票信息</view>
<view v-if="!order.needReceipt" class="value">无需发票</view> <view v-if="!order.needReceipt" class="value">无需发票</view>
<view v-else class="value" @click="onReceipt(order.receiptVO)">查看发票</view> <view v-else class="value" @click="onReceipt(orderDetail.receipt)">查看发票</view>
</view> </view>
</view> </view>
</view> </view>

View File

@@ -1,246 +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; with:100%;">
<u-input 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" class="text-tips">{{ tips }}</view>
</div>
</u-form-item>
<view class="submit" @click="submit">登录</view>
<view 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 {
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() {
// whetherNavigate();
this.$refs.validateCodeForm.setRules(this.codeRules);
/**
* 条件编译判断当前客户端类型
*/
//#ifdef H5
this.clientType = "H5";
//#endif
//#ifdef APP-PLUS
this.clientType = "APP";
//#endif
},
watch: {
async flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
// 向后端请求验证码
uni.showLoading({
title: "正在获取验证码",
});
let res = await sendMobile(this.codeForm.mobile);
uni.hideLoading();
// 这里此提示会被this.start()方法中的提示覆盖
if (res.data.success) {
this.$refs.uCode.start();
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
this.flage = false;
}
} else {
this.$u.toast("请倒计时结束后再发送");
}
} else {
this.$refs.verification.hide();
}
},
},
methods: {
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
// 登录
submit() {
if (!this.status) {
/**
* 用户必须了解
* 用户协议以及隐私政策
*/
uni.showToast({
title: "请您阅读并同意用户协议以及隐私政策",
duration: 2000,
icon: "none",
});
return false;
}
let _this = this;
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
/**
* 清空当前账号信息
*/
storage.setHasLogin(false);
storage.setAccessToken("");
storage.setRefreshToken("");
storage.setUuid(this.uuid.v1());
storage.setUserInfo({});
/**
* 执行登录
*/
smsLogin(this.codeForm, _this.clientType).then((res) => {
if (res.data.success) {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
/**
* 登录成功后获取个人信息
*/
getUserInfo().then((user) => {
if (user.data.success) {
/**
* 个人信息存储到缓存userInfo中
*/
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
// 登录成功
uni.showToast({
title: "登录成功!",
icon: "none",
});
/**
* 计算出当前router路径
* 1.如果跳转的链接为登录页面或跳转的链接为空页面。则会重新跳转到首页
* 2.都不满足返回跳转页面
*/
whetherNavigate();
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
});
}
});
},
// 跳转到一键登录
clickLogin() {
this.$emit("open", "click");
},
/**点击验证码*/
codeChange(text) {
this.tips = text;
},
/** 结束验证码后执行 */
end() {},
/**获取验证码 */
getCode() {
if (this.tips == "重新获取") {
this.codeFlag = true;
uni.showLoading({
title: "加载中",
});
setTimeout(() => {
this.$refs.verification.hide();
uni.hideLoading();
}, 2000);
}
if (!this.$u.test.mobile(this.codeForm.mobile)) {
uni.showToast({
title: "请输入正确手机号",
icon: "none",
});
return false;
}
if (!this.flage) {
this.$refs.verification.error();
return false;
}
},
// 点击获取验证码
start() {
this.$u.toast("验证码已发送");
this.flage = false;
this.codeFlag = false;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("./login.scss");
// #ifdef MP-WEIXIN
@import url("./mp-codeLogin.scss");
// #endif
</style>

View File

@@ -6,7 +6,6 @@
margin: 40rpx 0; margin: 40rpx 0;
} }
.login-ball { .login-ball {
background-image: linear-gradient(25deg, #fa123b, #ff6b35, #ff9f28, #ffcc03);
border-bottom-left-radius: 300rpx; border-bottom-left-radius: 300rpx;
height: 400rpx; height: 400rpx;
position: relative; position: relative;
@@ -43,25 +42,22 @@ span {
.submit { .submit {
height: 80rpx; height: 80rpx;
line-height: 80rpx; line-height: 80rpx;
background-image: linear-gradient(90deg, #ff6b35, #ff9f28, #ffcc03);
color: #fff; color: #fff;
text-align: center; text-align: center;
font-size: 30rpx; font-size: 30rpx;
border-radius: 100px; border-radius: 100px;
} }
.logo { .logo {
margin-top: 20rpx;
width: 200rpx; width: 200rpx;
height: 200rpx; height: 200rpx;
text-align: center; text-align: center;
transform: scale(2.5);
} }
.logo-cell { .logo-cell {
text-align: center; text-align: center;
} }
.text-tips { .text-tips {
text-align: center; text-align: center;
color: #ff9f28;
} }
.tips { .tips {
position: absolute; position: absolute;

View File

@@ -1,55 +1,129 @@
<template> <template>
<view v-if="mpWechatLogin"> <div class="wrapper">
<!-- 背景 --> <div v-if="!wechatLogin">
<view class="login-ball small"></view> <u-navbar :is-back="showBack" :border-bottom="false"></u-navbar>
<div>
<div class="title">{{loginTitleWay[current].title}}</div>
<div :class="current == 1 ? 'desc-light':'desc'">{{loginTitleWay[current].desc}}<span
v-if="current == 1">{{mobile | secrecyMobile}}</span></div>
</div>
<!-- 手机号 -->
<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>
<view class="logo-cell"> </div>
<image class="logo" src="/static/logo.png" mode="aspectFit"></image> <!-- 输入验证码 -->
</view> <div v-show="current==1" class="box-code">
<view class="title">LiLi商城</view> <verifyCode type="bottom" @confirm="submit" boxActiveColor="#D8D8D8" v-model="code" isFocus
boxNormalColor="#D8D8D8" cursorColor="#D8D8D8" />
<!-- 验证码登录 --> <div class="fetch-btn">
<codeLogin @open="open" :status="value" v-if="login && loginData.code" /> <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>
<onClickLogin @open="open" :status="value" v-if="login && loginData.click" /> <span @tap="fetchCode" :style="{color:codeColor}"> {{tips}}</span>
<view class="form"> </view> </div>
</div>
<!-- 隐私政策 --> <!-- 循环出当前可使用的第三方登录模式 -->
<div class="privacy"> <div class="flex login-list">
<u-checkbox-group :icon-size="24" width="45rpx"> <div :style="{background:item.color}" class="login-item" v-for="(item,index) in loginList" :key="index">
<u-checkbox v-model="value" active-color="rgb(255, 107, 53)"></u-checkbox> <u-icon v-if="item.title!='APPLE'" color="#fff" size="42" :name="item.icon" @click="navigateLogin(item)">
</u-icon>
</u-checkbox-group> <u-image v-else src="/static/appleidButton@2x.png" :lazy-load="false" @click="navigateLogin(item)" width="80"
同意<span @click="handleClick('user')">用户协议</span><span @click="handleClick('privacy')">隐私政策</span> height="80" />
</div>
</div>
<myVerification v-if="codeFlag" @send="verification" class="verification" ref="verification" business="LOGIN" />
</div> </div>
</view> <view v-else>
<wechatH5Login />
</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 wechatH5Login from "./wechatH5Login.vue";
import { webConnect } from "@/api/connect.js"; import { webConnect } from "@/api/connect.js";
export default { export default {
onShow() { components: { myVerification, verifyCode, wechatH5Login },
// #ifdef MP-WEIXIN
this.mpWechatLogin = false;
if (this.$options.filters.isLogin("auth")) {
getCurrentPages().length > 1
? uni.navigateBack({
delta: getCurrentPages().length - 2,
})
: uni.switchTab({
url: "/pages/tabbar/home/index",
});
} else {
uni.navigateTo({
url: "/pages/passport/wechatMPLogin",
});
}
// #endif
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() {
//#ifdef H5 //#ifdef H5
let isWXBrowser = /micromessenger/i.test(navigator.userAgent); let isWXBrowser = /micromessenger/i.test(navigator.userAgent);
if (isWXBrowser) { if (isWXBrowser) {
@@ -62,45 +136,139 @@ export default {
} }
//#endif //#endif
}, },
data() {
return {
mpWechatLogin: true, //是否加载微信登录
value: true, //隐私政策
loginData: {
code: true, //验证码登录
click: false,
},
login: true, //登录
};
},
watch: {},
components: {
codeLogin,
onClickLogin,
},
mounted() {
// #ifndef APP-PLUS
//判断是否微信浏览器
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
this.wechatLogin = true;
return;
}
// #endif
/**
* 条件编译判断当前客户端类型
*/
//#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
},
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) => {
let data = res.data; let data = res.data;
if (data.success) { if (data.success) {
storage.setAccessToken(data.result.accessToken); storage.setAccessToken(data.result.accessToken);
@@ -124,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>

View File

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

View File

@@ -1,280 +0,0 @@
<template>
<div class="form">
<u-form ref="validateCodeForm">
<div class="login-list">
<!-- 循环出当前可使用的第三方登录模式 -->
<div class="login-item" v-for="(item,index) in loginList" :key="index">
<u-icon :color="item.color" size="80" :name="item.icon" @click="navigateLogin(item)"></u-icon>
</div>
</div>
<view 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 {
loginList: [
{
icon: "weixin-circle-fill",
color: "#00a327",
title: "微信",
code: "WECHAT",
},
{
icon: "qq-circle-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) => {
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
});
whetherNavigate()
}
});
},
//微信小程序获取openid
async weixinMPOpenID(res) {
await miniProgramLogin(res.code).then((res) => {
uni.setStorageSync("openid", res.data);
});
},
},
};
</script>
<style lang="scss" scoped>
@import url("./login.scss");
.submit {
margin: 80rpx 0 40rpx 0;
}
.login-list {
display: flex;
padding: 40rpx 0;
justify-content: space-between;
.login-item {
font-size: 24rpx;
text-align: center;
> * {
margin: 4rpx 0;
}
}
}
</style>

View File

@@ -0,0 +1,153 @@
<template>
<view class="container">
<u-navbar :custom-back="back" title="公众网页登录"></u-navbar>
<view class="wx-auth-container">
<div class="box">
<view class="logo-info">
<text class="title">欢迎进入{{ projectName }}</text>
</view>
<view class="small-tips">
<view>为您提供优质服务,{{ projectName }}需要获取以下信息</view>
<view>您的公开信息昵称头像</view>
</view>
<view class="btns">
<button @click="getUserProfile()" class="btn-auth">使用微信授权</button>
<div @click="backToHome" class="btn-callback">暂不登录</div>
</view>
</div>
</view>
</view>
</template>
<script>
import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
import config from "@/config/config";
import api from "@/config/api.js";
export default {
data() {
return {
// 授权信息展示,商城名称
projectName: config.name,
};
},
//微信小程序进入页面先获取code否则几率出现code和后续交互数据不对应情况
mounted() {
// 小程序默认分享
uni.showShareMenu({ withShareTicket: true });
},
methods: {
back() {
whetherNavigate();
},
getUserProfile() {
let code = "WECHAT";
let buyer = api.buyer;
window.open(buyer + `/connect/login/web/` + code, "_self");
},
backToHome() {
uni.switchTab({
url: `/pages/tabbar/home/index`,
});
},
},
};
</script>
<style lang="scss" scoped>
.wx-auth-container {
width: 100%;
margin-top: 20%;
}
.logo-info {
display: flex;
flex-wrap: nowrap;
justify-content: flex-start;
flex-direction: row;
align-items: flex-start;
padding: 20rpx;
flex-direction: column;
font-weight: bold;
}
image {
width: 100px;
height: 100px;
text-align: center;
-webkit-transform: scale(2.5);
transform: scale(2.5);
}
text.title,
text.shop {
display: inline-block;
font-size: 60rpx;
color: #333;
}
.box {
margin: 0 32rpx;
}
/* 文字提示*/
.small-tips {
width: 94%;
padding: 20rpx;
font-size: 24rpx;
margin: 0 0 20rpx;
color: #999;
}
.btn-auth {
width: 92%;
background: $light-color;
color: #fff;
margin: 0 auto 40rpx;
border-radius: 100px;
animation: mymove 5s infinite;
-webkit-animation: mymove 5s infinite; /*Safari and Chrome*/
animation-direction: alternate; /*轮流反向播放动画。*/
animation-timing-function: ease-in-out; /*动画的速度曲线*/
/* Safari 和 Chrome */
-webkit-animation: mymove 5s infinite;
-webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
}
.btn-callback {
text-align: center;
font-size: 30rpx;
background: #ededed;
height: 90rpx;
line-height: 90rpx;
border-radius: 100px;
width: 92%;
margin: 0 auto;
}
.btns {
margin-top: 100rpx;
display: flex;
flex-direction: column;
width: 100%;
justify-content: center;
}
@keyframes mymove {
0% {
transform: scale(1); /*开始为原始大小*/
}
25% {
transform: scale(1.1); /*放大1.1倍*/
}
50% {
transform: scale(1);
}
75% {
transform: scale(1.1);
}
}
</style>

View File

@@ -12,14 +12,15 @@
<view class="wx-auth-container"> <view class="wx-auth-container">
<div class="box"> <div class="box">
<view class="logo-info"> <view class="logo-info">
<text class="title">欢迎进入{{ projectName }}商城</text> <text class="title">欢迎进入{{ projectName }}</text>
</view> </view>
<view class="small-tips"> <view class="small-tips">
<view>为您提供优质服务,{{ projectName }}需要获取以下信息</view> <view>为您提供优质服务,{{ projectName }}需要获取以下信息</view>
<view>您的公开信息昵称头像</view> <view>您的公开信息昵称头像</view>
</view> </view>
<view class="btns"> <view class="btns">
<button type="primary" bindtap="getUserProfile" @click="getUserProfile()" class="btn-auth">确认微信授权</button> <button type="primary" bindtap="getUserProfile" @click="getUserProfile()" class="btn-auth">使用微信授权</button>
<div @click="backToHome" class="btn-callback">暂不登录</div>
</view> </view>
</div> </div>
</view> </view>
@@ -32,13 +33,14 @@ import { mpAutoLogin } from "@/api/connect.js";
import { whetherNavigate } from "@/utils/Foundation"; //登录跳转 import { whetherNavigate } from "@/utils/Foundation"; //登录跳转
import { getUserInfo } from "@/api/members"; import { getUserInfo } from "@/api/members";
import storage from "@/utils/storage.js"; import storage from "@/utils/storage.js";
import config from '@/config/config'
export default { export default {
data() { data() {
return { return {
// 是否展示手机号码授权弹窗,默认第一步不展示,要先获取用户基础信息 // 是否展示手机号码授权弹窗,默认第一步不展示,要先获取用户基础信息
phoneAuthPopup: false, phoneAuthPopup: false,
// 授权信息展示,商城名称 // 授权信息展示,商城名称
projectName: "LiLi", projectName: config.name,
//微信返回信息用于揭秘信息获取sessionkey //微信返回信息用于揭秘信息获取sessionkey
code: "", code: "",
//微信昵称 //微信昵称
@@ -50,7 +52,6 @@ export default {
//微信小程序进入页面先获取code否则几率出现code和后续交互数据不对应情况 //微信小程序进入页面先获取code否则几率出现code和后续交互数据不对应情况
mounted() { mounted() {
// 小程序默认分享 // 小程序默认分享
uni.showShareMenu({ withShareTicket: true }); uni.showShareMenu({ withShareTicket: true });
@@ -73,7 +74,12 @@ export default {
*/ */
back() { back() {
whetherNavigate('wx'); whetherNavigate("wx");
},
backToHome() {
uni.switchTab({
url: `/pages/tabbar/home/index`,
});
}, },
//获取用户信息 //获取用户信息
getUserProfile(e) { getUserProfile(e) {
@@ -129,11 +135,10 @@ export default {
getUserInfo().then((user) => { getUserInfo().then((user) => {
storage.setUserInfo(user.data.result); storage.setUserInfo(user.data.result);
storage.setHasLogin(true); storage.setHasLogin(true);
setTimeout(() => {
uni.navigateBack({ uni.navigateBack({
delta: 1, delta: 1,
}); });
}, 500);
}); });
}); });
}, },
@@ -218,27 +223,55 @@ text.shop {
} }
.register { .register {
color: #00a327 !important; color: $weChat-color !important;
border: none !important; border: none !important;
background: #fff !important; background: #fff !important;
} }
.btn {
width: 100%;
text-align: center;
}
.btn-auth { .btn-auth {
width: 92%; width: 92%;
margin: 0 auto 100rpx; margin: 0 auto 40rpx;
border-radius: 100px; border-radius: 100px;
animation: mymove 5s infinite;
-webkit-animation: mymove 5s infinite; /*Safari and Chrome*/
animation-direction: alternate; /*轮流反向播放动画。*/
animation-timing-function: ease-in-out; /*动画的速度曲线*/
/* Safari 和 Chrome */
-webkit-animation: mymove 5s infinite;
-webkit-animation-direction: alternate; /*轮流反向播放动画。*/
-webkit-animation-timing-function: ease-in-out; /*动画的速度曲线*/
}
.btn-callback {
text-align: center;
font-size: 30rpx;
background: #ededed;
height: 90rpx;
line-height: 90rpx;
border-radius: 100px;
width: 92%;
margin: 0 auto;
} }
.btns { .btns {
margin-top: 100rpx; margin-top: 100rpx;
display: flex; display: flex;
flex-direction: column;
width: 100%; width: 100%;
justify-content: center; justify-content: center;
} }
@keyframes mymove {
0% {
transform: scale(1); /*开始为原始大小*/
}
25% {
transform: scale(1.1); /*放大1.1倍*/
}
50% {
transform: scale(1);
}
75% {
transform: scale(1.1);
}
}
</style> </style>

View File

@@ -7,9 +7,11 @@
<!-- 仅h5有效 打开App --> <!-- 仅h5有效 打开App -->
<!-- 分享 --> <!-- 分享 -->
<shares v-if="shareFlage && goodsDetail.id" :skuId="this.routerVal.id" :goodsId="this.routerVal.goodsId" :link="'/pages/product/goods?id='+this.routerVal.id+'&goodsId='+this.routerVal.goodsId" <shares v-if="shareFlage && goodsDetail.id" :skuId="this.routerVal.id" :goodsId="this.routerVal.goodsId"
:link="'/pages/product/goods?id='+this.routerVal.id+'&goodsId='+this.routerVal.goodsId"
:thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods" @close="shareFlage = false" /> :thumbnail="goodsDetail.thumbnail" :goodsName="goodsDetail.goodsName" type="goods" @close="shareFlage = false" />
<popups v-model="popupsSwitch" @tapPopup="handleNavbarList" :popData="navbarListData" :x="navbarListX" :y="navbarListY" placement="top-start" /> <popups v-model="popupsSwitch" @tapPopup="handleNavbarList" :popData="navbarListData" :x="navbarListX"
:y="navbarListY" placement="top-start" />
<view class="index"> <view class="index">
<!-- topBar --> <!-- topBar -->
@@ -22,7 +24,8 @@
</div> </div>
<div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'"> <div class="headerList" :class="headerFlag ? 'tab-bar' : 'tab-bar scroll-hide'">
<div class="headerRow"> <div class="headerRow">
<div class="nav-item" v-for="header in headerList" :key="header.id" :class="{ cur: scrollId === header.id }" @click="headerTab(header.id)"> <div class="nav-item" v-for="header in headerList" :key="header.id"
:class="{ cur: scrollId === header.id }" @click="headerTab(header.id)">
{{ header.text }} {{ header.text }}
</div> </div>
</div> </div>
@@ -30,7 +33,8 @@
</div> </div>
</u-navbar> </u-navbar>
<u-navbar :border-bottom="false" v-show="!headerFlag" class="header-only-back" :background="navbarOnlyBack" :is-back="false"> <u-navbar :border-bottom="false" v-show="!headerFlag" class="header-only-back" :background="navbarOnlyBack"
:is-back="false">
<div> <div>
<div class="bg-back"> <div class="bg-back">
<u-icon size="40" @click="back()" name="arrow-left" class="icon-back"></u-icon> <u-icon size="40" @click="back()" name="arrow-left" class="icon-back"></u-icon>
@@ -42,7 +46,8 @@
</view> </view>
<view class="product-container" :style="{ height: productRefHeight }" ref="productRef" id="productRef"> <view class="product-container" :style="{ height: productRefHeight }" ref="productRef" id="productRef">
<scroll-view scroll-anchoring enableBackToTop="true" scroll-with-animation scroll-y class="scroll-page" :scroll-top="tabScrollTop" @scroll="pageScroll"> <scroll-view scroll-anchoring enableBackToTop="true" scroll-with-animation scroll-y class="scroll-page"
:scroll-top="tabScrollTop" @scroll="pageScroll">
<view> <view>
<!-- 轮播图 --> <!-- 轮播图 -->
<GoodsSwiper id="main1" :res="imgList" /> <GoodsSwiper id="main1" :res="imgList" />
@@ -58,7 +63,8 @@
{{ goodsDetail.goodsName || "" }} {{ goodsDetail.goodsName || "" }}
</view> </view>
<view class="favorite" @click="clickFavorite(goodsDetail.id)"> <view class="favorite" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'"></u-icon> <u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'">
</u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view> <view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view>
</view> </view>
</view> </view>
@@ -88,7 +94,8 @@
<view>分享</view> <view>分享</view>
</view> </view>
<view class="icons" @click="clickFavorite(goodsDetail.id)"> <view class="icons" @click="clickFavorite(goodsDetail.id)">
<u-icon size="30" :color="favorite ? '#f2270c' : '#262626'" :name="favorite ? 'heart-fill' : 'heart'"></u-icon> <u-icon size="30" :color="favorite ? '#f2270c' : '#262626'"
:name="favorite ? 'heart-fill' : 'heart'"></u-icon>
<view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view> <view :style="{ color: favorite ? '#f2270c' : '#262626' }">{{ favorite ? "已收藏" : "收藏" }}</view>
</view> </view>
</view> </view>
@@ -153,7 +160,8 @@
<storeLayout id="main7" :storeDetail="storeDetail" :goodsDetail="goodsDetail" :res="recommendList" /> <storeLayout id="main7" :storeDetail="storeDetail" :goodsDetail="goodsDetail" :res="recommendList" />
<!-- 宝贝详情 --> <!-- 宝贝详情 -->
<GoodsIntro id="main9" :res="goodsDetail" :goodsParams="goodsParams" :goodsId="goodsDetail.goodsId" v-if="goodsDetail.id" /> <GoodsIntro id="main9" :res="goodsDetail" :goodsParams="goodsParams" :goodsId="goodsDetail.goodsId"
v-if="goodsDetail.id" />
<!-- 宝贝推荐 --> <!-- 宝贝推荐 -->
<GoodsRecommend id="main11" :res="likeGoodsList" /> <GoodsRecommend id="main11" :res="likeGoodsList" />
@@ -178,7 +186,8 @@
</view> </view>
<!-- 正常结算页面 --> <!-- 正常结算页面 -->
<view class="detail-btn" v-if="!isGroup"> <view class="detail-btn" v-if="!isGroup">
<view class="to-store-car to-store-btn" v-if="goodsDetail.goodsType!='VIRTUAL_GOODS'" @click="shutMask(4)">加入购物车</view> <view class="to-store-car to-store-btn" v-if="goodsDetail.goodsType!='VIRTUAL_GOODS'" @click="shutMask(4)">
加入购物车</view>
<view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view> <view class="to-buy to-store-btn" @click="shutMask(4, 'buy')">立即购买</view>
<view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view> <view class="to-store-car to-store-btn" v-if="startTimer">暂未开始</view>
</view> </view>
@@ -195,30 +204,33 @@
</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" :goodsId="goodsDetail.id" :addressFlag="addressFlag" /> <popupAddress @closeAddress="closePopupAddress" @deliveryData="deliveryFun" v-if="goodsDetail.id"
:goodsId="goodsDetail.id" :addressFlag="addressFlag" />
<!-- 商品规格 商品详情以及默认参与活动的id--> <!-- 商品规格 商品详情以及默认参与活动的id-->
<popupGoods :addr="delivery" ref="popupGoods" @changed="changedGoods" @closeBuy="closePopupBuy" @queryCart="cartCount()" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" :id="productId" <popupGoods :addr="delivery" ref="popupGoods" @changed="changedGoods" @closeBuy="closePopupBuy"
@queryCart="cartCount()" :goodsDetail="goodsDetail" :goodsSpec="goodsSpec" :id="productId"
v-if="goodsDetail.id " :pointDetail="pointDetail" @handleClickSku="selectSku" :buyMask="buyMask" /> v-if="goodsDetail.id " :pointDetail="pointDetail" @handleClickSku="selectSku" :buyMask="buyMask" />
</view> </view>
</view> </view>
@@ -251,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,
@@ -274,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轴
@@ -328,7 +344,7 @@ export default {
top: 0, top: 0,
height: 50, height: 50,
}, },
goodsParams: [], // 商品参数 goodsParams: [], // 商品参数
headerFlag: false, //顶部导航显示与否 headerFlag: false, //顶部导航显示与否
headerList: [ headerList: [
//顶部导航文字按照规则来 详情全局搜索 //顶部导航文字按照规则来 详情全局搜索
@@ -362,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, //添加购物车直接购买,查看已选 弹窗
@@ -395,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) {
@@ -468,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]);
} }
}); });
@@ -475,12 +481,23 @@ export default {
this.init( this.init(
this.routerVal.id, this.routerVal.id,
this.routerVal.goodsId, this.routerVal.goodsId,
this.routerVal.distributionId, this.routerVal.distributionId
this.routerVal.whetherPoint
); );
} }
}, },
// #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}`;
},
/** /**
* 导航栏列表栏 * 导航栏列表栏
*/ */
@@ -506,35 +523,32 @@ export default {
/** /**
* 初始化信息 * 初始化信息
*/ */
async init(id, goodsId, distributionId) { async init(id, goodsId, distributionId = "") {
console.log(id, goodsId);
this.isGroup = false; //初始化拼团 this.isGroup = false; //初始化拼团
this.productId = id; // skuId this.productId = id; // skuId
// 这里请求获取到页面数据 解析数据 // 这里请求获取到页面数据 解析数据
uni.showLoading({
title: "加载中",
mask: true,
});
let response = await getGoods(id, goodsId); let response = await getGoods(id, goodsId);
if (!response.data.success) {
uni.navigateBack();
return false;
}
console.log(response);
if (!response.data.success) {
setTimeout(() => {
uni.navigateBack();
}, 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;
} }
} }
uni.hideLoading();
/**商品信息以及规格信息存储 */ /**商品信息以及规格信息存储 */
this.goodsDetail = response.data.result.data; this.goodsDetail = response.data.result.data;
this.goodsSpec = response.data.result.specs; this.goodsSpec = response.data.result.specs;
this.PromotionList = response.data.result.promotionMap; this.PromotionList = response.data.result.promotionMap;
this.goodsParams = response.data.result.goodsParamsDTOList || [] this.goodsParams = response.data.result.goodsParamsDTOList || [];
// 判断是否拼团活动或者积分商品 如果有则显示拼团活动信息 // 判断是否拼团活动或者积分商品 如果有则显示拼团活动信息
this.PromotionList && this.PromotionList &&
@@ -552,7 +566,7 @@ export default {
this.imgList = this.goodsDetail.goodsGalleryList; this.imgList = this.goodsDetail.goodsGalleryList;
// 获取店铺基本信息 // 获取店铺基本信息
this.getstoreBaseInfoFun(this.goodsDetail.storeId); this.getStoreBaseInfoFun(this.goodsDetail.storeId);
// 获取购物车 // 获取购物车
this.cartCount(); this.cartCount();
@@ -621,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;
}, },
/** 参与拼团 创建拼团 */ /** 参与拼团 创建拼团 */
@@ -676,8 +690,8 @@ export default {
/** /**
* 获取店铺信息 * 获取店铺信息
*/ */
getstoreBaseInfoFun(id) { getStoreBaseInfoFun(id) {
API_store.getstoreBaseInfo(id).then((res) => { API_store.getStoreBaseInfo(id).then((res) => {
if (res.data.success) { if (res.data.success) {
this.storeDetail = res.data.result; this.storeDetail = res.data.result;
} }
@@ -704,7 +718,7 @@ export default {
*/ */
getGoodsCollectionFun(goodsId) { getGoodsCollectionFun(goodsId) {
if (storage.getHasLogin()) { if (storage.getHasLogin()) {
API_Members.getGoodsIsCollect(goodsId, "GOODS").then((res) => { API_Members.getGoodsIsCollect("GOODS", goodsId).then((res) => {
this.favorite = res.data.result; this.favorite = res.data.result;
}); });
} }
@@ -726,6 +740,7 @@ export default {
/** /**
* 获取相似商品列表 * 获取相似商品列表
*
*/ */
getOtherLikeGoods() { getOtherLikeGoods() {
getGoodsList({ getGoodsList({
@@ -734,8 +749,8 @@ 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;
console.warn(this.likeGoodsList);
}); });
}, },
@@ -771,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) {
@@ -800,10 +814,6 @@ export default {
break; break;
} }
} else {
this.maskFlag = false;
this.cuxiao = false;
this.buyMask = false;
} }
}, },
@@ -816,7 +826,7 @@ export default {
this.deleteGoodsCollectionFun(id); this.deleteGoodsCollectionFun(id);
return false; return false;
} }
API_Members.collectionGoods(id, "GOODS").then((res) => { API_Members.collectionGoods("GOODS", id).then((res) => {
if (res.data.success) { if (res.data.success) {
uni.showToast({ uni.showToast({
title: "收藏成功!", title: "收藏成功!",

View File

@@ -0,0 +1,56 @@
<template>
<div class="wrapper">
<p>公司名称{{storeData.companyName}}</p>
<p>公司地址{{storeData.companyAddress}}</p>
<p>公司地址地区{{storeData.companyAddressPath}}</p>
<p>员工人数{{storeData.employeeNum}}</p>
<p>法定经营范围{{storeData.scope}}</p>
<u-image @click="preview()" width="100%" height="400rpx" mode="aspectFit" :src="storeData.licencePhoto"></u-image>
</div>
</template>
<script>
import { getLicencePhoto } from "@/api/store.js";
export default {
data() {
return {
storeData: {},
};
},
onLoad(options) {
this.getStoreLicencePhoto(options.id);
},
methods: {
async getStoreLicencePhoto(id) {
let res = await getLicencePhoto(id);
if (res.data.success) {
this.storeData = res.data.result;
}
},
/**
* 点击图片放大或保存
*/
preview() {
uni.previewImage({
current: 0,
urls: [this.storeData.licencePhoto],
longPressActions: {
itemList: ["保存图片"],
success: function (data) {},
fail: function (err) {},
},
});
},
},
};
</script>
<style lang="scss" scoped>
.wrapper {
padding: 32rpx;
> p {
margin: 20rpx 0;
}
}
</style>

View File

@@ -1,6 +0,0 @@
.search{
margin-top: 28rpx !important;
}
.status_bar{
height: calc(var(--status-bar-height) + 188rpx ) !important;
}

View File

@@ -71,14 +71,14 @@ export default {
goodsDetail: { goodsDetail: {
handler(val) { handler(val) {
this.grade = val.grade; this.grade = val.grade;
this.getGoodsComments(); this.getGoodsCommentsMethods();
}, },
deep: true, deep: true,
immediate: true, immediate: true,
}, },
}, },
mounted() { mounted() {
// this.getGoodsComments();
}, },
methods: { methods: {
parseLoaded() { parseLoaded() {
@@ -86,7 +86,7 @@ export default {
}, },
// 获取商品评论 // 获取商品评论
getGoodsComments() { getGoodsCommentsMethods() {
API_Members.getGoodsComments(this.goodsDetail.goodsId, this.params).then( API_Members.getGoodsComments(this.goodsDetail.goodsId, this.params).then(
(res) => { (res) => {
this.commDetail = res.data.result; this.commDetail = res.data.result;
@@ -223,10 +223,6 @@ export default {
color: #333; color: #333;
padding: 20rpx 0; padding: 20rpx 0;
} }
.img {
}
.bot { .bot {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -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>
@@ -125,7 +126,7 @@ export default {
width: 52rpx; width: 52rpx;
height: 6rpx; height: 6rpx;
background-image: linear-gradient(90deg, $jd-color, $jd-light-color); background-image: linear-gradient(90deg, $price-color, $price-light-color);
} }
} }
> .goods-detail-item { > .goods-detail-item {

Some files were not shown because too many files have changed in this diff Show More