头条小程序初始化

This commit is contained in:
Devil
2019-10-24 23:23:17 +08:00
parent c862723248
commit ffa0b25d23
191 changed files with 10856 additions and 0 deletions

519
public/appmini/old/toutiao/app.js Executable file
View File

@ -0,0 +1,519 @@
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();
// 缓存启动参数
tt.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 = tt.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 = tt.getSystemInfoSync();
tt.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 = tt.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) {
tt.showLoading({ title: "授权中..." });
var self = this;
tt.checkSession({
success: function () {
var openid = tt.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;
tt.login({
success: (res) => {
if (res.code) {
tt.request({
url: self.get_request_url('wechatuserauth', 'user'),
method: 'POST',
data: { authcode: res.code },
dataType: 'json',
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: (res) => {
if (res.data.code == 0) {
tt.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 {
tt.hideLoading();
self.showToast(res.data.msg);
}
},
fail: () => {
tt.hideLoading();
self.showToast('服务器请求出错');
},
});
}
},
fail: (e) => {
tt.hideLoading();
self.showToast('授权失败');
}
});
},
/**
* 获取用户授权信息
* object 回调操作对象
* method 回调操作对象的函数
* openid 用户openid
* auth_data 授权数据
*/
get_user_login_info(object, method, openid, auth_data) {
// 邀请人参数
var params = tt.getStorageSync(this.data.cache_launch_info_key) || null;
var referrer = (params == null) ? 0 : (params.referrer || 0);
// 远程解密数据
var self = this;
tt.request({
url: self.get_request_url('wechatuserinfo', '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) => {
tt.hideLoading();
if (res.data.code == 0) {
tt.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: () => {
tt.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:
tt.navigateTo({ url: '/pages/web-view/web-view?url=' + encodeURIComponent(value) });
break;
// 内部页面
case 1:
if (this.is_tabbar_pages(value))
{
tt.switchTab({ url: value });
} else {
tt.navigateTo({ url: value });
}
break;
// 跳转到外部小程序
case 2:
tt.navigateToMiniProgram({ appId: value });
break;
// 跳转到地图查看位置
case 3:
var values = value.split('|');
if (values.length != 4) {
this.showToast('事件值格式有误');
return false;
}
tt.openLocation({
name: values[0],
address: values[1],
longitude: values[2],
latitude: values[3],
});
break;
// 拨打电话
case 4:
tt.makePhoneCall({ phoneNumber: value });
break;
}
}
},
/**
* 默认弱提示方法
* msg [string] 提示信息
* status [string] 状态 默认error [正确success, 错误error]
*/
showToast(msg, status)
{
if ((status || 'error') == 'success')
{
tt.showToast({
title: msg,
duration: 3000
});
} else {
tt.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;
}
});

View File

@ -0,0 +1,67 @@
{
"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": "我的"
}
]
}
}

View File

@ -0,0 +1,473 @@
/* 框架样式覆盖 */
.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;
}

View File

@ -0,0 +1,23 @@
// components/badge.js
Component({
/**
* 组件的属性列表
*/
properties: {
propNumber: Number,
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

View File

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -0,0 +1,5 @@
<view tt: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>

View File

@ -0,0 +1,26 @@
.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;
}

View File

@ -0,0 +1,12 @@
const app = getApp();
Component({
data: {},
properties: {
propData: Array
},
methods: {
navigation_event(e) {
app.operation_event(e);
},
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,10 @@
<view tt:if="{{propData.length > 0}}">
<view class="data-list">
<view class="items" tt:for="{{propData}}" tt: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>

View File

@ -0,0 +1,32 @@
.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%;
}

View File

@ -0,0 +1,30 @@
// 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', {}, {});
}
}
})

View File

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

View File

@ -0,0 +1,6 @@
<view class="am-popup {{propClassname || ''}} {{(propShow || false) ? 'am-popup-show' : ''}} {{ (propAnimation || true) ? 'animation': '' }}" disable-scroll="{{propDisablescroll || true}}">
<view class="am-popup-mask" tt:if="{{propMask || true}}" bindtap="onMaskTap"></view>
<view class="am-popup-content am-popup-{{propPosition || 'bottom'}}">
<slot></slot>
</view>
</view>

View File

@ -0,0 +1,60 @@
.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;
}

View File

@ -0,0 +1,18 @@
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);
},
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,14 @@
<swiper
indicator-dots="{{propData.length > 0}}"
indicator-color="{{indicator_color}}"
indicator-active-color="{{indicator_active_color}}"
autoplay="{{propData.length > 0}}"
circular="{{circular}}"
class="banner"
tt:if="{{propData.length > 0}}">
<block tt:for="{{propData}}" tt: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>

