提交 686b1830 编写于 作者: D devil_gong

qq小程序

上级 b5f70f9e
......@@ -319,6 +319,88 @@ class User extends Common
return DataReturn(empty($result) ? '获取用户信息失败' : $result, -100);
}
/**
* QQ小程序获取用户授权
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-10-31
* @desc description
*/
public function QQUserAuth()
{
// 参数
if(empty($this->data_post['authcode']))
{
return DataReturn('授权码为空', -1);
}
// 授权
$result = (new \base\QQ(MyC('common_app_mini_qq_appid', '1109990622'), MyC('common_app_mini_qq_appsecret', 'PdVsj1n2sByQQBCi
')))->GetAuthSessionKey($this->data_post['authcode']);
if($result !== false)
{
return DataReturn('授权登录成功', 0, $result);
}
return DataReturn('授权登录失败', -100);
}
/**
* QQ小程序获取用户信息
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-10-31
* @desc description
*/
public function QQUserInfo()
{
// 参数校验
$p = [
[
'checked_type' => 'empty',
'key_name' => 'openid',
'error_msg' => 'openid为空',
],
[
'checked_type' => 'empty',
'key_name' => 'encrypted_data',
'error_msg' => '解密数据为空',
],
[
'checked_type' => 'empty',
'key_name' => 'iv',
'error_msg' => 'iv为空,请重试',
]
];
$ret = ParamsChecked($this->data_post, $p);
if($ret !== true)
{
return DataReturn($ret, -1);
}
// 先从数据库获取用户信息
$user = UserService::AppUserInfoHandle(null, 'qq_openid', $this->data_post['openid']);
if(empty($user))
{
$result = (new \base\QQ(MyC('common_app_mini_qq_appid', '1109990622'), MyC('common_app_mini_qq_appsecret', 'PdVsj1n2sByQQBCi
')))->DecryptData($this->data_post['encrypted_data'], $this->data_post['iv'], $this->data_post['openid']);
if(is_array($result))
{
$result['nick_name'] = isset($result['nickName']) ? $result['nickName'] : '';
$result['avatar'] = isset($result['avatarUrl']) ? $result['avatarUrl'] : '';
$result['gender'] = empty($result['gender']) ? 0 : ($result['gender'] == 2) ? 1 : 2;
$result['qq_unionid'] = isset($result['unionId']) ? $result['unionId'] : '';
$result['openid'] = $result['openId'];
$result['referrer']= isset($this->data_post['referrer']) ? $this->data_post['referrer'] : 0;
return UserService::AuthUserProgram($result, 'qq_openid');
}
} else {
return DataReturn('授权成功', 0, $user);
}
return DataReturn(empty($result) ? '获取用户信息失败' : $result, -100);
}
/**
* [ClientCenter 用户中心]
* @author Devil
......
<?php
// +----------------------------------------------------------------------
// | ShopXO 国内领先企业级B2C免费开源电商系统
// +----------------------------------------------------------------------
// | Copyright (c) 2011~2019 http://shopxo.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: Devil
// +----------------------------------------------------------------------
namespace base;
/**
* QQ驱动
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @date 2019-10-31
* @desc 支持所有文件存储到硬盘
*/
class QQ
{
// appid
private $_appid;
// appsecret
private $_appsecret;
/**
* [__construct 构造方法]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-12-30T18:04:05+0800
* @param [string] $app_id [应用appid]
* @param [string] $app_secret [应用密钥]
*/
public function __construct($app_id, $app_secret)
{
$this->_appid = $app_id;
$this->_appsecret = $app_secret;
}
/**
* [DecryptData 检验数据的真实性,并且获取解密后的明文]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-12-30T18:20:53+0800
* @param [string] $encrypted_data [加密的用户数据]
* @param [string] $iv [与用户数据一同返回的初始向量]
* @param [string] $openid [解密后的原文]
* @return [array|string] [成功返回用户信息数组, 失败返回错误信息]
*/
public function DecryptData($encrypted_data, $iv, $openid)
{
// 登录授权session
$login_key = 'qq_user_login_'.$openid;
$session_data = GS($login_key);
if($session_data === false)
{
return 'session key不存在';
}
// iv长度
if(strlen($iv) != 24)
{
return 'iv长度错误';
}
// 加密函数
if(!function_exists('openssl_decrypt'))
{
return 'openssl不支持';
}
$aes_cipher = base64_decode($encrypted_data);
$result = openssl_decrypt($aes_cipher, "AES-128-CBC", base64_decode($session_data['session_key']), 1, base64_decode($iv));
$data = json_decode($result, true);
if($data == NULL)
{
return '请重试!';
}
if($data['watermark']['appid'] != $this->_appid )
{
return 'appid不匹配';
}
// 缓存存储
$data_key = 'wechat_user_info_'.$openid;
SS($data_key, $data);
return $data;
}
/**
* [GetAuthSessionKey 根据授权code获取 session_key 和 openid]
* @author Devil
* @blog http://gong.gg/
* @version 1.0.0
* @datetime 2017-12-30T18:20:53+0800
* @param [string] $authcode [用户授权码]
* @return [string|boolean] [失败false, 成功返回appid|]
*/
public function GetAuthSessionKey($authcode)
{
// 请求获取session_key
$url = 'https://api.q.qq.com/sns/jscode2session?appid='.$this->_appid.'&secret='.$this->_appsecret.'&js_code='.$authcode.'&grant_type=authorization_code';
$result = json_decode(file_get_contents($url), true);
if(!empty($result['openid']))
{
// 从缓存获取用户信息
$key = 'qq_user_login_'.$result['openid'];
// 缓存存储
SS($key, $result);
return $result['openid'];
}
return false;
}
}
?>
\ No newline at end of file
App({
data: {
// 用户登录缓存key
cache_user_login_key: "cache_user_login_key",
// 用户信息缓存key
cache_user_info_key: "cache_shop_user_info_key",
// 用户站点信息缓存key
cache_user_merchant_key: "cache_shop_user_merchant_key",
// 设备信息缓存key
cache_system_info_key: "cache_shop_system_info_key",
// 用户地址选择缓存key
cache_buy_user_address_select_key: "cache_buy_user_address_select_key",
// 启动参数缓存key
cache_launch_info_key: "cache_shop_launch_info_key",
// 默认用户头像
default_user_head_src: "/images/default-user.png",
// 成功圆形提示图片
default_round_success_icon: "/images/default-round-success-icon.png",
// 错误圆形提示图片
default_round_error_icon: "/images/default-round-error-icon.png",
// tabbar页面
tabbar_pages: [
"index",
"goods-category",
"cart",
"user",
],
// 页面标题
common_pages_title: {
"goods_search": "商品搜索",
"goods_detail": "商品详情",
"goods_attribute": "属性",
"user_address": "我的地址",
"user_address_save_add": "新增地址",
"user_address_save_edit": "编辑地址",
"buy": "订单确认",
"user_order": "我的订单",
"user_order_detail": "订单详情",
"user_favor": "我的收藏",
"answer_form": "留言",
"answer_list": "问答",
"user_answer_list": "我的留言",
"user": "用户中心",
"goods_category": "分类",
"cart": "购物车",
"message": "消息",
"user_integral": "我的积分",
"user_goods_browse": "我的足迹",
"goods_comment": "商品评论",
"user_orderaftersale": "退款/售后",
"user_orderaftersale_detail": "订单售后",
"user_order_comments": "订单评论",
"coupon": "领劵中心",
"user_coupon": "优惠劵",
},
// 请求地址
request_url: "{{request_url}}",
request_url: 'http://tp5-dev.com/',
//request_url: 'https://test.shopxo.net/',
// 基础信息
application_title: "{{application_title}}",
application_describe: "{{application_describe}}",
},
/**
* 小程序初始化
*/
onLaunch(options) {
// 启动参数处理
options = this.launch_params_handle(options);
// 设置设备信息
this.set_system_info();
// 缓存启动参数
qq.setStorage({
key: this.data.cache_launch_info_key,
data: options
});
},
/**
* 启动参数处理
*/
launch_params_handle(params) {
// 启动参数处理
if ((params.query || null) != null) {
params = params.query;
}
if ((params.scene || null) != null) {
params = this.url_params_to_json(decodeURIComponent(params.scene));
}
return params;
},
/**
* 获取设备信息
*/
get_system_info() {
let system_info = qq.getStorageSync(this.data.cache_system_info_key) || null;
if (system_info == null) {
return this.set_system_info();
}
return system_info;
},
/**
* 设置设备信息
*/
set_system_info() {
var system_info = qq.getSystemInfoSync();
qq.setStorage({
key: this.data.cache_system_info_key,
data: system_info
});
return system_info;
},
/**
/**
* 请求地址生成
*/
get_request_url(a, c, m, params) {
a = a || "index";
c = c || "index";
m = m || "api";
params = params || "";
if (params != "" && params.substr(0, 1) != "&") {
params = "&" + params;
}
var user = this.get_user_cache_info();
var token = (user == false) ? '' : user.token || '';
return (
this.data.request_url +
"index.php?s=/" + m + "/" + c + "/" + a +
"&application=app&application_client_type=weixin" +
"&token=" +
token +
"&ajax=ajax" +
params
);
},
/**
* 从缓存获取用户信息
*/
get_user_cache_info() {
let user = qq.getStorageSync(this.data.cache_user_info_key) || null;
if (user == null) {
return false;
}
return user;
},
/**
* 用户登录
* object 回调操作对象
* method 回调操作对象的函数
* auth_data 授权数据
*/
user_auth_login(object, method, auth_data) {
qq.showLoading({ title: "授权中..." });
var self = this;
qq.checkSession({
success: function () {
var openid = qq.getStorageSync(self.data.cache_user_login_key) || null;
if (openid == null)
{
self.user_login(object, method, auth_data);
} else {
self.get_user_login_info(object, method, openid, auth_data);
}
},
fail: function () {
self.user_login(object, method, auth_data);
}
});
},
/**
* 用户登录
* object 回调操作对象
* method 回调操作对象的函数
* auth_data 授权数据
*/
user_login(object, method, auth_data) {
var self = this;
qq.login({
success: (res) => {
if (res.code) {
qq.request({
url: self.get_request_url('qquserauth', 'user'),
method: 'POST',
data: { authcode: res.code },
dataType: 'json',
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: (res) => {
if (res.data.code == 0) {
qq.setStorage({
key: self.data.cache_user_login_key,
data: res.data.data
});
self.get_user_login_info(object, method, res.data.data, auth_data);
} else {
qq.hideLoading();
self.showToast(res.data.msg);
}
},
fail: () => {
qq.hideLoading();
self.showToast('服务器请求出错');
},
});
}
},
fail: (e) => {
qq.hideLoading();
self.showToast('授权失败');
}
});
},
/**
* 获取用户授权信息
* object 回调操作对象
* method 回调操作对象的函数
* openid 用户openid
* auth_data 授权数据
*/
get_user_login_info(object, method, openid, auth_data) {
// 邀请人参数
var params = qq.getStorageSync(this.data.cache_launch_info_key) || null;
var referrer = (params == null) ? 0 : (params.referrer || 0);
// 远程解密数据
var self = this;
qq.request({
url: self.get_request_url('qquserinfo', 'user'),
method: 'POST',
data: {
"encrypted_data": auth_data.encryptedData,
"iv": auth_data.iv,
"openid": openid,
"referrer": referrer
},
dataType: 'json',
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: (res) => {
qq.hideLoading();
if (res.data.code == 0) {
qq.setStorage({
key: self.data.cache_user_info_key,
data: res.data.data,
success: (res) => {
if (typeof object === 'object' && (method || null) != null) {
object[method]();
}
},
fail: () => {
self.showToast('用户信息缓存失败');
}
});
} else {
self.showToast(res.data.msg);
}
},
fail: () => {
qq.hideLoading();
self.showToast('服务器请求出错');
},
});
},
/**
* 字段数据校验
* data 待校验的数据, 一维json对象
* validation 待校验的字段, 格式 [{fields: 'mobile', msg: '请填写手机号码'}, ...]
*/
fields_check(data, validation) {
for (var i in validation) {
var temp_value = data[validation[i]["fields"]];
var temp_is_can_zero = validation[i]["is_can_zero"] || null;
if ((temp_value == undefined || temp_value.length == 0 || temp_value == -1) || (temp_is_can_zero == null && temp_value == 0)
) {
this.showToast(validation[i]['msg']);
return false;
}
}
return true;
},
/**
* 获取当前时间戳
*/
get_timestamp() {
return parseInt(new Date().getTime() / 1000);
},
/**
* 获取日期
* format 日期格式(默认 yyyy-MM-dd h:m:s)
* timestamp 时间戳(默认当前时间戳)
*/
get_date(format, timestamp) {
var d = new Date((timestamp || this.get_timestamp()) * 1000);
var date = {
"M+": d.getMonth() + 1,
"d+": d.getDate(),
"h+": d.getHours(),
"m+": d.getMinutes(),
"s+": d.getSeconds(),
"q+": Math.floor((d.getMonth() + 3) / 3),
"S+": d.getMilliseconds()
};
if (/(y+)/i.test(format)) {
format = format.replace(RegExp.$1, (d.getFullYear() + '').substr(4 - RegExp.$1.length));
}
for (var k in date) {
if (new RegExp("(" + k + ")").test(format)) {
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
}
}
return format;
},
/**
* 获取对象、数组的长度、元素个数
* obj 要计算长度的元素(object、array、string)
*/
get_length(obj) {
var obj_type = typeof obj;
if (obj_type == "string") {
return obj.length;
} else if (obj_type == "object") {
var obj_len = 0;
for (var i in obj) {
obj_len++;
}
return obj_len;
}
return false;
},
/**
* 价格保留两位小数
* price 价格保留两位小数
*/
price_two_decimal(x) {
var f_x = parseFloat(x);
if (isNaN(f_x)) {
return 0;
}
var f_x = Math.round(x * 100) / 100;
var s_x = f_x.toString();
var pos_decimal = s_x.indexOf('.');
if (pos_decimal < 0) {
pos_decimal = s_x.length;
s_x += '.';
}
while (s_x.length <= pos_decimal + 2) {
s_x += '0';
}
return s_x;
},
/**
* 当前地址是否存在tabbar中
*/
is_tabbar_pages(url) {
if (url.indexOf("?") == -1)
{
var all = url.split("/");
} else {
var temp_str = url.split("?");
var all = temp_str[0].split("/");
}
if (all.length <= 0)
{
return false;
}
var temp_tabbar_pages = this.data.tabbar_pages;
for (var i in temp_tabbar_pages)
{
if (temp_tabbar_pages[i] == all[all.length-1])
{
return true;
}
}
return false;
},
/**
* 事件操作
*/
operation_event(e) {
var value = e.currentTarget.dataset.value || null;
var type = parseInt(e.currentTarget.dataset.type);
if (value != null) {
switch (type) {
// web
case 0:
qq.navigateTo({ url: '/pages/web-view/web-view?url=' + encodeURIComponent(value) });
break;
// 内部页面
case 1:
if (this.is_tabbar_pages(value))
{
qq.switchTab({ url: value });
} else {
qq.navigateTo({ url: value });
}
break;
// 跳转到外部小程序
case 2:
qq.navigateToMiniProgram({ appId: value });
break;
// 跳转到地图查看位置
case 3:
var values = value.split('|');
if (values.length != 4) {
this.showToast('事件值格式有误');
return false;
}
qq.openLocation({
name: values[0],
address: values[1],
longitude: values[2],
latitude: values[3],
});
break;
// 拨打电话
case 4:
qq.makePhoneCall({ phoneNumber: value });
break;
}
}
},
/**
* 默认弱提示方法
* msg [string] 提示信息
* status [string] 状态 默认error [正确success, 错误error]
*/
showToast(msg, status)
{
if ((status || 'error') == 'success')
{
qq.showToast({
title: msg,
duration: 3000
});
} else {
qq.showToast({
image: '/images/default-toast-error.png',
title: msg,
duration: 3000
});
}
},
/**
* 是否需要登录
* 是否需要绑定手机号码
*/
user_is_need_login(user) {
// 用户信息是否正确
if (user == false)
{
return true;
}
// 是否需要绑定手机号码
if ((user.is_mandatory_bind_mobile || 0) == 1)
{
if ((user.mobile || null) == null)
{
return true;
}
}
return false;
},
/**
* url参数转json对象
*/
url_params_to_json(url_params) {
var json = new Object();
if ((url_params || null) != null)
{
var arr = url_params.split('&');
for(var i = 0; i<arr.length; i++) {
var temp = arr[i].split('=');
json[temp[0]] = temp[1]
}
}
return json;
}
});
\ No newline at end of file
{
"pages": [
"pages/index/index",
"pages/goods-category/goods-category",
"pages/cart/cart",
"pages/user/user",
"pages/web-view/web-view",
"pages/login/login",
"pages/paytips/paytips",
"pages/goods-search/goods-search",
"pages/goods-detail/goods-detail",
"pages/goods-comment/goods-comment",
"pages/goods-attribute/goods-attribute",
"pages/buy/buy",
"pages/user-address/user-address",
"pages/user-address-save/user-address-save",
"pages/user-order/user-order",
"pages/user-order-detail/user-order-detail",
"pages/user-order-comments/user-order-comments",
"pages/user-faovr/user-faovr",
"pages/user-answer-list/user-answer-list",
"pages/answer-list/answer-list",
"pages/answer-form/answer-form",
"pages/message/message",
"pages/user-integral/user-integral",
"pages/user-goods-browse/user-goods-browse",
"pages/user-orderaftersale/user-orderaftersale",
"pages/user-orderaftersale-detail/user-orderaftersale-detail",
"pages/coupon/coupon",
"pages/user-coupon/user-coupon"
],
"window": {
"navigationBarTitleText": "{{application_title}}",
"navigationBarBackgroundColor": "#d2364c"
},
"tabBar": {
"color": "#8a8a8a",
"selectedColor": "#d2364c",
"backgroundColor": "#fff",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "/images/nav-icon-home.png",
"selectedIconPath": "/images/nav-icon-home-active.png",
"text": "首页"
},
{
"pagePath": "pages/goods-category/goods-category",
"iconPath": "/images/nav-icon-category.png",
"selectedIconPath": "/images/nav-icon-category-active.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "/images/nav-icon-cart.png",
"selectedIconPath": "/images/nav-icon-cart-active.png",
"text": "购物车"
},
{
"pagePath": "pages/user/user",
"iconPath": "/images/nav-icon-user.png",
"selectedIconPath": "/images/nav-icon-user-active.png",
"text": "我的"
}
]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"plugins": {},
"debug": true,
"sitemapLocation": "sitemap.json"
}
\ No newline at end of file
/* 框架样式覆盖 */
.a-textarea-control textarea {
font-size: 12px;
}
button:after, button:before {
border: 0;
border-radius: 0;
}
/* 公共样式 */
page {
background: #f5f5f5;
color: #4a4a4a;
}
page, textarea {
font-size: 28rpx;
}
input[type="text"],
input[type="number"],
input[type="idcard"],
input[type="digit"],
textarea {
-webkit-appearance: none;
border-radius: 5px;
box-sizing: border-box;
}
/* 导航分割 */
.spacing-nav-title {
position: relative;
color: #d2364c;
text-align: center;
background-color: #ffffff;
height: 80rpx;
line-height: 80rpx;
}
.spacing-nav-title .line {
display: inline-block;
width: 50%;
height: 1px;
background: #d2364c;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
}
.spacing-nav-title .text-wrapper {
position: relative;
display: inline-block;
padding: 0 8px;
background-color: #ffffff;
font-size: 36rpx;
font-weight: bold;
}
/* 模块分割间距 */
.spacing { padding-top: 20rpx; }
.spacing-10 { padding-top: 10rpx; }
.spacing-mb { margin-bottom: 20rpx; }
.spacing-mt { margin-top: 20rpx; }
.drift { position: fixed; left: -1000px; }
.nav-submit-fixed { background: #eee; height: 46px; position: fixed; bottom: 0; z-index: 10; }
.tips { background: #ffffeb url('data:image/png;base64,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') no-repeat 5rpx 12rpx; background-size: 35rpx 35rpx; color: #f7b240; border: 1px solid #faebd2; line-height: 36rpx; padding: 10rpx 10rpx 10rpx 45rpx; font-size: 26rpx; border-radius: 2px; display: block; }
.data-loding image { width: 60px; height: 60px; background-size: 80% 80% !important; }
/* 边框 */
.br { border: solid 1px #efefef; }
.br-b { border-bottom: solid 1px #efefef; }
.br-t { border-top: solid 1px #efefef; }
.br-l { border-left: solid 1px #efefef; }
.br-r { border-right: solid 1px #efefef; }
/* 虚线边框 */
.br-b-dashed { border-bottom: dashed 1px #efefef; }
.br-t-dashed { border-top: dashed 1px #efefef; }
.br-l-dashed { border-left: dashed 1px #efefef; }
.br-r-dashed { border-right: dashed 1px #efefef; }
/* 箭头符号 */
.arrow-right { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAA+klEQVRYR+3WsWrDMBAG4P/eotCQLlk73UGfq6O3BgLNEsg7JQQPZ7ADfos8gAeBijYTAsnpREJBXmX0f/7RCRNe/NCL81EBtYH/1YCq/gK4iMiu1PSYGlDVloi+AOyZ+bsEwgQYx/FtmqYDgFUphAmQvniOiDFuRaTxNGEGlEZkAWaIFsCHp4lsQEIMw7AIIRw9CBfgGgFgzcw/ljPhBtxoohGR7aOIIoC+799DCCciWsYYnwvwhKeWXA14w12AEuHZgFLhWYCS4WbAPDxn5m+NpukQquqZiD49V+81wgToum6TfkiYef/oRXPvPRPg3mY56xVQG6gN/AEiuagh/yEjYQAAAABJRU5ErkJggg=='); background-size: 18px 18px; background-repeat: no-repeat; background-position: center right; }
/* 常用样式 */
.fl { float: left; }
.fr { float: right; }
.bg-white { background-color: #fff; }
.wh-auto { width: 100%; }
.tc { text-align: center; }
.tl { text-align: left; }
.tr { text-align: right; }
.oh { overflow: hidden; }
.dis-none { display: none; }
.dis-block { display: block; }
.cr-main { color: #d2364c; }
.cr-666 { color: #666; }
.cr-888 { color: #888; }
.cr-ccc { color: #ccc; }
.cr-fff { color: #fff; }
.my-btn-default{
font-size: 38rpx;
color: #fff !important;
border: none !important;
background-color:#d2364c !important;
border-radius: 2px;
}
.my-btn-default.btn-disabled{
background-color: #a6a6a6 !important;
color: #fff !important;
}
.my-btn-gray{
font-size: 30rpx;
color: #fff !important;
border: none !important;
background-color:#a6a6a6 !important;
border-radius: 2px;
}
/* 文字超出部分使用省略号 */
.single-text {
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
}
.multi-text {
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
/* 没有数据状态/处理错误/加载中 */
.no-data-box {
padding: 80rpx 0;
}
.no-data-box image {
width: 160rpx;
margin-bottom: 30rpx;
}
.no-data-box .no-data-tips {
font-size: 28rpx;
color: #a6a6a6;
}
.no-data-loding {
padding-top: 15%;
padding-bottom: 10px;
}
/* 底线 */
.data-bottom-line{
padding: 40rpx;
overflow: hidden;
}
.data-bottom-line view {
width: 33.3%;
}
.data-bottom-line .left, .data-bottom-line .right{
margin-top: 5px;
border-bottom: 1px solid #e1e1e1;
}
.data-bottom-line .msg{
color: #999;
text-align: center;
font-size: 24rpx;
}
/* 业务公共 */
.copyright {
color: #a5a5a5;
text-align: center;
padding: 20rpx 0;
}
.copyright .text {
font-size: 26rpx;
font-weight: 400;
}
.sales-price {
color: #f40;
font-weight: bold;
font-size: 32rpx;
}
.original-price {
color: #888;
font-size: 26rpx;
text-decoration: line-through;
margin-left: 10rpx;
}
.submit-fixed {
position: fixed;
left: 0;
bottom: 0;
background: #d2364c !important;
color: #fff !important;
border: none;
width: 100%;
}
.bg-main, .bg-primary, .bg-warning {
color: #fff !important;
border: 0;
font-size: 34rpx;
}
.bg-main {
background-color: #d2364c !important;
}
.bg-primary {
background-color: #ed6977 !important;
}
.bg-warning {
background-color: #F37B1D !important;
}
.bg-active-main {
background-color: #d2364c !important;
color: #fff !important;
}
.submit-bottom {
height: 85rpx;
line-height: 85rpx;
font-size: 32rpx;
border-radius: 0;
}
button[disabled].bg-main {
background-color: #fbe0e5 !important;
color: #f7b6c2 !important;
}
button[disabled].bg-warning {
background-color: #ffcda6 !important;
color: #fdae70 !important;
}
button[disabled].bg-primary {
background-color: #ffd2d7 !important;
color: #ffa0ab !important;
}
.nav-back {
position: fixed;
left: 0;
bottom: 10%;
}
/*
滚动标签高度
*/
.scroll-box {
height: 100vh;
}
/*
分享组建样式
*/
.share-popup {
padding: 20rpx 10rpx 0 10rpx;
position: relative;
}
.share-popup .close {
position: absolute;
top: 20rpx;
right: 20rpx;
z-index: 2;
}
.share-popup-content {
padding: 0 20rpx;
margin-top: 40rpx;
text-align: left;
}
.share-popup-content .share-items {
padding: 30rpx 0;
height: 85rpx;
}
.share-popup-content .share-items:not(:first-child) {
border-top: 1px solid #f0f0f0;
}
.share-popup-content .share-items button {
background: transparent;
padding: 0;
width: 100%;
text-align: left;
margin: 0;
}
.share-popup-content .share-items image {
width: 80rpx;
height: 80rpx;
vertical-align: middle;
margin-right: 20rpx;
}
.share-popup-content .share-items .single-text {
width: calc(100% - 100rpx);
line-height: 85rpx;
}
/**
* 快捷导航
*/
.common-quick-nav {
border: 0;
padding: 15rpx;
background: rgba(0, 0, 0, 0.6);
position: fixed;
right: 10rpx;
border-radius: 50%;
width: 90rpx;
height: 90rpx;
z-index: 1;
}
.common-quick-nav image {
width: 60rpx;
height: 60rpx;
}
/**
* 在线客服
*/
.common-online-service {
bottom: 35%;
}
/**
* 表单
*/
.form-container .form-gorup {
padding: 20rpx 10rpx;
margin-bottom: 20rpx;
}
.form-container .form-gorup-title {
margin-bottom: 5rpx;
font-weight: 500;
}
.form-container .form-group-tips,
.form-container .form-group-tips-must {
margin-left: 20rpx;
font-size: 24rpx;
color: #ccc;
}
.form-container .form-group-tips-must {
color: #f00;
}
.form-container .form-gorup input,
.form-container .form-gorup textarea,
.form-container .form-gorup picker view.picker {
border-radius: 0;
width: 100%;
box-sizing: border-box;
padding: 0 10rpx;
}
.form-container .form-gorup input,
.form-container .form-gorup picker view.picker {
height: 70rpx;
line-height: 70rpx;
}
.form-container .form-gorup textarea {
padding: 0;
min-height: 70rpx;
}
/**
* 表单图片上传
*/
.form-container-upload .form-upload-data .item {
padding: 10rpx;
position: relative;
}
.form-container-upload .form-upload-data .delete-icon {
position: absolute;
top: 15rpx;
right: 15rpx;
color: #e5e5e5;
background-color: #d9534f;
padding: 5rpx 18rpx;
font-size: 30rpx;
border-style: solid;
border-width: 0 0 1px 1px;
border-color: #eee;
}
.form-container-upload .form-upload-data image {
width: 200rpx;
height: 200rpx;
padding: 5rpx;
border: 1px solid #eee;
display: block;
}
.form-container-upload .upload-icon {
margin: 10rpx 0 0 10rpx;
width: 210rpx;
height: 210rpx;
border: 1px dashed #e9e9e9;
}
/*
* 优惠劵 - 插件
*/
.coupon-container {
padding: 0 10rpx;
}
.coupon-container .item {
overflow: hidden;
height: 180rpx;
border: 1px solid #D2364C;
}
.coupon-container .v-left {
width: calc(100% - 140rpx);
padding: 30rpx 0 30rpx 20rpx;
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
}
.coupon-container .v-left .base {
color: #D2364C;
}
.coupon-container .v-left .base .symbol {
font-family: Verdana, Tahoma;
font-size: 48rpx;
font-weight: 400;
}
.coupon-container .v-left .base .price {
font-weight: 700;
font-family: arial;
font-size: 76rpx;
}
.coupon-container .v-left .base .desc {
margin-left: 20rpx;
}
.coupon-container .v-left base-tips, .coupon-container .v-left .base-time {
margin-top: 10rpx;
}
.coupon-container .v-right {
background: #d2364c;
width: 140rpx;
height: 180rpx;
color: #fff;
font-weight: 500;
position: relative;
text-align: center;
}
.coupon-container .v-right:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.coupon-container .v-right .circle {
display: block;
position: absolute;
left: -1px;
top: -3px;
width: 3px;
height: 180rpx;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAACpCAYAAADur4c3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3MjUzYzIwOS04ZWNlLTRlNTctODQ4OC01ZDExOTkwOGNkYmMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTM1QzgxREZGRDI5MTFFNTg3QjhGRUQ1MDY5OURERUQiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTM1QzgxREVGRDI5MTFFNTg3QjhGRUQ1MDY5OURERUQiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NTJiNzVkOGUtZDc2Yi00MzEzLWFmNmYtYTJkNTRlYTI4YTY1IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjcyNTNjMjA5LThlY2UtNGU1Ny04NDg4LTVkMTE5OTA4Y2RiYyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pvy+vnQAAAEqSURBVHjaYvz//z8DDDAxIAFyOVeBOAHEYfyPMDsLmXMfmfMT2YADDP8h4CEQq4A4aUDMA1LNSKZDXwJxGcg1yJaWIXOeInO+IxuwA+acK0AsA+IEADEbic7hhPOAer4DcQcQMyNb2oLMeYVsADcyZwPMObuBWBTEsQFpI9E54sjO+QvEc0F+YoHKJgHxJ2TnvEM2gBmZswrmnA1AzAXiaJPhHC1k58BNQ3bBTGTOR2QD/iJzFsH8Mw/kHxBHggzn2KA7BxzWyC5Yisz5imwACmc2LLY7QbEN4nCS4ZwAIGZFds5lUEpEdsF6nKn3PTJnAsiAV0BcBsSM5GamFCDmQXYOOJ8iu2Anzrz9HKU8ABlwDYgTKcnbo0XNaFEzWtQgipqOYVLUAAQYAKPWa4c8cIHnAAAAAElFTkSuQmCC) no-repeat;
}
.coupon-container .item-disabled .v-right {
background: #dfdfdf !important;
color: #c0c0c0 !important;
cursor: no-drop !important;
}
.coupon-container .item-disabled {
border: 1px solid #dfdfdf !important;
}
\ No newline at end of file
// components/badge.js
Component({
/**
* 组件的属性列表
*/
properties: {
propNumber: Number,
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
\ No newline at end of file
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<view qq:if="{{propNumber > 0}}" class="am-badge">
<view class="am-badge-text {{(propNumber > 99) ? 'am-badge-text-max' : ''}}">
<text>{{(propNumber > 99) ? '99+' : propNumber}}</text>
</view>
</view>
\ No newline at end of file
.am-badge {
display: inline-block;
position: relative;
vertical-align: middle;
}
.am-badge-text {
display: inline-block;
position: absolute;
right: 0;
transform: translate(50%, -50%);
top: 0px;
min-width: 16px;
padding: 0;
height: 16px;
line-height: 16px;
text-align: center;
background-color: #FF3B30;
border-radius: 16px;
color: #fff;
font-size: 10px;
padding: 1px 1px;
}
.am-badge-text-max {
padding: 1px 2px;
}
\ No newline at end of file
const app = getApp();
Component({
data: {},
properties: {
propData: Array
},
methods: {
navigation_event(e) {
app.operation_event(e);
},
},
});
{
"component": true
}
\ No newline at end of file
<view qq:if="{{propData.length > 0}}">
<view class="data-list">
<view class="items" qq:for="{{propData}}" qq:key="key">
<view class="items-content" data-value="{{item.event_value}}" data-type="{{item.event_type}}" bindtap="navigation_event" style="background-color:{{item.bg_color}}">
<image src="{{item.images_url}}" mode="aspectFit" />
</view>
<view class="title">{{item.name}}</view>
</view>
</view>
</view>
\ No newline at end of file
.data-list {
overflow: hidden;
background: #fff;
margin-bottom: 20rpx;
}
.data-list .items {
width: calc(25% - 60rpx);
float: left;
padding: 30rpx;
}
.items-content {
border-radius: 50%;
padding: 20rpx;
text-align: center;
width: 90rpx;
height: 90rpx;
}
.data-list .items image {
width: 80rpx !important;
height: 80rpx !important;
margin-top: 5rpx;
}
.data-list .items .title {
margin-top: 10rpx;
font-size: 32rpx;
text-align:center;
-o-text-overflow: ellipsis;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
max-width: 100%;
}
\ No newline at end of file
// components/popup.js
Component({
/**
* 组件的属性列表
*/
properties: {
propClassname: String,
propShow: Boolean,
propPosition: String,
propMask: Boolean,
propAnimation: Boolean,
propDisablescroll: Boolean
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
onMaskTap: function onMaskTap() {
this.triggerEvent('onclose', {}, {});
}
}
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<view class="am-popup {{propClassname || ''}} {{(propShow || false) ? 'am-popup-show' : ''}} {{ (propAnimation || true) ? 'animation': '' }}" disable-scroll="{{propDisablescroll || true}}">
<view class="am-popup-mask" qq:if="{{propMask || true}}" bindtap="onMaskTap"></view>
<view class="am-popup-content am-popup-{{propPosition || 'bottom'}}">
<slot></slot>
</view>
</view>
\ No newline at end of file
.am-popup-content {
position: fixed;
background:#fff;
z-index: 101;
}
.am-popup-mask {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.75);
opacity: 0;
pointer-events: none;
z-index: 100;
}
.am-popup-left {
transform: translateX(-100%);
left: 0;
top: 0;
bottom: 0;
}
.am-popup-right {
transform: translateX(100%);
right: 0;
top: 0;
bottom: 0;
}
.am-popup-top {
top: 0;
width: 100vw;
transform: translateY(-100%);
}
.am-popup-bottom {
bottom: 0;
width: 100vw;
transform: translateY(100%);
}
.am-popup-show .am-popup-content {
transform: none;
}
.am-popup-show .am-popup-mask {
opacity: 1;
pointer-events: auto;
}
.am-popup.animation .am-popup-content {
transition: all 0.15s linear;
}
.am-popup.animation .am-popup-mask {
transition: all 0.15s linear;
}
\ No newline at end of file
const app = getApp();
Component({
data: {
indicator_dots: false,
indicator_color: 'rgba(0, 0, 0, .3)',
indicator_active_color: '#e31c55',
autoplay: true,
circular: true,
},
properties: {
propData: Array
},
methods: {
banner_event(e) {
app.operation_event(e);
},
},
});
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
<swiper
indicator-dots="{{propData.length > 0}}"
indicator-color="{{indicator_color}}"
indicator-active-color="{{indicator_active_color}}"
autoplay="{{propData.length > 0}}"
circular="{{circular}}"
class="banner"
qq:if="{{propData.length > 0}}">
<block qq:for="{{propData}}" qq:key="key">
<swiper-item>
<image src="{{item.images_url}}" mode="widthFix" data-value="{{item.event_value}}" data-type="{{item.event_type}}" bindtap="banner_event" />
</swiper-item>
</block>
</swiper>
\ No newline at end of file
.banner {
background: #fff;
margin-bottom: 20rpx;
}
.banner image {
min-width: 100%;
}
.banner, .banner image {
height: 320rpx !important;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
form_submit_loading: false,
},
onLoad() {},
onShow() {
qq.setNavigationBarTitle({title: app.data.common_pages_title.answer_form});
this.init();
},
// 初始化
init() {
var user = app.get_user_cache_info(this, "init");
// 用户未绑定用户则转到登录页面
if (app.user_is_need_login(user)) {
qq.redirectTo({
url: "/pages/login/login?event_callback=init"
});
return false;
}
},
/**
* 表单提交
*/
formSubmit(e)
{
// 数据验证
var validation = [
{fields: 'name', msg: '请填写联系人'},
{fields: 'tel', msg: '请填写联系电话'},
{fields: 'content', msg: '请填写内容'}
];
if(app.fields_check(e.detail.value, validation))
{
qq.showLoading({title: '提交中...'});
this.setData({form_submit_loading: true});
// 网络请求
qq.request({
url: app.get_request_url('add', 'answer'),
method: 'POST',
data: e.detail.value,
dataType: 'json',
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: (res) => {
qq.hideLoading();
if(res.data.code == 0)
{
app.showToast(res.data.msg, "success");
setTimeout(function()
{
qq.redirectTo({
url: "/pages/user-answer-list/user-answer-list"
});
}, 2000);
} else {
this.setData({form_submit_loading: false});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.hideLoading();
this.setData({form_submit_loading: false});
app.showToast('服务器请求出错');
}
});
}
},
});
{
"enablePullDownRefresh": false
}
\ No newline at end of file
<form bindsubmit="formSubmit">
<view class="form-input bg-white spacing-mb">
<input type="text" class="wh-auto" name="name" placeholder="联系人" maxlength="30" />
</view>
<view class="form-input bg-white spacing-mb">
<input type="number" class="wh-auto" name="tel" placeholder="联系电话" maxlength="15" />
</view>
<view class="form-input bg-white spacing-mb">
<textarea name="content" class="content-textarea" maxlength="160" placeholder="请详细描述问题,我们将尽快为您解答!" />
</view>
<view class="bottom-btn-box fixed">
<button type="default" formType="submit" class="my-btn-default" hover-class="none" bindtap="submit_event" loading="{{form_submit_loading}}" disabled="{{form_submit_loading}}">提交</button>
</view>
</form>
\ No newline at end of file
.content{
padding: 10rpx;
}
.content-textarea {
padding-top: 10rpx;
min-height: 20vh;
}
.bottom-btn-box {
margin-top: 160rpx;
padding: 0 10rpx;
}
.form-input {
padding: 20rpx 10rpx;
}
.form-input input, .form-input textarea {
font-size: 30rpx;
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
data_list: [],
data_page_total: 0,
data_page: 1,
data_list_loding_status: 1,
data_bottom_line_status: false
},
onLoad() {
this.get_data_list();
},
onShow() {
qq.setNavigationBarTitle({title: app.data.common_pages_title.answer_list});
},
get_data_list(is_mandatory) {
// 分页是否还有数据
if ((is_mandatory || 0) == 0) {
if (this.data.data_bottom_line_status == true) {
return false;
}
}
// 加载loding
this.setData({
data_list_loding_status: 1
});
// 获取数据
qq.request({
url: app.get_request_url("common", "answer"),
method: "POST",
data: {
page: this.data.data_page
},
dataType: "json",
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: res => {
qq.stopPullDownRefresh();
if (res.data.code == 0) {
if (res.data.data.data.length > 0) {
if (this.data.data_page <= 1) {
var temp_data_list = res.data.data.data;
} else {
var temp_data_list = this.data.data_list;
var temp_data = res.data.data.data;
for (var i in temp_data) {
temp_data_list.push(temp_data[i]);
}
}
this.setData({
data_list: temp_data_list,
data_total: res.data.data.total,
data_page_total: res.data.data.page_total,
data_list_loding_status: 3,
data_page: this.data.data_page + 1
});
// 是否还有数据
if (this.data.data_page > 1 && this.data.data_page > this.data.data_page_total)
{
this.setData({ data_bottom_line_status: true });
} else {
this.setData({data_bottom_line_status: false});
}
} else {
this.setData({
data_list_loding_status: 0
});
}
} else {
this.setData({
data_list_loding_status: 0
});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.stopPullDownRefresh();
this.setData({
data_list_loding_status: 2
});
app.showToast("服务器请求出错");
}
});
},
// 下拉刷新
onPullDownRefresh() {
this.setData({ data_page: 1 });
this.get_data_list(1);
},
// 滚动加载
scroll_lower(e) {
this.get_data_list();
},
// 头像加载错误
user_avatar_error(e) {
var index = e.currentTarget.dataset.index || 0;
var temp_data_list = this.data_list;
for(var i in temp_data_list)
{
if(i == index)
{
temp_data_list[i]['avatar'] = app.data.default_user_head_src
}
}
this.setData({data_list: temp_data_list});
},
});
{
"enablePullDownRefresh": true
}
\ No newline at end of file
<scroll-view scroll-y="{{true}}" class="scroll-box" bindscrolltolower="scroll_lower" lower-threshold="30">
<view class="item bg-white spacing-mb" qq:if="{{data_list.length > 0}}" qq:for="{{data_list}}">
<view class="base">
<view class="oh">
<image class="avatar fl" src="{{item.avatar}}" mode="widthFix" data-index="{{index}}" binderror="user_avatar_error" />
<view class="desc fr tl">{{item.content}}</view>
</view>
<view class="cr-888 tr">{{item.add_time}}</view>
</view>
<view qq:if="{{(item.reply || null) != null}}" class="answer br-t">
<text class="reply-icon bg-main cr-fff"></text>
<text class="reply-content cr-888">{{item.reply}}</text>
</view>
</view>
<view qq:if="{{data_list.length == 0}}">
<import src="/pages/common/nodata.wxml" />
<template is="nodata" data="{{status: data_list_loding_status}}"></template>
</view>
<import src="/pages/common/bottom_line.wxml" />
<template is="bottom_line" data="{{status: data_bottom_line_status}}"></template>
</scroll-view>
\ No newline at end of file
.item {
padding: 10rpx;
}
.item .base, .item .content, .item .answer {
padding: 15rpx 0;
}
.item .base .desc {
width: calc(100% - 130rpx);
}
.item .base .avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
.item .answer .reply-icon {
border-radius: 5px;
padding: 0px 3px;
margin-right: 5px;
}
.item .answer .reply-content, .item .base .desc {
line-height: 42rpx;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
data_list_loding_status: 1,
buy_submit_disabled_status: false,
data_list_loding_msg: '',
params: null,
payment_list: [],
goods_list: [],
address: null,
address_id: 0,
total_price: 0,
user_note_value: '',
is_first: 1,
extension_data: [],
payment_id: 0,
common_order_is_booking: 0,
// 优惠劵
plugins_coupon_data: null,
plugins_use_coupon_id: 0,
plugins_choice_coupon_value: '选择优惠劵',
popup_plugins_coupon_status: false,
},
onLoad(params) {
if((params.data || null) == null || app.get_length(JSON.parse(params.data)) == 0)
{
qq.alert({
title: '温馨提示',
content: '订单信息有误',
buttonText: '确认',
success: () => {
qq.navigateBack();
},
});
} else {
this.setData({ params: JSON.parse(params.data)});
// 删除地址缓存
qq.removeStorageSync(app.data.cache_buy_user_address_select_key);
}
},
onShow() {
qq.setNavigationBarTitle({title: app.data.common_pages_title.buy});
this.init();
this.setData({is_first: 0});
},
// 获取数据列表
init() {
// 本地缓存地址
if(this.data.is_first == 0)
{
var cache_address = qq.getStorageSync(app.data.cache_buy_user_address_select_key);
if((cache_address || null) != null)
{
this.setData({
address: cache_address,
address_id: cache_address.id
});
} else {
this.setData({
address: null,
address_id: 0
});
}
}
// 加载loding
qq.showLoading({title: '加载中...'});
this.setData({
data_list_loding_status: 1
});
var data = this.data.params;
data['address_id'] = this.data.address_id;
data['payment_id'] = this.data.payment_id;
data['coupon_id'] = this.data.plugins_use_coupon_id;
qq.request({
url: app.get_request_url("index", "buy"),
method: "POST",
data: data,
dataType: "json",
success: res => {
qq.stopPullDownRefresh();
qq.hideLoading();
if (res.data.code == 0) {
var data = res.data.data;
if (data.goods_list.length == 0)
{
this.setData({data_list_loding_status: 0});
} else {
this.setData({
goods_list: data.goods_list,
total_price: data.base.actual_price,
extension_data: data.extension_data || [],
data_list_loding_status: 3,
common_order_is_booking: data.common_order_is_booking || 0,
plugins_coupon_data: data.plugins_coupon_data || null,
});
// 优惠劵选择处理
if ((data.plugins_coupon_data || null) != null)
{
if ((data.plugins_coupon_data.coupon_choice || null) != null)
{
this.setData({ plugins_choice_coupon_value: data.plugins_coupon_data.coupon_choice.coupon.desc });
} else {
var coupon_count = ((data.plugins_coupon_data.coupon_list || null) != null) ? data.plugins_coupon_data.coupon_list.length : 0;
this.setData({ plugins_choice_coupon_value: (coupon_count > 0) ? '可选优惠劵' + coupon_count + '' : '暂无可用优惠劵' });
}
}
// 地址
if (this.data.address == null || this.data.address_id == 0) {
if((data.base.address || null) != null) {
this.setData({
address: data.base.address,
address_id: data.base.address.id,
});
qq.setStorage({
key: app.data.cache_buy_user_address_select_key,
data: data.base.address,
});
}
}
// 支付方式
this.payment_list_data(data.payment_list);
}
} else {
this.setData({
data_list_loding_status: 2,
data_list_loding_msg: res.data.msg,
});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.stopPullDownRefresh();
qq.hideLoading();
this.setData({
data_list_loding_status: 2,
data_list_loding_msg: '服务器请求出错',
});
app.showToast("服务器请求出错");
}
});
},
// 下拉刷新
onPullDownRefresh() {
this.init();
},
// 用户留言事件
bind_user_note_event(e) {
this.setData({user_note_value: e.detail.value});
},
// 提交订单
buy_submit_event(e) {
// 表单数据
var data = this.data.params;
data['address_id'] = this.data.address_id;
data['payment_id'] = this.data.payment_id;
data['user_note'] = this.data.user_note_value;
data['coupon_id'] = this.data.plugins_use_coupon_id;
// 数据验证
var validation = [
{ fields: 'address_id', msg: '请选择地址' }
];
if (this.data.common_order_is_booking != 1) {
validation.push({ fields: 'payment_id', msg: '请选择支付方式' });
}
if (app.fields_check(data, validation)) {
// 加载loding
qq.showLoading({title: '提交中...'});
this.setData({ buy_submit_disabled_status: true });
qq.request({
url: app.get_request_url("add", "buy"),
method: "POST",
data: data,
dataType: "json",
success: res => {
qq.hideLoading();
if (res.data.code == 0) {
if (res.data.data.order.status == 1) {
qq.redirectTo({
url: '/pages/user-order/user-order?is_pay=1&order_id=' + res.data.data.order.id
});
} else {
qq.redirectTo({url: '/pages/user-order/user-order'});
}
} else {
app.showToast(res.data.msg);
this.setData({ buy_submit_disabled_status: false });
}
},
fail: () => {
qq.hideLoading();
this.setData({buy_submit_disabled_status: false});
app.showToast("服务器请求出错");
}
});
}
},
// 支付方式选择
payment_event(e) {
this.setData({ payment_id: e.currentTarget.dataset.value});
this.payment_list_data(this.data.payment_list);
this.init();
},
// 支付方式数据处理
payment_list_data(data) {
if (this.data.payment_id != 0) {
for (var i in data) {
if (data[i]['id'] == this.data.payment_id) {
data[i]['selected'] = 'selected';
} else {
data[i]['selected'] = '';
}
}
}
this.setData({payment_list: data || []});
},
// 优惠劵弹层开启
plugins_coupon_open_event(e) {
this.setData({ popup_plugins_coupon_status: true});
},
// 优惠劵弹层关闭
plugins_coupon_close_event(e) {
this.setData({ popup_plugins_coupon_status: false });
},
// 优惠劵选择
plugins_coupon_use_event(e) {
var index = e.currentTarget.dataset.index;
var value = e.currentTarget.dataset.value;
this.setData({
plugins_use_coupon_id: value,
popup_plugins_coupon_status: false,
});
this.init();
},
// 不使用优惠劵
plugins_coupon_not_use_event(e) {
this.setData({
plugins_use_coupon_id: 0,
popup_plugins_coupon_status: false,
});
this.init();
},
});
{
"enablePullDownRefresh": true,
"usingComponents": {
"component-popup": "/components/popup/popup"
}
}
\ No newline at end of file
<view qq:if="{{goods_list.length > 0}}" class="page">
<!-- 地址 -->
<view class="address bg-white arrow-right">
<navigator url="/pages/user-address/user-address?is_back=1" hover-class="none">
<view qq:if="{{address != null}}">
<view class="address-base oh">
<text>{{address.name}}</text>
<text class="fr">{{address.tel}}</text>
</view>
<view class="address-detail oh">
<image class="icon fl" src="/images/user-address.png" mode="widthFix" />
<view class="text fr">{{address.province_name}}{{address.city_name}}{{address.county_name}}{{address.address}}</view>
</view>
</view>
<view qq:if="{{address == null}}" class="no-address cr-888">
请选择地址
</view>
</navigator>
</view>
<view class="address-divider spacing-mb"></view>
<!-- 商品 -->
<view class="goods bg-white spacing-mb">
<view qq:for="{{goods_list}}" qq:key="key" class="goods-item oh">
<image class="goods-image fl" src="{{item.images}}" mode="aspectFill" />
<view class="goods-base">
<view class="goods-title multi-text">{{item.title}}</view>
<block qq:if="{{item.spec != null}}">
<view class="goods-spec cr-888" qq:for="{{item.spec}}" qq:key="key" qq:for-item="spec">{{spec.type}}:{{spec.value}}
</view>
</block>
</view>
<view class="oh goods-price">
<text class="sales-price">{{item.price}}
</text>
<text qq:if="{{item.original_price > 0}}" class="original-price">{{item.original_price}}
</text>
<text class="buy-number cr-888">x{{item.stock}}
</text>
</view>
</view>
</view>
<!-- 留言 -->
<view class="content-textarea-view bg-white spacing-mb">
<textarea qq:if="{{!popup_plugins_coupon_status}}" bindinput="bind_user_note_event" value="{{user_note_value}}" maxlength="60" placeholder="留言" class="wh-auto" />
<view qq:if="{{popup_plugins_coupon_status}}" class="cr-888">{{user_note_value || '留言'}}</view>
</view>
<!-- 优惠劵 -->
<view qq:if="{{(plugins_coupon_data || null) != null && plugins_coupon_data.coupon_list.length > 0}}" class="plugins-coupon bg-white spacing-mb arrow-right" bindtap="plugins_coupon_open_event">
<text class="cr-666">优惠劵</text>
<text class="cr-ccc fr">{{plugins_choice_coupon_value}}</text>
</view>
<!-- 扩展数据展示 -->
<view qq:if="{{extension_data.length > 0}}" class="extension-list spacing-mb">
<view qq:for="{{extension_data}}" qq:key="key" class="item oh">
<text class="cr-666 fl">{{item.name}}
</text>
<text class="text-tips fr">{{item.tips}}
</text>
</view>
</view>
<!-- 支付方式 -->
<view qq:if="{{payment_list.length > 0 && common_order_is_booking != 1}}" class="payment-list bg-white oh">
<view class="item tc fl" qq:for="{{payment_list}}" qq:key="key">
<view class="item-content br {{(item.selected || '')}}" data-value="{{item.id}}" bindtap="payment_event">
<image qq:if="{{(item.logo || null) != null}}" class="icon" src="{{item.logo}}" mode="widthFix" />
<text>{{item.name}}</text>
</view>
</view>
</view>
<!-- 导航 -->
<view class="buy-nav oh wh-auto">
<view class="nav-base bg-white fl single-text">
<text>合计</text>
<text class="sales-price">{{total_price}}</text>
</view>
<view class="fr nav-submit">
<button class="bg-main wh-auto" type="default" bindtap="buy_submit_event" disabled="{{buy_submit_disabled_status}}" hover-class="none">提交订单</button>
</view>
</view>
</view>
<view qq:if="{{goods.length == 0}}">
<import src="/pages/common/nodata.wxml" />
<template is="nodata" data="{{status: data_list_loding_status, msg: data_list_loding_msg}}"></template>
</view>
<!-- 优惠劵选择 -->
<component-popup prop-show="{{popup_plugins_coupon_status}}" prop-position="bottom" bindonclose="plugins_coupon_close_event">
<view class="plugins-coupon-popup bg-white">
<view class="close oh">
<view class="fr" catchtap="plugins_coupon_close_event">
<icon type="clear" size="20" />
</view>
</view>
<view qq:if="{{(plugins_coupon_data || null) != null && plugins_coupon_data.coupon_list.length > 0}}" class="coupon-container oh br-b">
<view class="not-use-tips tc">
<text bindtap="plugins_coupon_not_use_event">不使用优惠劵</text>
</view>
<block qq:for="{{plugins_coupon_data.coupon_list}}" qq:key="item">
<view class="item spacing-mt bg-white" style="border:1px solid {{item.coupon.bg_color_value}};">
<view class="v-left fl">
<view class="base single-text" style="color:{{item.coupon.bg_color_value}};">
<text class="symbol"></text>
<text class="price">{{item.coupon.discount_value}}</text>
<text class="unit">{{item.coupon.type_unit}}</text>
<text qq:if="{{(item.coupon.desc || null) != null}}" class="desc cr-888">{{item.coupon.desc}}</text>
</view>
<view qq:if="{{(item.coupon.use_limit_type_name || null) != null}}" class="base-tips cr-666 single-text">{{item.coupon.use_limit_type_name}}</view>
<view class="base-time cr-888 single-text">{{item.time_start_text}} {{item.time_end_text}}</view>
</view>
<view class="v-right fr" style="background:{{item.coupon.bg_color_value}};" data-index="{{index}}" data-value="{{item.id}}" bindtap="plugins_coupon_use_event">
<text class="circle"></text>
<text>{{plugins_use_coupon_id == item.id ? '已选' : '选择'}}</text>
</view>
</view>
</block>
</view>
</view>
</component-popup>
\ No newline at end of file
.page {
padding-bottom: 120rpx;
}
/**
* 地址
*/
.address {
padding: 10rpx;
}
.address-base, .address-detail {
padding: 10rpx 35rpx 10rpx 10rpx;
}
.address-detail .icon {
width: 35rpx;
height: 35rpx !important;
}
.address-detail .text {
width: calc(100% - 40rpx);
}
.address-divider {
height: 4px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAAECAYAAADWIIyPAAAAkklEQVR42mP4jwR+7tr1/4OzM1Xwt46O/6SA3Yd//HeLeU0V3DXjE0H7GGCMvw8f/v/o5UUVT39KTPz/78cPoj398Omf/75Jb6ji6ZSyd/9//PxHnMdBjvyUlEQVT4MC7++DB0R7GuTIlPJ3VPE0KPAePvlDlL1gj3/r6qJaEv+5YwdJSbxn5meqJfGdh74TbS8A1dn662xhNdIAAAAASUVORK5CYII=");
background-repeat-y: no-repeat;
}
.address-detail .text, .goods-title {
line-height: 36rpx;
}
.no-address {
height: 85rpx;
line-height: 85rpx;
}
/**
* 商品
*/
.goods .goods-item:not(:last-child) {
border-bottom: 1px dashed #efefef;
}
.goods-item {
padding: 20rpx 10rpx;
}
.goods-title, .goods-spec {
margin-bottom: 10rpx;
}
.goods-image {
width: 160rpx;
height: 160rpx;
margin-right: 20rpx;
}
.goods-price {
position: relative;
}
.buy-number {
position: absolute;
right: 0;
bottom: 0;
}
.goods-base {
min-height: 160rpx;
margin-left: 180rpx;
}
/**
* 导航
*/
.buy-nav {
position: fixed;
left: 0;
bottom: 0;
}
.buy-nav, .nav-base, .nav-submit button {
height: 100rpx;
}
.nav-base, .nav-submit button {
line-height: 100rpx;
}
.nav-base {
width: calc(60% - 20rpx);
padding: 0 10rpx;
}
.nav-submit {
width: 40%;
}
.nav-submit button {
border-radius: 0;
}
/**
* 支付方式
*/
.payment-list .item {
width: 50%;
}
.payment-list .item-content {
margin: 20rpx;
padding: 20rpx 10rpx;
}
.payment-list .item-content image {
width: 50rpx;
height: 50rpx !important;
vertical-align: middle;
margin-right: 10rpx;
}
.payment-list .selected {
border: 1px solid #d2364c;
color: #d2364c;
}
/**
* 扩展数据
*/
.extension-list {
background-color: #ffffeb;
}
.extension-list .item {
padding: 20rpx 10rpx;
}
.extension-list .item:not(:last-child) {
border-bottom: 1px dashed #ffe2cf;
}
.extension-list .item .text-tips {
color: #ff8f44;
}
/**
* 留言
*/
.content-textarea-view,
.content-textarea-view textarea {
height: 180rpx;
}
.content-textarea-view view {
padding: 12rpx;
}
/**
* 插件样式区域
*/
/**
* 优惠劵
*/
.plugins-coupon {
padding: 25rpx 40rpx 25rpx 10rpx;
}
.plugins-coupon-popup {
padding-top: 20rpx;
}
.plugins-coupon-popup .close {
margin-right: 20rpx;
}
.coupon-container {
max-height: 80vh;
overflow-y: scroll;
overflow-x: hidden;
padding-bottom: 50rpx;
}
.coupon-container .item,
.coupon-container .v-right,
.coupon-container .v-right .circle {
height: 230rpx;
}
.coupon-container .not-use-tips {
color: #f7b240;
font-size: 32rpx;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
data_list_loding_status: 1,
data_list_loding_msg: '',
data_bottom_line_status: false,
data_list: [],
swipe_index: null,
total_price: '0.00',
is_selected_all: false,
buy_submit_disabled_status: true,
},
onShow() {
qq.setNavigationBarTitle({ title: app.data.common_pages_title.cart });
this.init();
},
init(e) {
var user = app.get_user_cache_info(this, "init");
// 用户未绑定用户则转到登录页面
var msg = (user == false) ? '授权用户信息' : '绑定手机号码';
if (app.user_is_need_login(user)) {
qq.showModal({
title: '温馨提示',
content: msg,
confirmText: '确认',
cancelText: '暂不',
success: (result) => {
if (result.confirm) {
qq.navigateTo({
url: "/pages/login/login?event_callback=init"
});
} else {
this.setData({
data_list_loding_status: 0,
data_bottom_line_status: false,
data_list_loding_msg: '请先' + msg,
});
}
},
});
} else {
this.get_data();
}
},
// 获取数据
get_data() {
this.setData({
data_list_loding_status: 1,
total_price: '0.00',
is_selected_all: false,
buy_submit_disabled_status: true,
});
qq.request({
url: app.get_request_url("index", "cart"),
method: "POST",
data: {},
dataType: "json",
success: res => {
qq.stopPullDownRefresh();
if (res.data.code == 0) {
var data = res.data.data;
if (data.length > 0) {
for (var i in data) {
data[i]['right'] = [{ type: 'edit', text: '加入收藏' }, { type: 'delete', text: '删除' }];
}
}
this.setData({
data_list: data,
data_list_loding_status: data.length == 0 ? 0 : 3,
data_bottom_line_status: true,
data_list_loding_msg: '购物车空空如也',
});
} else {
this.setData({
data_list_loding_status: 2,
data_bottom_line_status: false,
data_list_loding_msg: res.data.msg,
});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.stopPullDownRefresh();
this.setData({
data_list_loding_status: 2,
data_bottom_line_status: false,
data_list_loding_msg: '服务器请求出错',
});
app.showToast("服务器请求出错");
}
});
},
// 下拉刷新
onPullDownRefresh() {
this.init();
},
// 数量输入事件
goods_buy_number_blur(e) {
var index = e.currentTarget.dataset.index || 0;
var buy_number = parseInt(e.detail.value) || 1;
this.goods_buy_number_func(index, buy_number);
},
// 数量操作事件
goods_buy_number_event(e) {
var index = e.currentTarget.dataset.index || 0;
var type = parseInt(e.currentTarget.dataset.type) || 0;
var temp_buy_number = parseInt(this.data.data_list[index]['stock']);
if (type == 0) {
var buy_number = temp_buy_number - 1;
} else {
var buy_number = temp_buy_number + 1;
}
this.goods_buy_number_func(index, buy_number);
},
// 数量处理方法
goods_buy_number_func(index, buy_number) {
var temp_data_list = this.data.data_list;
var buy_min_number = parseInt(temp_data_list[index]['buy_min_number']) || 1;
var buy_max_number = parseInt(temp_data_list[index]['buy_max_number']) || 0;
var inventory = parseInt(temp_data_list[index]['inventory']);
var inventory_unit = temp_data_list[index]['inventory_unit'];
if (buy_number < buy_min_number) {
buy_number = buy_min_number;
if (buy_min_number > 1) {
app.showToast('起购' + buy_min_number + inventory_unit );
return false;
}
}
if (buy_max_number > 0 && buy_number > buy_max_number) {
buy_number = buy_max_number;
app.showToast('限购' + buy_max_number + inventory_unit );
return false;
}
if (buy_number > inventory) {
buy_number = inventory;
app.showToast( '库存数量' + inventory + inventory_unit );
return false;
}
if (temp_data_list[index]['stock'] == 1 && buy_number == 1)
{
return false;
}
// 更新数据库
qq.request({
url: app.get_request_url("stock", "cart"),
method: "POST",
data: { "id": temp_data_list[index]['id'], "goods_id": temp_data_list[index]['goods_id'], "stock": buy_number},
dataType: "json",
success: res => {
qq.stopPullDownRefresh();
if (res.data.code == 0) {
temp_data_list[index]['stock'] = buy_number;
this.setData({ data_list: temp_data_list });
// 选择处理
this.selected_calculate();
} else {
app.showToast(res.data.msg);
}
},
fail: () => {
app.showToast("服务器请求出错");
}
});
},
// 收藏+删除
goods_favor_delete(id, goods_id, type) {
qq.request({
url: app.get_request_url('favor', 'goods'),
method: 'POST',
data: { "id": goods_id, "is_mandatory_favor": 1 },
dataType: 'json',
success: (res) => {
if (res.data.code == 0) {
this.cart_delete(id, type);
} else {
app.showToast(res.data.msg);
}
},
fail: () => {
app.showToast("服务器请求出错");
}
});
},
// 移除操作事件
cart_remove_event(e) {
var id = e.currentTarget.dataset.id || null;
var index = e.currentTarget.dataset.index || 0;
var goods_id = e.currentTarget.dataset.goodsid || 0;
var self = this;
if (id !== null) {
self.setData({ swipe_index: index})
qq.showActionSheet({
itemList: ['加入收藏', '删除'],
success(res) {
if (res.tapIndex == 0)
{
self.goods_favor_delete(id, goods_id, 'favor')
} else {
self.cart_delete(id, 'delete');
}
}
});
} else {
app.showToast("参数有误");
}
},
// 购物车删除
cart_delete(id, type) {
qq.request({
url: app.get_request_url('delete', 'cart'),
method: 'POST',
data: { "id": id },
dataType: 'json',
success: (res) => {
if (res.data.code == 0) {
var temp_data_list = this.data.data_list;
temp_data_list.splice(this.data.swipe_index, 1);
this.setData({
data_list: temp_data_list,
swipe_index: null,
data_list_loding_status: temp_data_list.length == 0 ? 0 : this.data.data_list_loding_status,
});
app.showToast(((type == 'delete') ? '删除成功' : '收藏成功'), 'success');
} else {
app.showToast((type == 'delete') ? '删除失败' : '收藏失败');
}
},
fail: () => {
app.showToast("服务器请求出错");
}
});
},
// 选中处理
selectedt_event(e) {
var type = e.currentTarget.dataset.type || null;
if (type != null)
{
var temp_data_list = this.data.data_list;
var temp_is_selected_all = this.data.is_selected_all;
switch(type) {
// 批量操作
case 'all' :
temp_is_selected_all = (temp_is_selected_all == true) ? false : true;
for (var i in temp_data_list) {
if (temp_data_list[i]['is_error'] != 1)
{
temp_data_list[i]['selected'] = temp_is_selected_all;
}
}
break;
// 节点操作
case 'node' :
var index = e.currentTarget.dataset.index || 0;
if (temp_data_list[index]['is_error'] != 1)
{
temp_data_list[index]['selected'] = (temp_data_list[index]['selected'] == true) ? false : true;
}
break;
}
this.setData({
data_list: temp_data_list,
is_selected_all: temp_is_selected_all,
});
// 选择处理
this.selected_calculate();
}
},
// 选中计算
selected_calculate() {
var total_price = 0;
var selected_count = 0;
var temp_data_list = this.data.data_list;
for (var i in temp_data_list) {
if ((temp_data_list[i]['selected'] || false) == true) {
total_price += temp_data_list[i]['stock'] * temp_data_list[i]['price'];
selected_count++;
}
}
this.setData({
total_price: total_price.toFixed(2),
buy_submit_disabled_status: (selected_count <= 0),
is_selected_all: (selected_count >= temp_data_list.length),
});
},
// 结算
buy_submit_event(e) {
var selected_count = 0;
var ids = [];
var temp_data_list = this.data.data_list;
for (var i in temp_data_list) {
if ((temp_data_list[i]['selected'] || false) == true) {
ids.push(temp_data_list[i]['id']);
selected_count++;
}
}
if (selected_count <= 0) {
app.showToast("请选择商品");
return false
}
// 进入订单确认页面
var data = {
"buy_type": "cart",
"ids": ids.join(',')
};
qq.navigateTo({
url: '/pages/buy/buy?data=' + JSON.stringify(data)
});
}
});
{
"enablePullDownRefresh": true,
"usingComponents": {
}
}
\ No newline at end of file
<view qq:if="{{data_list.length > 0}}" class="page">
<view qq:for="{{data_list}}" qq:key="key" class="goods-item oh bg-white">
<!-- 选择 -->
<view bindtap="selectedt_event" data-type="node" data-index="{{index}}" class="fl selected">
<image class="icon" src="/images/default-select{{(item.is_error || 0) == 1 ? '-disabled' : ((item.selected || false) ? '-active' : '')}}-icon.png" mode="widthFix" />
</view>
<view class="bg-white items">
<!-- 图片/链接 -->
<navigator url="/pages/goods-detail/goods-detail?goods_id={{item.goods_id}}">
<image class="goods-image fl" src="{{item.images}}" mode="aspectFill" />
</navigator>
<!-- 基础 -->
<view class="goods-base">
<view class="goods-title multi-text">{{item.title}}
</view>
<block qq:if="{{item.spec != null}}">
<view class="goods-attribute cr-888" qq:for="{{item.spec}}" qq:key="key" qq:for-item="spec">{{spec.type}}:{{spec.value}}</view>
</block>
</view>
<!-- 数量 -->
<view class="number-content tc oh">
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="0">-</view>
<input bindblur="goods_buy_number_blur" class="tc cr-888 fl" type="number" value="{{item.stock}}" data-index="{{index}}" />
<view bindtap="goods_buy_number_event" class="number-submit tc cr-888 fl" data-index="{{index}}" data-type="1">+</view>
</view>
<!-- 价格 -->
<view class="oh goods-price">
<text class="sales-price">{{item.price}}</text>
<text qq:if="{{item.original_price > 0}}" class="original-price">{{item.original_price}}</text>
<text class="buy-number cr-888">x{{item.stock}}</text>
<!-- 错误 -->
<text qq:if="{{(item.is_error || 0) == 1}}" class="error-msg">{{item.error_msg}}</text>
<!-- 移除 -->
<view class="fr remove" data-id="{{item.id}}" data-goodsid="{{item.goods_id}}" data-index="{{index}}" bindtap="cart_remove_event">移除</view>
</view>
</view>
</view>
<!-- 操作导航 -->
<view qq:if="{{data_list.length > 0}}" class="buy-nav oh wh-auto br-t">
<view class="nav-base bg-white fl single-text">
<view bindtap="selectedt_event" data-type="all" class="fl selected">
<image qq:if="{{is_selected_all}}" class="icon" src="/images/default-select-active-icon.png" mode="widthFix" />
<image wx:else class="icon" src="/images/default-select-icon.png" mode="widthFix" />
<text>全选</text>
</view>
<view class="fr price">
<view class="sales-price single-text fr">{{total_price}}</view>
<view class="fr">合计</view>
</view>
</view>
<view class="fr nav-submit">
<button class="bg-main wh-auto" type="default" bindtap="buy_submit_event" disabled="{{buy_submit_disabled_status}}" hover-class="none">结算</button>
</view>
</view>
</view>
<!-- 空购物车 -->
<view qq:if="{{data_list.length == 0 && data_list_loding_status == 0}}" class="no-data-box tc">
<image src="/images/default-cart-empty.png" mode="widthFix" />
<view class="no-data-tips">{{data_list_loding_msg || '购物车空空如也'}}</view>
<navigator url="/pages/index/index" open-type="switchTab" hover-class="none">
<button type="default" class="my-btn-default" hover-class="none">去逛逛</button>
</navigator>
</view>
<view qq:if="{{data_list.length == 0 && data_list_loding_status != 0}}">
<import src="/pages/common/nodata.wxml" />
<template is="nodata" data="{{status: data_list_loding_status, msg: data_list_loding_msg}}"></template>
</view>
\ No newline at end of file
/**
* 商品列表
*/
.page {
padding-bottom: 120rpx;
}
.goods-item {
padding: 20rpx 10rpx;
position: relative;
}
.goods-title {
line-height: 36rpx;
}
.goods-item:not(:last-child) {
border-bottom: 1px solid #eee;
}
.goods-title, .goods-attribute {
margin-bottom: 10rpx;
}
.goods-image {
width: 160rpx;
height: 160rpx;
margin-right: 20rpx;
}
.goods-base {
min-height: 160rpx;
margin-left: 180rpx;
}
.goods-price {
position: relative;
}
.buy-number {
margin-left: 20rpx;
}
.goods-item .items {
padding-left: 80rpx;
}
.goods-item .selected {
margin-top: 60rpx;
}
.goods-item .remove {
color: #e00303;
}
.goods-item .error-msg {
color: #f00;
margin-left: 15rpx;
}
/**
* 数量操作
*/
.number-content {
position: absolute;
right: 20rpx;
top: 100rpx;
background: #eee;
border-radius: 2px;
border: 1px solid #eee;
}
.number-content .number-submit
{
width: 80rpx;
font-weight: bold;
}
.number-content input {
width: 30px;
background: #fff;
border-radius: 0px;
}
.number-content .number-submit,
.number-content input
{
padding: 0;
vertical-align: middle;
height: 60rpx;
line-height: 60rpx;
}
/**
* 空购物车
*/
.no-data-box {
padding: 30% 0 0 0;
}
.no-data-box image {
width: 160rpx;
margin-bottom: 20rpx;
}
.no-data-box .no-data-tips {
font-size: 28rpx;
color: #a6a6a6;
}
.no-data-box navigator {
width: 220rpx;
margin: 0 auto;
}
.no-data-box button {
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
margin-top: 30rpx;
}
/**
* 操作导航
*/
.buy-nav {
position: fixed;
left: 0;
bottom: 0;
}
.buy-nav, .nav-base, .nav-submit button {
height: 100rpx;
}
.nav-base, .nav-submit button {
line-height: 100rpx;
}
.nav-base {
width: calc(75% - 20rpx);
padding: 0 10rpx;
}
.nav-submit {
width: 25%;
}
.nav-submit button {
border-radius: 0;
}
.page {
padding-bottom: 120rpx;
}
.selected .icon {
width: 50rpx;
height: 50rpx !important;
margin: 0 10rpx;
vertical-align: middle;
}
.buy-nav .price {
width: calc(100% - 140rpx);
}
.buy-nav .sales-price {
max-width: calc(100% - 40px);
}
\ No newline at end of file
<template name="bottom_line">
<view qq:if="{{(status || false)}}" class="data-bottom-line">
<view class="left fl"></view>
<view class="msg fl">我是有底线的</view>
<view class="right fr"></view>
</view>
</template>
\ No newline at end of file
<template name="copyright">
<view class="copyright">
<view class="text">Powered by ShopXO v1.7.0</view>
</view>
</template>
\ No newline at end of file
<template name="nodata">
<!-- 1 加载中 -->
<view qq:if="{{status == 1}}" class="no-data-loding tc">
<text>加载中...</text>
</view>
<!-- 2 处理错误 -->
<view wx:elif="{{status == 2}}" class="no-data-box tc">
<image src="/images/error.png" mode="widthFix" />
<view class="no-data-tips">{{msg || '处理错误'}}</view>
</view>
<!-- 0 默认没有数据 -->
<view wx:elif="{{status == 0}}" class="no-data-box tc">
<image src="/images/empty.png" mode="widthFix" />
<view class="no-data-tips">{{msg || '没有相关数据'}}</view>
</view>
</template>
\ No newline at end of file
const app = getApp();
Page({
data: {
data_bottom_line_status: false,
data_list_loding_status: 1,
data_list_loding_msg: '',
data_list: [],
data_base: null,
},
onLoad(params) {
this.init();
},
onShow() {
qq.setNavigationBarTitle({ title: app.data.common_pages_title.coupon });
},
init() {
// 获取数据
this.get_data_list();
},
// 获取数据
get_data_list() {
var self = this;
qq.showLoading({ title: "加载中..." });
if (self.data.data_list.length <= 0)
{
self.setData({
data_list_loding_status: 1
});
}
qq.request({
url: app.get_request_url("index", "coupon"),
method: "POST",
data: {},
dataType: "json",
success: res => {
qq.hideLoading();
qq.stopPullDownRefresh();
if (res.data.code == 0) {
var data = res.data.data;
var status = ((data.data || []).length > 0);
this.setData({
data_base: data.base || null,
data_list: data.data || [],
data_list_loding_msg: '',
data_list_loding_status: status ? 3 : 0,
data_bottom_line_status: status,
});
// 导航名称
if ((data.base || null) != null && (data.base.application_name || null) != null)
{
qq.setNavigationBarTitle({ title: data.base.application_name });
}
} else {
self.setData({
data_bottom_line_status: false,
data_list_loding_status: 2,
data_list_loding_msg: res.data.msg,
});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.hideLoading();
qq.stopPullDownRefresh();
self.setData({
data_bottom_line_status: false,
data_list_loding_status: 2,
data_list_loding_msg: '服务器请求出错',
});
app.showToast("服务器请求出错");
}
});
},
// 优惠劵领取事件
coupon_receive_event(e) {
var user = app.get_user_cache_info(this, "coupon_receive_event");
// 用户未绑定用户则转到登录页面
if (app.user_is_need_login(user)) {
qq.redirectTo({
url: "/pages/login/login?event_callback=coupon_receive_event"
});
return false;
} else {
var self = this;
var index = e.currentTarget.dataset.index;
var value = e.currentTarget.dataset.value;
var temp_list = this.data.data_list;
if (temp_list[index]['is_operable'] != 0) {
qq.showLoading({ title: "处理中..." });
qq.request({
url: app.get_request_url("receive", "coupon"),
method: "POST",
data: { "coupon_id": value },
dataType: "json",
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: res => {
qq.hideLoading();
if (res.data.code == 0) {
app.showToast(res.data.msg, "success");
if (self.data.data_base != null && self.data.data_base.is_repeat_receive != 1)
{
temp_list[index]['is_operable'] = 0;
temp_list[index]['is_operable_name'] = '已领取';
self.setData({ data_list: temp_list });
}
} else {
app.showToast(res.data.msg);
}
},
fail: () => {
qq.hideLoading();
app.showToast("服务器请求出错");
}
});
}
}
},
// 下拉刷新
onPullDownRefresh() {
this.get_data_list();
},
});
{
"enablePullDownRefresh": true
}
\ No newline at end of file
<image qq:if="{{(data_base || null) != null && (data_base.banner_images || null) != null}}" class="banner wh-auto dis-block" src="{{data_base.banner_images}}" mode="widthFix" />
<!-- 优惠劵列表 -->
<view qq:if="{{data_list.length > 0}}" class="coupon-container">
<block qq:for="{{data_list}}" qq:key="item">
<view class="item spacing-mt bg-white {{item.is_operable == 0 ? 'item-disabled' : ''}}" style="border:1px solid {{item.bg_color_value}};">
<view class="v-left fl">
<view class="base single-text" style="color:{{item.bg_color_value}};">
<text class="symbol"></text>
<text class="price">{{item.discount_value}}</text>
<text class="unit">{{item.type_unit}}</text>
<text qq:if="{{(item.desc || null) != null}}" class="desc cr-888">{{item.desc}}</text>
</view>
<view qq:if="{{(item.use_limit_type_name || null) != null}}" class="base-tips cr-666 single-text">{{item.use_limit_type_name}}</view>
</view>
<view class="v-right fr" bindtap="coupon_receive_event" data-index="{{index}}" data-value="{{item.id}}" style="background:{{item.bg_color_value}};">
<text class="circle"></text>
<text>{{item.is_operable_name}}</text>
</view>
</view>
</block>
</view>
<view qq:if="{{data_list_loding_status != 3}}">
<import src="/pages/common/nodata.wxml" />
<template is="nodata" data="{{status: data_list_loding_status, msg: data_list_loding_msg}}"></template>
</view>
<import src="/pages/common/bottom_line.wxml" />
<template is="bottom_line" data="{{status: data_bottom_line_status}}"></template>
\ No newline at end of file
const app = getApp();
Page({
data: {
goods_attribute: [],
},
onLoad(params) {
if((params.data || null) == null)
{
qq.alert({
title: '温馨提示',
content: '属性数据有误',
buttonText: '返回',
success: () => {
qq.navigateBack();
}
});
} else {
this.setData({goods_attribute: JSON.parse(params.data)});
}
},
onShow() {
qq.setNavigationBarTitle({title: app.data.common_pages_title.goods_attribute});
},
});
{
"enablePullDownRefresh": false
}
\ No newline at end of file
<view qq:if="{{goods_attribute.length > 0}}" class="goods-attribute bg-white">
<view qq:for="{{goods_attribute}}" class="item br-b oh">
<view class="title fl br-r">{{item.name}}</view>
<view class="content cr-888 fl">
<text qq:for="{{item.find}}" qq:for-index="keys" qq:for-item="items">
<text>{{items.name}}</text>
<text qq:if="{{keys < item.find.length-1}}"> , </text>
</text>
</view>
</view>
</view>
<view class="nav-back tc wh-auto">
<navigator url="/pages/goods-detail/goods-detail" open-type="navigateBack" hover-class="none">
<button type="default" size="mini" class="cr-888" hover-class="none">返回</button>
</navigator>
</view>
.goods-attribute {
padding: 0 10rpx;
}
.goods-attribute .item {
padding: 20rpx 0;
}
.goods-attribute .item .title {
width: 25%;
}
.goods-attribute .item .content {
width: calc(75% - 30rpx);
margin-left: 20rpx;
}
.goods-attribute .item view {
line-height: 46rpx;
}
\ No newline at end of file
const app = getApp();
Page({
data: {
tab_active: 0,
tab_active_text_color: '#d2364c',
tab_active_line_color: '#d2364c',
data_list_loding_status: 1,
data_bottom_line_status: false,
data_list: [],
data_content: [],
},
onShow() {
qq.setNavigationBarTitle({title: app.data.common_pages_title.goods_category});
this.init();
},
// 获取数据
init() {
// 加载loding
this.setData({
data_list_loding_status: 1,
});
// 加载loding
qq.request({
url: app.get_request_url("category", "goods"),
method: "POST",
data: {},
dataType: "json",
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: res => {
qq.stopPullDownRefresh();
if (res.data.code == 0) {
var data = res.data.data;
var data_content = [];
if (data.length > 0)
{
data[0]['active'] = 'nav-active';
data_content = data[0]['items'];
}
this.setData({
data_list: data,
data_content: data_content,
data_list_loding_status: data.length == 0 ? 0 : 3,
data_bottom_line_status: true,
});
} else {
this.setData({
data_list_loding_status: 0,
data_bottom_line_status: true,
});
app.showToast(res.data.msg);
}
},
fail: () => {
qq.stopPullDownRefresh();
this.setData({
data_list_loding_status: 2,
data_bottom_line_status: true,
});
app.showToast("服务器请求出错");
}
});
},
// 下拉刷新
onPullDownRefresh() {
this.init();
},
// 导航事件
nav_event(e) {
var index = e.currentTarget.dataset.index;
var temp_data = this.data.data_list;
for(var i in temp_data)
{
temp_data[i]['active'] = (index == i) ? 'nav-active' : '';
}
this.setData({
data_list: temp_data,
data_content: temp_data[index]['items'],
});
},
// 事件
category_event(e) {
qq.navigateTo({ url: '/pages/goods-search/goods-search?category_id=' + e.currentTarget.dataset.value});
}
});
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册