77 Commits
v4.3 ... master

Author SHA1 Message Date
Yer11214
7939998a30 fix: 更新我的积分页面标题
- 将我的积分页面的导航栏标题更新为“我的积分”,以提升用户体验。
2025-10-21 11:01:18 +08:00
Yer11214
1fcc016ccd refactor: 将深度选择器语法更新为v-deep
-在多个Vue和SCSS文件中用::v-deep替换弃用的/deep/选择器,以便更好地与Vue的范围样式兼容。
2025-10-21 10:33:59 +08:00
Yer11214
3219f6d576 feat: 更新用户信息获取逻辑
- 在personMsg.vue中添加onShow生命周期钩子,重新获取用户信息并更新表单数据
- 在bindMobile.vue中绑定手机成功后,获取最新用户信息并更新缓存
- 调整绑定手机按钮的样式以改善用户体验
2025-09-16 10:39:10 +08:00
Yer11214
83da8f3003 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2025-06-05 17:41:12 +08:00
Yer11214
c858c82950 优化app中应用升级逻辑 2025-06-05 17:40:49 +08:00
Yer11214
f9c7610976 update README.md.
Signed-off-by: Yer11214 <17633066053@163.com>
2025-03-31 03:21:06 +00:00
Chopper711
919af44fda feat: 更新售后细节和用户工具页面 (master)
- 修改afterSalesDetailExpress.vue中gotoGoodsDetail函数参数
- 调整快递公司、快递单号和发货时间选择器样式
- 在tool.vue中添加邀请用户功能和分享弹窗
- 在request.js中增加请求头带上邀请人信息
- 移除tpl_goods.vue中的调试日志
- App.vue增加启动时设置邀请人逻辑
- storage.js新增邀请人信息的存取方法
2025-02-21 18:40:15 +08:00
Chopper711
db7cfcea85 fix: 投诉相关处理 2025-02-21 16:16:57 +08:00
chc
e95aed8e38 延时展示提示信息,防止被删除 2025-01-20 18:35:53 +08:00
chc
24454e2546 获取登录用户功能修复。 2025-01-20 17:40:35 +08:00
chc
0ee03d9fcf 登录后重新获取用户信息,如果抛出异常,清空token缓存,回到我的页面 2025-01-20 16:34:07 +08:00
chc
c93862066b 注销用户提示语句错误 2025-01-20 15:43:23 +08:00
chc
46dbeb77c8 查看分包裹物流 2024-12-25 10:36:47 +08:00
chc
8bcc9de352 修改密码增加验证密码选项 2024-12-18 11:45:31 +08:00
chc
bac8e3a327 修改米缺少提交接口修改 2024-12-18 10:58:06 +08:00
chc
29a20afe93 1.店铺入驻法人证件信息处理2.验证手机号修改密码不需要旧密码 2024-12-18 10:30:58 +08:00
Yer11214
0ef3eb9bf7 修改im bug 2024-12-17 09:46:02 +08:00
Yer11214
ef6f572311 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2024-11-25 10:20:44 +08:00
Yer11214
c1fce859ce 新增商品详情绑定分销员校验 2024-11-25 10:20:13 +08:00
misworga831
2cd7b7b63f refactor: update goods list fetching to use currentGoodsId 2024-11-21 10:30:31 +08:00
chc
75991db6f6 Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2024-11-11 17:47:39 +08:00
chc
f894b5b1fc 拼团设置 2024-11-11 17:47:31 +08:00
Yer11214
7ae6967b1e 适配管理端活动链接 2024-11-11 15:22:09 +08:00
Yer11214
de94f212c3 选择地址功能添加loading方法 2024-10-18 15:25:37 +08:00
misworga831
d166d5943c fix: 已选择的分销商品,一直显示十个商品,下拉并没有增加 2024-09-23 22:34:06 +08:00
chc
c0e5d75cc6 订单增加部分发货状态 2024-09-18 15:25:32 +08:00
Yer11214
9195bcdeb5 update README.md.
Signed-off-by: Yer11214 <17633066053@163.com>
2024-07-19 02:14:48 +00:00
Yer11214
7778a62d6a fix: 🐛 修改bug在购买商品中规格为0不可编辑、购买、新增库存为0判断 2024-07-15 15:24:22 +08:00
RyanRan
31c341148f fix: 🐛 1:修改微信订阅,更改为每次支付成功之后请求订阅信息。2:修改微信支付在真机中支付成功跳转问题 2024-07-02 11:58:06 +08:00
lele0521
0b601e4f3e feat: 更新用户注销功能 2024-05-15 19:09:19 +08:00
lele0521
1d93d9103d Merge remote-tracking branch 'origin/master' 2024-05-15 18:55:48 +08:00
lele0521
5bc5152e49 feat: 更新用户注销功能 2024-05-15 18:55:41 +08:00
RyanRan
e9d1a81612 fix: 🐛 修改商品详情控制台报错bug 2024-04-29 16:29:58 +08:00
lele0521
7d3d06e8af fix: 修复虚拟订单核验码显示 2024-04-29 16:25:30 +08:00
lele0521
55bb6ab51a fix: 修复虚拟订单核验码显示 2024-04-29 16:11:56 +08:00
Yer
70c2e68bff fix: 🐛 修改砍价列表展示的Bug 2024-04-17 13:01:29 +08:00
Yer
17287df293 fix: 🐛 修改AppQQ登录appid 以及优化登录页面可能存在的bug 2024-03-15 12:02:39 +08:00
chc
a8d321c66d Merge branch 'master' of https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp 2024-03-11 15:55:56 +08:00
chc
fad004aed5 多货物订单无售后按钮 2024-03-11 15:55:48 +08:00
15386982806
fe9060073f 修改订单详情退款状态展示 2024-01-30 17:25:55 +08:00
15386982806
393c60200f 修改订单详情退款状态展示 2024-01-30 17:24:37 +08:00
Yer
e61222928e fix: 🐛 修复退出登录后haslogin没清空bug 2024-01-29 17:32:22 +08:00
misworga831
b51caa9135 fix: 新用户优化下单时,无地址无法下单问题 2024-01-27 10:50:42 +08:00
misworga831
992bb76072 fix: 修复已读信息接口不正确 2024-01-26 10:12:23 +08:00
misworga831
863315eaed fix: 优化虚拟商品订单不显示收货地址 2024-01-25 10:15:11 +08:00
misworga831
52bf47e358 fix: 兼容旧版本图片格式 2024-01-22 15:36:07 +08:00
Yer
8f49dce8f0 style: 解决分类搜索框页面h5不能点击问题 2024-01-17 15:46:13 +08:00
15386982806
4490a4119e 支持多包裹快递展示物流信息 2024-01-10 19:16:47 +08:00
15386982806
2d0b78af52 支持多包裹快递展示物流信息 2024-01-10 18:56:18 +08:00
15386982806
7148b32c43 订单货物展示退款状态与实际退款金额 2024-01-05 14:17:16 +08:00
lele0521
20b2ca04f0 feat: 新增会员绑定手机号功能 2023-12-04 17:19:07 +08:00
Chopper711
25677ced97 默认注释直播插件 2023-11-08 14:47:49 +08:00
Lele
4517c9562a fix: 修改优惠券类别显示 2023-10-27 18:11:02 +08:00
misworga831
2634017fb3 fix: 优化售后搜索 2023-10-16 18:33:52 +08:00
misworga831
b69c7d5a05 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2023-10-16 17:09:23 +08:00
misworga831
098bee9bb4 fix: 修复商品评论筛选 2023-10-16 17:09:18 +08:00
Yer
2d369ad729 fix: 🐛 解决在手机上拼团活动以及现实抢购系统栏看不到问题 2023-10-12 18:30:47 +08:00
Yer
3bf0be98cb feat: 我的足迹新增批量删除功能 2023-10-07 16:12:04 +08:00
Yer
1046a1052e feat: 个人中心优化tool方法 2023-09-28 17:22:19 +08:00
Yer
1cc6cc4ac7 修改反馈信息,回滚修改goods的代码 2023-09-26 19:22:58 +08:00
Yer
dae3e74a60 fix: 🐛 修改在部分手机分辨率下首页文字有误bug 2023-09-26 13:13:57 +08:00
Yer
fddceb5f36 fix: 🐛 修复在h5 搜索页面中点击刷新再点击回退不生效bug 2023-09-25 15:21:46 +08:00
Yer
2aed3b9305 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2023-09-19 17:18:46 +08:00
Yer
101aa279d8 fix: 🐛 修改了几个已知的bug 2023-09-19 17:18:44 +08:00
misworga831
abbadfbab1 fix: 完善订单投诉对话 2023-09-19 14:26:27 +08:00
Yer
8ad76a5278 fix: 🐛 修复昨天提交写错的问题 2023-09-15 17:14:13 +08:00
Yer
726a85e76c fix: 🐛 解决几个h5中会出现的Bug 2023-09-14 17:13:11 +08:00
Yer
2d69967f51 perf: 优化部分流程 2023-09-14 13:31:20 +08:00
Yer
4aeaa115dc fix: 🐛 修复部分bug 2023-09-13 15:52:08 +08:00
Yer
2d251faff1 feat: 优化个人信息页面,新增购物车删除功能 2023-09-13 09:36:37 +08:00
Yer
231936c91d feat: 新增微信小程序登录页面勾选协议功能 2023-09-07 11:41:07 +08:00
Yer
37b8e17cba feat: 微信小程序登录页面新增用户协议、隐私协议 2023-09-06 17:50:58 +08:00
Yer
7d928e3df9 fix: 🐛 修复店铺单个展示商品样式错bug 2023-09-05 11:53:02 +08:00
Yer
bb4435fab4 Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2023-09-04 10:27:12 +08:00
Yer
1e0580ba15 fix: 🐛 修复店铺入驻bug 2023-09-04 10:27:10 +08:00
misworga831
f5716c901d Merge branch 'master' of gitee.com:beijing_hongye_huicheng/lilishop-uniapp 2023-08-25 13:59:08 +08:00
misworga831
2c4c0ea4f0 fix: 优化小程序登录 2023-08-25 13:58:56 +08:00
126 changed files with 11746 additions and 1348 deletions

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ node_modules/
.hbuilderx/launch.json
.project.config.json
.project.private.config.json

35
App.vue
View File

@@ -2,15 +2,15 @@
/**
* vuex管理登录状态具体可以参考官方登录模板示例
*/
import {
mapMutations
} from "vuex";
import APPUpdate from "@/plugins/APPUpdate";
import {
getClipboardData
} from "@/js_sdk/h5-copy/h5-copy.js";
import config from "@/config/config";
import storage from "@/utils/storage";
import {
getClipboardData
} from "@/js_sdk/h5-copy/h5-copy.js";
import APPUpdate from "@/plugins/APPUpdate";
import storage from "@/utils/storage";
import {
mapMutations
} from "vuex";
@@ -20,14 +20,7 @@
* */
// #ifdef MP-WEIXIN
wx.onAppRoute((res) => {
const pages = getCurrentPages();
console.log("pages:" + pages.length,pages);
if (pages.length > 3) {
delete getCurrentPages()[2]
}
console.log('路由监听', {
res
})
})
// #endif
@@ -43,6 +36,7 @@
* 监听返回
*/
onBackPress(e) {
console.log("onBackPress-APP", e);
if (e.from == "backbutton") {
let routes = getCurrentPages();
let curRoute = routes[routes.length - 1].options;
@@ -70,11 +64,12 @@
methods: {
...mapMutations(["login"]),
},
onLaunch: function() {
// #ifdef APP-PLUS
this.checkArguments(); // 检测启动参数
APPUpdate();
onLaunch: function(val) {
if(val.query.inviter){
storage.setInviter(val.query.inviter)
}
// #ifdef APP-PLUS
// 重点是以下: 一定要监听后台恢复 !一定要
plus.globalEvent.addEventListener("newintent", (e) => {
this.checkArguments(); // 检测启动参数

View File

@@ -1,5 +1,12 @@
## Lilishop B2B2C 商城系统
### 近期常出现的问题解决方法
1. 高版本hbulider启动会报错建议先固定使用 4.45
2. 编译到微信小程序会报错 xxx defined 这里注意微信小程序基础调试库要使用 3.5.3
### 商城介绍
**官网**https://pickmall.cn
@@ -12,6 +19,12 @@
![image-20210511171611793](https://static.pickmall.cn/images/h5-qrcode.png)
## lilishop-uniapp如何在本地h5和微信小程序中运行
https://www.bilibili.com/video/BV17K8EemEh2/
## lilishop-uniapp如何打包h5到服务器
https://www.bilibili.com/video/BV1CX87exE64/
### 快速开始
#### 阅读文档
@@ -82,6 +95,8 @@ git clone https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
2.在`hbulider`中点击`运行`->`运行到小程序模拟器`->`微信开发者工具` 运行的时候需要配置小程序的`appid`,配置完成后即可运行
#### 运行 APP
##### 运行在安卓

View File

@@ -218,3 +218,13 @@ export function fillShipInfo(afterSaleSn, params) {
data: params,
});
}
// 添加交易投诉对话
export function communication(params) {
return http.request({
url: `/order/complain/communication`,
method: Method.POST,
needToken: true,
params
});
}

View File

@@ -14,6 +14,17 @@ export function resetByMobile(params) {
});
}
/**
* 绑定手机号码
* @param mobile
*/
export function bindMobile(params) {
return http.request({
url: `/passport/member/bindMobile`,
method: "POST",
params,
});
}
//获取自动发券
export function getAutoCoup(){
@@ -84,6 +95,19 @@ export function modifyPass(params) {
});
}
/**
* 修改密码
* @param newPassword
* @param password
*/
export function resetPassword(params) {
return http.request({
url: `/passport/member/resetPassword`,
method: "POST",
params,
});
}
/**
* 刷新token
*/
@@ -119,3 +143,12 @@ export function scannerCodeLoginConfirm(params){
needToken: true,
});
}
// 注销用户
export function logoffConfirm() {
return http.request({
url: '/passport/member/cancellation',
method: "PUT",
needToken: true,
})
}

View File

@@ -42,7 +42,7 @@ export function getMessages(params) {
*/
export function messageMarkAsRead(ids) {
return http.request({
url: `members/member-nocice-logs/${ids}/read`,
url: `/message/member/${ids}`,
method: Method.PUT,
needToken: true,
});

View File

@@ -319,3 +319,12 @@ export function reBuy(sn) {
params,
});
}
// 查看包裹列表
export function getPackage(orderSn) {
return http.request({
url: `/order/order/getPackage/${orderSn}`,
method: Method.GET,
needToken: true,
});
}

File diff suppressed because it is too large Load Diff

View File