View File

@ -0,0 +1,10 @@
.banner {
background: #fff;
margin-bottom: 20rpx;
}
.banner image {
min-width: 100%;
}
.banner, .banner image {
height: 320rpx !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,77 @@
const app = getApp();
Page({
data: {
form_submit_loading: false,
},
onLoad() {},
onShow() {
tt.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)) {
tt.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))
{
tt.showLoading({title: '提交中...'});
this.setData({form_submit_loading: true});
// 网络请求
tt.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) => {
tt.hideLoading();
if(res.data.code == 0)
{
app.showToast(res.data.msg, "success");
setTimeout(function()
{
tt.redirectTo({
url: "/pages/user-answer-list/user-answer-list"
});
}, 2000);
} else {
this.setData({form_submit_loading: false});
app.showToast(res.data.msg);
}
},
fail: () => {
tt.hideLoading();
this.setData({form_submit_loading: false});
app.showToast('服务器请求出错');
}
});
}
},
});

View File

@ -0,0 +1,3 @@
{
"enablePullDownRefresh": false
}

View File

@ -0,0 +1,15 @@
<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>

View File

@ -0,0 +1,21 @@
.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;
}

View File

@ -0,0 +1,119 @@
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() {
tt.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
});
// 获取数据
tt.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 => {
tt.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: () => {
tt.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});
},
});

View File

@ -0,0 +1,3 @@
{
"enablePullDownRefresh": true
}

View File

@ -0,0 +1,22 @@
<scroll-view scroll-y="{{true}}" class="scroll-box" bindscrolltolower="scroll_lower" lower-threshold="30">
<view class="item bg-white spacing-mb" tt:if="{{data_list.length > 0}}" tt: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 tt: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 tt:if="{{data_list.length == 0}}">
<import src="/pages/common/nodata.ttml" />
<template is="nodata" data="{{status: data_list_loding_status}}"></template>
</view>
<import src="/pages/common/bottom_line.ttml" />
<template is="bottom_line" data="{{status: data_bottom_line_status}}"></template>
</scroll-view>

View File

@ -0,0 +1,22 @@
.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;
}

View File

@ -0,0 +1,266 @@
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)
{
tt.alert({
title: '温馨提示',
content: '订单信息有误',
buttonText: '确认',
success: () => {
tt.navigateBack();
},
});
} else {
this.setData({ params: JSON.parse(params.data)});
// 删除地址缓存
tt.removeStorageSync(app.data.cache_buy_user_address_select_key);
}
},
onShow() {
tt.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 = tt.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
tt.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;
tt.request({
url: app.get_request_url("index", "buy"),
method: "POST",
data: data,
dataType: "json",
success: res => {
tt.stopPullDownRefresh();
tt.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,
});
tt.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: () => {
tt.stopPullDownRefresh();
tt.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
tt.showLoading({title: '提交中...'});
this.setData({ buy_submit_disabled_status: true });
tt.request({
url: app.get_request_url("add", "buy"),
method: "POST",
data: data,
dataType: "json",
success: res => {
tt.hideLoading();
if (res.data.code == 0) {
if (res.data.data.order.status == 1) {
tt.redirectTo({
url: '/pages/user-order/user-order?is_pay=1&order_id=' + res.data.data.order.id
});
} else {
tt.redirectTo({url: '/pages/user-order/user-order'});
}
} else {
app.showToast(res.data.msg);
this.setData({ buy_submit_disabled_status: false });
}
},
fail: () => {
tt.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();
},
});

View File

@ -0,0 +1,6 @@
{
"enablePullDownRefresh": true,
"usingComponents": {
"component-popup": "/components/popup/popup"
}
}

View File

@ -0,0 +1,125 @@
<view tt: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 tt: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 tt: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 tt:for="{{goods_list}}" tt: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 tt:if="{{item.spec != null}}">
<view class="goods-spec cr-888" tt:for="{{item.spec}}" tt:key="key" tt:for-item="spec">{{spec.type}}:{{spec.value}}
</view>
</block>
</view>
<view class="oh goods-price">
<text class="sales-price">¥{{item.price}}
</text>
<text tt: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 tt:if="{{!popup_plugins_coupon_status}}" bindinput="bind_user_note_event" value="{{user_note_value}}" maxlength="60" placeholder="留言" class="wh-auto" />
<view tt:if="{{popup_plugins_coupon_status}}" class="cr-888">{{user_note_value || '留言'}}</view>
</view>
<!-- 优惠劵 -->
<view tt: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 tt:if="{{extension_data.length > 0}}" class="extension-list spacing-mb">
<view tt:for="{{extension_data}}" tt:key="key" class="item oh">
<text class="cr-666 fl">{{item.name}}
</text>
<text class="text-tips fr">{{item.tips}}
</text>
</view>
</view>
<!-- 支付方式 -->
<view tt:if="{{payment_list.length > 0 && common_order_is_booking != 1}}" class="payment-list bg-white oh">
<view class="item tc fl" tt:for="{{payment_list}}" tt:key="key">
<view class="item-content br {{(item.selected || '')}}" data-value="{{item.id}}" bindtap="payment_event">
<image tt: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 tt:if="{{goods.length == 0}}">
<import src="/pages/common/nodata.ttml" />
<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 tt: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 tt:for="{{plugins_coupon_data.coupon_list}}" tt: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 tt:if="{{(item.coupon.desc || null) != null}}" class="desc cr-888">{{item.coupon.desc}}</text>
</view>
<view tt: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>

View File

@ -0,0 +1,166 @@
.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;
}

View File

@ -0,0 +1,335 @@
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() {
tt.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)) {
tt.showModal({
title: '温馨提示',
content: msg,
confirmText: '确认',
cancelText: '暂不',
success: (result) => {
if (result.confirm) {
tt.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,
});
tt.request({
url: app.get_request_url("index", "cart"),
method: "POST",
data: {},
dataType: "json",
success: res => {
tt.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: () => {
tt.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;
}
// 更新数据库
tt.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 => {
tt.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) {
tt.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})
tt.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) {
tt.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(',')
};
tt.navigateTo({
url: '/pages/buy/buy?data=' + JSON.stringify(data)
});
}
});

View File

@ -0,0 +1,5 @@
{
"enablePullDownRefresh": true,
"usingComponents": {
}
}

View File

@ -0,0 +1,75 @@
<view tt:if="{{data_list.length > 0}}" class="page">
<view tt:for="{{data_list}}" tt: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 tt:if="{{item.spec != null}}">
<view class="goods-attribute cr-888" tt:for="{{item.spec}}" tt:key="key" tt: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 tt:if="{{item.original_price > 0}}" class="original-price">¥{{item.original_price}}</text>
<text class="buy-number cr-888">x{{item.stock}}</text>
<!-- 错误 -->
<text tt: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 tt: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 tt: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 tt: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 tt:if="{{data_list.length == 0 && data_list_loding_status != 0}}">
<import src="/pages/common/nodata.ttml" />
<template is="nodata" data="{{status: data_list_loding_status, msg: data_list_loding_msg}}"></template>
</view>

View File

@ -0,0 +1,142 @@
/**
* 商品列表
*/
.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);
}

View File

@ -0,0 +1,7 @@
<template name="bottom_line">
<view tt:if="{{(status || false)}}" class="data-bottom-line">
<view class="left fl"></view>
<view class="msg fl">我是有底线的</view>
<view class="right fr"></view>
</view>
</template>

View File

@ -0,0 +1,5 @@
<template name="copyright">
<view class="copyright">
<view class="text">Powered by ShopXO v1.7.0</view>
</view>
</template>

View File

@ -0,0 +1,18 @@
<template name="nodata">
<!-- 1 加载中 -->
<view tt: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>

View File