@@ -93,14 +93,17 @@
</view>
</view>
</view>
<div class="soldout" v-if="goodsDetail.quantity === 0">
<u-alert-tips type="warning" title="商品已售罄" description="当前商品库存为0"></u-alert-tips>
</div>
<!-- 数量 -->
<view class="goods-skus-number flex flex-a-c flex-j-sb">
<view v-if="goodsDetail.quantity !== 0" class="goods-skus-number flex flex-a-c flex-j-sb">
<view class="view-class-title">数量</view>
<uni-number-box class="uNumber" :min="1" :max="999" v-model="num"></uni-number-box>
<uni-number-box class="uNumber" :min="1" :max="999" :disabled="goodsDetail.quantity === 0" v-model="num"></uni-number-box>
</view>
</scroll-view>
<!-- 按钮 -->
<view class="btns">
<view class="btns" v-if="goodsDetail.quantity !== 0">
<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>
@@ -209,6 +212,18 @@ export default {
this.$emit('changed', val);
},
deep: true
},
'goodsDetail.quantity': {
handler(val) {
if (val == 0) {
uni.showToast({
title: '商品已售罄',
duration: 2000,
icon: 'none'
})
this.num = 1;
}
}
}
},
@@ -400,6 +415,8 @@ export default {
mounted() {
this.formatSku(this.goodsSpec);
console.log("goodsDetail",this.goodsDetail)
}
};
</script>
@@ -420,7 +437,7 @@ export default {
box-shadow: 0 2px 6px 0 rgba(255, 65, 66, 0.2);
}
/deep/.u-icon-plus,
::v-deep.u-icon-plus,
.u-icon-minus,
.u-icon-disabled {
height: 30rpx !important;
@@ -440,7 +457,7 @@ export default {
}
}
/deep/ .uni-scroll-view {
::v-deep .uni-scroll-view {
overflow: hidden !important;
}
@@ -460,6 +477,9 @@ export default {
// #endif
margin-bottom: 10rpx;
}
.soldout{
margin: 20rpx 0;
}
.goods-skus-view {
overflow: hidden;
@@ -526,7 +546,7 @@ export default {
color: #999;
margin-left: 10rpx;
/deep/ span {
::v-deep span {
font-size: 30rpx;
}
}

View File

@@ -180,28 +180,40 @@ export default {
if (this.tabbars[index].id != item.id) {
this.tabbars[index].localName = item.name;
this.tabbars[index].id = item.id;
this.tabbars[index].center = item.center
if (index < this.tabbars.length - 1) {
this.tabbars.splice(index + 1, this.tabbars.length - index - 1);
}
if (this.tabbars.length < this.pickersize) {
let data = await getRegionsById(item.id);
// 当前选项级为最后一级时回调,将选中的数据返回
if (data.data.result.length == 0) {
this.$emit("funcValue", this.tabbars);
this.hide();
} else {
// 将新的数据填充进下一级
var current = {
localName: "请选择",
id: "",
children: data.data.result,
};
this.tabbars.push(current);
this.tabCurrentIndex++;
uni.showLoading({
title: "加载中",
mask:true
});
try {
let data = await getRegionsById(item.id);
uni.hideLoading();
// 当前选项级为最后一级时回调,将选中的数据返回
if (data.data.result.length == 0) {
this.$emit("funcValue", this.tabbars);
this.hide();
} else {
// 将新的数据填充进下一级
var current = {
localName: "请选择",
id: "",
children: data.data.result,
};
this.tabbars.push(current);
this.tabCurrentIndex++;
// 当前距离重新为最上面
this.$set(this,'scrollTop',0)
}
// 当前距离重新为最上面
this.$set(this,'scrollTop',0)
}
} catch (error) {
uni.hideLoading();
}
} else {
this.$emit("funcValue", this.tabbars);
this.hide();
@@ -387,4 +399,4 @@ export default {
icon {
margin-left: 40rpx;
}
</style>
</style>

View File

@@ -268,7 +268,7 @@ export default {
color: $main-color;
font-weight: bold;
/deep/ span:nth-of-type(1) {
::v-deep span:nth-of-type(1) {
font-size: 38rpx;
}
}

View File

@@ -331,7 +331,7 @@
color: $main-color;
font-weight: bold;
/deep/ span:nth-of-type(1) {
::v-deep span:nth-of-type(1) {
font-size: 38rpx;
}
}

View File

@@ -25,7 +25,7 @@
}}
</div>
<!-- 兜底策略如果金额是0 -->
<div class="price" v-if="!item.price">
<div class="price" v-if="!item.price && !type">
¥<span>0 </span>.00
</div>
</view>
@@ -162,7 +162,7 @@
color: $main-color;
font-weight: bold;
/deep/ span:nth-of-type(1) {
::v-deep span:nth-of-type(1) {
font-size: 48rpx;
}
}

View File

@@ -0,0 +1,225 @@
<template>
<div class="index">
<view v-model="show" class="slot-content">
<image @click="downLoad()" class="img" :src="imgUrl" />
<div class="canvas-hide">
<!-- #ifdef MP-WEIXIN -->
<canvas id="canvas" type="2d" style="width: 560px; height: 800px" />
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<canvas canvas-id="canvas" id="canvas" style="width: 560px; height: 800px" />
<!-- #endif -->
</div>
</view>
</div>
</template>
<script>
// 引入绘制插件
import DrawPoster from "@/js_sdk/u-draw-poster";
// 生成二维码
import uQRCode from '@/components/Sansnn-uQRCode/uqrcode.js';
export default {
data: () => ({
imgUrl: "", //绘制出来的图片路径
show: false, //是否展示模态框
dp: {}, //绘制的dp对象用于存储绘制等一些方法。
logo: require("@/pages/passport/static/logo-title.png"), // 本地logo地址
myFace: require("@/pages/passport/static/missing-face.png"), // 本地默认头像
sharingLink: '', // 二维码链接
}),
props: {
/**
* 父级传参的数据
*/
res: {
type: null,
default: "",
},
},
onUnload() {},
onReady() {},
methods: {
/** 解决微信小程序中图片模糊问题 */
// #ifdef MP-WEIXIN
st2: (size) => size * 2,
// #endif
// #ifndef MP-WEIXIN
st2: (size) => size,
// #endif
/** 保存图片 */
downLoad() {
uni.saveImageToPhotosAlbum({
filePath: this.imgUrl,
success: function () {
uni.showToast({title: "保存成功!",icon: "none",});
},
fail: function () {
uni.showToast({title: "保存失败,请稍后重试!",icon: "none",});
},
});
},
/** 创建canvas */
async init() {
this.show = true;
this.dp = await DrawPoster.build({
selector: "canvas",
componentThis: this,
loading: true,
debugging: true,
});
let dp = this.dp;
// #ifdef MP-WEIXIN
// 用于微信小程序中画布错乱问题
dp.canvas.width = this.st2(560);
dp.canvas.height = this.st2(800);
// #endif
this.showQRCode(dp);
},
/** 生成二维码 */
async showQRCode(dp){
await uQRCode.make({
canvasId: 'canvas', // canvas画布
componentInstance: this,
text: this.res.bottom.code, // 二维码内容
size: 130, // 二维码大小
margin: 5, // 二维码内边距
backgroundColor: '#ffffff', // 二维码背景颜色
foregroundColor: '#000000', // !二维码色块颜色
fileType: 'jpg',
errorCorrectLevel: 0, // <== 关键 容错率M:0,L:1,H:2,Q:3,
// errorCorrectLevel: uQRCode.errorCorrectLevel.M, // <== 关键 容错率M:0,L:1,H:2,Q:3,
success: res => {
this.sharingLink = res; // res => 图片路径
// 对画布进行绘制
this.draw(dp);
},
fail: res => {
// console.log('失败',res)
}
})
},
async draw(dp) {
const { face, nickName, desc } = this.res.memberInfo;
const { width, height, background, title } = this.res.container;
const { code, img, price } = this.res.bottom;
/** 绘制背景 */
await dp.draw((ctx) => {
ctx.fillStyle = background;
ctx.fillRoundRect( this.st2(0), this.st2(0), this.st2(width), this.st2(height), this.st2(12));
ctx.clip();
});
/** 绘制圆角矩形 */
await dp.draw(async (ctx)=>{
// 设置矩形色彩
ctx.fillStyle = "#ffffff";
// 设置图形轮廓的颜色。默认情况下线条和填充颜色都是黑色CSS 颜色值 #000000
ctx.strokeStyle = "#ffffff";
// 这个属性设置当前绘线的粗细。属性值必须为正数。描述线段宽度的数字。 0、 负数、 Infinity 和 NaN 会被忽略。默认值是1.0。
ctx.lineWidth = this.st2(1);
// 进行绘制
ctx.fillRoundRect(30, 150, 500, 620, 0);
// ctx.strokeRoundRect(30, 150, 500, 620, 0);
// ctx.strokeRect(30, 150, 500, 620, 0);
})
/** 绘制图片 */
dp.draw(async (ctx) => {
await Promise.all([
// 绘制头像face
ctx.drawImage(face?face:this.myFace, this.st2(30), this.st2(30), this.st2(90), this.st2(90)),
// 绘制Logo
// ctx.drawImage( this.logo, this.st2(175), this.st2(0), this.st2(256), this.st2(144)),
// 中间图片
ctx.drawImage(img, this.st2(60), this.st2(170), this.st2(440), this.st2(440)),
// 二维码
ctx.drawImage(this.sharingLink, this.st2(375), this.st2(625), this.st2(130), this.st2(130))
]);
});
/** 绘制顶部文字(昵称 简述) */
await dp.draw((ctx) => {
ctx.fillStyle = "#666";
ctx.font = `${this.st2(24)}px PingFang SC`;
ctx.fillText(nickName, this.st2(150), this.st2(65));
ctx.fillStyle = "#666";
ctx.font = `${this.st2(24)}px PingFang SC`;
ctx.fillText(desc, this.st2(150), this.st2(105));
});
/** 绘制中间文字(商品名称 价格) */
await dp.draw((ctx) => {
ctx.fillStyle = "#333";
ctx.font = `bold ${this.st2(24)}px PingFang SC`;
ctx.textAlign = "left";
ctx.fillWarpText({
text: title,
lineHeight: this.st2(32),
maxWidth: this.st2(280),
x: this.st2(60),
y: this.st2(710),
layer: 2,
});
ctx.fillStyle = "#ff3c2a";
ctx.font = `${this.st2(38)}px PingFang SC`;
ctx.textAlign = "left";
ctx.fillText(price, this.st2(60), this.st2(665));
});
/** 绘制底部文字 */
// await dp.draw((ctx) => {
// ctx.fillStyle = "#666";
// ctx.font = `${this.st2(24)}px PingFang SC`;
// ctx.fillText("长按图片,识别二维码", this.st2(200), this.st2(866));
// ctx.fillStyle = "#666";
// ctx.font = `${this.st2(24)}px PingFang SC`;
// ctx.fillText("查看商品详情", this.st2(200), this.st2(900));
// });
// 绘制生成本地地址
this.imgUrl = await dp.createImagePath();
},
},
async mounted() {
this.init();
},
};
</script>
<style lang="scss" scoped>
page,
.index {
height: 100%;
}
.canvas-hide {
/* 1 */
position: fixed;
right: 100vw;
bottom: 100vh;
/* 2 */
z-index: -9999;
/* 3 */
opacity: 0;
}
.index {
position: relative;
text-align: center;
background: rgba($color: grey, $alpha: 0.2);
}
image {
display: block;
}
.img {
width: 560rpx;
height: 800rpx;
}
.qrcode-content {
width: 100rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
}
</style>

View File

@@ -121,7 +121,15 @@ export default {
* 回退到上一级
*/
onClickLeft() {
uni.navigateBack();
const paths = getCurrentPages();
console.log(paths)
if(paths.length > 1){
uni.navigateBack();
}else{
uni.switchTab({
url:"/pages/tabbar/home/index"
})
}
},
/**
@@ -156,7 +164,7 @@ export default {
width: 100%;
//border-bottom: 1px #f5f5f5 solid; //HM修改 去掉边框
box-sizing: border-box;
font-size: $uni-font-size-base;
font-size: 24rpx;
.left-box {
display: flex;

View File

@@ -7,8 +7,8 @@
* @param {sn,price}
*/
import { initiatePay } from "@/api/trade";
import { getWeChatMpMessage } from "@/api/message.js";
import { initiatePay } from "@/api/trade";
class LiLiWXPay {
constructor(...payList) {
this.data = payList[0];
@@ -65,52 +65,40 @@ 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,
});
},
});
//订阅消息
getWeChatMpMessage().then((res) => {
var message = res.data.result;
var templateid = message.map((item) => item.code);
uni.requestSubscribeMessage({
tmplIds: templateid,
success: (res) => {
},
fail: (res) => {
console.log('fail', res)
uni.showToast({
icon: "none",
title: "订阅消息失败",
})
},
complete: (res) => {
console.log('complete', res)
/**
* 已经支付成功
*/
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;

View File

@@ -116,7 +116,7 @@
},
"apple" : {},
"qq" : {
"appid" : "101918501"
"appid" : "101918503"
}
},
"geolocation" : {
@@ -204,14 +204,17 @@
"permission" : {
"scope.userLocation" : {
"desc" : "位置信息将用于高德地图的效果展示"
},
"scope.writePhotosAlbum" : {
"desc" : "将用于保存图片"
}
},
"plugins" : {
"live-player-plugin" : {
"version" : "1.3.0",
"provider" : "wx2b03c6e691cd7370"
}
},
"plugins" : {},
// 直播插件注释
// "live-player-plugin" : {
// "version" : "1.3.0",
// "provider" : "wx2b03c6e691cd7370"
// }
"requiredPrivateInfos" : [ "chooseLocation", "getLocation" ]
},
"h5" : {

View File

@@ -36,6 +36,7 @@
"path": "pages/tabbar/cart/cartList",
"style": {
"navigationBarTitleText": "购物车",
"navigationStyle": "custom", // 隐藏系统导航栏
"navigationBarBackgroundColor": "#fff",
"enablePullDownRefresh":true //实现下拉刷新样式
@@ -274,6 +275,16 @@
}
}
},
{
"path": "set/securityCenter/bindMobile",
"style": {
"navigationBarTitleText": "绑定手机号",
"app-plus": {
}
}
},
{
"path": "im/list",
@@ -301,6 +312,18 @@
"navigationBarTitleText": "意见反馈"
}
},
{
"path": "set/securityCenter/updatePwdTab",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "set/securityCenter/editLoginPassword",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "set/securityCenter/securityCenter",
"style": {
@@ -531,7 +554,7 @@
"style": {
"navigationBarTitleText": "限时抢购",
"navigationStyle": "custom", // 隐藏系统导航栏
"navigationBarTextStyle": "white" ,
"navigationBarTextStyle": "black" ,
"app-plus": {
"titleNView": {
"homeButton":true
@@ -545,7 +568,7 @@
"style": {
"navigationBarTitleText": "拼团活动",
"navigationStyle": "custom", // 隐藏系统导航栏
"navigationBarTextStyle": "white" ,
"navigationBarTextStyle": "black" ,
"app-plus": {
// 将回弹属性关掉
"bounce": "none"
@@ -707,6 +730,12 @@
"navigationBarTitleText": "订单详情"
}
},
{
"path": "deliverDetail",
"style": {
"navigationBarTitleText": "物流详情"
}
},
{
"path": "evaluate/evaluateDetail",
"style": {

View File

@@ -17,8 +17,10 @@
<view class="text"> 使用范围{{
coupon.scopeType == 'ALL' && coupon.storeId == '0'
? "全平台"
: coupon.scopeType == "PORTION_CATEGORY"
? "仅限品类"
: coupon.scopeType == "PORTION_GOODS"
? "部分商品"
: coupon.scopeType == "PORTION_GOODS_CATEGORY"
? "部分分类商品"
: coupon.storeName == 'platform' ? '全平台' :coupon.storeName+''
}}使用</view>
<view class="text"> 有效期至{{coupon.endTime}}</view>

View File

@@ -53,7 +53,7 @@
<text>立即</text><br />
<text>使用</text>
</view>
<view class="used" v-else @click="clickWay(item)">
<view class="used" v-if="current == 0 && routerVal.selectedCoupon.includes(item.id)" @click="clickWay(item)">
<text>取消</text><br />
<text>使用</text>
</view>

View File

@@ -70,8 +70,10 @@
>使用范围{{
coupon.scopeType == "ALL" && coupon.storeId == "0"
? "全平台"
: coupon.scopeType == "PORTION_CATEGORY"
? "仅限品类"
: coupon.scopeType == "PORTION_GOODS"
? "部分商品"
: coupon.scopeType == "PORTION_GOODS_CATEGORY"
? "部分分类商品"
: coupon.storeName == "platform"
? "全平台"
: coupon.storeName + ""

View File

@@ -447,7 +447,7 @@
width: 100%;
}
/deep/ .u-row {
::v-deep .u-row {
width: 100% !important;
display: flex;
justify-content: space-between !important;

View File

@@ -14,6 +14,9 @@
<span v-if="isBuy &&!master.toBeGroupedNum >0">
已成功拼团
</span>
<span v-if="!master.toBeGroupedNum >0">
拼团已结束
</span>
</div>
<div v-if="isMaster && !isOver">
@@ -24,7 +27,7 @@
去首页逛逛
</div>
</div>
<div v-if="!isMaster && !isOver && !isBuy">
<div v-if="!isMaster && !isOver && !isBuy && master.toBeGroupedNum">
<div class="share-user" @click="toBuy">
参与拼团
</div>
@@ -45,7 +48,7 @@
</div>
<!-- 倒计时 -->
<div class="count-down" v-if="!isOver">
<div class="count-down" v-if="!isOver && master.toBeGroupedNum">
<u-count-down bg-color="#ededed" :hide-zero-day="true" @end="isOver" :timestamp="timeStamp"></u-count-down>
</div>

View File

@@ -5,7 +5,7 @@
{{ Number(payPrice) | unitPrice }}
</div>
<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>
</div>
@@ -16,7 +16,7 @@
<div>
支付方式
</div>
<div>{{paymentMethod | paymentTypeFilter}}</div>
<div>{{ paymentMethod | paymentTypeFilter }}</div>
</div>
</div>
</div>
@@ -60,7 +60,7 @@ export default {
this.from = options.from || "";
this.payPrice = options.payPrice || 0;
this.orderType = options.orderType;
// this.sendMessage()
},
methods: {
checkOrder() {
@@ -77,11 +77,6 @@ export default {
this.navigateTo("/pages/order/myOrder?status=0");
}
},
changeStatus(val) {
if (val) {
this.sendMessage();
}
},
navigateTo(url, type) {
if (type === "switch") {
@@ -105,6 +100,7 @@ export default {
padding: 0 20rpx 20rpx;
width: 80%;
}
.pay-btns {
display: flex;
width: 50%;
@@ -112,7 +108,7 @@ export default {
margin: 0 auto;
color: #fff;
> div {
>div {
padding: 6px 12px;
border: 1px solid #fff;
border-radius: 100px;
@@ -146,7 +142,7 @@ export default {
border-radius: 20rpx;
background: rgba($color: $main-color, $alpha: 0.2);
> h2 {
>h2 {
margin-top: 20rpx;
font-size: 40rpx;
color: $main-color;

View File

@@ -15,7 +15,9 @@
<u-input v-model="form.mobile" type="number" maxlength="11" placeholder="请输入收货人手机号码" />
</u-form-item>
<u-form-item label="所在区域" label-width="130" prop="___path">
<u-input v-model="form.___path" type="select" @click="showPicker" placeholder="请选择所在地区" />
<div @click="showPicker" >
{{ form.___path || '请选择所在地区' }}
</div>
</u-form-item>
<u-form-item class="detailAddress" label="详细地址" label-width="130" prop="detail">
<u-input type="textarea" v-model="form.detail" maxlength="100" height="150" placeholder="街道楼牌号等" />
@@ -290,7 +292,7 @@ export default {
</script>
<style scoped lang="scss">
.detailAddress {
/deep/ .u-form-item--left {
::v-deep .u-form-item--left {
display: flex;
align-items: flex-start;
}
@@ -330,7 +332,7 @@ export default {
width: 100%;
padding-top: 3%;
/deep/ .u-form-item {
::v-deep .u-form-item {
background-color: #fff;
padding: 24rpx 30rpx;
}
@@ -339,7 +341,7 @@ export default {
background-color: $main-color;
}
/deep/.u-checkbox {
::v-deep.u-checkbox {
margin: 30rpx 30rpx 0 30rpx;
.u-label-class.u-checkbox__label {
@@ -348,7 +350,7 @@ export default {
}
}
}
/deep/ .u-checkbox__label {
::v-deep .u-checkbox__label {
font-size: 28rpx;
}
</style>

View File

@@ -1,9 +1,9 @@
/deep/ .u-input__input,
::v-deep .u-input__input,
.u-input {
font-size: 80rpx !important;
height: 102rpx !important;
}
/deep/ .u-input__input {
::v-deep .u-input__input {
height: 100%;
font-size: 80rpx;
}
@@ -43,4 +43,4 @@
border-radius: 10rpx;
text-align: center;
line-height: 90rpx;
}
}

View File

@@ -66,42 +66,45 @@
<!-- 商品列表 -->
<view class="goods-list">
<u-swipe-action v-for="(item, index) in goodsList" :disabled="!params.checked" :show="item.___selected" @open="openAction(item)" :index="index" :options="options" bg-color="#fff"
ref="swiperAction" :key="item.id" @click="changeActionTab(item)">
<scroll-view class="body-view" scroll-y @scrolltolower="renderDate">
<u-swipe-action v-for="(item, index) in goodsList" :disabled="!params.checked" :show="item.___selected" @open="openAction(item)" :index="index" :options="options" bg-color="#fff"
ref="swiperAction" :key="item.id" @click="changeActionTab(item)">
<div class="goods-item">
<view class="goods-item-img" @click="handleNavgationGoods(item)">
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
</view>
<view class="goods-item-desc">
<!-- 商品描述 -->
<view class="-item-title" @click="handleNavgationGoods(item)">
{{ item.goodsName }}
<div class="goods-item">
<view class="goods-item-img" @click="handleNavgationGoods(item)">
<u-image width="176rpx" height="176rpx" :src="item.thumbnail"></u-image>
</view>
<!-- 商品金额 -->
<view class="-item-price" @click="handleNavgationGoods(item)">
佣金:
<span> {{ item.commission | unitPrice }}</span>
</view>
<!-- 比率佣金 -->
<view class="-item-bottom">
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
<!-- <view class="-item-bl">
比率:
<span>{{ "5.00%" }}</span>
</view> -->
<view class="-item-yj">
<span>{{ item.price | unitPrice }}</span>
<view class="goods-item-desc">
<!-- 商品描述 -->
<view class="-item-title" @click="handleNavgationGoods(item)">
{{ item.goodsName }}
</view>
<!-- 商品金额 -->
<view class="-item-price" @click="handleNavgationGoods(item)">
佣金:
<span> {{ item.commission | unitPrice }}</span>
</view>
<!-- 比率佣金 -->
<view class="-item-bottom">
<view class="-item-bootom-money" @click="handleNavgationGoods(item)">
<!-- <view class="-item-bl">
比率:
<span>{{ "5.00%" }}</span>
</view> -->
<view class="-item-yj">
<span>{{ item.price | unitPrice }}</span>
</view>
</view>
<view>
<view class="click" v-if="!params.checked" @click="handleClickGoods(item)">立即选取</view>
<view class="click" v-if="params.checked" @click="handleLink(item)">分销商品</view>
</view>
</view>
<view>
<view class="click" v-if="!params.checked" @click="handleClickGoods(item)">立即选取</view>
<view class="click" v-if="params.checked" @click="handleLink(item)">分销商品</view>
</view>
</view>
</view>
</div>
</u-swipe-action>
</div>
</u-swipe-action>
</scroll-view>
<view class="empty">
<!-- <u-empty v-if="empty" text="没有分销商品了" mode="list"></u-empty> -->
@@ -295,15 +298,30 @@ export default {
});
this.goodsList.push(...res.data.result.records);
}
if (this.goodsList.length == 0) {
if (this.goodsList.length === 0) {
this.empty = true;
}
});
},
/**
* 底部加载数据
*/
renderDate() {
this.params.pageNumber += 1;
this.init();
},
},
};
</script>
<style lang="scss" scoped>
.body-view {
overflow-y: auto;
height: calc(100vh - 44px - 80rpx - 104rpx);
}
.canvas-hide {
/* 1 */
position: fixed;

View File

@@ -82,13 +82,13 @@ export default {
};
</script>
<style lang="scss" scoped>
/deep/ .u-input__input,
::v-deep .u-input__input,
.u-input {
font-size: 80rpx !important;
height: 102rpx !important;
}
/deep/ .u-input__input{
::v-deep .u-input__input{
height: 100%;
font-size: 80rpx;
}
@@ -126,4 +126,4 @@ export default {
text-align: center;
line-height: 90rpx;
}
</style>
</style>

View File

@@ -158,36 +158,36 @@
</view>
</view>
<!-- loading是显示 -->
<!-- <view v-show="msgLoad" class=" margin-left margin-top">
<view class="chat-img flex-row-center">
<image style="height: 75rpx;width: 75rpx;" src="../../static/image/robt.png" mode="aspectFit"></image>
</view>
<view class="flex" style="width: 500rpx;">
<view class="margin-left padding-chat flex-column-start"
style="border-radius: 35rpx;background-color: #f9f9f9;">
<view class="cuIcon-loading turn-load" style="font-size: 35rpx;color: #3e9982;">
</view>
</view>
</view>
</view> -->
<!-- 防止消息底部被遮 -->
<view style="height: 120rpx;">
<view style="height: 120rpx;">
</view>
</view>
<!-- 底部导航栏 -->
<view :style="{position: 'fixed',bottom:inputHeight+'px'}" class="flex-column-center" :animation="animationData">
<view :style="{position: 'fixed', bottom:inputHeight+'px'}" class="flex-column-center bottom-dh" :animation="animationData">
<view class="bottom-dh-char flex-row-around" style="font-size: 55rpx;">
<!-- vue无法使用软键盘"发送" -->
<input @focus="inputBindFocus" @blur="eventHandle" :adjust-position="false" v-model="msg" class="dh-input" type="text" style="background-color: #f0f0f0;" @confirm="sendMessage"
confirm-type="send" placeholder="用一句简短的话描述您的问题" />
<!-- #ifndef MP-WEIXIN -->
<div v-if="!isShow" @click="navigateToBottom" class="dh-input">
用一句简短的话描述您的问题
</div>
<input v-show="isShow" ref="inputRef" :focus="isShow" @focus="inputBindFocus" @blur="eventHandle" :adjust-position="false" v-model="msg" class="dh-input" type="text" style="background-color: #f0f0f0;" @confirm="sendMessage"
confirm-type="send" placeholder="用一句简短的话描述您的问题" />
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<input ref="inputRef" @focus="inputBindFocus" @blur="eventHandle" :adjust-position="false" v-model="msg" class="dh-input" type="text" style="background-color: #f0f0f0;" @confirm="sendMessage"
confirm-type="send" placeholder="用一句简短的话描述您的问题" />
<!-- #endif -->
<view @click="sendMessage" class="cu-tag bg-main-color send round">
发送
发送
</view>
<!-- <text @click="ckAdd" class="cuIcon-roundaddfill text-brown"></text> -->
</view>
</view>
<div id="bottom"></div>
</view>
</template>
@@ -233,26 +233,7 @@ export default {
if (this.resolve.goodsid) {
this.commodityDetails()
}
// 如果需要缓存消息缓存msgList即可
// 监听键盘拉起
// 因为无法控制键盘拉起的速度,所以这里尽量以慢速处理
uni.onKeyboardHeightChange(res => {
const query = uni.createSelectorQuery()
query.select('#msgList').boundingClientRect(data => {
// 若消息体没有超过2倍的键盘则向下移动差值,防止遮住消息体
var up = res.height * 2 - data.height - l * 110
if (up > 0) {
// 动态改变空盒子高度
this.messageBoxMove(up, 300)
// 记录改变的值,若不收回键盘且发送了消息用来防止消息过多被遮盖
mgUpHeight = up
}
// 收回
if (res.height == 0) {
this.messageBoxMove(0, 0)
}
}).exec();
})
var query = uni.getSystemInfoSync()
l = query.screenWidth / 750
@@ -270,8 +251,12 @@ export default {
}
// this.ws.connect();
this.sokcet();
this.socket();
},
// 页面隐藏
onHide () {
uni.closeSocket();
@@ -321,30 +306,65 @@ export default {
goodListData: {},
count: 0, //判断socket断开连接请求次数
inputHeight:0,
isShow:false,
}
},
// watch: {
// 'ws.callBackMapping': {
// handler: function (val) {
// val = JSON.parse(val)
// if (val.messageResultType == 'MESSAGE') {
// this.msgList.push(val.result)
// }
// this.newMessageNum++;
// //接收到消息后发送已读
// let msg = val
// msg.operation_type = 'READ'
// this.ws.send(JSON.stringify(msg))
// }
// }
// },
onPageScroll (e) {
// #ifdef APP-PLUS
uni.hideKeyboard()
this.isShow = false
// #endif
},
methods: {
navigateToBottom(){
// #ifdef H5
this.isShow = true
this.$refs.inputRef.focus()
// #endif
// #ifdef APP-PLUS
this.$nextTick(() => {
uni.pageScrollTo({
scrollTop: 5000000,
duration: 50,
success: () => {
setTimeout(() => {
this.isShow = true
}, 200);
;
},
fail: () => { },
complete: () => {}
});
});
// #endif
},
eventHandle(){
this.inputHeight = 0
this.isShow = false
},
inputBindFocus(e){
if (e.detail.height) {
this.inputHeight = e.detail.height //这个高度就是软键盘的高度
// #ifdef APP-PLUS
// 判断是否是ios
if (uni.getSystemInfoSync().platform == 'ios') {
this.inputHeight = e.detail.height - 40 //这个高度就是软键盘的高度
}else{
this.inputHeight = e.detail.height
}
// #endif
// #ifndef APP-PLUS
this.inputHeight = e.detail.height //这个高度就是软键盘的高度
// #endif
}
},
sendMessage () {
@@ -404,7 +424,7 @@ export default {
});
})
},
sokcet () {
socket () {
var _this = this;
uni.closeSocket();
this.socketOpen = false;
@@ -455,7 +475,7 @@ export default {
// 监听是否断线,断线进行重新连接
uni.onSocketClose((res) => {
if (res.code != null && res.code != 1000) {
this.sokcet()
this.socket()
}
})
},
@@ -825,6 +845,7 @@ export default {
margin-left: 10rpx;
}
.dh-input {
line-height: 65rpx;
width: 500rpx;
height: 65rpx;
border-radius: 30rpx;
@@ -871,6 +892,19 @@ uni-page-head {
right: 0;
z-index: 9999;
}
.bottom-dh{
position: fixed; // input 所在盒子设置绝对定位
flex-shrink: 0;
width: 100%;
left: 0;
bottom: 0; // 默认 0
z-index: 199;
padding-bottom: env(safe-area-inset-bottom);
background: #FFFFFF;
box-sizing: border-box;
}
</style>
<style lang="scss" scoped>

View File

@@ -86,7 +86,7 @@
background: #f9f9f9;
}
/deep/ .u-col-2 {
::v-deep .u-col-2 {
height: 60px;
line-height: 60px;
text-align: center !important;

View File

@@ -300,7 +300,7 @@
width: 100%;
}
/deep/ .u-swipe-content {
::v-deep .u-swipe-content {
overflow: hidden;
}

View File

@@ -1,22 +1,25 @@
<template>
<view class="myTracks">
<u-navbar title="我的足迹">
<div slot="right">
<div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
</div>
</u-navbar>
<u-notice-bar mode="vertical" :list="['右划删除浏览记录']"></u-notice-bar>
<u-empty text="暂无历史记录" style="margin-top:200rpx;" mode="history" v-if="whetherEmpty"></u-empty>
<div v-else>
<view v-if="item" v-for="(item, index) in trackList" :key="index">
<view class="myTracks-title" @click="navigateToStore(item)" v-if="item.storeName">{{item.storeName}}</view>
<view v-for="(item, index) in trackList" :key="index">
<view class="myTracks-title" @click="navigateToStore(item)">{{item.storeName}}</view>
<view class="myTracks-items">
<u-swipe-action style="width: 100%;" :show="item.show" :index="index" :key="item.id"
@click="delTracks" @open="open" :options="options">
<!-- 已失效商品 -->
<div class="myTracks-item lose-goods" v-if="!item.storeName && !item.goodsName && !item.price">
已失效商品
</div>
<!-- 正常有效商品 -->
<view v-else class="myTracks-item">
<view class="myTracks-item">
<u-checkbox-group v-if="isEdit" class="store-line-check">
<u-checkbox shape="circle" :active-color="lightColor" v-model="item.checked"
@change="checkboxChangeDP(item)"></u-checkbox>
</u-checkbox-group>
<view class="myTracks-item-img" @click.stop="navigateToDetail(item)">
<image :src="item.thumbnail"></image>
</view>
@@ -36,7 +39,9 @@
<view class="myTracks-divider"></view>
</view>
<div @click="handleClickDeleteSelected" v-if="isEdit" class="submit">
删除所选
</div>
</div>
</view>
@@ -51,7 +56,7 @@
export default {
data() {
return {
isEdit:false,
whetherEmpty: false, //是否数据为空
params: {
pageNumber: 1,
@@ -59,6 +64,7 @@
order: "desc",
sort: "updateTime",
},
lightColor:this.$lightColor,
options: [{
text: '删除',
style: {
@@ -86,6 +92,21 @@
this.getList();
},
methods: {
checkboxChangeDP(val){
console.log(val)
},
// 删除所选的数据
handleClickDeleteSelected(val){
const ids = this.trackList.filter(item=>item.checked).map(item=>item.goodsId);
if(!ids.length){
uni.showToast({
title:"请选择删除数据",
icon:"none"
})
}else{
this.delTracks(0,ids)
}
},
/**
* 导航到店铺
*/
@@ -120,11 +141,12 @@
});
myTrackList(this.params).then((res) => {
uni.stopPullDownRefresh();
if (this.$store.state.isShowToast){ uni.hideLoading() };
uni.hideLoading();
if (res.statusCode == 200) {
res.data.result.records.length &&
res.data.result.records.forEach((item) => {
item.show = false;
item.checked = false
});
let data = res.data.result.records;
@@ -141,10 +163,11 @@
/**
* 删除足迹
*/
delTracks(index) {
deleteHistoryListId(this.trackList[index].goodsId).then((res) => {
delTracks(index,ids) {
deleteHistoryListId(ids || this.trackList[index].goodsId).then((res) => {
if (res.data.code == 200) {
this.trackList = [];
this.params.pageNumber = 1
this.getList();
} else {
uni.showToast({
@@ -160,9 +183,18 @@
</script>
<style lang="scss" scoped>
.lose-goods{
color: $main-color;
padding-left: 50rpx !important;
.submit{
position: fixed;
bottom: 20rpx;
left: 10%;
width: 80%;
height: 80rpx;
color: #fff;
border-radius: 100px;
display: flex;
align-items: center;
justify-content: center;
background: $light-color;
}
.myTracks {
width: 100%;
@@ -234,10 +266,39 @@
padding: 10rpx 0 0 0;
}
.myTracks-action {
display: flex;
justify-content: space-between;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #fff;
height: 75rpx;
align-items: center;
padding: 0 32rpx;
}
.myTracks-action-btn {
width: 130rpx;
height: 60rpx;
line-height: 60rpx;
}
.myTracks-divider {
width: 100%;
height: 20rpx;
}
.myTracks-action-check {
align-items: center;
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.edit{
padding-right: 32rpx;
}
</style>

View File

@@ -151,10 +151,10 @@ export default {
border-radius: 0 0 20rpx 20rpx;
margin: 0 20rpx;
font-size: 26rpx;
/deep/ .u-col {
::v-deep .u-col {
text-align: center !important;
}
/deep/ .u-col:first-child {
::v-deep .u-col:first-child {
border-right: 1px solid $border-color-light;
}
.pcolor {

View File

@@ -84,7 +84,7 @@ export default {
}
if (!this.feedBack.context) {
uni.showToast({
title: "请填写反馈类型",
title: "请填写反馈信息",
duration: 2000,
icon: "none",
});
@@ -143,7 +143,7 @@ export default {
padding: 32rpx;
margin-bottom: 40rpx;
}
/deep/ .u-input__textarea {
::v-deep .u-input__textarea {
padding: 12px;
}
.feedBack-box:nth-of-type(1) {

View File

@@ -16,21 +16,32 @@
</u-form-item>
<u-form-item label="生日" label-width="150" right-icon="arrow-right">
<u-input v-model="birthday" disabled placeholder="请选择出生日期" @click="showBirthday = true" />
<u-picker v-model="showBirthday" mode="time" :confirm-color="lightColor" @confirm="selectTime"></u-picker>
<div style="width: 100%;" @click="showBirthday = true">{{ birthday || '请选择出生日期' }}</div>
<u-picker v-model="showBirthday" mode="time" :confirm-color="lightColor" @confirm="selectTime"></u-picker>
</u-form-item>
<u-form-item label="城市" label-width="150" placeholder="请选择城市" right-icon="arrow-right">
<u-input v-model="form.___path" disabled @click="clickRegion" />
<div style="width: 100%;" @click="clickRegion">{{ form.___path || '请选择城市' }}</div>
</u-form-item>
<view class="submit" @click="submit">保存</view>
<view class="submit" @click="quiteLoginOut">退出登录</view>
<u-form-item label="手机号" label-width="150">
<view v-if="form.mobile">
{{form.mobile}}
</view>
<view v-else>
<view class="submit" style="text-align: left;" @click="navigateTo(form.username)">绑定手机号码</view>
</view>
</u-form-item>
</u-form>
<div class="bottom">
<view class="submit" @click="submit">保存</view>
<view class="submit light" @click="quiteLoginOut">退出登录</view>
</div>
<m-city :provinceData="region" headTitle="区域选择" ref="cityPicker" @funcValue="getPickerParentValue" pickerSize="4"></m-city>
</view>
</template>
<script>
import { saveUserInfo } from "@/api/members.js";
import { saveUserInfo, getUserInfo } from "@/api/members.js";
import { upload } from "@/api/common.js";
import storage from "@/utils/storage.js";
import uFormItem from "@/uview-ui/components/u-form-item/u-form-item.vue";
@@ -48,6 +59,8 @@ export default {
region: storage.getUserInfo().region || [], //地址
sex: storage.getUserInfo().sex, //性别
___path: storage.getUserInfo().region,
mobile: storage.getUserInfo().mobile,
username: storage.getUserInfo().username,
},
birthday: storage.getUserInfo().birthday || "", //生日
photo: [
@@ -158,15 +171,43 @@ export default {
this.form.birthday = `${time.year}-${time.month}-${time.day}`;
this.birthday = `${time.year} - ${time.month} - ${time.day}`;
},
navigateTo(username) {
uni.navigateTo({
url: '/pages/mine/set/securityCenter/bindMobile' + '?username=' + username,
});
},
},
/**
* 加载数据
*/
onLoad() {},
/**
* 页面显示时执行
*/
onShow() {
// 从缓存中重新获取用户信息
const userInfo = storage.getUserInfo();
// 更新表单数据
this.form.nickName = userInfo.nickName || "";
this.form.birthday = userInfo.birthday || "";
this.form.face = userInfo.face || "/static/missing-face.png";
this.form.region = userInfo.region || [];
this.form.sex = userInfo.sex;
this.form.___path = userInfo.region;
this.form.mobile = userInfo.mobile;
this.form.username = userInfo.username;
this.birthday = userInfo.birthday || "";
},
};
</script>
<style>
page{
background: #fff;
}
</style>
<style lang="scss" scoped>
.submit {
height: 90rpx;
@@ -178,6 +219,7 @@ export default {
margin: 0 auto;
color: $main-color;
border-radius: 100px;
}
.head {
height: 260rpx;
@@ -194,7 +236,7 @@ export default {
border-radius: 50%;
}
}
/deep/ .u-form {
::v-deep .u-form {
background-color: #ffffff;
padding: 0;
margin-top: 30rpx;
@@ -207,4 +249,21 @@ export default {
.form {
background-color: #ffffff;
}
.bottom{
position: fixed;
bottom: 40px;
display: flex;
align-items: center;
width: 100%;
>.submit{
background: $light-color;
color: #fff;
width: 40%;
}
}
.light{
background: rgba($color: $light-color, $alpha: 0.2) !important;
color: $light-color !important;
}
</style>

View File

@@ -0,0 +1,227 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
绑定手机号码
</h2>
<view class="verification"></view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<view v-if="!validateFlage">
<u-form-item label-width="120" label="手机号" prop="mobile">
<u-input maxlength="11" v-model="codeForm.mobile" placeholder="请输入您的手机号" />
</u-form-item>
<u-form-item class="sendCode" label-width="120" prop="code" label="验证码">
<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>
<view @tap="getCode" class="text-tips">{{ tips }}</view>
</u-form-item>
<view class="submit" @click="validatePhone">绑定</view>
<myVerification keep-running @send="verification" class="verification" ref="verification"
business="BIND_MOBILE" />
</view>
</u-form>
</view>
</view>
</template>
<script>
import {
sendMobile,
bindMobile
} from "@/api/login";
import { getUserInfo } from "@/api/members.js";
import storage from "@/utils/storage.js";
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
step: 0, //当前验证步骤
flage: false, //是否验证码验证
codeForm: {
mobile: "", //手机号
code: "", //验证码
username: "", //用户名
},
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
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"],
}, ],
},
};
},
onLoad(options) {
this.codeForm.username = options.username;
},
onReady() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
watch: {
flage(val) {
if (val) {
if (this.$refs.uCode.canGetCode) {
uni.showLoading({
title: "正在获取验证码",
});
sendMobile(this.codeForm.mobile, "BIND_MOBILE").then((res) => {
if (this.$store.state.isShowToast){ 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;
this.$refs.verification.getCode();
}
})
} else {
this.$u.toast("请倒计时结束后再发送");
}
}
},
},
methods: {
// 验证码验证
verification(val) {
this.flage = val == this.$store.state.verificationKey ? true : false;
},
// 验证手机号
validatePhone() {
this.$refs.validateCodeForm.validate((valid) => {
if (valid) {
bindMobile(this.codeForm).then((res) => {
if (res.data.success) {
this.validateFlage = !this.validateFlage;
// 获取最新的用户信息并更新缓存
getUserInfo().then(userRes => {
if (userRes.data.success) {
storage.setUserInfo(userRes.data.result);
}
// 显示成功提示
uni.showToast({
title: "绑定成功!",
duration: 2000,
icon: "none",
});
// 返回上一页
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
});
}
});
}
});
},
codeChange(text) {
this.tips = text;
},
end() {
this.flage = false;
this.$refs.verification.getCode()
},
/**获取验证码 */
getCode() {
if (this.tips == "重新获取") {
this.$refs.verification.error(); //发送
}
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 = true;
this.$refs.verification.hide();
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
}
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
page {
background: #fff;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>

View File

@@ -0,0 +1,160 @@
<template>
<view class="box">
<view class="box-tips">
<h2 class='h2'>
{{verificationTitle.title}}
</h2>
<view class="verification">{{verificationTitle.desc}}</view>
</view>
<view class="form">
<u-form :model="codeForm" ref="validateCodeForm">
<u-form-item label-width="120" label="旧密码">
<u-input type="password" v-model="oldPassword" placeholder="请输入您的旧密码" />
</u-form-item>
<u-form-item label-width="120" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
</u-form-item>
<u-form-item label-width="120" label="确认密码">
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
</u-form-item>
<view class="submit" @click="updatePassword">修改密码</view>
</u-form>
</view>
</view>
</template>
<script>
import {
resetByMobile,
modifyPass
} from "@/api/login";
import {
md5
} from "@/utils/md5.js"; // md5
import myVerification from "@/components/verification/verification.vue"; //验证
import uuid from "@/utils/uuid.modified.js";
export default {
components: {
myVerification,
},
data() {
return {
uuid,
validateFlage: false, //是否进行了手机号验证
verificationTitle: {
title: "修改密码",
desc: "请验证并输入密码",
},
step: 0, //当前验证步骤
flage: false, //是否验证码验证
codeForm: {
mobile: "", //手机号
code: "", //验证码
},
newPassword: "", //新密码
password: "", //密码
oldPassword: '', //旧密码
tips: "", //提示
seconds: 69, // 60s等待时间
// 验证码登录校验
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() {
// 必须要在onReady生命周期因为onLoad生命周期组件可能尚未创建完毕
this.$refs.validateCodeForm.setRules(this.codeRules);
},
methods: {
// 修改密码
updatePassword() {
if(this.password !== this.newPassword){
uni.showToast({
title: "两次输入密码不一致!",
icon: "none",
});
return;
}
modifyPass({
password: md5(this.oldPassword),
newPassword: md5(this.newPassword),
}).then((res) => {
if (res.data.success) {
uni.showToast({
title: "修改成功!",
duration: 2000,
icon: "none",
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1000);
}
});
},
},
};
</script>
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
::v-deep .u-form-item--right__content__slot {
display: flex;
}
}
.h2 {
font-size: 40rpx;
font-weight: bold;
}
page {
background: #fff;
}
.box {
padding: 80rpx 0;
border-radius: 20rpx;
}
.submit {
background: $light-color;
}
.box-tips {
margin: 0 72rpx;
}
.verification {
font-size: 24rpx;
color: #999;
margin-top: 10rpx;
}
</style>

View File

@@ -25,14 +25,12 @@
business="FIND_USER" />
</view>
<view v-if="validateFlage">
<u-form-item label-width="120" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
<u-form-item label-width="120" label="密码">
<u-input type="password" v-model="password" placeholder="请输入您的密码" />
</u-form-item>
<u-form-item label-width="120" label="密码">
<u-input type="password" v-model="newPassword" placeholder="请输入您的新密码" />
<u-form-item label-width="120" label="确认密码">
<u-input type="password" v-model="newPassword" placeholder="请再次输入您的密码" />
</u-form-item>
<view class="submit" @click="updatePassword">修改密码</view>
@@ -46,7 +44,7 @@
import {
sendMobile,
resetByMobile,
modifyPass
resetPassword
} from "@/api/login";
import {
@@ -139,8 +137,14 @@
methods: {
// 修改密码
updatePassword() {
modifyPass({
newPassword: md5(this.newPassword),
if(this.password !== this.newPassword){
uni.showToast({
title: "两次输入密码不一致!",
icon: "none",
});
return;
}
resetPassword({
password: md5(this.password),
}).then((res) => {
if (res.data.success) {
@@ -237,12 +241,12 @@
<style lang="scss" scoped>
@import url("@/pages/passport/login.scss");
/deep/ .u-form-item {
::v-deep .u-form-item {
margin: 40rpx 0;
}
.sendCode {
/deep/ .u-form-item--right__content__slot {
::v-deep .u-form-item--right__content__slot {
display: flex;
}
}

View File

@@ -1,7 +1,7 @@
<template>
<view class="securityCenter">
<u-cell-group>
<u-cell-item title="修改密码" @click="navigateTo('/pages/mine/set/securityCenter/editPassword')"></u-cell-item>
<u-cell-item title="修改密码" @click="navigateTo('/pages/mine/set/securityCenter/updatePwdTab')"></u-cell-item>
<u-cell-item title="注销账户" @click="zhuxiao"></u-cell-item>
</u-cell-group>
</view>

View File

@@ -0,0 +1,34 @@
<template>
<view class="securityCenter">
<u-cell-group>
<u-cell-item title="验证密码" @click="navigateTo('/pages/mine/set/securityCenter/editLoginPassword')"></u-cell-item>
<u-cell-item title="验证手机号" @click="navigateTo('/pages/mine/set/securityCenter/editPassword')"></u-cell-item>
</u-cell-group>
</view>
</template>
<script>
export default {
data() {
return {
mobile: "", //存储手机号
};
},
methods: {
navigateTo(url) {
uni.navigateTo({
url: url,
});
},
},
};
</script>
<style lang="scss" scoped>
.securityCenter {
.u-cell {
line-height: normal;
}
}
</style>

View File

@@ -18,6 +18,7 @@
<!-- #ifndef MP-WEIXIN -->
<u-cell-item title="安全中心" @click="navigateTo('/pages/mine/set/securityCenter/securityCenter')"></u-cell-item>
<!-- #endif -->
<u-cell-item title="用户注销" v-if="userInfo.id" @click="logoff"></u-cell-item>
<u-cell-item title="意见反馈" @click="navigateTo('/pages/mine/set/feedBack')"></u-cell-item>
<!-- #ifndef H5 -->
<!-- #endif -->
@@ -56,7 +57,12 @@ export default {
this.$options.filters.quiteLoginOut();
},
/**
* 用户注销
*/
logoff(){
this.$options.filters.logoff();
},
/**
* 读取当前缓存
@@ -196,11 +202,11 @@ export default {
color: #333333;
}
/deep/ .u-cell__value {
::v-deep .u-cell__value {
color: #cccccc !important;
}
/deep/ .u-cell__right-icon-wrap {
::v-deep .u-cell__right-icon-wrap {
color: #cccccc !important;
}
</style>

View File

@@ -86,7 +86,7 @@ page {
line-height: 70rpx;
font-size: 24rpx;
}
/deep/ .uni-input-input {
::v-deep .uni-input-input {
font-size: 24rpx;
}
}
@@ -441,7 +441,7 @@ view {
padding-top: 300rpx;
color: #999999;
text-align: center;
/deep/ .u-image {
::v-deep .u-image {
width: 346rpx;
height: 304rpx;
}

View File

@@ -12,11 +12,11 @@
</view>
<div class="u-tabs-search">
<u-search
placeholder="请输入订单编号"
placeholder="请输入订单编号/商品名称/售后单号"
@search="submitSearchOrderList(current)"
@clear="submitSearchOrderList(current)"
@clear="clear(current)"
@custom="submitSearchOrderList(current)"
v-model="orderSn"
v-model="keywords"
>
</u-search>
</div>
@@ -239,13 +239,13 @@ export default {
pageSize: 10,
},
status: "loadmore",
orderSn: "", // 搜索订单sn
keywords: "", // 搜索订单sn
};
},
onLoad(options) {
this.orderList = [];
this.params.pageNumber = 1;
if (options.orderSn) this.params.orderSn = options.orderSn;
if (options.orderSn) this.params.keywords = options.orderSn;
this.searchOrderList(this.current);
},
onPullDownRefresh() {
@@ -261,6 +261,14 @@ export default {
this.orderList = [];
this.searchOrderList(current);
},
// 清空
clear(current){
this.params.pageNumber = 1;
this.logParams.pageNumber = 1;
this.params.keywords = ''
this.orderList = [];
this.searchOrderList(current);
},
/**
* 切换tab页时初始化数据
*/
@@ -282,7 +290,7 @@ export default {
*/
searchOrderList(index) {
if (index == 0) {
this.orderSn ? (this.params.orderSn = this.orderSn) : "";
this.keywords ? (this.params.keywords = this.keywords) : "";
this.getOrderList();
} else {
this.logParams = {
@@ -294,7 +302,7 @@ export default {
if (index === 1) {
this.logParams.serviceStatus = "APPLY";
}
this.orderSn ? (this.logParams.orderSn = this.orderSn) : "";
this.keywords ? (this.logParams.keywords = this.keywords) : "";
this.orderList = [];
this.getAfterSaleLogList();
}

View File

@@ -37,9 +37,8 @@
<view class="body-view">
<!-- 退款原因 -->
<view class="opt-view">
<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-form-item label="申请原因" :label-width="150" >
<div style="width: 100%; text-align: right;" @click="reasonSelectShow = true">{{ form.reason || '请选择申请原因' }}</div>
</u-form-item>
<u-form-item label="申请说明" :label-width="150">
<u-input input-align="right" type="textarea" v-model="form.problemDesc" placeholder="请描述申请售后的说明" />

View File

@@ -10,7 +10,7 @@
</view>
</view>
<view>
<view class="goods-item-view" @click="gotoGoodsDetail(sku.skuId)">
<view class="goods-item-view" @click="gotoGoodsDetail(sku)">
<view class="goods-img">
<u-image border-radius="6" width="131rpx" height="131rpx" :src="sku.image"></u-image>
</view>
@@ -30,33 +30,41 @@
<view class="opt-view">
<view class="img-title" style="font-size: 30rpx">填写物流信息</view>
<u-form-item label="返回方式" :label-width="150">
<u-input type="text" input-align="right" value="快递至第三方卖家" />
<div style="width: 100%; text-align: right;">快递至第三方卖家</div>
</u-form-item>
<u-form-item label="快递公司" :label-width="150">
<u-input v-model="form.courierCompany" type="select" input-align="right" :select-open="companySelectShow" @click="companySelectShow = true" placeholder="请选择快递公司" />
<div style="width: 100%; text-align: right;" @click="companySelectShow = true">
{{ form.courierCompany || '请选择快递公司' }}
</div>
</u-form-item>
<u-form-item label="快递单号" :label-width="150">
<u-input input-align="right" v-model="form.logisticsNo" placeholder="请输入快递单号" />
<u-input input-align="right" v-model="form.logisticsNo" placeholder="请输入快递单号"/>
</u-form-item>
<u-form-item label="发货时间" :label-width="150">
<u-input input-align="right" type="selects" disabled v-model="form.mDeliverTime" @click="timeshow = true" placeholder="请选择发货时间" />
<div style="width: 100%; text-align: right;" @click="timeshow = true">{{
form.mDeliverTime || '请选择发货时间'
}}
</div>
</u-form-item>
</view>
</scroll-view>
<view class="submit-view">
<u-button ripple :customStyle="{'background':$lightColor,'color':'#fff' }" shape="circle" @click="onSubmit">提交申请</u-button>
<u-button ripple :customStyle="{'background':$lightColor,'color':'#fff' }" shape="circle" @click="onSubmit">
提交申请
</u-button>
</view>
</u-form>
<u-select mode="single-column" :list="companyList" v-model="companySelectShow" @confirm="companySelectConfirm"></u-select>
<u-select mode="single-column" :list="companyList" v-model="companySelectShow"
@confirm="companySelectConfirm"></u-select>
<u-calendar v-model="timeshow" :mode="'date'" @change="onTimeChange"></u-calendar>
<u-toast ref="uToast" />
<u-toast ref="uToast"/>
</view>
</template>
<script>
import { getLogistics } from "@/api/address.js";
import { fillShipInfo } from "@/api/after-sale.js";
import {getLogistics} from "@/api/address.js";
import {fillShipInfo} from "@/api/after-sale.js";
import storage from "@/utils/storage";
export default {
@@ -77,7 +85,7 @@ export default {
};
},
onLoad(options) {
this.sku = storage.getAfterSaleData();
let navTitle = "服务单详情";
uni.setNavigationBarTitle({
@@ -122,13 +130,39 @@ export default {
* 点击提交
*/
onSubmit() {
delete this.form.courierCompany;
if (this.form.logisticsId == "") {
this.$refs.uToast.show({
title: "请选择快递公司",
type: "error",
});
return;
}
if (this.form.logisticsNo == "") {
this.$refs.uToast.show({
title: "请填写快递单号",
type: "error",
});
return;
}
if (this.form.mDeliverTime == "") {
this.$refs.uToast.show({
title: "请选择发货时间",
type: "error",
});
return;
}
uni.showLoading({
title: "加载中",
mask: true,
});
delete this.form.courierCompany;
fillShipInfo(this.serviceDetail.sn, this.form).then((res) => {
if (this.$store.state.isShowToast){ uni.hideLoading() };
if (this.$store.state.isShowToast) {
uni.hideLoading()
}
;
if (res.statusCode === 200) {
this.$refs.uToast.show({
title: "提交成功",
@@ -139,6 +173,11 @@ export default {
}
});
},
gotoGoodsDetail(sku) {
uni.navigateTo({
url: `/pages/product/goods?id=${sku.skuId}&goodsId=${sku.goodsId}`,
});
},
},
};
</script>
@@ -149,12 +188,15 @@ page,
background: $page-color-base;
height: 100%;
}
.mp-iphonex-bottom {
overflow: hidden;
}
.after-sales-goods-detail-view {
background-color: #fff;
padding: 10rpx 0rpx;
.header {
background-color: #f7f7f7;
color: #999999;
@@ -164,15 +206,18 @@ page,
align-items: center;
justify-content: center;
line-height: 70rpx;
.header-text {
background-color: #999999;
padding: 10rpx 30rpx;
border-radius: 50rpx;
}
.seller-name {
color: $main-color;
}
}
.goods-item-view {
display: flex;
flex-direction: row;
@@ -182,15 +227,18 @@ page,
.goods-info {
padding-left: 30rpx;
flex: 1;
.goods-title {
margin-bottom: 10rpx;
color: $font-color-dark;
}
.goods-specs {
font-size: 24rpx;
margin-bottom: 10rpx;
color: #cccccc;
}
.goods-price {
display: flex;
flex-direction: row;
@@ -198,23 +246,27 @@ page,
font-size: 28rpx;
margin-bottom: 10rpx;
color: $light-color;
.num {
font-size: 24rpx;
color: #999999;
}
}
}
.goods-num {
width: 60rpx;
color: $main-color;
}
}
}
.opt-view {
background-color: #fff;
padding: 40rpx 30rpx 0rpx 30rpx;
font-size: 26rpx;
.how-view {
display: flex;
flex-direction: row;
@@ -223,18 +275,21 @@ page,
height: 80rpx;
border-bottom: 1px solid $page-color-base;
}
.explain-view {
display: flex;
flex-direction: row;
align-items: center;
height: 150rpx;
}
.img-title {
height: 80rpx;
display: flex;
flex-direction: row;
align-items: center;
}
.images-view {
padding: 20rpx;
display: flex;
@@ -243,6 +298,7 @@ page,
flex-wrap: wrap;
}
}
.submit-view {
position: fixed;
z-index: 999;

View File

@@ -68,6 +68,7 @@ export default {
orderStatusList: {
//订单状态列表
UNDELIVERED: "待发货",
PARTS_DELIVERED: "部分发货",
UNPAID: "未付款",
PAID: "已付款",
DELIVERED: "已发货",
@@ -216,7 +217,7 @@ export default {
}
}
/deep/ .u-input__textarea {
::v-deep .u-input__textarea {
padding: 0;
}
.cell-title {

View File

@@ -34,7 +34,16 @@
<span>{{ complaint.content }}</span>
</view>
</view>
<view class="speak-way" v-else>暂无对话</view>
<view class="speak-way" v-else>暂无对话</view>
<div v-if="complainDetail.complainStatus!='COMPLETE'">
<view class="tips">回复对话</view>
<view class="cell-item complain-content">
<view class="cell-view content">
<u-input type="textarea" height="70rpx" auto-height v-model="complainValue" />
</view>
</view>
<view class="submit-btn" @click="handleSubmit">回复</view>
</div>
<view class="tips">平台仲裁</view>
<u-cell-group>
<u-cell-item :arrow="false" title="仲裁意见" :value="complainDetail.arbitrationResult || '暂无'"></u-cell-item>
@@ -43,13 +52,15 @@
</template>
<script>
import { getComplainDetail } from "@/api/after-sale";
import { getComplainDetail, communication } from "@/api/after-sale";
export default {
data() {
return {
complainId: "",
complainValue: "", //回复内容
complainDetail: "", //投诉详情
statusData: {
NEW: "新投诉",
NEW: "新投诉",
NO_APPLY: "未申请",
APPLYING: "申请中",
COMPLETE: "已完成",
@@ -61,6 +72,7 @@ export default {
},
onLoad(option) {
this.complainId = option.id;
this.init(option.id);
},
methods: {
@@ -78,6 +90,38 @@ export default {
},
});
},
handleSubmit() {
if (!this.complainValue) {
uni.showToast({
title: "请输入回复内容",
duration: 2000,
icon: "none",
});
return;
}
let params = {
content: this.complainValue,
complainId: this.complainId,
};
communication(params).then((res) => {
if (res.data.success) {
uni.showToast({
title: "回复成功",
duration: 2000,
icon: "none",
});
this.complainValue = '';
this.init(this.complainId);
} else {
uni.showToast({
title: res.data.message,
duration: 2000,
icon: "none",
});
}
});
},
/**
* 初始化投诉详情
*/
@@ -126,4 +170,32 @@ export default {
.tips {
margin: 40rpx 32rpx;
}
.cell {
width: 100%;
background: #fff;
padding: 26rpx;
}
.complain-content {
margin: 40rpx 32rpx;
display: flex;
align-items: center;
.content {
width: 100%;
}
.title {
width: 140rpx;
}
}
.submit-btn {
width: 70%;
margin: 0 auto;
height: 80rpx;
line-height: 80rpx;
color: #fff;
text-align: center;
background: $light-color;
margin-top: 20px;
border-radius: 200px;
}
</style>

View File

@@ -28,9 +28,8 @@
<view class="complain-speak"> {{ item.complainTopic }} </view>
</view>
<view class="complain-btn">
<u-tag mode="plain" @click="handleClear(item)" class="complain-tag" text="撤销投诉" type="info" v-if="
item.complainStatus != 'EXPIRED' && item.complainStatus != 'CANCEL'
" />
<u-tag mode="plain" @click="handleClear(item)" class="complain-tag" text="撤销投诉" type="info"
v-if="item.complainStatus === 'APPLYING' || item.complainStatus === 'NEW'" />
<u-tag mode="plain" @click="handleInfo(item)" class="complain-tag" text="投诉详情" type="info" />
</view>
</view>
@@ -163,7 +162,7 @@ export default {
font-size: 24rpx;
color: #999;
}
/deep/ .seller-name {
::v-deep .seller-name {
width: auto !important;
}
.complain-btn {

View File

@@ -0,0 +1,248 @@
<template>
<div>
<view class="logistics-detail">
<view class="card">
<div v-if="logisticsList && logisticsList.length>0">
<ul class="express-log" v-for="(packageItem, packageIndex) in logisticsList" :key="packageIndex" v-if="packageItem">
<div class="layui-layer-wrap">
<dl>
<dt>物流公司</dt>
<dd><div class="text-box">{{ packageItem.logisticsName }}</div></dd>
</dl>
<dl>
<dt>快递单号</dt>
<dd>
<div nctype="ordersSn" class="text-box">
<a class="item" :href='"https://www.baidu.com/s?wd="+packageItem.logisticsNo' target="_blank">{{ packageItem.logisticsNo }}</a>
</div>
</dd>
</dl>
<div class="div-express-log">
<ul class="express-log express-log-name">
<li v-for="(item, index) in packageItem.orderPackageItemList" :key="index">
<p class="time" style="width: 50%;"><span>商品名称</span><span>{{ item.goodsName }}</span></p>
<p class="time" style="width: 30%;"><span>发货时间</span><span>{{ item.logisticsTime }}</span></p>
<p class="time" style="width: 20%;"><span>发货数量</span><span>{{ item.deliverNumber }}</span></p>
</li>
</ul>
</div>
<div class="div-express-log">
<ul class="express-log" v-if="packageItem.traces && packageItem.traces.traces">
<li v-for="(item, index) in packageItem.traces.traces" :key="index">
<span class="time">{{ item.AcceptTime || item.acceptTime }}</span>
<span class="detail">{{ item.AcceptStation || item.remark }}</span>
</li>
</ul>
<ul class="express-log" v-else>
<li>暂无物流信息</li>
</ul>
</div>
</div>
</ul>
</div>
</view>
</view>
</div>
</template>
<script>
import { getPackage } from "@/api/trade.js";
export default {
data() {
return {
order: {},
logisticsList: [],
}
},
components: {
},
computed: {
},
onLoad(option) {
let sn = option.order_sn;
this.tracesList(sn);
},
mounted() {
},
methods: {
tracesList(sn) {
getPackage(sn).then((res) => {
if(res.data.success){
this.logisticsList = res.data.result;
}
});
},
},
}
</script>
<style >
page {
background: #fff;
}
</style>
<style lang="scss" scoped>
// @import url('./goods.scss');
.goods-item-view {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10rpx 30rpx;
.goods-img {
flex: 1;
}
.goods-info {
padding-left: 30rpx;
flex: 3;
.goods-title {
margin-bottom: 10rpx;
color: $font-color-dark;
}
.goods-specs {
font-size: 24rpx;
margin-bottom: 10rpx;
color: #cccccc;
}
.goods-price {
font-size: 28rpx;
margin-bottom: 10rpx;
color: #ff5a10;
}
}
.goods-num {
>.good-complaint {
margin-top: 10rpx;
}
text-align: center;
flex: 1;
width: 60rpx;
color: $main-color;
}
}
.goods-info {
flex: 2;
}
.card-title {
background: #f2f2f2;
}
.logistics-detail {
margin-top: 20rpx;
padding: 0 16rpx;
}
.card {
background: #fff;
border-radius: 20rpx;
width: 100%;
> .card-title {
font-size: 24rpx;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
padding: 16rpx;
}
> .time-line {
padding: 16rpx 32rpx;
}
}
.u-order-title {
font-weight: bold;
}
.u-order-desc {
font-size: 26rpx;
color: #666;
margin: 10rpx 0;
}
.u-order-time {
font-size: 24rpx;
color: #999;
}
.empty {
padding: 40rpx 0;
}
.express-log {
/*margin: 5px -10px 5px 5px;*/
padding: 20rpx;
list-style-type: none;
li {
display: flex;
margin-top: 18rpx;
}
li:nth-of-type(1) {
margin-top: 0;
}
.time {
width: 140rpx;
display: flex;
// float: left;
flex-direction: column;
font-size: 24rpx;
line-height: 40rpx;
span:nth-of-type(1) {
margin-bottom: 16rpx;
}
}
.detail {
width: 100%;
flex: 1;
margin-left: 30rpx;
display: inline-block;
font-size: 24rpx;
line-height: 40rpx;
}
li {
line-height: 60rpx;
}
}
.layui-layer-wrap {
dl {
border-top: solid 1px #f5f5f5;
margin-top: -2rpx;
overflow: hidden;
dt {
font-size: 26rpx;
line-height: 40rpx;
display: inline-block;
padding: 16rpx 1% 16rpx 0;
color: #999;
}
dd {
font-size: 26rpx;
line-height: 40rpx;
display: inline-block;
padding: 16rpx 0 16rpx 16rpx;
border-left: solid 2rpx #f5f5f5;
.text-box {
line-height: 40rpx;
color: #333;
word-break: break-all;
}
}
}
}
.div-express-log {
// max-height: 600rpx;
border: solid 2rpx #e7e7e7;
background: #fafafa;
border-radius: 10rpx;
margin-bottom: 6rpx;
// overflow-y: auto;
// overflow-x: auto;
}
</style>

View File

@@ -115,7 +115,8 @@ export default {
onShow() {
this.orderList = [];
this.params.pageNumber = 1;
this.current == 0 ? this.loadData() : this.loadComments();
this.current = 0
this.loadData()
},
watch: {
/**

View File

@@ -386,13 +386,13 @@
</div>
</template>
<script>
import * as API_Trade from "@/api/trade";
import * as API_Address from "@/api/address";
import * as API_Order from "@/api/order";
import * as API_Trade from "@/api/trade";
import configs from "@/config/config";
import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
import invoices from "@/pages/order/invoice/setInvoice";
import { mapState } from "vuex";
import LiLiWXPay from "@/js_sdk/lili-pay/wx-pay.js";
import configs from "@/config/config";
export default {
onLoad: function (val) {
this.routerVal = val;
@@ -445,6 +445,8 @@ export default {
notSupportFreight: [], //不支持运费
notSupportFreightGoodsList: ["以下商品超出配送范围:"],
storeAddress: "",
originOrderData:"", // 原始订单数据
};
},
watch: {
@@ -482,6 +484,7 @@ export default {
* 监听返回
*/
onBackPress(e) {
console.log("onBackPress", e);
if (e.from == "backbutton") {
let routes = getCurrentPages();
let curRoute = routes[routes.length - 1].options;
@@ -495,7 +498,7 @@ export default {
});
}
});
console.log("curRoute.addId",curRoute.addId)
if (curRoute.addId) {
uni.reLaunch({
url: "/pages/tabbar/cart/cartList",
@@ -651,7 +654,7 @@ export default {
});
return false;
}
} else if (this.shippingText === "LOGISTICS" && this.orderMessage.cartTypeEnum != 'VIRTUAL') {
} else if (this.shippingText === "LOGISTICS" && this.orderMessage.cartTypeEnum !== 'VIRTUAL') {
if (!this.address.id) {
uni.showToast({
title: "请选择地址",
@@ -785,18 +788,29 @@ export default {
this.notSupportFreight = [];
// 获取结算参数
API_Trade.getCheckoutParams(this.routerVal.way).then((res) => {
// 获取结算参数 进行首次判断
this.originOrderData = this.orderMessage ? JSON.parse(JSON.stringify(this.orderMessage)) : ""
if (
!res.data.result.checkedSkuList ||
res.data.result.checkedSkuList.length === 0
) {
uni.switchTab({
url: "/pages/tabbar/cart/cartList",
});
if(!this.originOrderData.checkedSkuList.length){
uni.switchTab({
url: "/pages/tabbar/cart/cartList",
});
}
}
if (res.data.result.skuList.length <= 0) {
uni.navigateTo({
url: "/pages/order/myOrder?status=0",
});
if(!this.originOrderData.skuList.length){
uni.navigateTo({
url: "/pages/order/myOrder?status=0",
});
}
}
let repeatData;
@@ -867,7 +881,7 @@ page {
}
.uinput {
/deep/ input {
::v-deep input {
text-align: right;
}
}
@@ -962,7 +976,7 @@ page {
text-align: left;
}
/deep/ .u-col-3 {
::v-deep .u-col-3 {
text-align: right;
}
@@ -997,7 +1011,7 @@ page {
}
}
/deep/ .u-notice-bar-wrap {
::v-deep .u-notice-bar-wrap {
width: 100% !important;
}
@@ -1114,11 +1128,11 @@ page {
color: #333333;
}
/deep/ .u-col {
::v-deep .u-col {
padding: 36rpx 0 !important;
}
/deep/ .u-col-3,
::v-deep .u-col-3,
.tipsColor {
color: #333;
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,19 +10,19 @@
</div>
<!-- 物流信息 -->
<view class="info-view logistics-view">
<view class="logistics-List" v-if="logisticsList && logisticsList.traces.length != 0 ">
<view class="logistics-List-title">
{{ logisticsList.traces[logisticsList.traces.length - 1].AcceptStation }}
</view>
<view class="logistics-List-time">
{{ logisticsList.traces[logisticsList.traces.length - 1].AcceptTime }}
</view>
</view>
<view class="logistics-List" v-else>
<view class="logistics-List">
<view class="verificationCode" v-if="order.verificationCode">
券码 {{ order.orderStatus == 'CANCELLED' ? '已失效' : order.verificationCode }}
</view>
<view @click="handleClickDeliver()" class="info-view logi-view" v-else-if="orderPackage && orderPackage.length">
<view class="verificationCode">
当前订单有 {{ orderPackage.length }} 个包裹快递
</view>
<div>
点击此处查看
</div>
</view>
<view v-else class="logistics-List-title">
{{ '暂无物流信息' }}
</view>
@@ -30,7 +30,7 @@
</view>
<!-- 地址 -->
<view class="info-view" v-if="order.deliveryMethod == 'LOGISTICS'">
<view class="info-view" v-if="order.deliveryMethod === 'LOGISTICS' && order.orderType !== 'VIRTUAL'">
<view class="address-view">
<view>
<view class="address-title">
@@ -44,7 +44,7 @@
</view>
<!-- 提货地址 -->
<view class="info-view" v-if="order.deliveryMethod == 'SELF_PICK_UP'">
<view class="info-view" v-if="order.deliveryMethod === 'SELF_PICK_UP'">
<view class="address-view">
<view>
<view class="order-info-view">
@@ -83,6 +83,9 @@
<view class="goods-price">
{{ sku.goodsPrice | unitPrice }}
<!-- <span v-if="sku.point">+{{ sku.point }}积分</span> -->
<span style="font-size: 24rpx;margin-left: 14rpx;color: #ff9900;" v-if="sku.isRefund && sku.isRefund !== 'NO_REFUND'">
{{refundPriceList(sku.isRefund)}} ({{ sku.refundPrice | unitPrice("") }})
</span>
</view>
</view>
<view class="goods-num">
@@ -105,11 +108,11 @@
<view class="title">商品总价</view>
<view class="value">{{ order.goodsPrice | unitPrice }}</view>
</view>
<view class="order-info-view">
<view class="order-info-view" v-if="order.freightPrice">
<view class="title">运费</view>
<view class="value">{{ order.freightPrice | unitPrice }}</view>
</view>
<view class="order-info-view">
<view class="order-info-view" v-if="order.priceDetailDTO">
<view class="title">优惠券</view>
<view class="value main-color">-{{ order.priceDetailDTO.couponPrice | unitPrice }}</view>
</view>
@@ -159,7 +162,7 @@
<view class="order-info-view">
<view class="title">订单备注</view>
<view class="value">{{
order.remark
order.remark || '暂无备注'
}}</view>
</view>
<view class="order-info-view">
@@ -249,7 +252,7 @@
</template>
<script>
import { getExpress } from "@/api/trade.js";
import { getExpress, getPackage } from "@/api/trade.js";
import { cancelOrder, confirmReceipt, getOrderDetail } from "@/api/order.js";
import shares from "@/components/m-share/index"; //分享
@@ -278,6 +281,10 @@ export default {
title: "待发货",
value: "商品等待发货中",
},
PARTS_DELIVERED: {
title: "部分发货",
value: "商品已部分发货。",
},
DELIVERED: {
title: "已发货",
value: "商品已发货,请您耐心等待",
@@ -307,6 +314,7 @@ export default {
cancelList: "",
rogShow: false,
reason: "",
orderPackage:"",
};
},
onLoad(options) {
@@ -314,6 +322,34 @@ export default {
this.sn = options.sn;
},
methods: {
//获取包裹
async getOrderPackage() {
getPackage(this.order.sn).then(res => {
if (res.data.success) {
this.orderPackage = res.data.result
}
})
},
handleClickDeliver(){
uni.navigateTo({
url: `/pages/order/deliverDetail?order_sn=${this.order.sn}`,
});
},
// 退款状态枚举
refundPriceList(status) {
switch (status) {
case 'ALL_REFUND':
return "全部退款";
case 'PART_REFUND':
return "部分退款";
case 'NO_REFUND':
return "未退款";
case 'REFUNDING':
return "退款中";
default:
return "";
}
},
callPhone(){
this.$options.filters.callPhone(this.order.storeAddressMobile )
},
@@ -359,7 +395,8 @@ export default {
this.orderGoodsList = order.orderItems;
this.orderDetail = res.data.result;
if (this.order.deliveryMethod === 'LOGISTICS') {
this.loadLogistics(sn)
this.loadLogistics(sn);
this.getOrderPackage();
}
if (this.$store.state.isShowToast){ uni.hideLoading() };
});

View File

@@ -17,12 +17,12 @@
:border-bottom="false"
prop="companyAddressPath"
label="公司所在地"
><u-input
type="select"
>
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
<u-input
disabled
:custom-style="defaultInputStyle"
v-model="form.companyAddressPath"
disabled
@click="showPicker()"
/></u-form-item>
<u-form-item
required
@@ -162,8 +162,18 @@
:max-count="1"
:show-progress="false"
></u-upload>
<u-upload
:file-list="legalPhotoFileList"
:header="{ accessToken: storage.getAccessToken() }"
:action="action"
width="200"
@on-uploaded="onUploaded($event, 'legalPhoto')"
:max-count="1"
:show-progress="false"
></u-upload>
</div>
</u-form-item>
{{form}}
</div>
</u-form>
<div class="submit" @click="validatorStep1Form">提交/下一步</div>
@@ -277,7 +287,18 @@ export default {
{ pattern: RegExp.licenseNum, message: "请输入正确的营业执照号" },
],
scope: [{ required: true, message: "请填写营业执照所示经营范围" }],
legalPhoto: [{ required: true, message: "请上传法人身份证照片" }],
legalPhoto: [{ required: true, message: "请上传法人身份证照片" },
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说返回true表示校验通过返回false表示不通过
// this.$u.test.mobile()就是返回true或者false的
return value.length === 2;
},
message: "请上传法人身份证正反照片",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
}],
licencePhoto: [{ required: true, message: "请上传营业执照" }],
legalName: [{ required: true, message: "请输入法人姓名" }],
legalId: [
@@ -314,10 +335,13 @@ export default {
// 图片上传
onUploaded(lists, key) {
let images = [];
if(!this.form[key]){
this.form[key] = [];
}
lists.forEach((item) => {
images.push(item.response.result);
});
this.form[key] = images;
this.form[key].push(images[0]);
},
getPickerParentValue(e) {
this.form.companyAddressIdPath = [];
@@ -338,6 +362,7 @@ export default {
},
// 显示三级地址联动
showPicker() {
console.log(this.$refs)
this.$refs.cityPicker.show();
},
validatorStep1Form() {

View File

@@ -33,7 +33,10 @@
:border-bottom="false"
prop="goodsManagementCategory"
label="店铺经营类目"
><u-input
>
<div @click="showCategory()" style="margin-right: 30rpx;">选择</div>
<u-input
:custom-style="defaultInputStyle"
v-model="goodsManagementCategory"
disabled
@@ -46,15 +49,17 @@
prop="storeAddressPath"
label="店铺所在地"
>
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
<u-input
:custom-style="defaultInputStyle"
v-model="form.storeAddressPath"
disabled
@click="showPicker()"
/>
</u-form-item>
<u-form-item
<!-- <u-form-item
required
:border-bottom="false"
prop="storeAddressPath"
@@ -62,7 +67,7 @@
>
<div class="get-center" @click="clickUniMap()">开始定位</div>
<div class="tips-success" v-if="form.storeCenter">已成功定位</div>
</u-form-item>
</u-form-item> -->
<u-form-item
required
@@ -287,7 +292,7 @@ export default {
},
getPickerParentValue(e) {
this.form.storeAddressIdPath = [];
console.log(e)
let name = "";
e.forEach((item, index) => {
if (item.id) {
@@ -298,9 +303,11 @@ export default {
} else {
name += item.localName + ",";
}
this.form.storeAddressPath = name;
this.$set(this.form,'storeAddressPath',name)
}
});
this.form.storeCenter = e[e.length-1].center
},
// 显示三级地址联动
showPicker() {

View File

@@ -11,7 +11,7 @@
position: relative;
}
/deep/ .u-form-item--right__content__slot {
::v-deep .u-form-item--right__content__slot {
width: 100%;
display: block;
}

View File

@@ -183,7 +183,7 @@
onShow() {
// 只要是app登录的全部清除内容
// #ifdef APP-PLUS
// #ifdef APP-PLUS
storage.setAccessToken("");
storage.setRefreshToken("");
storage.setUserInfo({});
@@ -204,7 +204,7 @@
},
mounted() {
// #ifndef APP-PLUS
//判断是否微信浏览器
var ua = window.navigator.userAgent.toLowerCase();
@@ -363,8 +363,22 @@
icon: "none",
});
getUserInfo().then((user) => {
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
if(user.data.success){
storage.setUserInfo(user.data.result);
storage.setHasLogin(true);
}else {
setTimeout(() => {
uni.showToast({
title: user.data.message,
icon: "none",
});
storage.setAccessToken('');
storage.setRefreshToken('');
uni.switchTab({
url: "/pages/tabbar/user/my",
});
}, 500);
}
});
getCurrentPages().length > 1 ?
uni.navigateBack({
@@ -428,7 +442,7 @@
//写入用户信息
uni.setStorageSync("nickname", infoRes.userInfo.nickName);
uni.setStorageSync("avatar", infoRes.userInfo.avatarUrl);
uni.setStorageSync("unionId", infoRes.userInfo.unionId);
uni.setStorageSync("unionId", infoRes.userInfo.unionId || infoRes.userInfo.unionid);
// #ifdef MP-WEIXIN
//微信小程序获取openid 需要特殊处理 如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id
@@ -460,7 +474,7 @@
token:{unionId:"",openId:uni.getStorageSync("openid")}
};
uni.getStorageSync("unionId") ? (params.token.unionId = uni.getStorageSync("unionId")) : delete params.token;
openIdLogin(params, clientType).then((res) => {
if (!res.data.success) {
let errormessage = "第三方登录暂不可用";
@@ -503,9 +517,17 @@
});
}
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
setTimeout(() => {
uni.showToast({
title: user.data.message,
icon: "none",
});
storage.setAccessToken('');
storage.setRefreshToken('');
uni.switchTab({
url: "/pages/tabbar/user/my",
});
}, 500);
}
});
}
@@ -556,7 +578,6 @@
// 登录成功之后获取用户信息
getUserInfoMethods(res) {
console.log(res);
if (res.data.success) {
storage.setAccessToken(res.data.result.accessToken);
storage.setRefreshToken(res.data.result.refreshToken);
@@ -574,17 +595,26 @@
storage.setAutoCp(0)
// 登录成功
uni.showToast({
title: "登录成功!",
title:"提示",
content: "登录成功!",
icon: "none",
});
whetherNavigate();
}else{
setTimeout(() => {
uni.showToast({
title: user.data.message,
icon: "none",
});
storage.setAccessToken('');
storage.setRefreshToken('');
uni.switchTab({
url: "/pages/tabbar/user/my",
});
}, 500);
} else {
uni.switchTab({
url: "/pages/tabbar/home/index",
});
}
});
}
@@ -599,9 +629,9 @@
uni.navigateTo({
url: "/pages/mine/help/tips?type=" + val,
});
},
// 点击获取验证码
start() {
this.codeColor = "#999";

View File

@@ -20,10 +20,18 @@
<view>您的公开信息昵称头像</view>
</view>
<view class="btns">
<button type="primary" bindtap="getUserProfile" @click="getUserProfile()"
<button type="primary" :disabled="logingFlag" bindtap="getUserProfile" @click="getUserProfile()"
class="btn-auth">登录</button>
<div @click="backToHome" class="btn-callback">暂不登录</div>
</view>
<div class="privacy">
<u-checkbox shape="circle" v-model="checked" :active-color="lightColor">
<div class="flex">
阅读并同意<navigator class="light-color" url="/pages/mine/help/tips?type=PRIVACY_POLICY">隐私协议</navigator>
<navigator class="light-color" url="/pages/mine/help/tips?type=USER_AGREEMENT">用户协议</navigator>
</div>
</u-checkbox>
</div>
</div>
</view>
</view>
@@ -45,6 +53,8 @@
export default {
data() {
return {
lightColor:this.$lightColor,
checked:false,
configs:config,
// 是否展示手机号码授权弹窗,默认第一步不展示,要先获取用户基础信息
phoneAuthPopup: false,
@@ -54,6 +64,7 @@
code: "",
//微信昵称
nickName: "",
logingFlag: false,
//微信头像
image: "",
};
@@ -66,7 +77,19 @@
withShareTicket: true
});
let that = this;
//获取code
uni.login({
success: (res) => {
if(res.errMsg === "login:ok") {
this.code = res.code
} else {
uni.showToast({
title: "系统异常,请联系管理员!"
})
}
},
});
},
methods: {
@@ -93,27 +116,23 @@
//获取用户信息
getUserProfile(e) {
let that = this;
//获取code
uni.login({
success: (res) => {
if(res.errMsg === "login:ok") {
that.code = res.code
} else {
uni.showToast({
title: "系统异常,请联系管理员!"
})
}
},
});
if(!this.checked){
uni.showToast({
title:"请勾选协议",
icon:'none'
})
return
}
this.logingFlag = true;
if (this.code) {
// 推荐使用wx.getUserProfile获取用户信息开发者每次通过该接口获取用户个人信息均需用户确认
uni.getUserProfile({
desc: "用于完善会员资料", // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
that.nickName = res.userInfo.nickName;
that.image = res.userInfo.avatarUrl;
console.log("success", res)
this.nickName = res.userInfo.nickName;
this.image = res.userInfo.avatarUrl;
/**
* 根据公有的配置设置登录方式
@@ -152,13 +171,15 @@
});
});
});
},
fail: (res) => {
console.log("fail", res)
},
});
}
this.logingFlag = false;
}
},
//获取手机号授权
@@ -353,4 +374,10 @@
transform: scale(1.1);
}
}
.privacy{
text-align: center;
margin-top: 20rpx;
width: 100%;
}
</style>

View File

@@ -121,7 +121,7 @@ export default {
padding: 32rpx;
}
/deep/ .u-col {
::v-deep .u-col {
text-align: center;
padding: 16rpx 0 !important;
}

View File

@@ -155,15 +155,17 @@ export default {
* 顶部筛选条件
*/
select(index) {
this.params = {
pageNumber: 1,
pageSize: 10,
};
this.selectIndex = index;
this.params.grade = ["", "GOOD", "MODERATE", "WORSE", ""][
this.selectIndex
];
this.selectIndex == 4 ? (this.params.haveImage = 1) : true;
this.params.pageNumber = 1;
this.params.pageSize = 10;
this.selectIndex === 4 ? (this.params.haveImage = 1) : true;
this.commDetail = [];
if (this.selectIndex == 0) {
if (this.selectIndex === 0) {
this.params = {
pageNumber: 1,
pageSize: 10,

View File

@@ -554,7 +554,7 @@ export default {
this.productId = id; // skuId
// 这里请求获取到页面数据 解析数据
let response = await getGoods(id, goodsId);
let response = await getGoods(id || 'undefined', goodsId);
// 判断当前接口返回内容
if (!response.data.success) {
@@ -567,7 +567,7 @@ export default {
// }, 500);
}
// 这里是绑定分销员
if (distributionId || this.$store.state.distributionId) {
if ((distributionId || this.$store.state.distributionId) && this.$options.filters.isLogin("auth")) {
let disResult = await getGoodsDistribution(distributionId);
if (!disResult.data.success || disResult.statusCode == 403) {
this.$store.state.distributionId = distributionId;
@@ -594,7 +594,7 @@ export default {
}
});
// 轮播图
this.imgList = this.goodsDetail.goodsGalleryList;
this.imgList = this.goodsDetail.goodsGalleryList.filter(i => i.indexOf("\"url\":") === -1 && i.indexOf("\"status\":") === -1);
// 获取店铺基本信息
this.getStoreBaseInfoFun(this.goodsDetail.storeId);
@@ -793,8 +793,8 @@ export default {
getGoodsList({
pageNumber: 1,
pageSize: 10,
category: this.goodsDetail.categoryId,
keyword: this.goodsDetail.name,
currentGoodsId: this.goodsDetail.id,
keyword: this.goodsDetail.name
}).then((res) => {
this.likeGoodsList = res.data.result.records;
});

View File

@@ -120,18 +120,18 @@ export default {
.empty {
margin: 40rpx 0;
}
.goods-detail /deep/ .vhtml {
.goods-detail ::v-deep .vhtml {
overflow: hidden;
width: 100%;
}
.vhtml {
/deep/ img {
::v-deep img {
display: block !important;
}
}
/deep/ img {
::v-deep img {
width: 100%;
}
.goods-detail-box {

View File

@@ -104,7 +104,7 @@ export default {
}
}
/deep/ .image-wrapper image {
::v-deep .image-wrapper image {
opacity: 1 !important;
}

View File

@@ -125,7 +125,7 @@ export default {
display: block;
}
/deep/ .u-mode-light-error {
::v-deep .u-mode-light-error {
border: none;
}

View File

@@ -126,7 +126,7 @@ export default {
color: #333333;
margin-left: 20rpx;
}
/deep/ .u-mode-light-error {
::v-deep .u-mode-light-error {
border: none;
}
.coupon{

View File

@@ -35,7 +35,7 @@
background: #ffe7e6 !important;
text-align: center !important;
}
/deep/ .u-mode-light-error {
::v-deep .u-mode-light-error {
border: none;
}

View File

@@ -67,7 +67,7 @@ export default {
<style lang="scss" scoped>
@import "../product.scss";
.recommend-item-name {
height: 70rpx;
height: 60rpx;
color: #333;
font-weight: 400;
font-size: 24rpx;
@@ -87,14 +87,14 @@ export default {
overflow: hidden;
border-radius: 12rpx;
/deep/ .u-image__image {
::v-deep .u-image__image {
height: 218rpx;
border-radius: 12rpx !important;
}
}
.recommend-item-img {
/deep/ .u-image__image {
::v-deep .u-image__image {
width: 100% !important;
}
}
@@ -190,7 +190,7 @@ export default {
flex-wrap: wrap;
justify-content: space-between;
/deep/ .u-row {
::v-deep .u-row {
width: 100%;
}

View File

@@ -101,7 +101,7 @@ page {
color: $price-color;
font-size: 32rpx;
line-height: 1;
/deep/ .price {
::v-deep .price {
font-size: 60rpx;
}
}
@@ -124,7 +124,7 @@ page {
overflow: hidden;
border-radius: 12rpx;
/deep/ .u-image__image {
::v-deep .u-image__image {
// width: 228rpx;
height: 228rpx;
border-radius: 12rpx !important;
@@ -200,7 +200,7 @@ page {
font-size: 30rpx;
transition: all 0.5s;
}
/deep/ .u-navbar {
::v-deep .u-navbar {
padding-left: 10rpx;
}
.nav-item {
@@ -356,7 +356,7 @@ page {
z-index: 8;
width: 100%;
/deep/ .u-row {
::v-deep .u-row {
width: 100%;
}
}
@@ -368,7 +368,7 @@ page {
color: #fff;
padding: 0 20rpx;
/deep/ .price {
::v-deep .price {
font-size: 36rpx;
font-weight: 400;
text-align: left;

View File

@@ -85,7 +85,7 @@
<u-tabs :list="tabs" :active-color="mainColor" :is-scroll="false" :current="current" @change="changeTab"></u-tabs>
<div class="content" v-if="current == 0">
<u-empty style='margin-top:100rpx' v-if="goodsList.length == 0" class="empty" text='暂无商品信息'></u-empty>
<goodsTemplate v-else :res="goodsList" :storeName="false" />
<goodsTemplate style="width:100%;" v-else :res="goodsList" :storeName="false" />
</div>
<!-- 全部分类 -->
<div class="category" v-if="current == 1">

View File

@@ -290,7 +290,7 @@ page {
}
.index-item-img {
/deep/ .u-image {
::v-deep .u-image {
width: 346rpx !important;
height: 320rpx !important;
border-radius: 10rpx !important;

View File

@@ -26,7 +26,7 @@
color: #999999;
margin: 0 20rpx;
/deep/ view {
::v-deep view {
line-height: 1.75;
}
}
@@ -121,7 +121,7 @@
text-align: center;
padding: 6rpx 16rpx;
}
/deep/ .empty {
::v-deep .empty {
position: relative;
padding-top: 20%;
> .empty-content {

View File

@@ -1,5 +1,10 @@
<template>
<div class="wrapper">
<u-navbar :is-back="false" title="购物车">
<div slot="right">
<div class="light-color edit" @click="isEdit = !isEdit">{{ !isEdit ? '编辑' : '完成'}}</div>
</div>
</u-navbar>
<!-- 空白页-->
<view v-if="!loading && (cartDetail.cartList == '' || cartDetail.cartList == [] || !cartDetail)" class="empty">
<image src="/static/emptyCart.png" mode="aspectFit"></image>
@@ -8,7 +13,6 @@
<navigator class="navigator" url="/pages/tabbar/home/index" open-type="switchTab">随便逛逛></navigator>
</view>
</view>
<!-- 店铺商品信息 -->
<div class="content">
<div class="box box2" :class="{ invalid: isInvalid(item) }" v-for="(item, index) in cartDetail.cartList"
@@ -73,7 +77,7 @@
{{ skuItem.goodsSku.goodsName }}
</p>
<!-- 规格 -->
<p class="sp-type">{{skuItem.goodsSku.simpleSpecs}}</p>
<p class="sp-type" style="width:300rpx">{{skuItem.goodsSku.simpleSpecs}}</p>
<p class="sp-type" v-if="skuItem.goodsSku.salesModel == 'WHOLESALE'">批发商品</p>
<p class="sp-number">
<view class="sp-price">
@@ -554,6 +558,10 @@ page {
.u-image {
box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.05);
}
.edit{
padding-right: 32rpx;
font-size: 28rpx;
}
.promotion-notice {
margin-top: 10px;
margin-left: 68rpx;
@@ -562,7 +570,7 @@ page {
font-weight: bold;
display: flex;
align-items: center;
/deep/ .tips {
::v-deep .tips {
margin: 0 8rpx 0 0;
background: $main-color;
border-radius: 100px;
@@ -596,14 +604,14 @@ page {
}
/* 空白页 */
/deep/ .u-number-input {
::v-deep .u-number-input {
background: #fff !important;
border: 1px solid #ededed;
margin: 0 !important;
}
/deep/ .u-icon-minus,
/deep/ .u-icon-plus {
::v-deep .u-icon-minus,
::v-deep .u-icon-plus {
background: #ffffff !important;
border: 1px solid #ededed;
color: #333 !important;
@@ -657,7 +665,7 @@ page {
display: flex;
align-items: center;
/deep/ .number {
::v-deep .number {
line-height: 1;
font-size: 30rpx;
> span {
@@ -683,7 +691,7 @@ page {
height: 100%;
}
/deep/ .u-col {
::v-deep .u-col {
padding: 24rpx 0 !important;
}
@@ -727,7 +735,7 @@ page {
.goods-config {
display: flex;
align-items: center;
/deep/ .invalid {
::v-deep .invalid {
display: block;
width: 80rpx !important;
}
@@ -757,7 +765,7 @@ page {
height: 40rpx;
border-left: 1px solid #eeeeee;
/deep/ span {
::v-deep span {
margin-left: 20rpx;
}
}
@@ -806,10 +814,10 @@ page {
display: flex;
justify-content: space-between;
> .sp-price {
/deep/ span:nth-of-type(1) {
::v-deep span:nth-of-type(1) {
font-size: 38rpx;
}
/deep/ span:nth-of-type(2) {
::v-deep span:nth-of-type(2) {
font-size: 24rpx;
}
}

View File

@@ -2,7 +2,12 @@
<view class="category-wrap">
<u-navbar class="navbar" :is-back="false">
<div class="title">商品分类</div>
<!-- #ifdef H5 -->
<u-search class="nav-search" @click.native="search" placeholder="搜索商品" :show-action="false"></u-search>
<!-- #endif -->
<!-- #ifndef H5 -->
<u-search class="nav-search" disabled @click.native="search" placeholder="搜索商品" :show-action="false"></u-search>
<!-- #endif -->
</u-navbar>
<view class="content">
<scroll-view scroll-y scroll-with-animation class="left-aside">
@@ -206,7 +211,7 @@ uni-scroll-view .uni-scroll-view::-webkit-scrollbar {
border-radius: 8px;
margin-bottom: 20rpx;
}
/deep/ .u-image {
::v-deep .u-image {
width: 140rpx !important;
height: 140rpx !important;
border-radius: 8px !important;

View File

@@ -32,9 +32,38 @@ export function modelNavigateTo(item) {
break;
// 活动
case "marketing":
uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
});
switch (val.___promotion) {
// 积分商品
case "POINTS_GOODS":
uni.navigateTo({
url: `/pages/promotion/point/detail?id=${val.promotionId}`,
});
break;
// 砍价
case "KANJIA":
uni.navigateTo({
url: `/pages/promotion/bargain/detail?id=${val.promotionId}`,
});
break;
// 优惠券商品
case "COUPON":
uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
});
break;
// 满减商品
case "FULL_DISCOUNT":
uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
});
break;
// 秒杀频道
case "SECKILL":
uni.navigateTo({
url: "/pages/product/goods?id=" + val.skuId + "&goodsId=" + val.goodsId,
});
break;
}
break;
case "pages":
uni.navigateTo({
@@ -205,4 +234,4 @@ function seacnCode() {
}
},
});
}
}

View File

@@ -108,7 +108,6 @@ export default {
handler(val) {
// 监听父级的值 如果有值将值赋给selected
if (val) {
console.log(val)
// 如果第一个标签页绑定为商品
this.selected.val = this.res.list[0].listWay[0] ? this.res.list[0].listWay[0].type: '';
// 如果第一个标签为绑定为分类

View File

@@ -45,7 +45,7 @@ export default {
<style lang="scss" scoped>
.web-view {
/deep/ .web-view {
::v-deep .web-view {
padding: 0;
margin: 0;
}

View File

@@ -219,7 +219,7 @@ body {
line-height: 1;
}
/deep/ .u-icon,
::v-deep .u-icon,
.u-icon {
margin-top: 106rpx;
}

View File

@@ -97,6 +97,10 @@
</view>
<!-- <view class="interact-item" @click="inviter()">-->
<!-- <image src="/static/mine/share.png" mode=""></image>-->
<!-- <view>邀新</view>-->
<!-- </view>-->
<view class="interact-item" @click="navigateTo('/pages/mine/set/setUp')">
<image src="/static/mine/setting.png" mode=""></image>
<view>设置</view>
@@ -105,6 +109,23 @@
</view>
</div>
<template>
<u-popup v-model="sharingShow" mode="bottom" border-radius="14">
<view style="margin: 10px; text-align: center;"> 请邀请用户扫描二维码或者将地址复制转发给其他用户 </view>
<view class='qrcode'>
<uqrcode ref="uqrcode" canvas-id="qrcode" :value="sharingLink" :options="{ margin: 10 }">
</uqrcode>
</view>
<view class="copy-text" @click="getDetail(sharingLink)">
{{sharingLink}}
</view>
<view class="confrim-btn">
<u-button @click="sharingShow = false;">关闭</u-button>
</view>
</u-popup>
</template>
</view>
</view>
</template>
@@ -117,16 +138,46 @@ import storage from "@/utils/storage";
export default {
data() {
return {
configs,
storage
configs,
storage,
repayingShow: false, //分销清退弹框
sharingShow: false,
sharingLink: ""
}
},
methods: {
handleNavigate(url) {
uni.navigateTo({
url,
});
},
inviter() {
if (storage.getUserInfo().id) {
this.sharingLink = this.configs.shareLink + "?inviter=" + this.storage.getUserInfo().id
this.sharingShow = true
} else {
uni.showToast({
title: "请先登录",
duration: 2000,
icon: "none",
});
}
},
navigateTo(url) {
uni.navigateTo({
url,
});
const ignores = [
'/pages/mine/set/setUp',
'/pages/mine/set/editionIntro',
'/pages/mine/set/feedBack'
]
if (!ignores.includes(url)) {
if (this.$options.filters.tipsToLogin('normal')) {
this.handleNavigate(url)
}
}
else {
this.handleNavigate(url)
}
},
linkMsgDetail(){
@@ -179,41 +230,58 @@ export default {
</script>
<style lang="scss" scoped>
.copy-text {
display: flex;
align-items: center;
justify-content: center;
margin: 10px;
line-break: anywhere;
}
.interact-tools {
border-left: none;
border-right: none;
border-left: none;
border-right: none;
.interactBox {
height: 156rpx;
}
.interact-container {
margin: 0 20rpx;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1);
.interact-item-img {
width: 52rpx !important;
height: 52rpx !important;
// margin-bottom: !important;
margin: 0 auto 6rpx auto !important;
}
image {
width: 52rpx;
height: 52rpx;
margin-bottom: 6rpx;
}
display: flex;
align-items: center;
flex-wrap: wrap;
text-align: center;
.interactBox {
height: 156rpx;
}
.interact-item {
font-size: $font-sm;
width: 25%;
height: 160rpx;
padding: 30rpx;
}
}
.interact-container {
margin: 0 20rpx;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 24rpx 0 rgba($color: #f6f6f6, $alpha: 1);
.interact-item-img {
width: 52rpx !important;
height: 52rpx !important;
// margin-bottom: !important;
margin: 0 auto 6rpx auto !important;
}
image {
width: 52rpx;
height: 52rpx;
margin-bottom: 6rpx;
}
display: flex;
align-items: center;
flex-wrap: wrap;
text-align: center;
.interact-item {
font-size: $font-sm;
width: 25%;
height: 160rpx;
padding: 30rpx;
}
}
}
.qrcode {
margin: 0 auto;
width: 200px;
}
</style>

View File

@@ -5,6 +5,27 @@
import { getAppVersion } from "@/api/message.js";
const platform = uni.getSystemInfoSync().platform;
// 版本号比较函数
function compareVersion(version1, version2) {
const v1Parts = version1.split('.').map(Number);
const v2Parts = version2.split('.').map(Number);
const maxLength = Math.max(v1Parts.length, v2Parts.length);
for (let i = 0; i < maxLength; i++) {
const v1Part = v1Parts[i] || 0;
const v2Part = v2Parts[i] || 0;
if (v1Part > v2Part) {
return 1;
} else if (v1Part < v2Part) {
return -1;
}
}
return 0;
}
// 主颜色
const $mainColor = "#1ABC9C";
// 弹窗图标url
@@ -29,7 +50,7 @@ export const getServerNo = function (callback) {
platform == "android" ? (type = "ANDROID") : (type = "IOS");
getAppVersion(type).then((res) => {
if (res.data.success && res.data.result.downloadUrl) {
if (res.data.success && res.data.result && res.data.result.downloadUrl) {
let response = res.data.result;
let result = {};
result.versionCode = response.version;
@@ -854,11 +875,9 @@ function downloadPopup(data, callback, cancelCallback, rebootCallback) {
export default function (isPrompt = false) {
getCurrentNo((version) => {
getServerNo((res) => {
if (res.versionCode.replace(/\./g, "") <= version.version.replace(/\./g, "")) {
if (compareVersion(res.versionCode, version.version) <= 0) {
return false;
}
if (res.forceUpdate) {
if (/\.wgt$/i.test(res.downloadUrl)) {
getDownload(res);

BIN
static/mine/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -65,7 +65,7 @@ $font-weight: 400;
}
.bg-light-color {
background-color: $light-color !important;
/deep/ * {
::v-deep * {
background-color: $light-color !important;
}
}

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,392 @@
# 介绍
`uQRCode`是一款基于`Javascript`环境开发的二维码生成插件,适用所有`Javascript`运行环境的前端应用和`Node.js`应用。
`uQRCode`可扩展性高,它支持自定义渲染二维码,可通过`uQRCode API`得到二维码绘制关键信息后,使用`canvas``svg``js`操作`dom`的方式绘制二维码图案。还可自定义二维码样式,如随机颜色、圆点、方块、块与块之间的间距等。
欢迎加入群聊【uQRCode交流群】[695070434](https://jq.qq.com/?_wv=1027&k=JRjzDqiw)。
# 设计器
uQRCode发布了配套的可视化设计器可根据自己喜好在设计器中设计二维码样式一键生成配置代码复制到项目中详情请在微信小程序搜索“柚子二维码”或扫描下方小程序码体验。
![uQRCode设计器](https://uqrcode.cn/mp_weixin_code.jpg)
## 设计器模板示例
![uQRCode设计器](https://uqrcode.cn/yz_1.png)
![uQRCode设计器](https://uqrcode.cn/yz_2.png)
![uQRCode设计器](https://uqrcode.cn/yz_3.png)
![uQRCode设计器](https://uqrcode.cn/yz_4.png)
![uQRCode设计器](https://uqrcode.cn/yz_5.png)
![uQRCode设计器](https://uqrcode.cn/yz_6.png)
![uQRCode设计器](https://uqrcode.cn/yz_7.png)
![uQRCode设计器](https://uqrcode.cn/yz_8.png)
![uQRCode设计器](https://uqrcode.cn/yz_9.png)
# 快速上手
> 在`uni-app`中,我们更推荐使用组件方式来生成二维码,组件方式大大提高了页面的可读性以及避开了一些平台容易出问题的地方,当组件无法满足需求的时候,再考虑切换成原生方式。
官方文档:[https://uqrcode.cn/doc](https://uqrcode.cn/doc)。
github地址[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode)。
npm地址[https://www.npmjs.com/package/uqrcodejs](https://www.npmjs.com/package/uqrcodejs)。
uni-app插件市场地址[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)。
## 原生方式
原生方式仅需要获取`uqrcode.js`文件便可使用。详细配置请移步到:文档 > [原生](https://uqrcode.cn/doc/document/native.html)。
### 安装
1. 通过`npm`安装,成功后即可使用`import``require`进行引用。
``` bash
# npm安装
npm install uqrcodejs
# 或者
npm install @uqrcode/js
```
2. 通过项目开源地址获取`uqrcode.js`,下载`uqrcode.js`后,将其复制到您项目指定目录,在页面中引入`uqrcode.js`文件即可开始使用。
### 引入
- 通过`import`引入。
``` javascript
// npm安装
import UQRCode from 'uqrcodejs'; // npm install uqrcodejs
// 或者
import UQRCode from '@uqrcode/js'; // npm install @uqrcode/js
```
- `Node.js`通过`require`引入。
``` javascript
// npm安装
const UQRCode = require('uqrcodejs'); // npm install uqrcodejs
// 或者
const UQRCode = require('@uqrcode/js'); // npm install @uqrcode/js
```
- 原生浏览器环境在js脚本加载时添加到`window`。
``` html
<script type="text/javascript" src="uqrcode.js"></script>
<script>
var UQRCode = window.UQRCode;
</script>
```
### 简单用法
`uQRCode`基于`Canvas API`封装了一套方法,建议开发者使用`canvas`生成,一键调用,非常方便。以下是示例:
- HTML示例
- DOM部分
``` html
<canvas id="qrcode" width="200" height="200"></canvas>
```
- JS部分
``` javascript
// 获取uQRCode实例
var qr = new UQRCode();
// 设置二维码内容
qr.data = "https://uqrcode.cn/doc";
// 设置二维码大小必须与canvas设置的宽高一致
qr.size = 200;
// 调用制作二维码方法
qr.make();
// 获取canvas元素
var canvas = document.getElementById("qrcode");
// 获取canvas上下文
var canvasContext = canvas.getContext("2d");
// 设置uQRCode实例的canvas上下文
qr.canvasContext = canvasContext;
// 调用绘制方法将二维码图案绘制到canvas上
qr.drawCanvas();
```
- uni-app示例
- Template部分
``` html
<canvas id="qrcode" canvas-id="qrcode" style="width: 200px;height: 200px;"></canvas>
```
- JS部分
``` javascript
onReady() {
// 获取uQRCode实例
var qr = new UQRCode();
// 设置二维码内容
qr.data = "https://uqrcode.cn/doc";
// 设置二维码大小必须与canvas设置的宽高一致
qr.size = 200;
// 调用制作二维码方法
qr.make();
// 获取canvas上下文
var canvasContext = uni.createCanvasContext('qrcode', this); // 如果是组件this必须传入
// 设置uQRCode实例的canvas上下文
qr.canvasContext = canvasContext;
// 调用绘制方法将二维码图案绘制到canvas上
qr.drawCanvas();
}
```
- 微信小程序推荐使用Canvas 2D关于Canvas 2D的使用请参考微信开放文档。
### 高级用法
考虑到部分平台可能不支持`canvas`,所以`uQRCode`并没有强制要求和`canvas`一起使用,您还可以选择其他方式来生成二维码,例如使用`js`操作`dom`进行绘制或是使用`svg`绘制等。以下是示例:
- uni-app v-for+view
```html
<template>
<view>
<view class="qrcode">
<view v-for="(row, rowI) in modules" :key="rowI" style="display: flex;flex-direction: row;">
<view v-for="(col, colI) in row" :key="colI">
<view v-if="col.isBlack" style="width: 10px;height: 10px;background-color: black;">
<!-- 黑色码点 -->
</view>
<view v-else style="width: 10px;height: 10px;background-color: white;">
<!-- 白色码点 -->
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import UQRCode from '../../uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js';
export default {
data() {
return {
modules: []
}
},
onLoad() {
const qr = new UQRCode();
qr.data = 'uQRCode';
qr.make();
this.modules = qr.modules;
},
methods: {
}
}
</script>
```
- js操作dom
``` html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>uQRCode二维码生成</title>
</head>
<body>
<div id="qrcode" style="position: relative;"></div>
<script type="text/javascript" src="uqrcode.js"></script>
<script>
// 引入uQRCode
var UQRCode = window.UQRCode;
// 获取uQRCode实例
var qr = new UQRCode();
// 设置二维码内容
qr.data = "https://uqrcode.cn/doc";
// 设置二维码大小必须与canvas设置的宽高一致
qr.size = 200;
// 设置二维码前景图,可以是路径
qr.foregroundImageSrc =
'data:image/png;base64,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';
// 调用制作二维码方法
qr.make();
var drawModules = qr.getDrawModules();
// 遍历drawModules创建dom元素
var qrHtml = '';
for (var i = 0; i < drawModules.length; i++) {
var drawModule = drawModules[i];
switch (drawModule.type) {
case 'tile':
/* 绘制小块 */
qrHtml += `<div style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;background: ${drawModule.color};"></div>`;
break;
case 'image':
/* 绘制图像 */
qrHtml += `<img style="position: absolute;left: ${drawModule.x}px;top: ${drawModule.y}px;width: ${drawModule.width}px;height: ${drawModule.height}px;" src="${drawModule.imageSrc}" />`;
break;
}
}
document.getElementById('qrcode').innerHTML = qrHtml;
</script>
</body>
</html>
```
- svg
``` html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>uQRCode二维码生成</title>
</head>
<body>
<svg id="qrcode" width="200" height="200" xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>
<script type="text/javascript" src="uqrcode.js"></script>
<script>
// 引入uQRCode
var UQRCode = window.UQRCode;
// 获取uQRCode实例
var qr = new UQRCode();
// 设置二维码内容
qr.data = "https://uqrcode.cn/doc";
// 设置二维码大小必须与canvas设置的宽高一致
qr.size = 200;
// 设置二维码前景图,可以是路径
qr.foregroundImageSrc =
'data:image/png;base64,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';
// 调用制作二维码方法
qr.make();
var drawModules = qr.getDrawModules();
// 遍历drawModules创建svg元素
var qrHtml = '';
for (var i = 0; i < drawModules.length; i++) {
var drawModule = drawModules[i];
switch (drawModule.type) {
case 'tile':
/* 绘制小块 */
qrHtml += `<rect x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" style="fill: ${drawModule.color};" />`;
break;
case 'image':
/* 绘制图像 */
qrHtml += `<image href="${drawModule.imageSrc}" x="${drawModule.x}" y="${drawModule.y}" width="${drawModule.width}" height="${drawModule.height}" />`;
break;
}
}
document.getElementById('qrcode').innerHTML = qrHtml;
</script>
</body>
</html>
```
> 更多用法大家自行探索咯,期待分享哟~
### 导出临时文件路径
原生方式基于`Canvas`的,请自行参阅各平台`Canvas`的导出方式。以下是部分示例:
- uni-app
```javascript
// 通过uni.createCanvasContext方式创建绘制上下文的对应导出API为uni.canvasToTempFilePath
// 调用完ctx.draw()方法后不能第一时间导出,否则会异常,需要有一定的延时
setTimeout(() => {
uni.canvasToTempFilePath(
{
canvasId: this.canvasId,
fileType: this.fileType,
width: this.canvasWidth,
height: this.canvasHeight,
success: res => {
console.log(res);
},
fail: err => {
console.log(err);
}
},
// this // 组件内使用必传当前实例
);
}, 300);
```
- Canvas2D
```javascript
// 得到base64
console.log(canvas.toDataURL());
// 得到buffer
console.log(canvas.toBuffer());
```
### 保存二维码到本地相册
必须在导出临时文件路径成功后再执行保存。uni-app通用保存方式H5除外
```javascript
uni.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: res => {
console.log(res);
},
fail: err => {
console.log(err);
}
});
```
H5可以通过设置`<a>`标签`href`属性的方式进行保存:
```javascript
const aEle = document.createElement('a');
aEle.download = 'uQRCode'; // 设置下载的文件名,默认是'下载'
aEle.href = tempFilePath;
document.body.appendChild(aEle);
aEle.click();
aEle.remove(); // 下载之后把创建的元素删除
```
经过测试PC端浏览器可以下载部分安卓自带或第三方浏览器可以下载安卓微信浏览器不适用移动端iOS所有浏览器均不适用差异较大还是推荐各位导出文件给图片组件显示然后提示用户通过长按图片进行保存这种方式。
## uni-app组件方式
### 安装
通过uni-app插件市场地址安装[https://ext.dcloud.net.cn/plugin?id=1287](https://ext.dcloud.net.cn/plugin?id=1287)。详细配置请移步到:文档 > [uni-app组件](https://uqrcode.cn/doc/document/uni-app.html)。
### 引入
uni-app默认为easycom模式可直接键入`<uqrcode>`标签。
### 简单用法
安装`uqrcode`组件后,在`template`中键入`<uqrcode/>`。设置`ref`属性可使用组件内部方法,`canvas-id`属性为组件内部的canvas组件标识`value`属性为二维码生成对应内容,`options`为配置选项可配置二维码样式绘制Logo等详见[options](https://uqrcode.cn/doc/document/uni-app.html#options) 。
``` html
<uqrcode ref="uqrcode" canvas-id="qrcode" value="https://uqrcode.cn/doc" :options="{ margin: 10 }"></uqrcode>
```
### 导出临时文件路径
为了保证方法调用成功,请在 [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 事件返回`success=true`后调用。
```javascript
// uqrcode为组件的ref名称
this.$refs.uqrcode.toTempFilePath({
success: res => {
console.log(res);
}
});
```
### 保存二维码到本地相册
为了保证方法调用成功,请在 [complete](https://uqrcode.cn/doc/document/uni-app.html#complete) 事件返回`success=true`后调用。
```javascript
// uqrcode为组件的ref名称
this.$refs.uqrcode.save({
success: () => {
uni.showToast({
icon: 'success',
title: '保存成功'
});
}
});
```
## 更多使用说明请前往官方文档查看:[https://uqrcode.cn/doc](https://uqrcode.cn/doc)。

View File

@@ -0,0 +1,12 @@
## 4.0.62022-12-12
修复`getDrawModules`,第一次获取结果正常,后续获取`tile`模块不存在的问题;
修复安卓type:normal因Canvas API使用了小数或为0的参数导致生成异常的问题安卓非2d Canvas部分API参数不支持携带小数部分API参数必须大于0
## 4.0.12022-11-28
优化组件loading属性的表现
新增组件type选项normal以便于在某些条件编译初始为type=2d时还可以选择使用非2d组件类型
修复组件条件编译在其他编辑器语法提示报错;
修复原生对es5的支持。
## 4.0.02022-11-21
v4版本源代码全面开放开源地址[https://github.com/Sansnn/uQRCode](https://github.com/Sansnn/uQRCode)
升级说明v4为大版本更新虽然已尽可能兼容上一代版本但不可避免的还是存在一些细节差异若更新后出现问题请参考对照[v3 文档](https://uqrcode.cn/doc/v3)[v4 文档](https://uqrcode.cn/doc)进行修改。

View File

@@ -0,0 +1 @@
export const cacheImageList = [];

View File

@@ -0,0 +1,41 @@
function Queue() {
let waitingQueue = this.waitingQueue = [];
let isRunning = this.isRunning = false; // 记录是否有未完成的任务
function execute(task, resolve, reject) {
task()
.then((data) => {
resolve(data);
})
.catch((e) => {
reject(e);
})
.finally(() => {
// 等待任务队列中如果有任务则触发它否则设置isRunning = false,表示无任务状态
if (waitingQueue.length) {
const next = waitingQueue.shift();
execute(next.task, next.resolve, next.reject);
} else {
isRunning = false;
}
});
}
this.exec = function(task) {
return new Promise((resolve, reject) => {
if (isRunning) {
waitingQueue.push({
task,
resolve,
reject
});
} else {
isRunning = true;
execute(task, resolve, reject);
}
});
}
}
/* 队列实例某些平台一起使用多个组件时需要通过队列逐一绘制否则部分绘制方法异常nvue端的iOS gcanvas尤其明显在不通过队列绘制时会出现图片丢失的情况 */
export const queueDraw = new Queue();
export const queueLoadImage = new Queue();

View File

@@ -0,0 +1,3 @@
declare module '*/common/cache' {
export const cacheImageList: Array;
}

View File

@@ -0,0 +1,4 @@
declare module '*/common/queue' {
export const queueDraw: any;
export const queueLoadImage: any;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,241 @@
const isWeex = typeof WXEnvironment !== 'undefined';
const isWeexIOS = isWeex && /ios/i.test(WXEnvironment.platform);
const isWeexAndroid = isWeex && !isWeexIOS;
import GLmethod from '../context-webgl/GLmethod';
const GCanvasModule =
(typeof weex !== 'undefined' && weex.requireModule) ? (weex.requireModule('gcanvas')) :
(typeof __weex_require__ !== 'undefined') ? (__weex_require__('@weex-module/gcanvas')) : {};
let isDebugging = false;
let isComboDisabled = false;
const logCommand = (function () {
const methodQuery = [];
Object.keys(GLmethod).forEach(key => {
methodQuery[GLmethod[key]] = key;
})
const queryMethod = (id) => {
return methodQuery[parseInt(id)] || 'NotFoundMethod';
}
const logCommand = (id, cmds) => {
const mId = cmds.split(',')[0];
const mName = queryMethod(mId);
console.log(`=== callNative - componentId:${id}; method: ${mName}; cmds: ${cmds}`);
}
return logCommand;
})();
function joinArray(arr, sep) {
let res = '';
for (let i = 0; i < arr.length; i++) {
if (i !== 0) {
res += sep;
}
res += arr[i];
}
return res;
}
const commandsCache = {}
const GBridge = {
callEnable: (ref, configArray) => {
commandsCache[ref] = [];
return GCanvasModule.enable({
componentId: ref,
config: configArray
});
},
callEnableDebug: () => {
isDebugging = true;
},
callEnableDisableCombo: () => {
isComboDisabled = true;
},
callSetContextType: function (componentId, context_type) {
GCanvasModule.setContextType(context_type, componentId);
},
callReset: function(id){
GCanvasModule.resetComponent && canvasModule.resetComponent(componentId);
},
render: isWeexIOS ? function (componentId) {
return GCanvasModule.extendCallNative({
contextId: componentId,
type: 0x60000001
});
} : function (componentId) {
return callGCanvasLinkNative(componentId, 0x60000001, 'render');
},
render2d: isWeexIOS ? function (componentId, commands, callback) {
if (isDebugging) {
console.log('>>> >>> render2d ===');
console.log('>>> commands: ' + commands);
}
GCanvasModule.render([commands, callback?true:false], componentId, callback);
} : function (componentId, commands,callback) {
if (isDebugging) {
console.log('>>> >>> render2d ===');
console.log('>>> commands: ' + commands);
}
callGCanvasLinkNative(componentId, 0x20000001, commands);
if(callback){
callback();
}
},
callExtendCallNative: isWeexIOS ? function (componentId, cmdArgs) {
throw 'should not be here anymore ' + cmdArgs;
} : function (componentId, cmdArgs) {
throw 'should not be here anymore ' + cmdArgs;
},
flushNative: isWeexIOS ? function (componentId) {
const cmdArgs = joinArray(commandsCache[componentId], ';');
commandsCache[componentId] = [];
if (isDebugging) {
console.log('>>> >>> flush native ===');
console.log('>>> commands: ' + cmdArgs);
}
const result = GCanvasModule.extendCallNative({
"contextId": componentId,
"type": 0x60000000,
"args": cmdArgs
});
const res = result && result.result;
if (isDebugging) {
console.log('>>> result: ' + res);
}
return res;
} : function (componentId) {
const cmdArgs = joinArray(commandsCache[componentId], ';');
commandsCache[componentId] = [];
if (isDebugging) {
console.log('>>> >>> flush native ===');
console.log('>>> commands: ' + cmdArgs);
}
const result = callGCanvasLinkNative(componentId, 0x60000000, cmdArgs);
if (isDebugging) {
console.log('>>> result: ' + result);
}
return result;
},
callNative: function (componentId, cmdArgs, cache) {
if (isDebugging) {
logCommand(componentId, cmdArgs);
}
commandsCache[componentId].push(cmdArgs);
if (!cache || isComboDisabled) {
return GBridge.flushNative(componentId);
} else {
return undefined;
}
},
texImage2D(componentId, ...args) {
if (isWeexIOS) {
if (args.length === 6) {
const [target, level, internalformat, format, type, image] = args;
GBridge.callNative(
componentId,
GLmethod.texImage2D + ',' + 6 + ',' + target + ',' + level + ',' + internalformat + ',' + format + ',' + type + ',' + image.src
)
} else if (args.length === 9) {
const [target, level, internalformat, width, height, border, format, type, image] = args;
GBridge.callNative(
componentId,
GLmethod.texImage2D + ',' + 9 + ',' + target + ',' + level + ',' + internalformat + ',' + width + ',' + height + ',' + border + ',' +
+ format + ',' + type + ',' + (image ? image.src : 0)
)
}
} else if (isWeexAndroid) {
if (args.length === 6) {
const [target, level, internalformat, format, type, image] = args;
GCanvasModule.texImage2D(componentId, target, level, internalformat, format, type, image.src);
} else if (args.length === 9) {
const [target, level, internalformat, width, height, border, format, type, image] = args;
GCanvasModule.texImage2D(componentId, target, level, internalformat, width, height, border, format, type, (image ? image.src : 0));
}
}
},
texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image) {
if (isWeexIOS) {
if (arguments.length === 8) {
GBridge.callNative(
componentId,
GLmethod.texSubImage2D + ',' + 6 + ',' + target + ',' + level + ',' + xoffset + ',' + yoffset, + ',' + format + ',' + type + ',' + image.src
)
}
} else if (isWeexAndroid) {
GCanvasModule.texSubImage2D(componentId, target, level, xoffset, yoffset, format, type, image.src);
}
},
bindImageTexture(componentId, src, imageId) {
GCanvasModule.bindImageTexture([src, imageId], componentId);
},
perloadImage([url, id], callback) {
GCanvasModule.preLoadImage([url, id], function (image) {
image.url = url;
image.id = id;
callback(image);
});
},
measureText(text, fontStyle, componentId) {
return GCanvasModule.measureText([text, fontStyle], componentId);
},
getImageData (componentId, x, y, w, h, callback) {
GCanvasModule.getImageData([x, y,w,h],componentId,callback);
},
putImageData (componentId, data, x, y, w, h, callback) {
GCanvasModule.putImageData([x, y,w,h,data],componentId,callback);
},
toTempFilePath(componentId, x, y, width, height, destWidth, destHeight, fileType, quality, callback){
GCanvasModule.toTempFilePath([x, y, width,height, destWidth, destHeight, fileType, quality], componentId, callback);
}
}
export default GBridge;

View File

@@ -0,0 +1,18 @@
class FillStyleLinearGradient {
constructor(x0, y0, x1, y1) {
this._start_pos = { _x: x0, _y: y0 };
this._end_pos = { _x: x1, _y: y1 };
this._stop_count = 0;
this._stops = [0, 0, 0, 0, 0];
}
addColorStop = function (pos, color) {
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
this._stops[this._stop_count] = { _pos: pos, _color: color };
this._stop_count++;
}
}
}
export default FillStyleLinearGradient;

View File

@@ -0,0 +1,8 @@
class FillStylePattern {
constructor(img, pattern) {
this._style = pattern;
this._img = img;
}
}
export default FillStylePattern;

View File

@@ -0,0 +1,17 @@
class FillStyleRadialGradient {
constructor(x0, y0, r0, x1, y1, r1) {
this._start_pos = { _x: x0, _y: y0, _r: r0 };
this._end_pos = { _x: x1, _y: y1, _r: r1 };
this._stop_count = 0;
this._stops = [0, 0, 0, 0, 0];
}
addColorStop(pos, color) {
if (this._stop_count < 5 && 0.0 <= pos && pos <= 1.0) {
this._stops[this._stop_count] = { _pos: pos, _color: color };
this._stop_count++;
}
}
}
export default FillStyleRadialGradient;

View File

@@ -0,0 +1,666 @@
import FillStylePattern from './FillStylePattern';
import FillStyleLinearGradient from './FillStyleLinearGradient';
import FillStyleRadialGradient from './FillStyleRadialGradient';
import GImage from '../env/image.js';
import {
ArrayBufferToBase64,
Base64ToUint8ClampedArray
} from '../env/tool.js';
export default class CanvasRenderingContext2D {
_drawCommands = '';
_globalAlpha = 1.0;
_fillStyle = 'rgb(0,0,0)';
_strokeStyle = 'rgb(0,0,0)';
_lineWidth = 1;
_lineCap = 'butt';
_lineJoin = 'miter';
_miterLimit = 10;
_globalCompositeOperation = 'source-over';
_textAlign = 'start';
_textBaseline = 'alphabetic';
_font = '10px sans-serif';
_savedGlobalAlpha = [];
timer = null;
componentId = null;
_notCommitDrawImageCache = [];
_needRedrawImageCache = [];
_redrawCommands = '';
_autoSaveContext = true;
// _imageMap = new GHashMap();
// _textureMap = new GHashMap();
constructor() {
this.className = 'CanvasRenderingContext2D';
//this.save()
}
setFillStyle(value) {
this.fillStyle = value;
}
set fillStyle(value) {
this._fillStyle = value;
if (typeof(value) == 'string') {
this._drawCommands = this._drawCommands.concat("F" + value + ";");
} else if (value instanceof FillStylePattern) {
const image = value._img;
if (!image.complete) {
image.onload = () => {
var index = this._needRedrawImageCache.indexOf(image);
if (index > -1) {
this._needRedrawImageCache.splice(index, 1);
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
this._redrawflush(true);
}
}
this._notCommitDrawImageCache.push(image);
} else {
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
}
//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
} else if (value instanceof FillStyleLinearGradient) {
var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
value._stop_count;
for (var i = 0; i < value._stop_count; ++i) {
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
}
this._drawCommands = this._drawCommands.concat(command + ";");
} else if (value instanceof FillStyleRadialGradient) {
var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
.toFixed(2) + "," +
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," + value._end_pos._r.toFixed(2) + "," +
value._stop_count;
for (var i = 0; i < value._stop_count; ++i) {
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
}
this._drawCommands = this._drawCommands.concat(command + ";");
}
}
get fillStyle() {
return this._fillStyle;
}
get globalAlpha() {
return this._globalAlpha;
}
setGlobalAlpha(value) {
this.globalAlpha = value;
}
set globalAlpha(value) {
this._globalAlpha = value;
this._drawCommands = this._drawCommands.concat("a" + value.toFixed(2) + ";");
}
get strokeStyle() {
return this._strokeStyle;
}
setStrokeStyle(value) {
this.strokeStyle = value;
}
set strokeStyle(value) {
this._strokeStyle = value;
if (typeof(value) == 'string') {
this._drawCommands = this._drawCommands.concat("S" + value + ";");
} else if (value instanceof FillStylePattern) {
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
this._drawCommands = this._drawCommands.concat("G" + image._id + "," + value._style + ";");
} else if (value instanceof FillStyleLinearGradient) {
var command = "D" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," +
value._end_pos._x.toFixed(2) + "," + value._end_pos._y.toFixed(2) + "," +
value._stop_count;
for (var i = 0; i < value._stop_count; ++i) {
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
}
this._drawCommands = this._drawCommands.concat(command + ";");
} else if (value instanceof FillStyleRadialGradient) {
var command = "H" + value._start_pos._x.toFixed(2) + "," + value._start_pos._y.toFixed(2) + "," + value._start_pos._r
.toFixed(2) + "," +
value._end_pos._x.toFixed(2) + "," + value._end_pos._y + ",".toFixed(2) + value._end_pos._r.toFixed(2) + "," +
value._stop_count;
for (var i = 0; i < value._stop_count; ++i) {
command += ("," + value._stops[i]._pos + "," + value._stops[i]._color);
}
this._drawCommands = this._drawCommands.concat(command + ";");
}
}
get lineWidth() {
return this._lineWidth;
}
setLineWidth(value) {
this.lineWidth = value;
}
set lineWidth(value) {
this._lineWidth = value;
this._drawCommands = this._drawCommands.concat("W" + value + ";");
}
get lineCap() {
return this._lineCap;
}
setLineCap(value) {
this.lineCap = value;
}
set lineCap(value) {
this._lineCap = value;
this._drawCommands = this._drawCommands.concat("C" + value + ";");
}
get lineJoin() {
return this._lineJoin;
}
setLineJoin(value) {
this.lineJoin = value
}
set lineJoin(value) {
this._lineJoin = value;
this._drawCommands = this._drawCommands.concat("J" + value + ";");
}
get miterLimit() {
return this._miterLimit;
}
setMiterLimit(value) {
this.miterLimit = value
}
set miterLimit(value) {
this._miterLimit = value;
this._drawCommands = this._drawCommands.concat("M" + value + ";");
}
get globalCompositeOperation() {
return this._globalCompositeOperation;
}
set globalCompositeOperation(value) {
this._globalCompositeOperation = value;
let mode = 0;
switch (value) {
case "source-over":
mode = 0;
break;
case "source-atop":
mode = 5;
break;
case "source-in":
mode = 0;
break;
case "source-out":
mode = 2;
break;
case "destination-over":
mode = 4;
break;
case "destination-atop":
mode = 4;
break;
case "destination-in":
mode = 4;
break;
case "destination-out":
mode = 3;
break;
case "lighter":
mode = 1;
break;
case "copy":
mode = 2;
break;
case "xor":
mode = 6;
break;
default:
mode = 0;
}
this._drawCommands = this._drawCommands.concat("B" + mode + ";");
}
get textAlign() {
return this._textAlign;
}
setTextAlign(value) {
this.textAlign = value
}
set textAlign(value) {
this._textAlign = value;
let Align = 0;
switch (value) {
case "start":
Align = 0;
break;
case "end":
Align = 1;
break;
case "left":
Align = 2;
break;
case "center":
Align = 3;
break;
case "right":
Align = 4;
break;
default:
Align = 0;
}
this._drawCommands = this._drawCommands.concat("A" + Align + ";");
}
get textBaseline() {
return this._textBaseline;
}
setTextBaseline(value) {
this.textBaseline = value
}
set textBaseline(value) {
this._textBaseline = value;
let baseline = 0;
switch (value) {
case "alphabetic":
baseline = 0;
break;
case "middle":
baseline = 1;
break;
case "top":
baseline = 2;
break;
case "hanging":
baseline = 3;
break;
case "bottom":
baseline = 4;
break;
case "ideographic":
baseline = 5;
break;
default:
baseline = 0;
break;
}
this._drawCommands = this._drawCommands.concat("E" + baseline + ";");
}
get font() {
return this._font;
}
setFontSize(size) {
var str = this._font;
var strs = str.trim().split(/\s+/);
for (var i = 0; i < strs.length; i++) {
var values = ["normal", "italic", "oblique", "normal", "small-caps", "normal", "bold",
"bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900",
"normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
];
if (-1 == values.indexOf(strs[i].trim())) {
if (typeof size === 'string') {
strs[i] = size;
} else if (typeof size === 'number') {
strs[i] = String(size) + 'px';
}
break;
}
}
this.font = strs.join(" ");
}
set font(value) {
this._font = value;
this._drawCommands = this._drawCommands.concat("j" + value + ";");
}
setTransform(a, b, c, d, tx, ty) {
this._drawCommands = this._drawCommands.concat("t" +
(a === 1 ? "1" : a.toFixed(2)) + "," +
(b === 0 ? "0" : b.toFixed(2)) + "," +
(c === 0 ? "0" : c.toFixed(2)) + "," +
(d === 1 ? "1" : d.toFixed(2)) + "," + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
}
transform(a, b, c, d, tx, ty) {
this._drawCommands = this._drawCommands.concat("f" +
(a === 1 ? "1" : a.toFixed(2)) + "," +
(b === 0 ? "0" : b.toFixed(2)) + "," +
(c === 0 ? "0" : c.toFixed(2)) + "," +
(d === 1 ? "1" : d.toFixed(2)) + "," + tx + "," + ty + ";");
}
resetTransform() {
this._drawCommands = this._drawCommands.concat("m;");
}
scale(a, d) {
this._drawCommands = this._drawCommands.concat("k" + a.toFixed(2) + "," +
d.toFixed(2) + ";");
}
rotate(angle) {
this._drawCommands = this._drawCommands
.concat("r" + angle.toFixed(6) + ";");
}
translate(tx, ty) {
this._drawCommands = this._drawCommands.concat("l" + tx.toFixed(2) + "," + ty.toFixed(2) + ";");
}
save() {
this._savedGlobalAlpha.push(this._globalAlpha);
this._drawCommands = this._drawCommands.concat("v;");
}
restore() {
this._drawCommands = this._drawCommands.concat("e;");
this._globalAlpha = this._savedGlobalAlpha.pop();
}
createPattern(img, pattern) {
if (typeof img === 'string') {
var imgObj = new GImage();
imgObj.src = img;
img = imgObj;
}
return new FillStylePattern(img, pattern);
}
createLinearGradient(x0, y0, x1, y1) {
return new FillStyleLinearGradient(x0, y0, x1, y1);
}
createRadialGradient = function(x0, y0, r0, x1, y1, r1) {
return new FillStyleRadialGradient(x0, y0, r0, x1, y1, r1);
};
createCircularGradient = function(x0, y0, r0) {
return new FillStyleRadialGradient(x0, y0, 0, x0, y0, r0);
};
strokeRect(x, y, w, h) {
this._drawCommands = this._drawCommands.concat("s" + x + "," + y + "," + w + "," + h + ";");
}
clearRect(x, y, w, h) {
this._drawCommands = this._drawCommands.concat("c" + x + "," + y + "," + w +
"," + h + ";");
}
clip() {
this._drawCommands = this._drawCommands.concat("p;");
}
resetClip() {
this._drawCommands = this._drawCommands.concat("q;");
}
closePath() {
this._drawCommands = this._drawCommands.concat("o;");
}
moveTo(x, y) {
this._drawCommands = this._drawCommands.concat("g" + x.toFixed(2) + "," + y.toFixed(2) + ";");
}
lineTo(x, y) {
this._drawCommands = this._drawCommands.concat("i" + x.toFixed(2) + "," + y.toFixed(2) + ";");
}
quadraticCurveTo = function(cpx, cpy, x, y) {
this._drawCommands = this._drawCommands.concat("u" + cpx + "," + cpy + "," + x + "," + y + ";");
}
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y, ) {
this._drawCommands = this._drawCommands.concat(
"z" + cp1x.toFixed(2) + "," + cp1y.toFixed(2) + "," + cp2x.toFixed(2) + "," + cp2y.toFixed(2) + "," +
x.toFixed(2) + "," + y.toFixed(2) + ";");
}
arcTo(x1, y1, x2, y2, radius) {
this._drawCommands = this._drawCommands.concat("h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";");
}
beginPath() {
this._drawCommands = this._drawCommands.concat("b;");
}
fillRect(x, y, w, h) {
this._drawCommands = this._drawCommands.concat("n" + x + "," + y + "," + w +
"," + h + ";");
}
rect(x, y, w, h) {
this._drawCommands = this._drawCommands.concat("w" + x + "," + y + "," + w + "," + h + ";");
}
fill() {
this._drawCommands = this._drawCommands.concat("L;");
}
stroke(path) {
this._drawCommands = this._drawCommands.concat("x;");
}
arc(x, y, radius, startAngle, endAngle, anticlockwise) {
let ianticlockwise = 0;
if (anticlockwise) {
ianticlockwise = 1;
}
this._drawCommands = this._drawCommands.concat(
"y" + x.toFixed(2) + "," + y.toFixed(2) + "," +
radius.toFixed(2) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
";"
);
}
fillText(text, x, y) {
let tmptext = text.replace(/!/g, "!!");
tmptext = tmptext.replace(/,/g, "!,");
tmptext = tmptext.replace(/;/g, "!;");
this._drawCommands = this._drawCommands.concat("T" + tmptext + "," + x + "," + y + ",0.0;");
}
strokeText = function(text, x, y) {
let tmptext = text.replace(/!/g, "!!");
tmptext = tmptext.replace(/,/g, "!,");
tmptext = tmptext.replace(/;/g, "!;");
this._drawCommands = this._drawCommands.concat("U" + tmptext + "," + x + "," + y + ",0.0;");
}
measureText(text) {
return CanvasRenderingContext2D.GBridge.measureText(text, this.font, this.componentId);
}
isPointInPath = function(x, y) {
throw new Error('GCanvas not supported yet');
}
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (typeof image === 'string') {
var imgObj = new GImage();
imgObj.src = image;
image = imgObj;
}
if (image instanceof GImage) {
if (!image.complete) {
imgObj.onload = () => {
var index = this._needRedrawImageCache.indexOf(image);
if (index > -1) {
this._needRedrawImageCache.splice(index, 1);
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
this._redrawflush(true);
}
}
this._notCommitDrawImageCache.push(image);
} else {
CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
}
var srcArgs = [image, sx, sy, sw, sh, dx, dy, dw, dh];
var args = [];
for (var arg in srcArgs) {
if (typeof(srcArgs[arg]) != 'undefined') {
args.push(srcArgs[arg]);
}
}
this.__drawImage.apply(this, args);
//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
}
}
__drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
const numArgs = arguments.length;
function drawImageCommands() {
if (numArgs === 3) {
const x = parseFloat(sx) || 0.0;
const y = parseFloat(sy) || 0.0;
return ("d" + image._id + ",0,0," +
image.width + "," + image.height + "," +
x + "," + y + "," + image.width + "," + image.height + ";");
} else if (numArgs === 5) {
const x = parseFloat(sx) || 0.0;
const y = parseFloat(sy) || 0.0;
const width = parseInt(sw) || image.width;
const height = parseInt(sh) || image.height;
return ("d" + image._id + ",0,0," +
image.width + "," + image.height + "," +
x + "," + y + "," + width + "," + height + ";");
} else if (numArgs === 9) {
sx = parseFloat(sx) || 0.0;
sy = parseFloat(sy) || 0.0;
sw = parseInt(sw) || image.width;
sh = parseInt(sh) || image.height;
dx = parseFloat(dx) || 0.0;
dy = parseFloat(dy) || 0.0;
dw = parseInt(dw) || image.width;
dh = parseInt(dh) || image.height;
return ("d" + image._id + "," +
sx + "," + sy + "," + sw + "," + sh + "," +
dx + "," + dy + "," + dw + "," + dh + ";");
}
}
this._drawCommands += drawImageCommands();
}
_flush(reserve, callback) {
const commands = this._drawCommands;
this._drawCommands = '';
CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
this._needRender = false;
}
_redrawflush(reserve, callback) {
const commands = this._redrawCommands;
CanvasRenderingContext2D.GBridge.render2d(this.componentId, commands, callback);
if (this._needRedrawImageCache.length == 0) {
this._redrawCommands = '';
}
}
draw(reserve, callback) {
if (!reserve) {
this._globalAlpha = this._savedGlobalAlpha.pop();
this._savedGlobalAlpha.push(this._globalAlpha);
this._redrawCommands = this._drawCommands;
this._needRedrawImageCache = this._notCommitDrawImageCache;
if (this._autoSaveContext) {
this._drawCommands = ("v;" + this._drawCommands);
this._autoSaveContext = false;
} else {
this._drawCommands = ("e;X;v;" + this._drawCommands);
}
} else {
this._needRedrawImageCache = this._needRedrawImageCache.concat(this._notCommitDrawImageCache);
this._redrawCommands += this._drawCommands;
if (this._autoSaveContext) {
this._drawCommands = ("v;" + this._drawCommands);
this._autoSaveContext = false;
}
}
this._notCommitDrawImageCache = [];
if (this._flush) {
this._flush(reserve, callback);
}
}
getImageData(x, y, w, h, callback) {
CanvasRenderingContext2D.GBridge.getImageData(this.componentId, x, y, w, h, function(res) {
res.data = Base64ToUint8ClampedArray(res.data);
if (typeof(callback) == 'function') {
callback(res);
}
});
}
putImageData(data, x, y, w, h, callback) {
if (data instanceof Uint8ClampedArray) {
data = ArrayBufferToBase64(data);
CanvasRenderingContext2D.GBridge.putImageData(this.componentId, data, x, y, w, h, function(res) {
if (typeof(callback) == 'function') {
callback(res);
}
});
}
}
toTempFilePath(x, y, width, height, destWidth, destHeight, fileType, quality, callback) {
CanvasRenderingContext2D.GBridge.toTempFilePath(this.componentId, x, y, width, height, destWidth, destHeight,
fileType, quality,
function(res) {
if (typeof(callback) == 'function') {
callback(res);
}
});
}
}

View File

@@ -0,0 +1,11 @@
export default class WebGLActiveInfo {
className = 'WebGLActiveInfo';
constructor({
type, name, size
}) {
this.type = type;
this.name = name;
this.size = size;
}
}

View File

@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLBuffer';
function uuid(id) {
return getTransferedObjectUUID(name, id);
}
export default class WebGLBuffer {
className = name;
constructor(id) {
this.id = id;
}
static uuid = uuid;
uuid() {
return uuid(this.id);
}
}

View File

@@ -0,0 +1,21 @@
import {getTransferedObjectUUID} from './classUtils';
const name = 'WebGLFrameBuffer';
function uuid(id) {
return getTransferedObjectUUID(name, id);
}
export default class WebGLFramebuffer {
className = name;
constructor(id) {
this.id = id;
}
static uuid = uuid;
uuid() {
return uuid(this.id);
}
}

View File

@@ -0,0 +1,298 @@
export default {
"DEPTH_BUFFER_BIT": 256,
"STENCIL_BUFFER_BIT": 1024,
"COLOR_BUFFER_BIT": 16384,
"POINTS": 0,
"LINES": 1,
"LINE_LOOP": 2,
"LINE_STRIP": 3,
"TRIANGLES": 4,
"TRIANGLE_STRIP": 5,
"TRIANGLE_FAN": 6,
"ZERO": 0,
"ONE": 1,
"SRC_COLOR": 768,
"ONE_MINUS_SRC_COLOR": 769,
"SRC_ALPHA": 770,
"ONE_MINUS_SRC_ALPHA": 771,
"DST_ALPHA": 772,
"ONE_MINUS_DST_ALPHA": 773,
"DST_COLOR": 774,
"ONE_MINUS_DST_COLOR": 775,
"SRC_ALPHA_SATURATE": 776,
"FUNC_ADD": 32774,
"BLEND_EQUATION": 32777,
"BLEND_EQUATION_RGB": 32777,
"BLEND_EQUATION_ALPHA": 34877,
"FUNC_SUBTRACT": 32778,
"FUNC_REVERSE_SUBTRACT": 32779,
"BLEND_DST_RGB": 32968,
"BLEND_SRC_RGB": 32969,
"BLEND_DST_ALPHA": 32970,
"BLEND_SRC_ALPHA": 32971,
"CONSTANT_COLOR": 32769,
"ONE_MINUS_CONSTANT_COLOR": 32770,
"CONSTANT_ALPHA": 32771,
"ONE_MINUS_CONSTANT_ALPHA": 32772,
"BLEND_COLOR": 32773,
"ARRAY_BUFFER": 34962,
"ELEMENT_ARRAY_BUFFER": 34963,
"ARRAY_BUFFER_BINDING": 34964,
"ELEMENT_ARRAY_BUFFER_BINDING": 34965,
"STREAM_DRAW": 35040,
"STATIC_DRAW": 35044,
"DYNAMIC_DRAW": 35048,
"BUFFER_SIZE": 34660,
"BUFFER_USAGE": 34661,
"CURRENT_VERTEX_ATTRIB": 34342,
"FRONT": 1028,
"BACK": 1029,
"FRONT_AND_BACK": 1032,
"TEXTURE_2D": 3553,
"CULL_FACE": 2884,
"BLEND": 3042,
"DITHER": 3024,
"STENCIL_TEST": 2960,
"DEPTH_TEST": 2929,
"SCISSOR_TEST": 3089,
"POLYGON_OFFSET_FILL": 32823,
"SAMPLE_ALPHA_TO_COVERAGE": 32926,
"SAMPLE_COVERAGE": 32928,
"NO_ERROR": 0,
"INVALID_ENUM": 1280,
"INVALID_VALUE": 1281,
"INVALID_OPERATION": 1282,
"OUT_OF_MEMORY": 1285,
"CW": 2304,
"CCW": 2305,
"LINE_WIDTH": 2849,
"ALIASED_POINT_SIZE_RANGE": 33901,
"ALIASED_LINE_WIDTH_RANGE": 33902,
"CULL_FACE_MODE": 2885,
"FRONT_FACE": 2886,
"DEPTH_RANGE": 2928,
"DEPTH_WRITEMASK": 2930,
"DEPTH_CLEAR_VALUE": 2931,
"DEPTH_FUNC": 2932,
"STENCIL_CLEAR_VALUE": 2961,
"STENCIL_FUNC": 2962,
"STENCIL_FAIL": 2964,
"STENCIL_PASS_DEPTH_FAIL": 2965,
"STENCIL_PASS_DEPTH_PASS": 2966,
"STENCIL_REF": 2967,
"STENCIL_VALUE_MASK": 2963,
"STENCIL_WRITEMASK": 2968,
"STENCIL_BACK_FUNC": 34816,
"STENCIL_BACK_FAIL": 34817,
"STENCIL_BACK_PASS_DEPTH_FAIL": 34818,
"STENCIL_BACK_PASS_DEPTH_PASS": 34819,
"STENCIL_BACK_REF": 36003,
"STENCIL_BACK_VALUE_MASK": 36004,
"STENCIL_BACK_WRITEMASK": 36005,
"VIEWPORT": 2978,
"SCISSOR_BOX": 3088,
"COLOR_CLEAR_VALUE": 3106,
"COLOR_WRITEMASK": 3107,
"UNPACK_ALIGNMENT": 3317,
"PACK_ALIGNMENT": 3333,
"MAX_TEXTURE_SIZE": 3379,
"MAX_VIEWPORT_DIMS": 3386,
"SUBPIXEL_BITS": 3408,
"RED_BITS": 3410,
"GREEN_BITS": 3411,
"BLUE_BITS": 3412,
"ALPHA_BITS": 3413,
"DEPTH_BITS": 3414,
"STENCIL_BITS": 3415,
"POLYGON_OFFSET_UNITS": 10752,
"POLYGON_OFFSET_FACTOR": 32824,
"TEXTURE_BINDING_2D": 32873,
"SAMPLE_BUFFERS": 32936,
"SAMPLES": 32937,
"SAMPLE_COVERAGE_VALUE": 32938,
"SAMPLE_COVERAGE_INVERT": 32939,
"COMPRESSED_TEXTURE_FORMATS": 34467,
"DONT_CARE": 4352,
"FASTEST": 4353,
"NICEST": 4354,
"GENERATE_MIPMAP_HINT": 33170,
"BYTE": 5120,
"UNSIGNED_BYTE": 5121,
"SHORT": 5122,
"UNSIGNED_SHORT": 5123,
"INT": 5124,
"UNSIGNED_INT": 5125,
"FLOAT": 5126,
"DEPTH_COMPONENT": 6402,
"ALPHA": 6406,
"RGB": 6407,
"RGBA": 6408,
"LUMINANCE": 6409,
"LUMINANCE_ALPHA": 6410,
"UNSIGNED_SHORT_4_4_4_4": 32819,
"UNSIGNED_SHORT_5_5_5_1": 32820,
"UNSIGNED_SHORT_5_6_5": 33635,
"FRAGMENT_SHADER": 35632,
"VERTEX_SHADER": 35633,
"MAX_VERTEX_ATTRIBS": 34921,
"MAX_VERTEX_UNIFORM_VECTORS": 36347,
"MAX_VARYING_VECTORS": 36348,
"MAX_COMBINED_TEXTURE_IMAGE_UNITS": 35661,
"MAX_VERTEX_TEXTURE_IMAGE_UNITS": 35660,
"MAX_TEXTURE_IMAGE_UNITS": 34930,
"MAX_FRAGMENT_UNIFORM_VECTORS": 36349,
"SHADER_TYPE": 35663,
"DELETE_STATUS": 35712,
"LINK_STATUS": 35714,
"VALIDATE_STATUS": 35715,
"ATTACHED_SHADERS": 35717,
"ACTIVE_UNIFORMS": 35718,
"ACTIVE_ATTRIBUTES": 35721,
"SHADING_LANGUAGE_VERSION": 35724,
"CURRENT_PROGRAM": 35725,
"NEVER": 512,
"LESS": 513,
"EQUAL": 514,
"LEQUAL": 515,
"GREATER": 516,
"NOTEQUAL": 517,
"GEQUAL": 518,
"ALWAYS": 519,
"KEEP": 7680,
"REPLACE": 7681,
"INCR": 7682,
"DECR": 7683,
"INVERT": 5386,
"INCR_WRAP": 34055,
"DECR_WRAP": 34056,
"VENDOR": 7936,
"RENDERER": 7937,
"VERSION": 7938,
"NEAREST": 9728,
"LINEAR": 9729,
"NEAREST_MIPMAP_NEAREST": 9984,
"LINEAR_MIPMAP_NEAREST": 9985,
"NEAREST_MIPMAP_LINEAR": 9986,
"LINEAR_MIPMAP_LINEAR": 9987,
"TEXTURE_MAG_FILTER": 10240,
"TEXTURE_MIN_FILTER": 10241,
"TEXTURE_WRAP_S": 10242,
"TEXTURE_WRAP_T": 10243,
"TEXTURE": 5890,
"TEXTURE_CUBE_MAP": 34067,
"TEXTURE_BINDING_CUBE_MAP": 34068,
"TEXTURE_CUBE_MAP_POSITIVE_X": 34069,
"TEXTURE_CUBE_MAP_NEGATIVE_X": 34070,
"TEXTURE_CUBE_MAP_POSITIVE_Y": 34071,
"TEXTURE_CUBE_MAP_NEGATIVE_Y": 34072,
"TEXTURE_CUBE_MAP_POSITIVE_Z": 34073,
"TEXTURE_CUBE_MAP_NEGATIVE_Z": 34074,
"MAX_CUBE_MAP_TEXTURE_SIZE": 34076,
"TEXTURE0": 33984,
"TEXTURE1": 33985,
"TEXTURE2": 33986,
"TEXTURE3": 33987,
"TEXTURE4": 33988,
"TEXTURE5": 33989,
"TEXTURE6": 33990,
"TEXTURE7": 33991,
"TEXTURE8": 33992,
"TEXTURE9": 33993,
"TEXTURE10": 33994,
"TEXTURE11": 33995,
"TEXTURE12": 33996,
"TEXTURE13": 33997,
"TEXTURE14": 33998,
"TEXTURE15": 33999,
"TEXTURE16": 34000,
"TEXTURE17": 34001,
"TEXTURE18": 34002,
"TEXTURE19": 34003,
"TEXTURE20": 34004,
"TEXTURE21": 34005,
"TEXTURE22": 34006,
"TEXTURE23": 34007,
"TEXTURE24": 34008,
"TEXTURE25": 34009,
"TEXTURE26": 34010,
"TEXTURE27": 34011,
"TEXTURE28": 34012,
"TEXTURE29": 34013,
"TEXTURE30": 34014,
"TEXTURE31": 34015,
"ACTIVE_TEXTURE": 34016,
"REPEAT": 10497,
"CLAMP_TO_EDGE": 33071,
"MIRRORED_REPEAT": 33648,
"FLOAT_VEC2": 35664,
"FLOAT_VEC3": 35665,
"FLOAT_VEC4": 35666,
"INT_VEC2": 35667,
"INT_VEC3": 35668,
"INT_VEC4": 35669,
"BOOL": 35670,
"BOOL_VEC2": 35671,
"BOOL_VEC3": 35672,
"BOOL_VEC4": 35673,
"FLOAT_MAT2": 35674,
"FLOAT_MAT3": 35675,
"FLOAT_MAT4": 35676,
"SAMPLER_2D": 35678,
"SAMPLER_CUBE": 35680,
"VERTEX_ATTRIB_ARRAY_ENABLED": 34338,
"VERTEX_ATTRIB_ARRAY_SIZE": 34339,
"VERTEX_ATTRIB_ARRAY_STRIDE": 34340,
"VERTEX_ATTRIB_ARRAY_TYPE": 34341,
"VERTEX_ATTRIB_ARRAY_NORMALIZED": 34922,
"VERTEX_ATTRIB_ARRAY_POINTER": 34373,
"VERTEX_ATTRIB_ARRAY_BUFFER_BINDING": 34975,
"IMPLEMENTATION_COLOR_READ_TYPE": 35738,
"IMPLEMENTATION_COLOR_READ_FORMAT": 35739,
"COMPILE_STATUS": 35713,
"LOW_FLOAT": 36336,
"MEDIUM_FLOAT": 36337,
"HIGH_FLOAT": 36338,
"LOW_INT": 36339,
"MEDIUM_INT": 36340,
"HIGH_INT": 36341,
"FRAMEBUFFER": 36160,
"RENDERBUFFER": 36161,
"RGBA4": 32854,
"RGB5_A1": 32855,
"RGB565": 36194,
"DEPTH_COMPONENT16": 33189,
"STENCIL_INDEX8": 36168,
"DEPTH_STENCIL": 34041,
"RENDERBUFFER_WIDTH": 36162,
"RENDERBUFFER_HEIGHT": 36163,
"RENDERBUFFER_INTERNAL_FORMAT": 36164,
"RENDERBUFFER_RED_SIZE": 36176,
"RENDERBUFFER_GREEN_SIZE": 36177,
"RENDERBUFFER_BLUE_SIZE": 36178,
"RENDERBUFFER_ALPHA_SIZE": 36179,
"RENDERBUFFER_DEPTH_SIZE": 36180,
"RENDERBUFFER_STENCIL_SIZE": 36181,
"FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE": 36048,
"FRAMEBUFFER_ATTACHMENT_OBJECT_NAME": 36049,
"FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL": 36050,
"FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE": 36051,
"COLOR_ATTACHMENT0": 36064,
"DEPTH_ATTACHMENT": 36096,
"STENCIL_ATTACHMENT": 36128,
"DEPTH_STENCIL_ATTACHMENT": 33306,
"NONE": 0,
"FRAMEBUFFER_COMPLETE": 36053,
"FRAMEBUFFER_INCOMPLETE_ATTACHMENT": 36054,
"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT": 36055,
"FRAMEBUFFER_INCOMPLETE_DIMENSIONS": 36057,
"FRAMEBUFFER_UNSUPPORTED": 36061,
"FRAMEBUFFER_BINDING": 36006,
"RENDERBUFFER_BINDING": 36007,
"MAX_RENDERBUFFER_SIZE": 34024,
"INVALID_FRAMEBUFFER_OPERATION": 1286,
"UNPACK_FLIP_Y_WEBGL": 37440,
"UNPACK_PREMULTIPLY_ALPHA_WEBGL": 37441,
"CONTEXT_LOST_WEBGL": 37442,
"UNPACK_COLORSPACE_CONVERSION_WEBGL": 37443,
"BROWSER_DEFAULT_WEBGL": 37444
};

View File

@@ -0,0 +1,142 @@
let i = 1;
const GLmethod = {};
GLmethod.activeTexture = i++; //1
GLmethod.attachShader = i++;
GLmethod.bindAttribLocation = i++;
GLmethod.bindBuffer = i++;
GLmethod.bindFramebuffer = i++;
GLmethod.bindRenderbuffer = i++;
GLmethod.bindTexture = i++;
GLmethod.blendColor = i++;
GLmethod.blendEquation = i++;
GLmethod.blendEquationSeparate = i++; //10
GLmethod.blendFunc = i++;
GLmethod.blendFuncSeparate = i++;
GLmethod.bufferData = i++;
GLmethod.bufferSubData = i++;
GLmethod.checkFramebufferStatus = i++;
GLmethod.clear = i++;
GLmethod.clearColor = i++;
GLmethod.clearDepth = i++;
GLmethod.clearStencil = i++;
GLmethod.colorMask = i++; //20
GLmethod.compileShader = i++;
GLmethod.compressedTexImage2D = i++;
GLmethod.compressedTexSubImage2D = i++;
GLmethod.copyTexImage2D = i++;
GLmethod.copyTexSubImage2D = i++;
GLmethod.createBuffer = i++;
GLmethod.createFramebuffer = i++;
GLmethod.createProgram = i++;
GLmethod.createRenderbuffer = i++;
GLmethod.createShader = i++; //30
GLmethod.createTexture = i++;
GLmethod.cullFace = i++;
GLmethod.deleteBuffer = i++;
GLmethod.deleteFramebuffer = i++;
GLmethod.deleteProgram = i++;
GLmethod.deleteRenderbuffer = i++;
GLmethod.deleteShader = i++;
GLmethod.deleteTexture = i++;
GLmethod.depthFunc = i++;
GLmethod.depthMask = i++; //40
GLmethod.depthRange = i++;
GLmethod.detachShader = i++;
GLmethod.disable = i++;
GLmethod.disableVertexAttribArray = i++;
GLmethod.drawArrays = i++;
GLmethod.drawArraysInstancedANGLE = i++;
GLmethod.drawElements = i++;
GLmethod.drawElementsInstancedANGLE = i++;
GLmethod.enable = i++;
GLmethod.enableVertexAttribArray = i++; //50
GLmethod.flush = i++;
GLmethod.framebufferRenderbuffer = i++;
GLmethod.framebufferTexture2D = i++;
GLmethod.frontFace = i++;
GLmethod.generateMipmap = i++;
GLmethod.getActiveAttrib = i++;
GLmethod.getActiveUniform = i++;
GLmethod.getAttachedShaders = i++;
GLmethod.getAttribLocation = i++;
GLmethod.getBufferParameter = i++; //60
GLmethod.getContextAttributes = i++;
GLmethod.getError = i++;
GLmethod.getExtension = i++;
GLmethod.getFramebufferAttachmentParameter = i++;
GLmethod.getParameter = i++;
GLmethod.getProgramInfoLog = i++;
GLmethod.getProgramParameter = i++;
GLmethod.getRenderbufferParameter = i++;
GLmethod.getShaderInfoLog = i++;
GLmethod.getShaderParameter = i++; //70
GLmethod.getShaderPrecisionFormat = i++;
GLmethod.getShaderSource = i++;
GLmethod.getSupportedExtensions = i++;
GLmethod.getTexParameter = i++;
GLmethod.getUniform = i++;
GLmethod.getUniformLocation = i++;
GLmethod.getVertexAttrib = i++;
GLmethod.getVertexAttribOffset = i++;
GLmethod.isBuffer = i++;
GLmethod.isContextLost = i++; //80
GLmethod.isEnabled = i++;
GLmethod.isFramebuffer = i++;
GLmethod.isProgram = i++;
GLmethod.isRenderbuffer = i++;
GLmethod.isShader = i++;
GLmethod.isTexture = i++;
GLmethod.lineWidth = i++;
GLmethod.linkProgram = i++;
GLmethod.pixelStorei = i++;
GLmethod.polygonOffset = i++; //90
GLmethod.readPixels = i++;
GLmethod.renderbufferStorage = i++;
GLmethod.sampleCoverage = i++;
GLmethod.scissor = i++;
GLmethod.shaderSource = i++;
GLmethod.stencilFunc = i++;
GLmethod.stencilFuncSeparate = i++;
GLmethod.stencilMask = i++;
GLmethod.stencilMaskSeparate = i++;
GLmethod.stencilOp = i++; //100
GLmethod.stencilOpSeparate = i++;
GLmethod.texImage2D = i++;
GLmethod.texParameterf = i++;
GLmethod.texParameteri = i++;
GLmethod.texSubImage2D = i++;
GLmethod.uniform1f = i++;
GLmethod.uniform1fv = i++;
GLmethod.uniform1i = i++;
GLmethod.uniform1iv = i++;
GLmethod.uniform2f = i++; //110
GLmethod.uniform2fv = i++;
GLmethod.uniform2i = i++;
GLmethod.uniform2iv = i++;
GLmethod.uniform3f = i++;
GLmethod.uniform3fv = i++;
GLmethod.uniform3i = i++;
GLmethod.uniform3iv = i++;
GLmethod.uniform4f = i++;
GLmethod.uniform4fv = i++;
GLmethod.uniform4i = i++; //120
GLmethod.uniform4iv = i++;
GLmethod.uniformMatrix2fv = i++;
GLmethod.uniformMatrix3fv = i++;
GLmethod.uniformMatrix4fv = i++;
GLmethod.useProgram = i++;
GLmethod.validateProgram = i++;
GLmethod.vertexAttrib1f = i++; //new
GLmethod.vertexAttrib2f = i++; //new
GLmethod.vertexAttrib3f = i++; //new
GLmethod.vertexAttrib4f = i++; //new //130
GLmethod.vertexAttrib1fv = i++; //new
GLmethod.vertexAttrib2fv = i++; //new
GLmethod.vertexAttrib3fv = i++; //new
GLmethod.vertexAttrib4fv = i++; //new
GLmethod.vertexAttribPointer = i++;
GLmethod.viewport = i++;
export default GLmethod;

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