@ -0,0 +1,131 @@
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() {
tt.setNavigationBarTitle({ title: app.data.common_pages_title.coupon });
},
init() {
// 获取数据
this.get_data_list();
},
// 获取数据
get_data_list() {
var self = this;
tt.showLoading({ title: "加载中..." });
if (self.data.data_list.length <= 0)
{
self.setData({
data_list_loding_status: 1
});
}
tt.request({
url: app.get_request_url("index", "coupon"),
method: "POST",
data: {},
dataType: "json",
success: res => {
tt.hideLoading();
tt.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)
{
tt.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: () => {
tt.hideLoading();
tt.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)) {
tt.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) {
tt.showLoading({ title: "处理中..." });
tt.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 => {
tt.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: () => {
tt.hideLoading();
app.showToast("服务器请求出错");
}
});
}
}
},
// 下拉刷新
onPullDownRefresh() {
this.get_data_list();
},
});

View File

@ -0,0 +1,3 @@
{
"enablePullDownRefresh": true
}

View File

@ -0,0 +1,30 @@
<image tt: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 tt:if="{{data_list.length > 0}}" class="coupon-container">
<block tt:for="{{data_list}}" tt: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 tt:if="{{(item.desc || null) != null}}" class="desc cr-888">{{item.desc}}</text>
</view>
<view tt: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 tt:if="{{data_list_loding_status != 3}}">
<import src="/pages/common/nodata.ttml" />
<template is="nodata" data="{{status: data_list_loding_status, msg: data_list_loding_msg}}"></template>
</view>
<import src="/pages/common/bottom_line.ttml" />
<template is="bottom_line" data="{{status: data_bottom_line_status}}"></template>

View File

@ -0,0 +1,25 @@
const app = getApp();
Page({
data: {
goods_attribute: [],
},
onLoad(params) {
if((params.data || null) == null)
{
tt.alert({
title: '温馨提示',
content: '属性数据有误',
buttonText: '返回',
success: () => {
tt.navigateBack();
}
});
} else {
this.setData({goods_attribute: JSON.parse(params.data)});
}
},
onShow() {
tt.setNavigationBarTitle({title: app.data.common_pages_title.goods_attribute});
},
});

View File

@ -0,0 +1,3 @@
{
"enablePullDownRefresh": false
}

View File

@ -0,0 +1,17 @@
<view tt:if="{{goods_attribute.length > 0}}" class="goods-attribute bg-white">
<view tt:for="{{goods_attribute}}" class="item br-b oh">
<view class="title fl br-r">{{item.name}}</view>
<view class="content cr-888 fl">
<text tt:for="{{item.find}}" tt:for-index="keys" tt:for-item="items">
<text>{{items.name}}</text>
<text tt: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>

View File

@ -0,0 +1,16 @@
.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;
}

View File

@ -0,0 +1,92 @@
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() {
tt.setNavigationBarTitle({title: app.data.common_pages_title.goods_category});
this.init();
},
// 获取数据
init() {
// 加载loding
this.setData({
data_list_loding_status: 1,
});
// 加载loding
tt.request({
url: app.get_request_url("category", "goods"),
method: "POST",
data: {},
dataType: "json",
header: { 'content-type': 'application/x-www-form-urlencoded' },
success: res => {
tt.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: () => {
tt.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) {
tt.navigateTo({ url: '/pages/goods-search/goods-search?category_id=' + e.currentTarget.dataset.value});
}
});

View File

@ -0,0 +1,4 @@
{
"usingComponents": {
}
}

View File

@ -0,0 +1,23 @@
<view class='left-nav'>
<block tt:for="{{data_list}}" tt:key="key">
<view class='items {{item.active || ""}}' data-index="{{index}}" bindtap='nav_event'>
<text>{{item.name}}</text>
</view>
</block>
</view>
<view class='right-content bg-white'>
<block tt:if="{{data_content.length > 0}}">
<block tt:for="{{data_content}}" tt:key="keys" tt:for-item="v">
<view class="content-items" data-value="{{v.id}}" bindtap="category_event">
<image tt:if="{{(v.icon || null) != null}}" src="{{v.icon}}" mode="aspectFit" class="icon" />
<view class="text single-text">{{v.name}}</view>
</view>
</block>
</block>
</view>
<view tt:if="{{data_list.length == 0 && data_list_loding_status != 0}}">
<import src="/pages/common/nodata.ttml" />
<template is="nodata" data="{{status: data_list_loding_status}}">
</template>
</view>

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