Commit 7645b796 authored by wanghuihui's avatar wanghuihui

初始化项目

parent bf31901d
Pipeline #97 failed with stages
var util = require('./utils/util.js');
var api = require('./config/api.js');
var user = require('./utils/user.js');
import touch from './utils/touch.js'
App({
onLaunch: function() {
const updateManager = wx.getUpdateManager();
wx.getUpdateManager().onUpdateReady(function() {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
}
}
})
})
},
onShow: function(options) {
user.checkLogin().then(res => {
this.globalData.hasLogin = true;
}).catch(() => {
this.globalData.hasLogin = false;
});
},
globalData: {
hasLogin: false
},
touch: new touch()
})
\ No newline at end of file
{
"pages": [
"pages/index/index",
"pages/index2/index2",
"pages/search/search",
"pages/hotGoods/hotGoods",
"pages/brand/brand",
"pages/cart/cart",
"pages/ucenter/index/index",
"pages/topicCommentPost/topicCommentPost",
"pages/commentPost/commentPost",
"pages/comment/comment",
"pages/groupon/grouponDetail/grouponDetail",
"pages/about/about",
"pages/auth/register/register",
"pages/auth/accountLogin/accountLogin",
"pages/auth/reset/reset",
"pages/auth/login/login",
"pages/brandDetail/brandDetail",
"pages/topicComment/topicComment",
"pages/topic/topic",
"pages/topicDetail/topicDetail",
"pages/groupon/myGroupon/myGroupon",
"pages/ucenter/orderDetail/orderDetail",
"pages/ucenter/footprint/footprint",
"pages/ucenter/feedback/feedback",
"pages/ucenter/collect/collect",
"pages/payResult/payResult",
"pages/category/category",
"pages/goods/goods",
"pages/groupon/grouponList/grouponList",
"pages/coupon/coupon",
"pages/newGoods/newGoods",
"pages/catalog/catalog",
"pages/ucenter/couponSelect/couponSelect",
"pages/ucenter/order/order",
"pages/ucenter/couponList/couponList",
"pages/ucenter/addressAdd/addressAdd",
"pages/ucenter/address/address",
"pages/ucenter/setUp/setUp",
"pages/ucenter/nickName/nickName",
"pages/ucenter/avatarCropper/avatarCropper",
"pages/checkout/checkout",
"pages/activity/activity"
],
"window": {
"navigationBarBackgroundColor": "#FFFFFF",
"navigationBarTitleText": "戈友商城",
"enablePullDownRefresh": true,
"navigationBarTextStyle": "black",
"backgroundColor": "#FFFFFF",
"backgroundTextStyle": "dark"
},
"tabBar": {
"backgroundColor": "#ffffff",
"borderStyle": "black",
"selectedColor": "#E31436",
"color": "#666",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "static/images/home.png",
"selectedIconPath": "static/images/home@selected.png",
"text": "首页"
},
{
"pagePath": "pages/catalog/catalog",
"iconPath": "static/images/category.png",
"selectedIconPath": "static/images/category@selected.png",
"text": "分类"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "static/images/cart.png",
"selectedIconPath": "static/images/cart@selected.png",
"text": "购物车"
},
{
"pagePath": "pages/ucenter/index/index",
"iconPath": "static/images/my.png",
"selectedIconPath": "static/images/my@selected.png",
"text": "个人"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true,
"sitemapLocation": "sitemap.json"
}
\ No newline at end of file
/**app.wxss**/
.container {
box-sizing: border-box;
background-color: #f4f4f4;
font-family: PingFangSC-Light, helvetica, 'Heiti SC';
}
view, image, text, navigator {
box-sizing: border-box;
padding: 0;
margin: 0;
}
view, text {
font-family: PingFangSC-Light, helvetica, 'Heiti SC';
font-size: 29rpx;
color: #333;
}
/**
* xz-cropper 头像裁切
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.WeCropper = factory());
}(this, (function () { 'use strict';
var device = void 0;
var TOUCH_STATE = ['touchstarted', 'touchmoved', 'touchended'];
function firstLetterUpper (str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
function setTouchState (instance) {
var arg = [], len = arguments.length - 1;
while ( len-- > 0 ) arg[ len ] = arguments[ len + 1 ];
TOUCH_STATE.forEach(function (key, i) {
if (arg[i] !== undefined) {
instance[key] = arg[i];
}
});
}
function validator (instance, o) {
Object.defineProperties(instance, o);
}
function getDevice () {
if (!device) {
device = wx.getSystemInfoSync();
}
return device
}
var tmp = {};
var ref = getDevice();
var pixelRatio = ref.pixelRatio;
var DEFAULT = {
id: {
default: 'cropper',
get: function get () {
return tmp.id
},
set: function set (value) {
if (typeof (value) !== 'string') {
console.error(("id:" + value + " is invalid"));
}
tmp.id = value;
}
},
width: {
default: 750,
get: function get () {
return tmp.width
},
set: function set (value) {
if (typeof (value) !== 'number') {
console.error(("width:" + value + " is invalid"));
}
tmp.width = value;
}
},
height: {
default: 750,
get: function get () {
return tmp.height
},
set: function set (value) {
if (typeof (value) !== 'number') {
console.error(("height:" + value + " is invalid"));
}
tmp.height = value;
}
},
pixelRatio: {
default: pixelRatio,
get: function get () {
return tmp.pixelRatio
},
set: function set (value) {
if (typeof (value) !== 'number') {
console.error(("pixelRatio:" + value + " is invalid"));
}
tmp.pixelRatio = value;
}
},
scale: {
default: 2.5,
get: function get () {
return tmp.scale
},
set: function set (value) {
if (typeof (value) !== 'number') {
console.error(("scale:" + value + " is invalid"));
}
tmp.scale = value;
}
},
zoom: {
default: 5,
get: function get () {
return tmp.zoom
},
set: function set (value) {
if (typeof (value) !== 'number') {
console.error(("zoom:" + value + " is invalid"));
} else if (value < 0 || value > 10) {
console.error("zoom should be ranged in 0 ~ 10");
}
tmp.zoom = value;
}
},
src: {
default: '',
get: function get () {
return tmp.src
},
set: function set (value) {
if (typeof (value) !== 'string') {
console.error(("src:" + value + " is invalid"));
}
tmp.src = value;
}
},
cut: {
default: {},
get: function get () {
return tmp.cut
},
set: function set (value) {
if (typeof (value) !== 'object') {
console.error(("cut:" + value + " is invalid"));
}
tmp.cut = value;
}
},
boundStyle: {
default: {},
get: function get () {
return tmp.boundStyle
},
set: function set (value) {
if (typeof (value) !== 'object') {
console.error(("boundStyle:" + value + " is invalid"));
}
tmp.boundStyle = value;
}
},
onReady: {
default: null,
get: function get () {
return tmp.ready
},
set: function set (value) {
tmp.ready = value;
}
},
onBeforeImageLoad: {
default: null,
get: function get () {
return tmp.beforeImageLoad
},
set: function set (value) {
tmp.beforeImageLoad = value;
}
},
onImageLoad: {
default: null,
get: function get () {
return tmp.imageLoad
},
set: function set (value) {
tmp.imageLoad = value;
}
},
onBeforeDraw: {
default: null,
get: function get () {
return tmp.beforeDraw
},
set: function set (value) {
tmp.beforeDraw = value;
}
}
};
var ref$1 = getDevice();
var windowWidth = ref$1.windowWidth;
function prepare () {
var self = this;
// v1.4.0 版本中将不再自动绑定we-cropper实例
self.attachPage = function () {
var pages = getCurrentPages();
// 获取到当前page上下文
var pageContext = pages[pages.length - 1];
// 把this依附在Page上下文的wecropper属性上,便于在page钩子函数中访问
Object.defineProperty(pageContext, 'wecropper', {
get: function get () {
console.warn(
'Instance will not be automatically bound to the page after v1.4.0\n\n' +
'Please use a custom instance name instead\n\n' +
'Example: \n' +
'this.mycropper = new WeCropper(options)\n\n' +
'// ...\n' +
'this.mycropper.getCropperImage()'
);
return self
}
});
};
self.createCtx = function () {
var id = self.id;
var targetId = self.targetId;
if (id) {
self.ctx = self.ctx || wx.createCanvasContext(id);
self.targetCtx = self.targetCtx || wx.createCanvasContext(targetId);
} else {
console.error("constructor: create canvas context failed, 'id' must be valuable");
}
};
self.deviceRadio = windowWidth / 750;
}
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var tools = createCommonjsModule(function (module, exports) {
/**
* String type check
*/
exports.isStr = function (v) { return typeof v === 'string'; };
/**
* Number type check
*/
exports.isNum = function (v) { return typeof v === 'number'; };
/**
* Array type check
*/
exports.isArr = Array.isArray;
/**
* undefined type check
*/
exports.isUndef = function (v) { return v === undefined; };
exports.isTrue = function (v) { return v === true; };
exports.isFalse = function (v) { return v === false; };
/**
* Function type check
*/
exports.isFunc = function (v) { return typeof v === 'function'; };
/**
* Quick object check - this is primarily used to tell
* Objects from primitive values when we know the value
* is a JSON-compliant type.
*/
exports.isObj = exports.isObject = function (obj) {
return obj !== null && typeof obj === 'object'
};
/**
* Strict object type check. Only returns true
* for plain JavaScript objects.
*/
var _toString = Object.prototype.toString;
exports.isPlainObject = function (obj) {
return _toString.call(obj) === '[object Object]'
};
/**
* Check whether the object has the property.
*/
var hasOwnProperty = Object.prototype.hasOwnProperty;
exports.hasOwn = function (obj, key) {
return hasOwnProperty.call(obj, key)
};
/**
* Perform no operation.
* Stubbing args to make Flow happy without leaving useless transpiled code
*/
exports.noop = function (a, b, c) {};
/**
* Check if val is a valid array index.
*/
exports.isValidArrayIndex = function (val) {
var n = parseFloat(String(val));
return n >= 0 && Math.floor(n) === n && isFinite(val)
};
});
var tools_7 = tools.isFunc;
var tools_10 = tools.isPlainObject;
var EVENT_TYPE = ['ready', 'beforeImageLoad', 'beforeDraw', 'imageLoad'];
function observer () {
var self = this;
self.on = function (event, fn) {
if (EVENT_TYPE.indexOf(event) > -1) {
if (tools_7(fn)) {
event === 'ready'
? fn(self)
: self[("on" + (firstLetterUpper(event)))] = fn;
}
} else {
console.error(("event: " + event + " is invalid"));
}
return self
};
}
function wxPromise (fn) {
return function (obj) {
if ( obj === void 0 ) obj = {};
return new Promise(function (resolve, reject) {
obj.success = function (res) {
resolve(res);
};
obj.fail = function (err) {
reject(err);
};
fn(obj);
})
}
}
function draw (ctx, reserve) {
if ( reserve === void 0 ) reserve = false;
return new Promise(function (resolve) {
ctx.draw(reserve, resolve);
})
}
var getImageInfo = wxPromise(wx.getImageInfo);
var canvasToTempFilePath = wxPromise(wx.canvasToTempFilePath);
var base64 = createCommonjsModule(function (module, exports) {
/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */
(function(root) {
// Detect free variables `exports`.
var freeExports = 'object' == 'object' && exports;
// Detect free variable `module`.
var freeModule = 'object' == 'object' && module &&
module.exports == freeExports && module;
// Detect free variable `global`, from Node.js or Browserified code, and use
// it as `root`.
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal;
if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {
root = freeGlobal;
}
/*--------------------------------------------------------------------------*/
var InvalidCharacterError = function(message) {
this.message = message;
};
InvalidCharacterError.prototype = new Error;
InvalidCharacterError.prototype.name = 'InvalidCharacterError';
var error = function(message) {
// Note: the error messages used throughout this file match those used by
// the native `atob`/`btoa` implementation in Chromium.
throw new InvalidCharacterError(message);
};
var TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// http://whatwg.org/html/common-microsyntaxes.html#space-character
var REGEX_SPACE_CHARACTERS = /[\t\n\f\r ]/g;
// `decode` is designed to be fully compatible with `atob` as described in the
// HTML Standard. http://whatwg.org/html/webappapis.html#dom-windowbase64-atob
// The optimized base64-decoding algorithm used is based on @atk’s excellent
// implementation. https://gist.github.com/atk/1020396
var decode = function(input) {
input = String(input)
.replace(REGEX_SPACE_CHARACTERS, '');
var length = input.length;
if (length % 4 == 0) {
input = input.replace(/==?$/, '');
length = input.length;
}
if (
length % 4 == 1 ||
// http://whatwg.org/C#alphanumeric-ascii-characters
/[^+a-zA-Z0-9/]/.test(input)
) {
error(
'Invalid character: the string to be decoded is not correctly encoded.'
);
}
var bitCounter = 0;
var bitStorage;
var buffer;
var output = '';
var position = -1;
while (++position < length) {
buffer = TABLE.indexOf(input.charAt(position));
bitStorage = bitCounter % 4 ? bitStorage * 64 + buffer : buffer;
// Unless this is the first of a group of 4 characters…
if (bitCounter++ % 4) {
// …convert the first 8 bits to a single ASCII character.
output += String.fromCharCode(
0xFF & bitStorage >> (-2 * bitCounter & 6)
);
}
}
return output;
};
// `encode` is designed to be fully compatible with `btoa` as described in the
// HTML Standard: http://whatwg.org/html/webappapis.html#dom-windowbase64-btoa
var encode = function(input) {
input = String(input);
if (/[^\0-\xFF]/.test(input)) {
// Note: no need to special-case astral symbols here, as surrogates are
// matched, and the input is supposed to only contain ASCII anyway.
error(
'The string to be encoded contains characters outside of the ' +
'Latin1 range.'
);
}
var padding = input.length % 3;
var output = '';
var position = -1;
var a;
var b;
var c;
var buffer;
// Make sure any padding is handled outside of the loop.
var length = input.length - padding;
while (++position < length) {
// Read three bytes, i.e. 24 bits.
a = input.charCodeAt(position) << 16;
b = input.charCodeAt(++position) << 8;
c = input.charCodeAt(++position);
buffer = a + b + c;
// Turn the 24 bits into four chunks of 6 bits each, and append the
// matching character for each of them to the output.
output += (
TABLE.charAt(buffer >> 18 & 0x3F) +
TABLE.charAt(buffer >> 12 & 0x3F) +
TABLE.charAt(buffer >> 6 & 0x3F) +
TABLE.charAt(buffer & 0x3F)
);
}
if (padding == 2) {
a = input.charCodeAt(position) << 8;
b = input.charCodeAt(++position);
buffer = a + b;
output += (
TABLE.charAt(buffer >> 10) +
TABLE.charAt((buffer >> 4) & 0x3F) +
TABLE.charAt((buffer << 2) & 0x3F) +
'='
);
} else if (padding == 1) {
buffer = input.charCodeAt(position);
output += (
TABLE.charAt(buffer >> 2) +
TABLE.charAt((buffer << 4) & 0x3F) +
'=='
);
}
return output;
};
var base64 = {
'encode': encode,
'decode': decode,
'version': '0.1.0'
};
// Some AMD build optimizers, like r.js, check for specific condition patterns
// like the following:
if (
typeof undefined == 'function' &&
typeof undefined.amd == 'object' &&
undefined.amd
) {
undefined(function() {
return base64;
});
} else if (freeExports && !freeExports.nodeType) {
if (freeModule) { // in Node.js or RingoJS v0.8.0+
freeModule.exports = base64;
} else { // in Narwhal or RingoJS v0.7.0-
for (var key in base64) {
base64.hasOwnProperty(key) && (freeExports[key] = base64[key]);
}
}
} else { // in Rhino or a web browser
root.base64 = base64;
}
}(commonjsGlobal));
});
function makeURI (strData, type) {
return 'data:' + type + ';base64,' + strData
}
function fixType (type) {
type = type.toLowerCase().replace(/jpg/i, 'jpeg');
var r = type.match(/png|jpeg|bmp|gif/)[0];
return 'image/' + r
}
function encodeData (data) {
var str = '';
if (typeof data === 'string') {
str = data;
} else {
for (var i = 0; i < data.length; i++) {
str += String.fromCharCode(data[i]);
}
}
return base64.encode(str)
}
/**
* 获取图像区域隐含的像素数据
* @param canvasId canvas标识
* @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
* @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
* @param width 将要被提取的图像数据矩形区域的宽度
* @param height 将要被提取的图像数据矩形区域的高度
* @param done 完成回调
*/
function getImageData (canvasId, x, y, width, height, done) {
wx.canvasGetImageData({
canvasId: canvasId,
x: x,
y: y,
width: width,
height: height,
success: function success (res) {
done(res);
},
fail: function fail (res) {
done(null);
console.error('canvasGetImageData error: ' + res);
}
});
}
/**
* 生成bmp格式图片
* 按照规则生成图片响应头和响应体
* @param oData 用来描述 canvas 区域隐含的像素数据 { data, width, height } = oData
* @returns {*} base64字符串
*/
function genBitmapImage (oData) {
//
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
//
var biWidth = oData.width;
var biHeight = oData.height;
var biSizeImage = biWidth * biHeight * 3;
var bfSize = biSizeImage + 54; // total header size = 54 bytes
//
// typedef struct tagBITMAPFILEHEADER {
// WORD bfType;
// DWORD bfSize;
// WORD bfReserved1;
// WORD bfReserved2;
// DWORD bfOffBits;
// } BITMAPFILEHEADER;
//
var BITMAPFILEHEADER = [
// WORD bfType -- The file type signature; must be "BM"
0x42, 0x4D,
// DWORD bfSize -- The size, in bytes, of the bitmap file
bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
// WORD bfReserved1 -- Reserved; must be zero
0, 0,
// WORD bfReserved2 -- Reserved; must be zero
0, 0,
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
54, 0, 0, 0
];
//
// typedef struct tagBITMAPINFOHEADER {
// DWORD biSize;
// LONG biWidth;
// LONG biHeight;
// WORD biPlanes;
// WORD biBitCount;
// DWORD biCompression;
// DWORD biSizeImage;
// LONG biXPelsPerMeter;
// LONG biYPelsPerMeter;
// DWORD biClrUsed;
// DWORD biClrImportant;
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
//
var BITMAPINFOHEADER = [
// DWORD biSize -- The number of bytes required by the structure
40, 0, 0, 0,
// LONG biWidth -- The width of the bitmap, in pixels
biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
// LONG biHeight -- The height of the bitmap, in pixels
biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
1, 0,
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
// has a maximum of 2^24 colors (16777216, Truecolor)
24, 0,
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
0, 0, 0, 0,
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
// LONG biXPelsPerMeter, unused
0, 0, 0, 0,
// LONG biYPelsPerMeter, unused
0, 0, 0, 0,
// DWORD biClrUsed, the number of color indexes of palette, unused
0, 0, 0, 0,
// DWORD biClrImportant, unused
0, 0, 0, 0
];
var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
var aImgData = oData.data;
var strPixelData = '';
var biWidth4 = biWidth << 2;
var y = biHeight;
var fromCharCode = String.fromCharCode;
do {
var iOffsetY = biWidth4 * (y - 1);
var strPixelRow = '';
for (var x = 0; x < biWidth; x++) {
var iOffsetX = x << 2;
strPixelRow += fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
fromCharCode(aImgData[iOffsetY + iOffsetX]);
}
for (var c = 0; c < iPadding; c++) {
strPixelRow += String.fromCharCode(0);
}
strPixelData += strPixelRow;
} while (--y)
var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
return strEncoded
}
/**
* 转换为图片base64
* @param canvasId canvas标识
* @param x 将要被提取的图像数据矩形区域的左上角 x 坐标
* @param y 将要被提取的图像数据矩形区域的左上角 y 坐标
* @param width 将要被提取的图像数据矩形区域的宽度
* @param height 将要被提取的图像数据矩形区域的高度
* @param type 转换图片类型
* @param done 完成回调
*/
function convertToImage (canvasId, x, y, width, height, type, done) {
if ( done === void 0 ) done = function () {};
if (type === undefined) { type = 'png'; }
type = fixType(type);
if (/bmp/.test(type)) {
getImageData(canvasId, x, y, width, height, function (data) {
var strData = genBitmapImage(data);
tools_7(done) && done(makeURI(strData, 'image/' + type));
});
} else {
console.error('暂不支持生成\'' + type + '\'类型的base64图片');
}
}
var CanvasToBase64 = {
convertToImage: convertToImage,
// convertToPNG: function (width, height, done) {
// return convertToImage(width, height, 'png', done)
// },
// convertToJPEG: function (width, height, done) {
// return convertToImage(width, height, 'jpeg', done)
// },
// convertToGIF: function (width, height, done) {
// return convertToImage(width, height, 'gif', done)
// },
convertToBMP: function (ref, done) {
if ( ref === void 0 ) ref = {};
var canvasId = ref.canvasId;
var x = ref.x;
var y = ref.y;
var width = ref.width;
var height = ref.height;
if ( done === void 0 ) done = function () {};
return convertToImage(canvasId, x, y, width, height, 'bmp', done)
}
};
function methods () {
var self = this;
var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
var boundHeight = self.height; // 裁剪框默认高度,即整个画布高度
var id = self.id;
var targetId = self.targetId;
var pixelRatio = self.pixelRatio;
var ref = self.cut;
var x = ref.x; if ( x === void 0 ) x = 0;
var y = ref.y; if ( y === void 0 ) y = 0;
var width = ref.width; if ( width === void 0 ) width = boundWidth;
var height = ref.height; if ( height === void 0 ) height = boundHeight;
self.updateCanvas = function (done) {
if (self.croperTarget) {
// 画布绘制图片
self.ctx.drawImage(
self.croperTarget,
self.imgLeft,
self.imgTop,
self.scaleWidth,
self.scaleHeight
);
}
tools_7(self.onBeforeDraw) && self.onBeforeDraw(self.ctx, self);
self.setBoundStyle(self.boundStyle); // 设置边界样式
self.ctx.draw(false, done);
return self
};
self.pushOrign = function (src) {
self.src = src;
tools_7(self.onBeforeImageLoad) && self.onBeforeImageLoad(self.ctx, self);
return getImageInfo({ src: src })
.then(function (res) {
var innerAspectRadio = res.width / res.height;
var customAspectRadio = width / height;
self.croperTarget = res.path;
if (innerAspectRadio < customAspectRadio) {
self.rectX = x;
self.baseWidth = width;
self.baseHeight = width / innerAspectRadio;
self.rectY = y - Math.abs((height - self.baseHeight) / 2);
} else {
self.rectY = y;
self.baseWidth = height * innerAspectRadio;
self.baseHeight = height;
self.rectX = x - Math.abs((width - self.baseWidth) / 2);
}
self.imgLeft = self.rectX;
self.imgTop = self.rectY;
self.scaleWidth = self.baseWidth;
self.scaleHeight = self.baseHeight;
self.update();
return new Promise(function (resolve) {
self.updateCanvas(resolve);
})
})
.then(function () {
tools_7(self.onImageLoad) && self.onImageLoad(self.ctx, self);
})
};
self.getCropperBase64 = function (done) {
if ( done === void 0 ) done = function () {};
CanvasToBase64.convertToBMP({
canvasId: id,
x: x,
y: y,
width: width,
height: height
}, done);
};
self.getCropperImage = function () {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
var customOptions = args[0];
var fn = args[args.length - 1];
var canvasOptions = {
canvasId: id,
x: x,
y: y,
width: width,
height: height
};
var task = function () { return Promise.resolve(); };
if (
tools_10(customOptions) &&
customOptions.original
) {
// original mode
task = function () {
self.targetCtx.drawImage(
self.croperTarget,
self.imgLeft * pixelRatio,
self.imgTop * pixelRatio,
self.scaleWidth * pixelRatio,
self.scaleHeight * pixelRatio
);
canvasOptions = {
canvasId: targetId,
x: x * pixelRatio,
y: y * pixelRatio,
width: width * pixelRatio,
height: height * pixelRatio
};
return draw(self.targetCtx)
};
}
return task()
.then(function () {
if (tools_10(customOptions)) {
canvasOptions = Object.assign({}, canvasOptions, customOptions);
}
return canvasToTempFilePath(canvasOptions)
})
.then(function (res) {
var tempFilePath = res.tempFilePath;
tools_7(fn) && fn.call(self, tempFilePath);
return tempFilePath
})
.catch(function () {
tools_7(fn) && fn.call(self, null);
})
};
}
/**
* 获取最新缩放值
* @param oldScale 上一次触摸结束后的缩放值
* @param oldDistance 上一次触摸结束后的双指距离
* @param zoom 缩放系数
* @param touch0 第一指touch对象
* @param touch1 第二指touch对象
* @returns {*}
*/
var getNewScale = function (oldScale, oldDistance, zoom, touch0, touch1) {
var xMove, yMove, newDistance;
// 计算二指最新距离
xMove = Math.round(touch1.x - touch0.x);
yMove = Math.round(touch1.y - touch0.y);
newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
return oldScale + 0.001 * zoom * (newDistance - oldDistance)
};
function update () {
var self = this;
if (!self.src) { return }
self.__oneTouchStart = function (touch) {
self.touchX0 = Math.round(touch.x);
self.touchY0 = Math.round(touch.y);
};
self.__oneTouchMove = function (touch) {
var xMove, yMove;
// 计算单指移动的距离
if (self.touchended) {
return self.updateCanvas()
}
xMove = Math.round(touch.x - self.touchX0);
yMove = Math.round(touch.y - self.touchY0);
var imgLeft = Math.round(self.rectX + xMove);
var imgTop = Math.round(self.rectY + yMove);
self.outsideBound(imgLeft, imgTop);
self.updateCanvas();
};
self.__twoTouchStart = function (touch0, touch1) {
var xMove, yMove, oldDistance;
self.touchX1 = Math.round(self.rectX + self.scaleWidth / 2);
self.touchY1 = Math.round(self.rectY + self.scaleHeight / 2);
// 计算两指距离
xMove = Math.round(touch1.x - touch0.x);
yMove = Math.round(touch1.y - touch0.y);
oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove));
self.oldDistance = oldDistance;
};
self.__twoTouchMove = function (touch0, touch1) {
var oldScale = self.oldScale;
var oldDistance = self.oldDistance;
var scale = self.scale;
var zoom = self.zoom;
self.newScale = getNewScale(oldScale, oldDistance, zoom, touch0, touch1);
// 设定缩放范围
self.newScale <= 1 && (self.newScale = 1);
self.newScale >= scale && (self.newScale = scale);
self.scaleWidth = Math.round(self.newScale * self.baseWidth);
self.scaleHeight = Math.round(self.newScale * self.baseHeight);
var imgLeft = Math.round(self.touchX1 - self.scaleWidth / 2);
var imgTop = Math.round(self.touchY1 - self.scaleHeight / 2);
self.outsideBound(imgLeft, imgTop);
self.updateCanvas();
};
self.__xtouchEnd = function () {
self.oldScale = self.newScale;
self.rectX = self.imgLeft;
self.rectY = self.imgTop;
};
}
var handle = {
// 图片手势初始监测
touchStart: function touchStart (e) {
var self = this;
var ref = e.touches;
var touch0 = ref[0];
var touch1 = ref[1];
if (!self.src) { return }
setTouchState(self, true, null, null);
// 计算第一个触摸点的位置,并参照改点进行缩放
self.__oneTouchStart(touch0);
// 两指手势触发
if (e.touches.length >= 2) {
self.__twoTouchStart(touch0, touch1);
}
},
// 图片手势动态缩放
touchMove: function touchMove (e) {
var self = this;
var ref = e.touches;
var touch0 = ref[0];
var touch1 = ref[1];
if (!self.src) { return }
setTouchState(self, null, true);
// 单指手势时触发
if (e.touches.length === 1) {
self.__oneTouchMove(touch0);
}
// 两指手势触发
if (e.touches.length >= 2) {
self.__twoTouchMove(touch0, touch1);
}
},
touchEnd: function touchEnd (e) {
var self = this;
if (!self.src) { return }
setTouchState(self, false, false, true);
self.__xtouchEnd();
}
};
function cut () {
var self = this;
var boundWidth = self.width; // 裁剪框默认宽度,即整个画布宽度
var boundHeight = self.height;
// 裁剪框默认高度,即整个画布高度
var ref = self.cut;
var x = ref.x; if ( x === void 0 ) x = 0;
var y = ref.y; if ( y === void 0 ) y = 0;
var width = ref.width; if ( width === void 0 ) width = boundWidth;
var height = ref.height; if ( height === void 0 ) height = boundHeight;
/**
* 设置边界
* @param imgLeft 图片左上角横坐标值
* @param imgTop 图片左上角纵坐标值
*/
self.outsideBound = function (imgLeft, imgTop) {
self.imgLeft = imgLeft >= x
? x
: self.scaleWidth + imgLeft - x <= width
? x + width - self.scaleWidth
: imgLeft;
self.imgTop = imgTop >= y
? y
: self.scaleHeight + imgTop - y <= height
? y + height - self.scaleHeight
: imgTop;
};
/**
* 设置边界样式
* @param color 边界颜色
*/
self.setBoundStyle = function (ref) {
if ( ref === void 0 ) ref = {};
var color = ref.color; if ( color === void 0 ) color = '#04b00f';
var mask = ref.mask; if ( mask === void 0 ) mask = 'rgba(0, 0, 0, 0.3)';
var lineWidth = ref.lineWidth; if ( lineWidth === void 0 ) lineWidth = 1;
var boundOption = [
{
start: { x: x - lineWidth, y: y + 10 - lineWidth },
step1: { x: x - lineWidth, y: y - lineWidth },
step2: { x: x + 10 - lineWidth, y: y - lineWidth }
},
{
start: { x: x - lineWidth, y: y + height - 10 + lineWidth },
step1: { x: x - lineWidth, y: y + height + lineWidth },
step2: { x: x + 10 - lineWidth, y: y + height + lineWidth }
},
{
start: { x: x + width - 10 + lineWidth, y: y - lineWidth },
step1: { x: x + width + lineWidth, y: y - lineWidth },
step2: { x: x + width + lineWidth, y: y + 10 - lineWidth }
},
{
start: { x: x + width + lineWidth, y: y + height - 10 + lineWidth },
step1: { x: x + width + lineWidth, y: y + height + lineWidth },
step2: { x: x + width - 10 + lineWidth, y: y + height + lineWidth }
}
];
// 绘制半透明层
self.ctx.beginPath();
self.ctx.setFillStyle(mask);
self.ctx.fillRect(0, 0, x, boundHeight);
self.ctx.fillRect(x, 0, width, y);
self.ctx.fillRect(x, y + height, width, boundHeight - y - height);
self.ctx.fillRect(x + width, 0, boundWidth - x - width, boundHeight);
self.ctx.fill();
boundOption.forEach(function (op) {
self.ctx.beginPath();
self.ctx.setStrokeStyle(color);
self.ctx.setLineWidth(lineWidth);
self.ctx.moveTo(op.start.x, op.start.y);
self.ctx.lineTo(op.step1.x, op.step1.y);
self.ctx.lineTo(op.step2.x, op.step2.y);
self.ctx.stroke();
});
};
}
var version = "1.3.4";
var WeCropper = function WeCropper (params) {
var self = this;
var _default = {};
validator(self, DEFAULT);
Object.keys(DEFAULT).forEach(function (key) {
_default[key] = DEFAULT[key].default;
});
Object.assign(self, _default, params);
self.prepare();
self.attachPage();
self.createCtx();
self.observer();
self.cutt();
self.methods();
self.init();
self.update();
return self
};
WeCropper.prototype.init = function init () {
var self = this;
var src = self.src;
self.version = version;
typeof self.onReady === 'function' && self.onReady(self.ctx, self);
if (src) {
self.pushOrign(src);
} else {
self.updateCanvas();
}
setTouchState(self, false, false, false);
self.oldScale = 1;
self.newScale = 1;
return self
};
Object.assign(WeCropper.prototype, handle);
WeCropper.prototype.prepare = prepare;
WeCropper.prototype.observer = observer;
WeCropper.prototype.methods = methods;
WeCropper.prototype.cutt = cut;
WeCropper.prototype.update = update;
return WeCropper;
})));
<template name="xz-cropper">
<canvas
class="cropper"
disable-scroll="true"
bindtouchstart="touchStart"
bindtouchmove="touchMove"
bindtouchend="touchEnd"
style="width:{{width}}px;height:{{height}}px;background-color: rgba(0, 0, 0, 0.8)"
canvas-id="{{id}}">
</canvas>
<canvas
class="cropper"
disable-scroll="true"
style="position: fixed; top: -{{width * pixelRatio}}px; left: -{{height * pixelRatio}}px; width:{{width * pixelRatio}}px;height:{{height * pixelRatio}}px;"
canvas-id="{{targetId}}">
</canvas>
</template>
\ No newline at end of file
// 以下是业务服务器API地址
// 本机开发时使用
var WxApiRoot = 'https://emall.exploring.cn/wx/';
// 局域网测试使用
//var WxApiRoot = 'http://192.168.1.195:8181/wx/';
// 云平台部署时使用
// var WxApiRoot = 'http://122.152.206.172:8080/wx/';
// 云平台上线时使用
// var WxApiRoot = 'https://www.menethil.com.cn/wx/';
module.exports = {
IndexUrl: WxApiRoot + 'home/index', //首页数据接口
ActivityGoodsList:WxApiRoot+'campaign/goods/list', //首页点击活动进入,查询活动商品列表
CatalogList: WxApiRoot + 'catalog/index', //分类目录全部分类数据接口
CatalogCurrent: WxApiRoot + 'catalog/current', //分类目录当前分类数据接口
AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录
AuthLoginByAccount: WxApiRoot + 'auth/login', //账号登录
AuthLogout: WxApiRoot + 'auth/logout', //账号登出
AuthRegister: WxApiRoot + 'auth/register', //账号注册
AuthReset: WxApiRoot + 'auth/reset', //账号密码重置
AuthRegisterCaptcha: WxApiRoot + 'auth/regCaptcha', //验证码
AuthBindPhone: WxApiRoot + 'auth/bindPhone', //绑定微信手机号
GoodsCount: WxApiRoot + 'goods/count', //统计商品总数
GoodsList: WxApiRoot + 'goods/list', //获得商品列表
GoodsCategory: WxApiRoot + 'goods/category', //获得分类数据
GoodsDetail: WxApiRoot + 'goods/detail', //获得商品的详情
GoodsNew: WxApiRoot + 'goods/new', //新品
GoodsHot: WxApiRoot + 'goods/hot', //热门
GoodsRelated: WxApiRoot + 'goods/related', //商品详情页的关联商品(大家都在看)
BrandList: WxApiRoot + 'brand/list', //品牌列表
BrandDetail: WxApiRoot + 'brand/detail', //品牌详情
CartList: WxApiRoot + 'cart/index', //获取购物车的数据
CartAdd: WxApiRoot + 'cart/add', // 添加商品到购物车
CartFastAdd: WxApiRoot + 'cart/fastadd', // 立即购买商品
CartUpdate: WxApiRoot + 'cart/update', // 更新购物车的商品
CartDelete: WxApiRoot + 'cart/delete', // 删除购物车的商品
CartChecked: WxApiRoot + 'cart/checked', // 选择或取消选择商品
CartGoodsCount: WxApiRoot + 'cart/goodscount', // 获取购物车商品件数
CartCheckout: WxApiRoot + 'cart/checkout', // 下单前信息确认
CollectList: WxApiRoot + 'collect/list', //收藏列表
CollectAddOrDelete: WxApiRoot + 'collect/addordelete', //添加或取消收藏
CommentList: WxApiRoot + 'comment/list', //评论列表
CommentCount: WxApiRoot + 'comment/count', //评论总数
CommentPost: WxApiRoot + 'comment/post', //发表评论
TopicList: WxApiRoot + 'topic/list', //专题列表
TopicDetail: WxApiRoot + 'topic/detail', //专题详情
TopicRelated: WxApiRoot + 'topic/related', //相关专题
SearchIndex: WxApiRoot + 'search/index', //搜索关键字
SearchResult: WxApiRoot + 'search/result', //搜索结果
SearchHelper: WxApiRoot + 'search/helper', //搜索帮助
SearchClearHistory: WxApiRoot + 'search/clearhistory', //搜索历史清楚
AddressList: WxApiRoot + 'address/list', //收货地址列表
AddressDetail: WxApiRoot + 'address/detail', //收货地址详情
AddressSave: WxApiRoot + 'address/save', //保存收货地址
AddressDelete: WxApiRoot + 'address/delete', //保存收货地址
ExpressQuery: WxApiRoot + 'express/query', //物流查询
RegionList: WxApiRoot + 'region/list', //获取区域列表
OrderSubmit: WxApiRoot + 'order/submit', // 提交订单
OrderPrepay: WxApiRoot + 'order/prepay', // 订单的预支付会话
OrderList: WxApiRoot + 'order/list', //订单列表
OrderDetail: WxApiRoot + 'order/detail', //订单详情
OrderCancel: WxApiRoot + 'order/cancel', //取消订单
OrderRefund: WxApiRoot + 'order/refund', //退款取消订单
OrderDelete: WxApiRoot + 'order/delete', //删除订单
OrderConfirm: WxApiRoot + 'order/confirm', //确认收货
OrderGoods: WxApiRoot + 'order/goods', // 代评价商品信息
OrderComment: WxApiRoot + 'order/comment', // 评价订单商品信息
FeedbackAdd: WxApiRoot + 'feedback/submit', //添加反馈
FootprintList: WxApiRoot + 'footprint/list', //足迹列表
FootprintDelete: WxApiRoot + 'footprint/delete', //删除足迹
UserFormIdCreate: WxApiRoot + 'formid/create', //用户FromId,用于发送模版消息
GroupOnList: WxApiRoot + 'groupon/list', //团购列表
GroupOn: WxApiRoot + 'groupon/query', //团购API-查询
GroupOnMy: WxApiRoot + 'groupon/my', //团购API-我的团购
GroupOnDetail: WxApiRoot + 'groupon/detail', //团购API-详情
GroupOnJoin: WxApiRoot + 'groupon/join', //团购API-详情
CouponList: WxApiRoot + 'coupon/list', //优惠券列表
CouponMyList: WxApiRoot + 'coupon/mylist', //我的优惠券列表
CouponSelectList: WxApiRoot + 'coupon/selectlist', //当前订单可用优惠券列表
CouponReceive: WxApiRoot + 'coupon/receive', //优惠券领取
CouponExchange: WxApiRoot + 'coupon/exchange', //优惠券兑换
StorageUpload: WxApiRoot + 'storage/upload', //图片上传,
UserIndex: WxApiRoot + 'user/index', //个人页面用户相关信息
UserNickName: WxApiRoot + 'user/nickName', //配置用户的昵称
UserGetSetUp: WxApiRoot + 'user/setUp', //配置用户信息,包括手机号
UploadPortrait: WxApiRoot + 'storage/head/portrait/upload', //上传头像
};
\ No newline at end of file
/**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/
var __placeImgeUrlHttps = "https";
var __emojisReg = '';
var __emojisBaseSrc = '';
var __emojis = {};
var wxDiscode = require('wxDiscode.js');
var HTMLParser = require('htmlparser.js');
// Empty Elements - HTML 5
var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");
// Block Elements - HTML 5
var block = makeMap("br,a,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
// Inline Elements - HTML 5
var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
// Elements that you can, intentionally, leave open
// (and which close themselves)
var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
// Attributes that have their values filled in disabled="disabled"
var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
// Special Elements (can contain anything)
var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block");
function makeMap(str) {
var obj = {}, items = str.split(",");
for (var i = 0; i < items.length; i++)
obj[items[i]] = true;
return obj;
}
function q(v) {
return '"' + v + '"';
}
function removeDOCTYPE(html) {
return html
.replace(/<\?xml.*\?>\n/, '')
.replace(/<!doctype.*\>\n/, '')
.replace(/<!DOCTYPE.*\>\n/, '');
}
function html2json(html, bindName) {
//处理字符串
html = removeDOCTYPE(html);
html = wxDiscode.strDiscode(html);
//生成node节点
var bufArray = [];
var results = {
node: bindName,
nodes: [],
images:[],
imageUrls:[]
};
HTMLParser(html, {
start: function (tag, attrs, unary) {
//debug(tag, attrs, unary);
// node for this element
var node = {
node: 'element',
tag: tag,
};
if (block[tag]) {
node.tagType = "block";
} else if (inline[tag]) {
node.tagType = "inline";
} else if (closeSelf[tag]) {
node.tagType = "closeSelf";
}
if (attrs.length !== 0) {
node.attr = attrs.reduce(function (pre, attr) {
var name = attr.name;
var value = attr.value;
if (name == 'class') {
// console.dir(value);
// value = value.join("")
node.classStr = value;
}
// has multi attibutes
// make it array of attribute
if (name == 'style') {
// console.dir(value);
// value = value.join("")
node.styleStr = value;
}
if (value.match(/ /)) {
value = value.split(' ');
}
// if attr already exists
// merge it
if (pre[name]) {
if (Array.isArray(pre[name])) {
// already array, push to last
pre[name].push(value);
} else {
// single value, make it array
pre[name] = [pre[name], value];
}
} else {
// not exist, put it
pre[name] = value;
}
return pre;
}, {});
}
//对img添加额外数据
if (node.tag === 'img') {
node.imgIndex = results.images.length;
var imgUrl = node.attr.src;
imgUrl = wxDiscode.urlToHttpUrl(imgUrl, __placeImgeUrlHttps);
node.attr.src = imgUrl;
node.from = bindName;
results.images.push(node);
results.imageUrls.push(imgUrl);
}
if (unary) {
// if this tag dosen't have end tag
// like <img src="hoge.png"/>
// add to parents
var parent = bufArray[0] || results;
if (parent.nodes === undefined) {
parent.nodes = [];
}
parent.nodes.push(node);
} else {
bufArray.unshift(node);
}
},
end: function (tag) {
//debug(tag);
// merge into parent tag
var node = bufArray.shift();
if (node.tag !== tag) console.error('invalid state: mismatch end tag');
if (bufArray.length === 0) {
results.nodes.push(node);
} else {
var parent = bufArray[0];
if (parent.nodes === undefined) {
parent.nodes = [];
}
parent.nodes.push(node);
}
},
chars: function (text) {
//debug(text);
var node = {
node: 'text',
text: text,
textArray:transEmojiStr(text)
};
if (bufArray.length === 0) {
results.nodes.push(node);
} else {
var parent = bufArray[0];
if (parent.nodes === undefined) {
parent.nodes = [];
}
parent.nodes.push(node);
}
},
comment: function (text) {
//debug(text);
var node = {
node: 'comment',
text: text,
};
var parent = bufArray[0];
if (parent.nodes === undefined) {
parent.nodes = [];
}
parent.nodes.push(node);
},
});
return results;
};
function transEmojiStr(str){
// var eReg = new RegExp("["+__reg+' '+"]");
// str = str.replace(/\[([^\[\]]+)\]/g,':$1:')
var emojiObjs = [];
//如果正则表达式为空
if(__emojisReg.length == 0 || !__emojis){
var emojiObj = {}
emojiObj.node = "text";
emojiObj.text = str;
array = [emojiObj];
return array;
}
//这个地方需要调整
str = str.replace(/\[([^\[\]]+)\]/g,':$1:')
var eReg = new RegExp("[:]");
var array = str.split(eReg);
for(var i = 0; i < array.length; i++){
var ele = array[i];
var emojiObj = {};
if(__emojis[ele]){
emojiObj.node = "element";
emojiObj.tag = "emoji";
emojiObj.text = __emojis[ele];
emojiObj.baseSrc= __emojisBaseSrc;
}else{
emojiObj.node = "text";
emojiObj.text = ele;
}
emojiObjs.push(emojiObj);
}
return emojiObjs;
}
function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){
__emojisReg = reg;
__emojisBaseSrc=baseSrc;
__emojis=emojis;
}
module.exports = {
html2json: html2json,
emojisInit:emojisInit
};
/**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/,
endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/,
attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
// Empty Elements - HTML 5
var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr");
// Block Elements - HTML 5
var block = makeMap("a,address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video");
// Inline Elements - HTML 5
var inline = makeMap("abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var");
// Elements that you can, intentionally, leave open
// (and which close themselves)
var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");
// Attributes that have their values filled in disabled="disabled"
var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected");
// Special Elements (can contain anything)
var special = makeMap("wxxxcode-style,script,style,view,scroll-view,block");
function HTMLParser(html, handler) {
var index, chars, match, stack = [], last = html;
stack.last = function () {
return this[this.length - 1];
};
while (html) {
chars = true;
// Make sure we're not in a script or style element
if (!stack.last() || !special[stack.last()]) {
// Comment
if (html.indexOf("<!--") == 0) {
index = html.indexOf("-->");
if (index >= 0) {
if (handler.comment)
handler.comment(html.substring(4, index));
html = html.substring(index + 3);
chars = false;
}
// end tag
} else if (html.indexOf("</") == 0) {
match = html.match(endTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(endTag, parseEndTag);
chars = false;
}
// start tag
} else if (html.indexOf("<") == 0) {
match = html.match(startTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(startTag, parseStartTag);
chars = false;
}
}
if (chars) {
index = html.indexOf("<");
var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? "" : html.substring(index);
if (handler.chars)
handler.chars(text);
}
} else {
html = html.replace(new RegExp("([\\s\\S]*?)<\/" + stack.last() + "[^>]*>"), function (all, text) {
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, "$1$2");
if (handler.chars)
handler.chars(text);
return "";
});
parseEndTag("", stack.last());
}
if (html == last)
throw "Parse Error: " + html;
last = html;
}
// Clean up any remaining tags
parseEndTag();
function parseStartTag(tag, tagName, rest, unary) {
tagName = tagName.toLowerCase();
if (block[tagName]) {
while (stack.last() && inline[stack.last()]) {
parseEndTag("", stack.last());
}
}
if (closeSelf[tagName] && stack.last() == tagName) {
parseEndTag("", tagName);
}
unary = empty[tagName] || !!unary;
if (!unary)
stack.push(tagName);
if (handler.start) {
var attrs = [];
rest.replace(attr, function (match, name) {
var value = arguments[2] ? arguments[2] :
arguments[3] ? arguments[3] :
arguments[4] ? arguments[4] :
fillAttrs[name] ? name : "";
attrs.push({
name: name,
value: value,
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //"
});
});
if (handler.start) {
handler.start(tagName, attrs, unary);
}
}
}
function parseEndTag(tag, tagName) {
// If no tag name is provided, clean shop
if (!tagName)
var pos = 0;
// Find the closest opened tag of the same type
else
for (var pos = stack.length - 1; pos >= 0; pos--)
if (stack[pos] == tagName)
break;
if (pos >= 0) {
// Close all the open elements, up the stack
for (var i = stack.length - 1; i >= pos; i--)
if (handler.end)
handler.end(stack[i]);
// Remove the open elements from the stack
stack.length = pos;
}
}
};
function makeMap(str) {
var obj = {}, items = str.split(",");
for (var i = 0; i < items.length; i++)
obj[items[i]] = true;
return obj;
}
module.exports = HTMLParser;
/**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/
function getDefaultOpts(simple) {
'use strict';
var defaultOptions = {
omitExtraWLInCodeBlocks: {
defaultValue: false,
describe: 'Omit the default extra whiteline added to code blocks',
type: 'boolean'
},
noHeaderId: {
defaultValue: false,
describe: 'Turn on/off generated header id',
type: 'boolean'
},
prefixHeaderId: {
defaultValue: false,
describe: 'Specify a prefix to generated header ids',
type: 'string'
},
headerLevelStart: {
defaultValue: false,
describe: 'The header blocks level start',
type: 'integer'
},
parseImgDimensions: {
defaultValue: false,
describe: 'Turn on/off image dimension parsing',
type: 'boolean'
},
simplifiedAutoLink: {
defaultValue: false,
describe: 'Turn on/off GFM autolink style',
type: 'boolean'
},
literalMidWordUnderscores: {
defaultValue: false,
describe: 'Parse midword underscores as literal underscores',
type: 'boolean'
},
strikethrough: {
defaultValue: false,
describe: 'Turn on/off strikethrough support',
type: 'boolean'
},
tables: {
defaultValue: false,
describe: 'Turn on/off tables support',
type: 'boolean'
},
tablesHeaderId: {
defaultValue: false,
describe: 'Add an id to table headers',
type: 'boolean'
},
ghCodeBlocks: {
defaultValue: true,
describe: 'Turn on/off GFM fenced code blocks support',
type: 'boolean'
},
tasklists: {
defaultValue: false,
describe: 'Turn on/off GFM tasklist support',
type: 'boolean'
},
smoothLivePreview: {
defaultValue: false,
describe: 'Prevents weird effects in live previews due to incomplete input',
type: 'boolean'
},
smartIndentationFix: {
defaultValue: false,
description: 'Tries to smartly fix identation in es6 strings',
type: 'boolean'
}
};
if (simple === false) {
return JSON.parse(JSON.stringify(defaultOptions));
}
var ret = {};
for (var opt in defaultOptions) {
if (defaultOptions.hasOwnProperty(opt)) {
ret[opt] = defaultOptions[opt].defaultValue;
}
}
return ret;
}
/**
* Created by Tivie on 06-01-2015.
*/
// Private properties
var showdown = {},
parsers = {},
extensions = {},
globalOptions = getDefaultOpts(true),
flavor = {
github: {
omitExtraWLInCodeBlocks: true,
prefixHeaderId: 'user-content-',
simplifiedAutoLink: true,
literalMidWordUnderscores: true,
strikethrough: true,
tables: true,
tablesHeaderId: true,
ghCodeBlocks: true,
tasklists: true
},
vanilla: getDefaultOpts(true)
};
/**
* helper namespace
* @type {{}}
*/
showdown.helper = {};
/**
* TODO LEGACY SUPPORT CODE
* @type {{}}
*/
showdown.extensions = {};
/**
* Set a global option
* @static
* @param {string} key
* @param {*} value
* @returns {showdown}
*/
showdown.setOption = function (key, value) {
'use strict';
globalOptions[key] = value;
return this;
};
/**
* Get a global option
* @static
* @param {string} key
* @returns {*}
*/
showdown.getOption = function (key) {
'use strict';
return globalOptions[key];
};
/**
* Get the global options
* @static
* @returns {{}}
*/
showdown.getOptions = function () {
'use strict';
return globalOptions;
};
/**
* Reset global options to the default values
* @static
*/
showdown.resetOptions = function () {
'use strict';
globalOptions = getDefaultOpts(true);
};
/**
* Set the flavor showdown should use as default
* @param {string} name
*/
showdown.setFlavor = function (name) {
'use strict';
if (flavor.hasOwnProperty(name)) {
var preset = flavor[name];
for (var option in preset) {
if (preset.hasOwnProperty(option)) {
globalOptions[option] = preset[option];
}
}
}
};
/**
* Get the default options
* @static
* @param {boolean} [simple=true]
* @returns {{}}
*/
showdown.getDefaultOptions = function (simple) {
'use strict';
return getDefaultOpts(simple);
};
/**
* Get or set a subParser
*
* subParser(name) - Get a registered subParser
* subParser(name, func) - Register a subParser
* @static
* @param {string} name
* @param {function} [func]
* @returns {*}
*/
showdown.subParser = function (name, func) {
'use strict';
if (showdown.helper.isString(name)) {
if (typeof func !== 'undefined') {
parsers[name] = func;
} else {
if (parsers.hasOwnProperty(name)) {
return parsers[name];
} else {
throw Error('SubParser named ' + name + ' not registered!');
}
}
}
};
/**
* Gets or registers an extension
* @static
* @param {string} name
* @param {object|function=} ext
* @returns {*}
*/
showdown.extension = function (name, ext) {
'use strict';
if (!showdown.helper.isString(name)) {
throw Error('Extension \'name\' must be a string');
}
name = showdown.helper.stdExtName(name);
// Getter
if (showdown.helper.isUndefined(ext)) {
if (!extensions.hasOwnProperty(name)) {
throw Error('Extension named ' + name + ' is not registered!');
}
return extensions[name];
// Setter
} else {
// Expand extension if it's wrapped in a function
if (typeof ext === 'function') {
ext = ext();
}
// Ensure extension is an array
if (!showdown.helper.isArray(ext)) {
ext = [ext];
}
var validExtension = validate(ext, name);
if (validExtension.valid) {
extensions[name] = ext;
} else {
throw Error(validExtension.error);
}
}
};
/**
* Gets all extensions registered
* @returns {{}}
*/
showdown.getAllExtensions = function () {
'use strict';
return extensions;
};
/**
* Remove an extension
* @param {string} name
*/
showdown.removeExtension = function (name) {
'use strict';
delete extensions[name];
};
/**
* Removes all extensions
*/
showdown.resetExtensions = function () {
'use strict';
extensions = {};
};
/**
* Validate extension
* @param {array} extension
* @param {string} name
* @returns {{valid: boolean, error: string}}
*/
function validate(extension, name) {
'use strict';
var errMsg = (name) ? 'Error in ' + name + ' extension->' : 'Error in unnamed extension',
ret = {
valid: true,
error: ''
};
if (!showdown.helper.isArray(extension)) {
extension = [extension];
}
for (var i = 0; i < extension.length; ++i) {
var baseMsg = errMsg + ' sub-extension ' + i + ': ',
ext = extension[i];
if (typeof ext !== 'object') {
ret.valid = false;
ret.error = baseMsg + 'must be an object, but ' + typeof ext + ' given';
return ret;
}
if (!showdown.helper.isString(ext.type)) {
ret.valid = false;
ret.error = baseMsg + 'property "type" must be a string, but ' + typeof ext.type + ' given';
return ret;
}
var type = ext.type = ext.type.toLowerCase();
// normalize extension type
if (type === 'language') {
type = ext.type = 'lang';
}
if (type === 'html') {
type = ext.type = 'output';
}
if (type !== 'lang' && type !== 'output' && type !== 'listener') {
ret.valid = false;
ret.error = baseMsg + 'type ' + type + ' is not recognized. Valid values: "lang/language", "output/html" or "listener"';
return ret;
}
if (type === 'listener') {
if (showdown.helper.isUndefined(ext.listeners)) {
ret.valid = false;
ret.error = baseMsg + '. Extensions of type "listener" must have a property called "listeners"';
return ret;
}
} else {
if (showdown.helper.isUndefined(ext.filter) && showdown.helper.isUndefined(ext.regex)) {
ret.valid = false;
ret.error = baseMsg + type + ' extensions must define either a "regex" property or a "filter" method';
return ret;
}
}
if (ext.listeners) {
if (typeof ext.listeners !== 'object') {
ret.valid = false;
ret.error = baseMsg + '"listeners" property must be an object but ' + typeof ext.listeners + ' given';
return ret;
}
for (var ln in ext.listeners) {
if (ext.listeners.hasOwnProperty(ln)) {
if (typeof ext.listeners[ln] !== 'function') {
ret.valid = false;
ret.error = baseMsg + '"listeners" property must be an hash of [event name]: [callback]. listeners.' + ln +
' must be a function but ' + typeof ext.listeners[ln] + ' given';
return ret;
}
}
}
}
if (ext.filter) {
if (typeof ext.filter !== 'function') {
ret.valid = false;
ret.error = baseMsg + '"filter" must be a function, but ' + typeof ext.filter + ' given';
return ret;
}
} else if (ext.regex) {
if (showdown.helper.isString(ext.regex)) {
ext.regex = new RegExp(ext.regex, 'g');
}
if (!ext.regex instanceof RegExp) {
ret.valid = false;
ret.error = baseMsg + '"regex" property must either be a string or a RegExp object, but ' + typeof ext.regex + ' given';
return ret;
}
if (showdown.helper.isUndefined(ext.replace)) {
ret.valid = false;
ret.error = baseMsg + '"regex" extensions must implement a replace string or function';
return ret;
}
}
}
return ret;
}
/**
* Validate extension
* @param {object} ext
* @returns {boolean}
*/
showdown.validateExtension = function (ext) {
'use strict';
var validateExtension = validate(ext, null);
if (!validateExtension.valid) {
console.warn(validateExtension.error);
return false;
}
return true;
};
/**
* showdownjs helper functions
*/
if (!showdown.hasOwnProperty('helper')) {
showdown.helper = {};
}
/**
* Check if var is string
* @static
* @param {string} a
* @returns {boolean}
*/
showdown.helper.isString = function isString(a) {
'use strict';
return (typeof a === 'string' || a instanceof String);
};
/**
* Check if var is a function
* @static
* @param {string} a
* @returns {boolean}
*/
showdown.helper.isFunction = function isFunction(a) {
'use strict';
var getType = {};
return a && getType.toString.call(a) === '[object Function]';
};
/**
* ForEach helper function
* @static
* @param {*} obj
* @param {function} callback
*/
showdown.helper.forEach = function forEach(obj, callback) {
'use strict';
if (typeof obj.forEach === 'function') {
obj.forEach(callback);
} else {
for (var i = 0; i < obj.length; i++) {
callback(obj[i], i, obj);
}
}
};
/**
* isArray helper function
* @static
* @param {*} a
* @returns {boolean}
*/
showdown.helper.isArray = function isArray(a) {
'use strict';
return a.constructor === Array;
};
/**
* Check if value is undefined
* @static
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
*/
showdown.helper.isUndefined = function isUndefined(value) {
'use strict';
return typeof value === 'undefined';
};
/**
* Standardidize extension name
* @static
* @param {string} s extension name
* @returns {string}
*/
showdown.helper.stdExtName = function (s) {
'use strict';
return s.replace(/[_-]||\s/g, '').toLowerCase();
};
function escapeCharactersCallback(wholeMatch, m1) {
'use strict';
var charCodeToEscape = m1.charCodeAt(0);
return '~E' + charCodeToEscape + 'E';
}
/**
* Callback used to escape characters when passing through String.replace
* @static
* @param {string} wholeMatch
* @param {string} m1
* @returns {string}
*/
showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
/**
* Escape characters in a string
* @static
* @param {string} text
* @param {string} charsToEscape
* @param {boolean} afterBackslash
* @returns {XML|string|void|*}
*/
showdown.helper.escapeCharacters = function escapeCharacters(text, charsToEscape, afterBackslash) {
'use strict';
// First we have to escape the escape characters so that
// we can build a character class out of them
var regexString = '([' + charsToEscape.replace(/([\[\]\\])/g, '\\$1') + '])';
if (afterBackslash) {
regexString = '\\\\' + regexString;
}
var regex = new RegExp(regexString, 'g');
text = text.replace(regex, escapeCharactersCallback);
return text;
};
var rgxFindMatchPos = function (str, left, right, flags) {
'use strict';
var f = flags || '',
g = f.indexOf('g') > -1,
x = new RegExp(left + '|' + right, 'g' + f.replace(/g/g, '')),
l = new RegExp(left, f.replace(/g/g, '')),
pos = [],
t, s, m, start, end;
do {
t = 0;
while ((m = x.exec(str))) {
if (l.test(m[0])) {
if (!(t++)) {
s = x.lastIndex;
start = s - m[0].length;
}
} else if (t) {
if (!--t) {
end = m.index + m[0].length;
var obj = {
left: {start: start, end: s},
match: {start: s, end: m.index},
right: {start: m.index, end: end},
wholeMatch: {start: start, end: end}
};
pos.push(obj);
if (!g) {
return pos;
}
}
}
}
} while (t && (x.lastIndex = s));
return pos;
};
/**
* matchRecursiveRegExp
*
* (c) 2007 Steven Levithan <stevenlevithan.com>
* MIT License
*
* Accepts a string to search, a left and right format delimiter
* as regex patterns, and optional regex flags. Returns an array
* of matches, allowing nested instances of left/right delimiters.
* Use the "g" flag to return all matches, otherwise only the
* first is returned. Be careful to ensure that the left and
* right format delimiters produce mutually exclusive matches.
* Backreferences are not supported within the right delimiter
* due to how it is internally combined with the left delimiter.
* When matching strings whose format delimiters are unbalanced
* to the left or right, the output is intentionally as a
* conventional regex library with recursion support would
* produce, e.g. "<<x>" and "<x>>" both produce ["x"] when using
* "<" and ">" as the delimiters (both strings contain a single,
* balanced instance of "<x>").
*
* examples:
* matchRecursiveRegExp("test", "\\(", "\\)")
* returns: []
* matchRecursiveRegExp("<t<<e>><s>>t<>", "<", ">", "g")
* returns: ["t<<e>><s>", ""]
* matchRecursiveRegExp("<div id=\"x\">test</div>", "<div\\b[^>]*>", "</div>", "gi")
* returns: ["test"]
*/
showdown.helper.matchRecursiveRegExp = function (str, left, right, flags) {
'use strict';
var matchPos = rgxFindMatchPos (str, left, right, flags),
results = [];
for (var i = 0; i < matchPos.length; ++i) {
results.push([
str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
str.slice(matchPos[i].match.start, matchPos[i].match.end),
str.slice(matchPos[i].left.start, matchPos[i].left.end),
str.slice(matchPos[i].right.start, matchPos[i].right.end)
]);
}
return results;
};
/**
*
* @param {string} str
* @param {string|function} replacement
* @param {string} left
* @param {string} right
* @param {string} flags
* @returns {string}
*/
showdown.helper.replaceRecursiveRegExp = function (str, replacement, left, right, flags) {
'use strict';
if (!showdown.helper.isFunction(replacement)) {
var repStr = replacement;
replacement = function () {
return repStr;
};
}
var matchPos = rgxFindMatchPos(str, left, right, flags),
finalStr = str,
lng = matchPos.length;
if (lng > 0) {
var bits = [];
if (matchPos[0].wholeMatch.start !== 0) {
bits.push(str.slice(0, matchPos[0].wholeMatch.start));
}
for (var i = 0; i < lng; ++i) {
bits.push(
replacement(
str.slice(matchPos[i].wholeMatch.start, matchPos[i].wholeMatch.end),
str.slice(matchPos[i].match.start, matchPos[i].match.end),
str.slice(matchPos[i].left.start, matchPos[i].left.end),
str.slice(matchPos[i].right.start, matchPos[i].right.end)
)
);
if (i < lng - 1) {
bits.push(str.slice(matchPos[i].wholeMatch.end, matchPos[i + 1].wholeMatch.start));
}
}
if (matchPos[lng - 1].wholeMatch.end < str.length) {
bits.push(str.slice(matchPos[lng - 1].wholeMatch.end));
}
finalStr = bits.join('');
}
return finalStr;
};
/**
* POLYFILLS
*/
if (showdown.helper.isUndefined(console)) {
console = {
warn: function (msg) {
'use strict';
alert(msg);
},
log: function (msg) {
'use strict';
alert(msg);
},
error: function (msg) {
'use strict';
throw msg;
}
};
}
/**
* Created by Estevao on 31-05-2015.
*/
/**
* Showdown Converter class
* @class
* @param {object} [converterOptions]
* @returns {Converter}
*/
showdown.Converter = function (converterOptions) {
'use strict';
var
/**
* Options used by this converter
* @private
* @type {{}}
*/
options = {},
/**
* Language extensions used by this converter
* @private
* @type {Array}
*/
langExtensions = [],
/**
* Output modifiers extensions used by this converter
* @private
* @type {Array}
*/
outputModifiers = [],
/**
* Event listeners
* @private
* @type {{}}
*/
listeners = {};
_constructor();
/**
* Converter constructor
* @private
*/
function _constructor() {
converterOptions = converterOptions || {};
for (var gOpt in globalOptions) {
if (globalOptions.hasOwnProperty(gOpt)) {
options[gOpt] = globalOptions[gOpt];
}
}
// Merge options
if (typeof converterOptions === 'object') {
for (var opt in converterOptions) {
if (converterOptions.hasOwnProperty(opt)) {
options[opt] = converterOptions[opt];
}
}
} else {
throw Error('Converter expects the passed parameter to be an object, but ' + typeof converterOptions +
' was passed instead.');
}
if (options.extensions) {
showdown.helper.forEach(options.extensions, _parseExtension);
}
}
/**
* Parse extension
* @param {*} ext
* @param {string} [name='']
* @private
*/
function _parseExtension(ext, name) {
name = name || null;
// If it's a string, the extension was previously loaded
if (showdown.helper.isString(ext)) {
ext = showdown.helper.stdExtName(ext);
name = ext;
// LEGACY_SUPPORT CODE
if (showdown.extensions[ext]) {
console.warn('DEPRECATION WARNING: ' + ext + ' is an old extension that uses a deprecated loading method.' +
'Please inform the developer that the extension should be updated!');
legacyExtensionLoading(showdown.extensions[ext], ext);
return;
// END LEGACY SUPPORT CODE
} else if (!showdown.helper.isUndefined(extensions[ext])) {
ext = extensions[ext];
} else {
throw Error('Extension "' + ext + '" could not be loaded. It was either not found or is not a valid extension.');
}
}
if (typeof ext === 'function') {
ext = ext();
}
if (!showdown.helper.isArray(ext)) {
ext = [ext];
}
var validExt = validate(ext, name);
if (!validExt.valid) {
throw Error(validExt.error);
}
for (var i = 0; i < ext.length; ++i) {
switch (ext[i].type) {
case 'lang':
langExtensions.push(ext[i]);
break;
case 'output':
outputModifiers.push(ext[i]);
break;
}
if (ext[i].hasOwnProperty(listeners)) {
for (var ln in ext[i].listeners) {
if (ext[i].listeners.hasOwnProperty(ln)) {
listen(ln, ext[i].listeners[ln]);
}
}
}
}
}
/**
* LEGACY_SUPPORT
* @param {*} ext
* @param {string} name
*/
function legacyExtensionLoading(ext, name) {
if (typeof ext === 'function') {
ext = ext(new showdown.Converter());
}
if (!showdown.helper.isArray(ext)) {
ext = [ext];
}
var valid = validate(ext, name);
if (!valid.valid) {
throw Error(valid.error);
}
for (var i = 0; i < ext.length; ++i) {
switch (ext[i].type) {
case 'lang':
langExtensions.push(ext[i]);
break;
case 'output':
outputModifiers.push(ext[i]);
break;
default:// should never reach here
throw Error('Extension loader error: Type unrecognized!!!');
}
}
}
/**
* Listen to an event
* @param {string} name
* @param {function} callback
*/
function listen(name, callback) {
if (!showdown.helper.isString(name)) {
throw Error('Invalid argument in converter.listen() method: name must be a string, but ' + typeof name + ' given');
}
if (typeof callback !== 'function') {
throw Error('Invalid argument in converter.listen() method: callback must be a function, but ' + typeof callback + ' given');
}
if (!listeners.hasOwnProperty(name)) {
listeners[name] = [];
}
listeners[name].push(callback);
}
function rTrimInputText(text) {
var rsp = text.match(/^\s*/)[0].length,
rgx = new RegExp('^\\s{0,' + rsp + '}', 'gm');
return text.replace(rgx, '');
}
/**
* Dispatch an event
* @private
* @param {string} evtName Event name
* @param {string} text Text
* @param {{}} options Converter Options
* @param {{}} globals
* @returns {string}
*/
this._dispatch = function dispatch (evtName, text, options, globals) {
if (listeners.hasOwnProperty(evtName)) {
for (var ei = 0; ei < listeners[evtName].length; ++ei) {
var nText = listeners[evtName][ei](evtName, text, this, options, globals);
if (nText && typeof nText !== 'undefined') {
text = nText;
}
}
}
return text;
};
/**
* Listen to an event
* @param {string} name
* @param {function} callback
* @returns {showdown.Converter}
*/
this.listen = function (name, callback) {
listen(name, callback);
return this;
};
/**
* Converts a markdown string into HTML
* @param {string} text
* @returns {*}
*/
this.makeHtml = function (text) {
//check if text is not falsy
if (!text) {
return text;
}
var globals = {
gHtmlBlocks: [],
gHtmlMdBlocks: [],
gHtmlSpans: [],
gUrls: {},
gTitles: {},
gDimensions: {},
gListLevel: 0,
hashLinkCounts: {},
langExtensions: langExtensions,
outputModifiers: outputModifiers,
converter: this,
ghCodeBlocks: []
};
// attacklab: Replace ~ with ~T
// This lets us use tilde as an escape char to avoid md5 hashes
// The choice of character is arbitrary; anything that isn't
// magic in Markdown will work.
text = text.replace(/~/g, '~T');
// attacklab: Replace $ with ~D
// RegExp interprets $ as a special character
// when it's in a replacement string
text = text.replace(/\$/g, '~D');
// Standardize line endings
text = text.replace(/\r\n/g, '\n'); // DOS to Unix
text = text.replace(/\r/g, '\n'); // Mac to Unix
if (options.smartIndentationFix) {
text = rTrimInputText(text);
}
// Make sure text begins and ends with a couple of newlines:
//text = '\n\n' + text + '\n\n';
text = text;
// detab
text = showdown.subParser('detab')(text, options, globals);
// stripBlankLines
text = showdown.subParser('stripBlankLines')(text, options, globals);
//run languageExtensions
showdown.helper.forEach(langExtensions, function (ext) {
text = showdown.subParser('runExtension')(ext, text, options, globals);
});
// run the sub parsers
text = showdown.subParser('hashPreCodeTags')(text, options, globals);
text = showdown.subParser('githubCodeBlocks')(text, options, globals);
text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
text = showdown.subParser('hashHTMLSpans')(text, options, globals);
text = showdown.subParser('stripLinkDefinitions')(text, options, globals);
text = showdown.subParser('blockGamut')(text, options, globals);
text = showdown.subParser('unhashHTMLSpans')(text, options, globals);
text = showdown.subParser('unescapeSpecialChars')(text, options, globals);
// attacklab: Restore dollar signs
text = text.replace(/~D/g, '$$');
// attacklab: Restore tildes
text = text.replace(/~T/g, '~');
// Run output modifiers
showdown.helper.forEach(outputModifiers, function (ext) {
text = showdown.subParser('runExtension')(ext, text, options, globals);
});
return text;
};
/**
* Set an option of this Converter instance
* @param {string} key
* @param {*} value
*/
this.setOption = function (key, value) {
options[key] = value;
};
/**
* Get the option of this Converter instance
* @param {string} key
* @returns {*}
*/
this.getOption = function (key) {
return options[key];
};
/**
* Get the options of this Converter instance
* @returns {{}}
*/
this.getOptions = function () {
return options;
};
/**
* Add extension to THIS converter
* @param {{}} extension
* @param {string} [name=null]
*/
this.addExtension = function (extension, name) {
name = name || null;
_parseExtension(extension, name);
};
/**
* Use a global registered extension with THIS converter
* @param {string} extensionName Name of the previously registered extension
*/
this.useExtension = function (extensionName) {
_parseExtension(extensionName);
};
/**
* Set the flavor THIS converter should use
* @param {string} name
*/
this.setFlavor = function (name) {
if (flavor.hasOwnProperty(name)) {
var preset = flavor[name];
for (var option in preset) {
if (preset.hasOwnProperty(option)) {
options[option] = preset[option];
}
}
}
};
/**
* Remove an extension from THIS converter.
* Note: This is a costly operation. It's better to initialize a new converter
* and specify the extensions you wish to use
* @param {Array} extension
*/
this.removeExtension = function (extension) {
if (!showdown.helper.isArray(extension)) {
extension = [extension];
}
for (var a = 0; a < extension.length; ++a) {
var ext = extension[a];
for (var i = 0; i < langExtensions.length; ++i) {
if (langExtensions[i] === ext) {
langExtensions[i].splice(i, 1);
}
}
for (var ii = 0; ii < outputModifiers.length; ++i) {
if (outputModifiers[ii] === ext) {
outputModifiers[ii].splice(i, 1);
}
}
}
};
/**
* Get all extension of THIS converter
* @returns {{language: Array, output: Array}}
*/
this.getAllExtensions = function () {
return {
language: langExtensions,
output: outputModifiers
};
};
};
/**
* Turn Markdown link shortcuts into XHTML <a> tags.
*/
showdown.subParser('anchors', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('anchors.before', text, options, globals);
var writeAnchorTag = function (wholeMatch, m1, m2, m3, m4, m5, m6, m7) {
if (showdown.helper.isUndefined(m7)) {
m7 = '';
}
wholeMatch = m1;
var linkText = m2,
linkId = m3.toLowerCase(),
url = m4,
title = m7;
if (!url) {
if (!linkId) {
// lower-case and turn embedded newlines into spaces
linkId = linkText.toLowerCase().replace(/ ?\n/g, ' ');
}
url = '#' + linkId;
if (!showdown.helper.isUndefined(globals.gUrls[linkId])) {
url = globals.gUrls[linkId];
if (!showdown.helper.isUndefined(globals.gTitles[linkId])) {
title = globals.gTitles[linkId];
}
} else {
if (wholeMatch.search(/\(\s*\)$/m) > -1) {
// Special case for explicit empty url
url = '';
} else {
return wholeMatch;
}
}
}
url = showdown.helper.escapeCharacters(url, '*_', false);
var result = '<a href="' + url + '"';
if (title !== '' && title !== null) {
title = title.replace(/"/g, '&quot;');
title = showdown.helper.escapeCharacters(title, '*_', false);
result += ' title="' + title + '"';
}
result += '>' + linkText + '</a>';
return result;
};
// First, handle reference-style links: [link text] [id]
/*
text = text.replace(/
( // wrap whole match in $1
\[
(
(?:
\[[^\]]*\] // allow brackets nested one level
|
[^\[] // or anything else
)*
)
\]
[ ]? // one optional space
(?:\n[ ]*)? // one optional newline followed by spaces
\[
(.*?) // id = $3
\]
)()()()() // pad remaining backreferences
/g,_DoAnchors_callback);
*/
text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)][ ]?(?:\n[ ]*)?\[(.*?)])()()()()/g, writeAnchorTag);
//
// Next, inline-style links: [link text](url "optional title")
//
/*
text = text.replace(/
( // wrap whole match in $1
\[
(
(?:
\[[^\]]*\] // allow brackets nested one level
|
[^\[\]] // or anything else
)
)
\]
\( // literal paren
[ \t]*
() // no id, so leave $3 empty
<?(.*?)>? // href = $4
[ \t]*
( // $5
(['"]) // quote char = $6
(.*?) // Title = $7
\6 // matching quote
[ \t]* // ignore any spaces/tabs between closing quote and )
)? // title is optional
\)
)
/g,writeAnchorTag);
*/
text = text.replace(/(\[((?:\[[^\]]*]|[^\[\]])*)]\([ \t]*()<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,
writeAnchorTag);
//
// Last, handle reference-style shortcuts: [link text]
// These must come last in case you've also got [link test][1]
// or [link test](/foo)
//
/*
text = text.replace(/
( // wrap whole match in $1
\[
([^\[\]]+) // link text = $2; can't contain '[' or ']'
\]
)()()()()() // pad rest of backreferences
/g, writeAnchorTag);
*/
text = text.replace(/(\[([^\[\]]+)])()()()()()/g, writeAnchorTag);
text = globals.converter._dispatch('anchors.after', text, options, globals);
return text;
});
showdown.subParser('autoLinks', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('autoLinks.before', text, options, globals);
var simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[^'">\s]+\.[^'">\s]+)(?=\s|$)(?!["<>])/gi,
delimUrlRegex = /<(((https?|ftp|dict):\/\/|www\.)[^'">\s]+)>/gi,
simpleMailRegex = /(?:^|[ \n\t])([A-Za-z0-9!#$%&'*+-/=?^_`\{|}~\.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?:$|[ \n\t])/gi,
delimMailRegex = /<(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi;
text = text.replace(delimUrlRegex, replaceLink);
text = text.replace(delimMailRegex, replaceMail);
// simpleURLRegex = /\b(((https?|ftp|dict):\/\/|www\.)[-.+~:?#@!$&'()*,;=[\]\w]+)\b/gi,
// Email addresses: <address@domain.foo>
if (options.simplifiedAutoLink) {
text = text.replace(simpleURLRegex, replaceLink);
text = text.replace(simpleMailRegex, replaceMail);
}
function replaceLink(wm, link) {
var lnkTxt = link;
if (/^www\./i.test(link)) {
link = link.replace(/^www\./i, 'http://www.');
}
return '<a href="' + link + '">' + lnkTxt + '</a>';
}
function replaceMail(wholeMatch, m1) {
var unescapedStr = showdown.subParser('unescapeSpecialChars')(m1);
return showdown.subParser('encodeEmailAddress')(unescapedStr);
}
text = globals.converter._dispatch('autoLinks.after', text, options, globals);
return text;
});
/**
* These are all the transformations that form block-level
* tags like paragraphs, headers, and list items.
*/
showdown.subParser('blockGamut', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('blockGamut.before', text, options, globals);
// we parse blockquotes first so that we can have headings and hrs
// inside blockquotes
text = showdown.subParser('blockQuotes')(text, options, globals);
text = showdown.subParser('headers')(text, options, globals);
// Do Horizontal Rules:
var key = showdown.subParser('hashBlock')('<hr />', options, globals);
text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm, key);
text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm, key);
text = text.replace(/^[ ]{0,2}([ ]?_[ ]?){3,}[ \t]*$/gm, key);
text = showdown.subParser('lists')(text, options, globals);
text = showdown.subParser('codeBlocks')(text, options, globals);
text = showdown.subParser('tables')(text, options, globals);
// We already ran _HashHTMLBlocks() before, in Markdown(), but that
// was to escape raw HTML in the original Markdown source. This time,
// we're escaping the markup we've just created, so that we don't wrap
// <p> tags around block-level tags.
text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
text = showdown.subParser('paragraphs')(text, options, globals);
text = globals.converter._dispatch('blockGamut.after', text, options, globals);
return text;
});
showdown.subParser('blockQuotes', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('blockQuotes.before', text, options, globals);
/*
text = text.replace(/
( // Wrap whole match in $1
(
^[ \t]*>[ \t]? // '>' at the start of a line
.+\n // rest of the first line
(.+\n)* // subsequent consecutive lines
\n* // blanks
)+
)
/gm, function(){...});
*/
text = text.replace(/((^[ \t]{0,3}>[ \t]?.+\n(.+\n)*\n*)+)/gm, function (wholeMatch, m1) {
var bq = m1;
// attacklab: hack around Konqueror 3.5.4 bug:
// "----------bug".replace(/^-/g,"") == "bug"
bq = bq.replace(/^[ \t]*>[ \t]?/gm, '~0'); // trim one level of quoting
// attacklab: clean up hack
bq = bq.replace(/~0/g, '');
bq = bq.replace(/^[ \t]+$/gm, ''); // trim whitespace-only lines
bq = showdown.subParser('githubCodeBlocks')(bq, options, globals);
bq = showdown.subParser('blockGamut')(bq, options, globals); // recurse
bq = bq.replace(/(^|\n)/g, '$1 ');
// These leading spaces screw with <pre> content, so we need to fix that:
bq = bq.replace(/(\s*<pre>[^\r]+?<\/pre>)/gm, function (wholeMatch, m1) {
var pre = m1;
// attacklab: hack around Konqueror 3.5.4 bug:
pre = pre.replace(/^ /mg, '~0');
pre = pre.replace(/~0/g, '');
return pre;
});
return showdown.subParser('hashBlock')('<blockquote>\n' + bq + '\n</blockquote>', options, globals);
});
text = globals.converter._dispatch('blockQuotes.after', text, options, globals);
return text;
});
/**
* Process Markdown `<pre><code>` blocks.
*/
showdown.subParser('codeBlocks', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('codeBlocks.before', text, options, globals);
/*
text = text.replace(text,
/(?:\n\n|^)
( // $1 = the code block -- one or more lines, starting with a space/tab
(?:
(?:[ ]{4}|\t) // Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
.*\n+
)+
)
(\n*[ ]{0,3}[^ \t\n]|(?=~0)) // attacklab: g_tab_width
/g,function(){...});
*/
// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
text += '~0';
var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g;
text = text.replace(pattern, function (wholeMatch, m1, m2) {
var codeblock = m1,
nextChar = m2,
end = '\n';
codeblock = showdown.subParser('outdent')(codeblock);
codeblock = showdown.subParser('encodeCode')(codeblock);
codeblock = showdown.subParser('detab')(codeblock);
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
if (options.omitExtraWLInCodeBlocks) {
end = '';
}
codeblock = '<pre><code>' + codeblock + end + '</code></pre>';
return showdown.subParser('hashBlock')(codeblock, options, globals) + nextChar;
});
// attacklab: strip sentinel
text = text.replace(/~0/, '');
text = globals.converter._dispatch('codeBlocks.after', text, options, globals);
return text;
});
/**
*
* * Backtick quotes are used for <code></code> spans.
*
* * You can use multiple backticks as the delimiters if you want to
* include literal backticks in the code span. So, this input:
*
* Just type ``foo `bar` baz`` at the prompt.
*
* Will translate to:
*
* <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
*
* There's no arbitrary limit to the number of backticks you
* can use as delimters. If you need three consecutive backticks
* in your code, use four for delimiters, etc.
*
* * You can use spaces to get literal backticks at the edges:
*
* ... type `` `bar` `` ...
*
* Turns to:
*
* ... type <code>`bar`</code> ...
*/
showdown.subParser('codeSpans', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('codeSpans.before', text, options, globals);
/*
text = text.replace(/
(^|[^\\]) // Character before opening ` can't be a backslash
(`+) // $2 = Opening run of `
( // $3 = The code block
[^\r]*?
[^`] // attacklab: work around lack of lookbehind
)
\2 // Matching closer
(?!`)
/gm, function(){...});
*/
if (typeof(text) === 'undefined') {
text = '';
}
text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
function (wholeMatch, m1, m2, m3) {
var c = m3;
c = c.replace(/^([ \t]*)/g, ''); // leading whitespace
c = c.replace(/[ \t]*$/g, ''); // trailing whitespace
c = showdown.subParser('encodeCode')(c);
return m1 + '<code>' + c + '</code>';
}
);
text = globals.converter._dispatch('codeSpans.after', text, options, globals);
return text;
});
/**
* Convert all tabs to spaces
*/
showdown.subParser('detab', function (text) {
'use strict';
// expand first n-1 tabs
text = text.replace(/\t(?=\t)/g, ' '); // g_tab_width
// replace the nth with two sentinels
text = text.replace(/\t/g, '~A~B');
// use the sentinel to anchor our regex so it doesn't explode
text = text.replace(/~B(.+?)~A/g, function (wholeMatch, m1) {
var leadingText = m1,
numSpaces = 4 - leadingText.length % 4; // g_tab_width
// there *must* be a better way to do this:
for (var i = 0; i < numSpaces; i++) {
leadingText += ' ';
}
return leadingText;
});
// clean up sentinels
text = text.replace(/~A/g, ' '); // g_tab_width
text = text.replace(/~B/g, '');
return text;
});
/**
* Smart processing for ampersands and angle brackets that need to be encoded.
*/
showdown.subParser('encodeAmpsAndAngles', function (text) {
'use strict';
// Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
// http://bumppo.net/projects/amputator/
text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, '&amp;');
// Encode naked <'s
text = text.replace(/<(?![a-z\/?\$!])/gi, '&lt;');
return text;
});
/**
* Returns the string, with after processing the following backslash escape sequences.
*
* attacklab: The polite way to do this is with the new escapeCharacters() function:
*
* text = escapeCharacters(text,"\\",true);
* text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
*
* ...but we're sidestepping its use of the (slow) RegExp constructor
* as an optimization for Firefox. This function gets called a LOT.
*/
showdown.subParser('encodeBackslashEscapes', function (text) {
'use strict';
text = text.replace(/\\(\\)/g, showdown.helper.escapeCharactersCallback);
text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g, showdown.helper.escapeCharactersCallback);
return text;
});
/**
* Encode/escape certain characters inside Markdown code runs.
* The point is that in code, these characters are literals,
* and lose their special Markdown meanings.
*/
showdown.subParser('encodeCode', function (text) {
'use strict';
// Encode all ampersands; HTML entities are not
// entities within a Markdown code span.
text = text.replace(/&/g, '&amp;');
// Do the angle bracket song and dance:
text = text.replace(/</g, '&lt;');
text = text.replace(/>/g, '&gt;');
// Now, escape characters that are magic in Markdown:
text = showdown.helper.escapeCharacters(text, '*_{}[]\\', false);
// jj the line above breaks this:
//---
//* Item
// 1. Subitem
// special char: *
// ---
return text;
});
/**
* Input: an email address, e.g. "foo@example.com"
*
* Output: the email address as a mailto link, with each character
* of the address encoded as either a decimal or hex entity, in
* the hopes of foiling most address harvesting spam bots. E.g.:
*
* <a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
* x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
* &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
*
* Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
* mailing list: <http://tinyurl.com/yu7ue>
*
*/
showdown.subParser('encodeEmailAddress', function (addr) {
'use strict';
var encode = [
function (ch) {
return '&#' + ch.charCodeAt(0) + ';';
},
function (ch) {
return '&#x' + ch.charCodeAt(0).toString(16) + ';';
},
function (ch) {
return ch;
}
];
addr = 'mailto:' + addr;
addr = addr.replace(/./g, function (ch) {
if (ch === '@') {
// this *must* be encoded. I insist.
ch = encode[Math.floor(Math.random() * 2)](ch);
} else if (ch !== ':') {
// leave ':' alone (to spot mailto: later)
var r = Math.random();
// roughly 10% raw, 45% hex, 45% dec
ch = (
r > 0.9 ? encode[2](ch) : r > 0.45 ? encode[1](ch) : encode[0](ch)
);
}
return ch;
});
addr = '<a href="' + addr + '">' + addr + '</a>';
addr = addr.replace(/">.+:/g, '">'); // strip the mailto: from the visible part
return addr;
});
/**
* Within tags -- meaning between < and > -- encode [\ ` * _] so they
* don't conflict with their use in Markdown for code, italics and strong.
*/
showdown.subParser('escapeSpecialCharsWithinTagAttributes', function (text) {
'use strict';
// Build a regex to find HTML tags and comments. See Friedl's
// "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
text = text.replace(regex, function (wholeMatch) {
var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g, '$1`');
tag = showdown.helper.escapeCharacters(tag, '\\`*_', false);
return tag;
});
return text;
});
/**
* Handle github codeblocks prior to running HashHTML so that
* HTML contained within the codeblock gets escaped properly
* Example:
* ```ruby
* def hello_world(x)
* puts "Hello, #{x}"
* end
* ```
*/
showdown.subParser('githubCodeBlocks', function (text, options, globals) {
'use strict';
// early exit if option is not enabled
if (!options.ghCodeBlocks) {
return text;
}
text = globals.converter._dispatch('githubCodeBlocks.before', text, options, globals);
text += '~0';
text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g, function (wholeMatch, language, codeblock) {
var end = (options.omitExtraWLInCodeBlocks) ? '' : '\n';
// First parse the github code block
codeblock = showdown.subParser('encodeCode')(codeblock);
codeblock = showdown.subParser('detab')(codeblock);
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing whitespace
codeblock = '<pre><code' + (language ? ' class="' + language + ' language-' + language + '"' : '') + '>' + codeblock + end + '</code></pre>';
codeblock = showdown.subParser('hashBlock')(codeblock, options, globals);
// Since GHCodeblocks can be false positives, we need to
// store the primitive text and the parsed text in a global var,
// and then return a token
return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
});
// attacklab: strip sentinel
text = text.replace(/~0/, '');
return globals.converter._dispatch('githubCodeBlocks.after', text, options, globals);
});
showdown.subParser('hashBlock', function (text, options, globals) {
'use strict';
text = text.replace(/(^\n+|\n+$)/g, '');
return '\n\n~K' + (globals.gHtmlBlocks.push(text) - 1) + 'K\n\n';
});
showdown.subParser('hashElement', function (text, options, globals) {
'use strict';
return function (wholeMatch, m1) {
var blockText = m1;
// Undo double lines
blockText = blockText.replace(/\n\n/g, '\n');
blockText = blockText.replace(/^\n/, '');
// strip trailing blank lines
blockText = blockText.replace(/\n+$/g, '');
// Replace the element text with a marker ("~KxK" where x is its key)
blockText = '\n\n~K' + (globals.gHtmlBlocks.push(blockText) - 1) + 'K\n\n';
return blockText;
};
});
showdown.subParser('hashHTMLBlocks', function (text, options, globals) {
'use strict';
var blockTags = [
'pre',
'div',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'blockquote',
'table',
'dl',
'ol',
'ul',
'script',
'noscript',
'form',
'fieldset',
'iframe',
'math',
'style',
'section',
'header',
'footer',
'nav',
'article',
'aside',
'address',
'audio',
'canvas',
'figure',
'hgroup',
'output',
'video',
'p'
],
repFunc = function (wholeMatch, match, left, right) {
var txt = wholeMatch;
// check if this html element is marked as markdown
// if so, it's contents should be parsed as markdown
if (left.search(/\bmarkdown\b/) !== -1) {
txt = left + globals.converter.makeHtml(match) + right;
}
return '\n\n~K' + (globals.gHtmlBlocks.push(txt) - 1) + 'K\n\n';
};
for (var i = 0; i < blockTags.length; ++i) {
text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}<' + blockTags[i] + '\\b[^>]*>', '</' + blockTags[i] + '>', 'gim');
}
// HR SPECIAL CASE
text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,
showdown.subParser('hashElement')(text, options, globals));
// Special case for standalone HTML comments:
text = text.replace(/(<!--[\s\S]*?-->)/g,
showdown.subParser('hashElement')(text, options, globals));
// PHP and ASP-style processor instructions (<?...?> and <%...%>)
text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,
showdown.subParser('hashElement')(text, options, globals));
return text;
});
/**
* Hash span elements that should not be parsed as markdown
*/
showdown.subParser('hashHTMLSpans', function (text, config, globals) {
'use strict';
var matches = showdown.helper.matchRecursiveRegExp(text, '<code\\b[^>]*>', '</code>', 'gi');
for (var i = 0; i < matches.length; ++i) {
text = text.replace(matches[i][0], '~L' + (globals.gHtmlSpans.push(matches[i][0]) - 1) + 'L');
}
return text;
});
/**
* Unhash HTML spans
*/
showdown.subParser('unhashHTMLSpans', function (text, config, globals) {
'use strict';
for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
text = text.replace('~L' + i + 'L', globals.gHtmlSpans[i]);
}
return text;
});
/**
* Hash span elements that should not be parsed as markdown
*/
showdown.subParser('hashPreCodeTags', function (text, config, globals) {
'use strict';
var repFunc = function (wholeMatch, match, left, right) {
// encode html entities
var codeblock = left + showdown.subParser('encodeCode')(match) + right;
return '\n\n~G' + (globals.ghCodeBlocks.push({text: wholeMatch, codeblock: codeblock}) - 1) + 'G\n\n';
};
text = showdown.helper.replaceRecursiveRegExp(text, repFunc, '^(?: |\\t){0,3}<pre\\b[^>]*>\\s*<code\\b[^>]*>', '^(?: |\\t){0,3}</code>\\s*</pre>', 'gim');
return text;
});
showdown.subParser('headers', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('headers.before', text, options, globals);
var prefixHeader = options.prefixHeaderId,
headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
// Set text-style headers:
// Header 1
// ========
//
// Header 2
// --------
//
setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
text = text.replace(setextRegexH1, function (wholeMatch, m1) {
var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
hLevel = headerLevelStart,
hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
return showdown.subParser('hashBlock')(hashBlock, options, globals);
});
text = text.replace(setextRegexH2, function (matchFound, m1) {
var spanGamut = showdown.subParser('spanGamut')(m1, options, globals),
hID = (options.noHeaderId) ? '' : ' id="' + headerId(m1) + '"',
hLevel = headerLevelStart + 1,
hashBlock = '<h' + hLevel + hID + '>' + spanGamut + '</h' + hLevel + '>';
return showdown.subParser('hashBlock')(hashBlock, options, globals);
});
// atx-style headers:
// # Header 1
// ## Header 2
// ## Header 2 with closing hashes ##
// ...
// ###### Header 6
//
text = text.replace(/^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm, function (wholeMatch, m1, m2) {
var span = showdown.subParser('spanGamut')(m2, options, globals),
hID = (options.noHeaderId) ? '' : ' id="' + headerId(m2) + '"',
hLevel = headerLevelStart - 1 + m1.length,
header = '<h' + hLevel + hID + '>' + span + '</h' + hLevel + '>';
return showdown.subParser('hashBlock')(header, options, globals);
});
function headerId(m) {
var title, escapedId = m.replace(/[^\w]/g, '').toLowerCase();
if (globals.hashLinkCounts[escapedId]) {
title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++);
} else {
title = escapedId;
globals.hashLinkCounts[escapedId] = 1;
}
// Prefix id to prevent causing inadvertent pre-existing style matches.
if (prefixHeader === true) {
prefixHeader = 'section';
}
if (showdown.helper.isString(prefixHeader)) {
return prefixHeader + title;
}
return title;
}
text = globals.converter._dispatch('headers.after', text, options, globals);
return text;
});
/**
* Turn Markdown image shortcuts into <img> tags.
*/
showdown.subParser('images', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('images.before', text, options, globals);
var inlineRegExp = /!\[(.*?)]\s?\([ \t]*()<?(\S+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(['"])(.*?)\6[ \t]*)?\)/g,
referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[(.*?)]()()()()()/g;
function writeImageTag (wholeMatch, altText, linkId, url, width, height, m5, title) {
var gUrls = globals.gUrls,
gTitles = globals.gTitles,
gDims = globals.gDimensions;
linkId = linkId.toLowerCase();
if (!title) {
title = '';
}
if (url === '' || url === null) {
if (linkId === '' || linkId === null) {
// lower-case and turn embedded newlines into spaces
linkId = altText.toLowerCase().replace(/ ?\n/g, ' ');
}
url = '#' + linkId;
if (!showdown.helper.isUndefined(gUrls[linkId])) {
url = gUrls[linkId];
if (!showdown.helper.isUndefined(gTitles[linkId])) {
title = gTitles[linkId];
}
if (!showdown.helper.isUndefined(gDims[linkId])) {
width = gDims[linkId].width;
height = gDims[linkId].height;
}
} else {
return wholeMatch;
}
}
altText = altText.replace(/"/g, '&quot;');
altText = showdown.helper.escapeCharacters(altText, '*_', false);
url = showdown.helper.escapeCharacters(url, '*_', false);
var result = '<img src="' + url + '" alt="' + altText + '"';
if (title) {
title = title.replace(/"/g, '&quot;');
title = showdown.helper.escapeCharacters(title, '*_', false);
result += ' title="' + title + '"';
}
if (width && height) {
width = (width === '*') ? 'auto' : width;
height = (height === '*') ? 'auto' : height;
result += ' width="' + width + '"';
result += ' height="' + height + '"';
}
result += ' />';
return result;
}
// First, handle reference-style labeled images: ![alt text][id]
text = text.replace(referenceRegExp, writeImageTag);
// Next, handle inline images: ![alt text](url =<width>x<height> "optional title")
text = text.replace(inlineRegExp, writeImageTag);
text = globals.converter._dispatch('images.after', text, options, globals);
return text;
});
showdown.subParser('italicsAndBold', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('italicsAndBold.before', text, options, globals);
if (options.literalMidWordUnderscores) {
//underscores
// Since we are consuming a \s character, we need to add it
text = text.replace(/(^|\s|>|\b)__(?=\S)([\s\S]+?)__(?=\b|<|\s|$)/gm, '$1<strong>$2</strong>');
text = text.replace(/(^|\s|>|\b)_(?=\S)([\s\S]+?)_(?=\b|<|\s|$)/gm, '$1<em>$2</em>');
//asterisks
text = text.replace(/(\*\*)(?=\S)([^\r]*?\S[*]*)\1/g, '<strong>$2</strong>');
text = text.replace(/(\*)(?=\S)([^\r]*?\S)\1/g, '<em>$2</em>');
} else {
// <strong> must go first:
text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g, '<strong>$2</strong>');
text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g, '<em>$2</em>');
}
text = globals.converter._dispatch('italicsAndBold.after', text, options, globals);
return text;
});
/**
* Form HTML ordered (numbered) and unordered (bulleted) lists.
*/
showdown.subParser('lists', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('lists.before', text, options, globals);
/**
* Process the contents of a single ordered or unordered list, splitting it
* into individual list items.
* @param {string} listStr
* @param {boolean} trimTrailing
* @returns {string}
*/
function processListItems (listStr, trimTrailing) {
// The $g_list_level global keeps track of when we're inside a list.
// Each time we enter a list, we increment it; when we leave a list,
// we decrement. If it's zero, we're not in a list anymore.
//
// We do this because when we're not inside a list, we want to treat
// something like this:
//
// I recommend upgrading to version
// 8. Oops, now this line is treated
// as a sub-list.
//
// As a single paragraph, despite the fact that the second line starts
// with a digit-period-space sequence.
//
// Whereas when we're inside a list (or sub-list), that line will be
// treated as the start of a sub-list. What a kludge, huh? This is
// an aspect of Markdown's syntax that's hard to parse perfectly
// without resorting to mind-reading. Perhaps the solution is to
// change the syntax rules such that sub-lists must start with a
// starting cardinal number; e.g. "1." or "a.".
globals.gListLevel++;
// trim trailing blank lines:
listStr = listStr.replace(/\n{2,}$/, '\n');
// attacklab: add sentinel to emulate \z
listStr += '~0';
var rgx = /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
isParagraphed = (/\n[ \t]*\n(?!~0)/.test(listStr));
listStr = listStr.replace(rgx, function (wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
checked = (checked && checked.trim() !== '');
var item = showdown.subParser('outdent')(m4, options, globals),
bulletStyle = '';
// Support for github tasklists
if (taskbtn && options.tasklists) {
bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
item = item.replace(/^[ \t]*\[(x|X| )?]/m, function () {
var otp = '<input type="checkbox" disabled style="margin: 0px 0.35em 0.25em -1.6em; vertical-align: middle;"';
if (checked) {
otp += ' checked';
}
otp += '>';
return otp;
});
}
// m1 - Leading line or
// Has a double return (multi paragraph) or
// Has sublist
if (m1 || (item.search(/\n{2,}/) > -1)) {
item = showdown.subParser('githubCodeBlocks')(item, options, globals);
item = showdown.subParser('blockGamut')(item, options, globals);
} else {
// Recursion for sub-lists:
item = showdown.subParser('lists')(item, options, globals);
item = item.replace(/\n$/, ''); // chomp(item)
if (isParagraphed) {
item = showdown.subParser('paragraphs')(item, options, globals);
} else {
item = showdown.subParser('spanGamut')(item, options, globals);
}
}
item = '\n<li' + bulletStyle + '>' + item + '</li>\n';
return item;
});
// attacklab: strip sentinel
listStr = listStr.replace(/~0/g, '');
globals.gListLevel--;
if (trimTrailing) {
listStr = listStr.replace(/\s+$/, '');
}
return listStr;
}
/**
* Check and parse consecutive lists (better fix for issue #142)
* @param {string} list
* @param {string} listType
* @param {boolean} trimTrailing
* @returns {string}
*/
function parseConsecutiveLists(list, listType, trimTrailing) {
// check if we caught 2 or more consecutive lists by mistake
// we use the counterRgx, meaning if listType is UL we look for UL and vice versa
var counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm,
subLists = [],
result = '';
if (list.search(counterRxg) !== -1) {
(function parseCL(txt) {
var pos = txt.search(counterRxg);
if (pos !== -1) {
// slice
result += '\n\n<' + listType + '>' + processListItems(txt.slice(0, pos), !!trimTrailing) + '</' + listType + '>\n\n';
// invert counterType and listType
listType = (listType === 'ul') ? 'ol' : 'ul';
counterRxg = (listType === 'ul') ? /^ {0,2}\d+\.[ \t]/gm : /^ {0,2}[*+-][ \t]/gm;
//recurse
parseCL(txt.slice(pos));
} else {
result += '\n\n<' + listType + '>' + processListItems(txt, !!trimTrailing) + '</' + listType + '>\n\n';
}
})(list);
for (var i = 0; i < subLists.length; ++i) {
}
} else {
result = '\n\n<' + listType + '>' + processListItems(list, !!trimTrailing) + '</' + listType + '>\n\n';
}
return result;
}
// attacklab: add sentinel to hack around khtml/safari bug:
// http://bugs.webkit.org/show_bug.cgi?id=11231
text += '~0';
// Re-usable pattern to match any entire ul or ol list:
var wholeList = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
if (globals.gListLevel) {
text = text.replace(wholeList, function (wholeMatch, list, m2) {
var listType = (m2.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
return parseConsecutiveLists(list, listType, true);
});
} else {
wholeList = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
//wholeList = /(\n\n|^\n?)( {0,3}([*+-]|\d+\.)[ \t]+[\s\S]+?)(?=(~0)|(\n\n(?!\t| {2,}| {0,3}([*+-]|\d+\.)[ \t])))/g;
text = text.replace(wholeList, function (wholeMatch, m1, list, m3) {
var listType = (m3.search(/[*+-]/g) > -1) ? 'ul' : 'ol';
return parseConsecutiveLists(list, listType);
});
}
// attacklab: strip sentinel
text = text.replace(/~0/, '');
text = globals.converter._dispatch('lists.after', text, options, globals);
return text;
});
/**
* Remove one level of line-leading tabs or spaces
*/
showdown.subParser('outdent', function (text) {
'use strict';
// attacklab: hack around Konqueror 3.5.4 bug:
// "----------bug".replace(/^-/g,"") == "bug"
text = text.replace(/^(\t|[ ]{1,4})/gm, '~0'); // attacklab: g_tab_width
// attacklab: clean up hack
text = text.replace(/~0/g, '');
return text;
});
/**
*
*/
showdown.subParser('paragraphs', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('paragraphs.before', text, options, globals);
// Strip leading and trailing lines:
text = text.replace(/^\n+/g, '');
text = text.replace(/\n+$/g, '');
var grafs = text.split(/\n{2,}/g),
grafsOut = [],
end = grafs.length; // Wrap <p> tags
for (var i = 0; i < end; i++) {
var str = grafs[i];
// if this is an HTML marker, copy it
if (str.search(/~(K|G)(\d+)\1/g) >= 0) {
grafsOut.push(str);
} else {
str = showdown.subParser('spanGamut')(str, options, globals);
str = str.replace(/^([ \t]*)/g, '<p>');
str += '</p>';
grafsOut.push(str);
}
}
/** Unhashify HTML blocks */
end = grafsOut.length;
for (i = 0; i < end; i++) {
var blockText = '',
grafsOutIt = grafsOut[i],
codeFlag = false;
// if this is a marker for an html block...
while (grafsOutIt.search(/~(K|G)(\d+)\1/) >= 0) {
var delim = RegExp.$1,
num = RegExp.$2;
if (delim === 'K') {
blockText = globals.gHtmlBlocks[num];
} else {
// we need to check if ghBlock is a false positive
if (codeFlag) {
// use encoded version of all text
blockText = showdown.subParser('encodeCode')(globals.ghCodeBlocks[num].text);
} else {
blockText = globals.ghCodeBlocks[num].codeblock;
}
}
blockText = blockText.replace(/\$/g, '$$$$'); // Escape any dollar signs
grafsOutIt = grafsOutIt.replace(/(\n\n)?~(K|G)\d+\2(\n\n)?/, blockText);
// Check if grafsOutIt is a pre->code
if (/^<pre\b[^>]*>\s*<code\b[^>]*>/.test(grafsOutIt)) {
codeFlag = true;
}
}
grafsOut[i] = grafsOutIt;
}
text = grafsOut.join('\n\n');
// Strip leading and trailing lines:
text = text.replace(/^\n+/g, '');
text = text.replace(/\n+$/g, '');
return globals.converter._dispatch('paragraphs.after', text, options, globals);
});
/**
* Run extension
*/
showdown.subParser('runExtension', function (ext, text, options, globals) {
'use strict';
if (ext.filter) {
text = ext.filter(text, globals.converter, options);
} else if (ext.regex) {
// TODO remove this when old extension loading mechanism is deprecated
var re = ext.regex;
if (!re instanceof RegExp) {
re = new RegExp(re, 'g');
}
text = text.replace(re, ext.replace);
}
return text;
});
/**
* These are all the transformations that occur *within* block-level
* tags like paragraphs, headers, and list items.
*/
showdown.subParser('spanGamut', function (text, options, globals) {
'use strict';
text = globals.converter._dispatch('spanGamut.before', text, options, globals);
text = showdown.subParser('codeSpans')(text, options, globals);
text = showdown.subParser('escapeSpecialCharsWithinTagAttributes')(text, options, globals);
text = showdown.subParser('encodeBackslashEscapes')(text, options, globals);
// Process anchor and image tags. Images must come first,
// because ![foo][f] looks like an anchor.
text = showdown.subParser('images')(text, options, globals);
text = showdown.subParser('anchors')(text, options, globals);
// Make links out of things like `<http://example.com/>`
// Must come after _DoAnchors(), because you can use < and >
// delimiters in inline links like [this](<url>).
text = showdown.subParser('autoLinks')(text, options, globals);
text = showdown.subParser('encodeAmpsAndAngles')(text, options, globals);
text = showdown.subParser('italicsAndBold')(text, options, globals);
text = showdown.subParser('strikethrough')(text, options, globals);
// Do hard breaks:
text = text.replace(/ +\n/g, ' <br />\n');
text = globals.converter._dispatch('spanGamut.after', text, options, globals);
return text;
});
showdown.subParser('strikethrough', function (text, options, globals) {
'use strict';
if (options.strikethrough) {
text = globals.converter._dispatch('strikethrough.before', text, options, globals);
text = text.replace(/(?:~T){2}([\s\S]+?)(?:~T){2}/g, '<del>$1</del>');
text = globals.converter._dispatch('strikethrough.after', text, options, globals);
}
return text;
});
/**
* Strip any lines consisting only of spaces and tabs.
* This makes subsequent regexs easier to write, because we can
* match consecutive blank lines with /\n+/ instead of something
* contorted like /[ \t]*\n+/
*/
showdown.subParser('stripBlankLines', function (text) {
'use strict';
return text.replace(/^[ \t]+$/mg, '');
});
/**
* Strips link definitions from text, stores the URLs and titles in
* hash references.
* Link defs are in the form: ^[id]: url "optional title"
*
* ^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1
* [ \t]*
* \n? // maybe *one* newline
* [ \t]*
* <?(\S+?)>? // url = $2
* [ \t]*
* \n? // maybe one newline
* [ \t]*
* (?:
* (\n*) // any lines skipped = $3 attacklab: lookbehind removed
* ["(]
* (.+?) // title = $4
* [")]
* [ \t]*
* )? // title is optional
* (?:\n+|$)
* /gm,
* function(){...});
*
*/
showdown.subParser('stripLinkDefinitions', function (text, options, globals) {
'use strict';
var regex = /^ {0,3}\[(.+)]:[ \t]*\n?[ \t]*<?(\S+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=~0))/gm;
// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
text += '~0';
text = text.replace(regex, function (wholeMatch, linkId, url, width, height, blankLines, title) {
linkId = linkId.toLowerCase();
globals.gUrls[linkId] = showdown.subParser('encodeAmpsAndAngles')(url); // Link IDs are case-insensitive
if (blankLines) {
// Oops, found blank lines, so it's not a title.
// Put back the parenthetical statement we stole.
return blankLines + title;
} else {
if (title) {
globals.gTitles[linkId] = title.replace(/"|'/g, '&quot;');
}
if (options.parseImgDimensions && width && height) {
globals.gDimensions[linkId] = {
width: width,
height: height
};
}
}
// Completely remove the definition from the text
return '';
});
// attacklab: strip sentinel
text = text.replace(/~0/, '');
return text;
});
showdown.subParser('tables', function (text, options, globals) {
'use strict';
if (!options.tables) {
return text;
}
var tableRgx = /^[ \t]{0,3}\|?.+\|.+\n[ \t]{0,3}\|?[ \t]*:?[ \t]*(?:-|=){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:-|=){2,}[\s\S]+?(?:\n\n|~0)/gm;
function parseStyles(sLine) {
if (/^:[ \t]*--*$/.test(sLine)) {
return ' style="text-align:left;"';
} else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
return ' style="text-align:right;"';
} else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
return ' style="text-align:center;"';
} else {
return '';
}
}
function parseHeaders(header, style) {
var id = '';
header = header.trim();
if (options.tableHeaderId) {
id = ' id="' + header.replace(/ /g, '_').toLowerCase() + '"';
}
header = showdown.subParser('spanGamut')(header, options, globals);
return '<th' + id + style + '>' + header + '</th>\n';
}
function parseCells(cell, style) {
var subText = showdown.subParser('spanGamut')(cell, options, globals);
return '<td' + style + '>' + subText + '</td>\n';
}
function buildTable(headers, cells) {
var tb = '<table>\n<thead>\n<tr>\n',
tblLgn = headers.length;
for (var i = 0; i < tblLgn; ++i) {
tb += headers[i];
}
tb += '</tr>\n</thead>\n<tbody>\n';
for (i = 0; i < cells.length; ++i) {
tb += '<tr>\n';
for (var ii = 0; ii < tblLgn; ++ii) {
tb += cells[i][ii];
}
tb += '</tr>\n';
}
tb += '</tbody>\n</table>\n';
return tb;
}
text = globals.converter._dispatch('tables.before', text, options, globals);
text = text.replace(tableRgx, function (rawTable) {
var i, tableLines = rawTable.split('\n');
// strip wrong first and last column if wrapped tables are used
for (i = 0; i < tableLines.length; ++i) {
if (/^[ \t]{0,3}\|/.test(tableLines[i])) {
tableLines[i] = tableLines[i].replace(/^[ \t]{0,3}\|/, '');
}
if (/\|[ \t]*$/.test(tableLines[i])) {
tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, '');
}
}
var rawHeaders = tableLines[0].split('|').map(function (s) { return s.trim();}),
rawStyles = tableLines[1].split('|').map(function (s) { return s.trim();}),
rawCells = [],
headers = [],
styles = [],
cells = [];
tableLines.shift();
tableLines.shift();
for (i = 0; i < tableLines.length; ++i) {
if (tableLines[i].trim() === '') {
continue;
}
rawCells.push(
tableLines[i]
.split('|')
.map(function (s) {
return s.trim();
})
);
}
if (rawHeaders.length < rawStyles.length) {
return rawTable;
}
for (i = 0; i < rawStyles.length; ++i) {
styles.push(parseStyles(rawStyles[i]));
}
for (i = 0; i < rawHeaders.length; ++i) {
if (showdown.helper.isUndefined(styles[i])) {
styles[i] = '';
}
headers.push(parseHeaders(rawHeaders[i], styles[i]));
}
for (i = 0; i < rawCells.length; ++i) {
var row = [];
for (var ii = 0; ii < headers.length; ++ii) {
if (showdown.helper.isUndefined(rawCells[i][ii])) {
}
row.push(parseCells(rawCells[i][ii], styles[ii]));
}
cells.push(row);
}
return buildTable(headers, cells);
});
text = globals.converter._dispatch('tables.after', text, options, globals);
return text;
});
/**
* Swap back in all the special characters we've hidden.
*/
showdown.subParser('unescapeSpecialChars', function (text) {
'use strict';
text = text.replace(/~E(\d+)E/g, function (wholeMatch, m1) {
var charCodeToReplace = parseInt(m1);
return String.fromCharCode(charCodeToReplace);
});
return text;
});
module.exports = showdown;
// HTML 支持的数学符号
function strNumDiscode(str){
str = str.replace(/&forall;/g, '∀');
str = str.replace(/&part;/g, '∂');
str = str.replace(/&exists;/g, '∃');
str = str.replace(/&empty;/g, '∅');
str = str.replace(/&nabla;/g, '∇');
str = str.replace(/&isin;/g, '∈');
str = str.replace(/&notin;/g, '∉');
str = str.replace(/&ni;/g, '∋');
str = str.replace(/&prod;/g, '∏');
str = str.replace(/&sum;/g, '∑');
str = str.replace(/&minus;/g, '−');
str = str.replace(/&lowast;/g, '∗');
str = str.replace(/&radic;/g, '√');
str = str.replace(/&prop;/g, '∝');
str = str.replace(/&infin;/g, '∞');
str = str.replace(/&ang;/g, '∠');
str = str.replace(/&and;/g, '∧');
str = str.replace(/&or;/g, '∨');
str = str.replace(/&cap;/g, '∩');
str = str.replace(/&cap;/g, '∪');
str = str.replace(/&int;/g, '∫');
str = str.replace(/&there4;/g, '∴');
str = str.replace(/&sim;/g, '∼');
str = str.replace(/&cong;/g, '≅');
str = str.replace(/&asymp;/g, '≈');
str = str.replace(/&ne;/g, '≠');
str = str.replace(/&le;/g, '≤');
str = str.replace(/&ge;/g, '≥');
str = str.replace(/&sub;/g, '⊂');
str = str.replace(/&sup;/g, '⊃');
str = str.replace(/&nsub;/g, '⊄');
str = str.replace(/&sube;/g, '⊆');
str = str.replace(/&supe;/g, '⊇');
str = str.replace(/&oplus;/g, '⊕');
str = str.replace(/&otimes;/g, '⊗');
str = str.replace(/&perp;/g, '⊥');
str = str.replace(/&sdot;/g, '⋅');
return str;
}
//HTML 支持的希腊字母
function strGreeceDiscode(str){
str = str.replace(/&Alpha;/g, 'Α');
str = str.replace(/&Beta;/g, 'Β');
str = str.replace(/&Gamma;/g, 'Γ');
str = str.replace(/&Delta;/g, 'Δ');
str = str.replace(/&Epsilon;/g, 'Ε');
str = str.replace(/&Zeta;/g, 'Ζ');
str = str.replace(/&Eta;/g, 'Η');
str = str.replace(/&Theta;/g, 'Θ');
str = str.replace(/&Iota;/g, 'Ι');
str = str.replace(/&Kappa;/g, 'Κ');
str = str.replace(/&Lambda;/g, 'Λ');
str = str.replace(/&Mu;/g, 'Μ');
str = str.replace(/&Nu;/g, 'Ν');
str = str.replace(/&Xi;/g, 'Ν');
str = str.replace(/&Omicron;/g, 'Ο');
str = str.replace(/&Pi;/g, 'Π');
str = str.replace(/&Rho;/g, 'Ρ');
str = str.replace(/&Sigma;/g, 'Σ');
str = str.replace(/&Tau;/g, 'Τ');
str = str.replace(/&Upsilon;/g, 'Υ');
str = str.replace(/&Phi;/g, 'Φ');
str = str.replace(/&Chi;/g, 'Χ');
str = str.replace(/&Psi;/g, 'Ψ');
str = str.replace(/&Omega;/g, 'Ω');
str = str.replace(/&alpha;/g, 'α');
str = str.replace(/&beta;/g, 'β');
str = str.replace(/&gamma;/g, 'γ');
str = str.replace(/&delta;/g, 'δ');
str = str.replace(/&epsilon;/g, 'ε');
str = str.replace(/&zeta;/g, 'ζ');
str = str.replace(/&eta;/g, 'η');
str = str.replace(/&theta;/g, 'θ');
str = str.replace(/&iota;/g, 'ι');
str = str.replace(/&kappa;/g, 'κ');
str = str.replace(/&lambda;/g, 'λ');
str = str.replace(/&mu;/g, 'μ');
str = str.replace(/&nu;/g, 'ν');
str = str.replace(/&xi;/g, 'ξ');
str = str.replace(/&omicron;/g, 'ο');
str = str.replace(/&pi;/g, 'π');
str = str.replace(/&rho;/g, 'ρ');
str = str.replace(/&sigmaf;/g, 'ς');
str = str.replace(/&sigma;/g, 'σ');
str = str.replace(/&tau;/g, 'τ');
str = str.replace(/&upsilon;/g, 'υ');
str = str.replace(/&phi;/g, 'φ');
str = str.replace(/&chi;/g, 'χ');
str = str.replace(/&psi;/g, 'ψ');
str = str.replace(/&omega;/g, 'ω');
str = str.replace(/&thetasym;/g, 'ϑ');
str = str.replace(/&upsih;/g, 'ϒ');
str = str.replace(/&piv;/g, 'ϖ');
str = str.replace(/&middot;/g, '·');
return str;
}
//
function strcharacterDiscode(str){
// 加入常用解析
str = str.replace(/&nbsp;/g, ' ');
str = str.replace(/&quot;/g, '"');
str = str.replace(/&amp;/g, '&');
// str = str.replace(/&lt;/g, '‹');
// str = str.replace(/&gt;/g, '›');
str = str.replace(/&lt;/g, '<');
str = str.replace(/&gt;/g, '>');
return str;
}
// HTML 支持的其他实体
function strOtherDiscode(str){
str = str.replace(/&OElig;/g, 'Œ');
str = str.replace(/&oelig;/g, 'œ');
str = str.replace(/&Scaron;/g, 'Š');
str = str.replace(/&scaron;/g, 'š');
str = str.replace(/&Yuml;/g, 'Ÿ');
str = str.replace(/&fnof;/g, 'ƒ');
str = str.replace(/&circ;/g, 'ˆ');
str = str.replace(/&tilde;/g, '˜');
str = str.replace(/&ensp;/g, '');
str = str.replace(/&emsp;/g, '');
str = str.replace(/&thinsp;/g, '');
str = str.replace(/&zwnj;/g, '');
str = str.replace(/&zwj;/g, '');
str = str.replace(/&lrm;/g, '');
str = str.replace(/&rlm;/g, '');
str = str.replace(/&ndash;/g, '–');
str = str.replace(/&mdash;/g, '—');
str = str.replace(/&lsquo;/g, '‘');
str = str.replace(/&rsquo;/g, '’');
str = str.replace(/&sbquo;/g, '‚');
str = str.replace(/&ldquo;/g, '“');
str = str.replace(/&rdquo;/g, '”');
str = str.replace(/&bdquo;/g, '„');
str = str.replace(/&dagger;/g, '†');
str = str.replace(/&Dagger;/g, '‡');
str = str.replace(/&bull;/g, '•');
str = str.replace(/&hellip;/g, '…');
str = str.replace(/&permil;/g, '‰');
str = str.replace(/&prime;/g, '′');
str = str.replace(/&Prime;/g, '″');
str = str.replace(/&lsaquo;/g, '‹');
str = str.replace(/&rsaquo;/g, '›');
str = str.replace(/&oline;/g, '‾');
str = str.replace(/&euro;/g, '€');
str = str.replace(/&trade;/g, '™');
str = str.replace(/&larr;/g, '←');
str = str.replace(/&uarr;/g, '↑');
str = str.replace(/&rarr;/g, '→');
str = str.replace(/&darr;/g, '↓');
str = str.replace(/&harr;/g, '↔');
str = str.replace(/&crarr;/g, '↵');
str = str.replace(/&lceil;/g, '⌈');
str = str.replace(/&rceil;/g, '⌉');
str = str.replace(/&lfloor;/g, '⌊');
str = str.replace(/&rfloor;/g, '⌋');
str = str.replace(/&loz;/g, '◊');
str = str.replace(/&spades;/g, '♠');
str = str.replace(/&clubs;/g, '♣');
str = str.replace(/&hearts;/g, '♥');
str = str.replace(/&diams;/g, '♦');
return str;
}
function strMoreDiscode(str){
str = str.replace(/\r\n/g,"");
str = str.replace(/\n/g,"");
str = str.replace(/code/g,"wxxxcode-style");
return str;
}
function strDiscode(str){
str = strNumDiscode(str);
str = strGreeceDiscode(str);
str = strcharacterDiscode(str);
str = strOtherDiscode(str);
str = strMoreDiscode(str);
return str;
}
function urlToHttpUrl(url,rep){
var patt1 = new RegExp("^//");
var result = patt1.test(url);
if(result){
url = rep+":"+url;
}
return url;
}
module.exports = {
strDiscode:strDiscode,
urlToHttpUrl:urlToHttpUrl
}
\ No newline at end of file
/**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/
/**
* utils函数引入
**/
import showdown from 'showdown.js';
import HtmlToJson from 'html2json.js';
/**
* 配置及公有属性
**/
/**
* 设置样式
*/
function deepStyleConfg(nodes, style) {
for(let i =0; i<nodes.length; i++) {
nodes[i].styleStr = style+nodes[i].styleStr
if (nodes[i].nodes) {
deepStyleConfg(nodes[i].nodes, nodes[i].styleStr)
}
}
}
/**
* 主函数入口区
**/
function wxParse(bindName = 'wxParseData', type='html', data='<div class="color:red;">数据不能为空</div>', target,imagePadding) {
var that = target;
var transData = {};//存放转化后的数据
if (type == 'html') {
transData = HtmlToJson.html2json(data, bindName);
// console.log(JSON.stringify(transData, ' ', ' '));
for (var i in transData.nodes) {
const style = transData.nodes[i].styleStr;
deepStyleConfg(transData.nodes[i].nodes, style)
}
} else if (type == 'md' || type == 'markdown') {
var converter = new showdown.Converter();
var html = converter.makeHtml(data);
transData = HtmlToJson.html2json(html, bindName);
// console.log(JSON.stringify(transData, ' ', ' '));
}
transData.view = {};
transData.view.imagePadding = 0;
if(typeof(imagePadding) != 'undefined'){
transData.view.imagePadding = imagePadding
}
var bindData = {};
bindData[bindName] = transData;
that.setData(bindData)
that.wxParseImgLoad = wxParseImgLoad;
that.wxParseImgTap = wxParseImgTap;
}
// 图片点击事件
function wxParseImgTap(e) {
var that = this;
var nowImgUrl = e.target.dataset.src;
var tagFrom = e.target.dataset.from;
if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) {
wx.previewImage({
current: nowImgUrl, // 当前显示图片的http链接
urls: that.data[tagFrom].imageUrls // 需要预览的图片http链接列表
})
}
}
/**
* 图片视觉宽高计算函数区
**/
function wxParseImgLoad(e) {
var that = this;
var tagFrom = e.target.dataset.from;
var idx = e.target.dataset.idx;
if (typeof (tagFrom) != 'undefined' && tagFrom.length > 0) {
calMoreImageInfo(e, idx, that, tagFrom)
}
}
// 假循环获取计算图片视觉最佳宽高
function calMoreImageInfo(e, idx, that, bindName) {
var temData = that.data[bindName];
if (temData.images.length == 0) {
return;
}
var temImages = temData.images;
//因为无法获取view宽度 需要自定义padding进行计算,稍后处理
var recal = wxAutoImageCal(e.detail.width, e.detail.height,that,bindName);
temImages[idx].width = recal.imageWidth;
temImages[idx].height = recal.imageheight;
temData.images = temImages;
var bindData = {};
bindData[bindName] = temData;
that.setData(bindData);
}
// 计算视觉优先的图片宽高
function wxAutoImageCal(originalWidth, originalHeight,that,bindName) {
//获取图片的原始长宽
var windowWidth = 0, windowHeight = 0;
var autoWidth = 0, autoHeight = 0;
var results = {};
wx.getSystemInfo({
success: function (res) {
var padding = that.data[bindName].view.imagePadding;
windowWidth = res.windowWidth-2*padding;
windowHeight = res.windowHeight;
//判断按照那种方式进行缩放
// console.log("windowWidth" + windowWidth);
if (originalWidth > windowWidth) {//在图片width大于手机屏幕width时候
autoWidth = windowWidth;
// console.log("autoWidth" + autoWidth);
autoHeight = (autoWidth * originalHeight) / originalWidth;
// console.log("autoHeight" + autoHeight);
results.imageWidth = autoWidth;
results.imageheight = autoHeight;
} else {//否则展示原来的数据
results.imageWidth = originalWidth;
results.imageheight = originalHeight;
}
}
})
return results;
}
function wxParseTemArray(temArrayName,bindNameReg,total,that){
var array = [];
var temData = that.data;
var obj = null;
for(var i = 0; i < total; i++){
var simArr = temData[bindNameReg+i].nodes;
array.push(simArr);
}
temArrayName = temArrayName || 'wxParseTemArray';
obj = JSON.parse('{"'+ temArrayName +'":""}');
obj[temArrayName] = array;
that.setData(obj);
}
/**
* 配置emojis
*
*/
function emojisInit(reg='',baseSrc="/wxParse/emojis/",emojis){
HtmlToJson.emojisInit(reg,baseSrc,emojis);
}
module.exports = {
wxParse: wxParse,
wxParseTemArray:wxParseTemArray,
emojisInit:emojisInit
}
<!--**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/-->
<!--基础元素-->
<template name="wxParseVideo">
<!--增加video标签支持,并循环添加-->
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<video class="{{item.classStr}} wxParse-{{item.tag}}-video" src="{{item.attr.src}}"></video>
</view>
</template>
<template name="wxParseImg">
<image class="{{item.classStr}} wxParse-{{item.tag}}" data-from="{{item.from}}" data-src="{{item.attr.src}}" data-idx="{{item.imgIndex}}" src="{{item.attr.src}}" mode="aspectFit" bindload="wxParseImgLoad" bindtap="wxParseImgTap" style="width:{{item.width}}px;height:{{item.height}}px;{{item.attr.style}}" />
</template>
<template name="WxEmojiView">
<view class="WxEmojiView wxParse-inline" style="{{item.styleStr}}">
<block wx:for="{{item.textArray}}" wx:key="">
<block class="{{item.text == '\\n' ? 'wxParse-hide':''}}" wx:if="{{item.node == 'text'}}">{{item.text}}</block>
<block wx:elif="{{item.node == 'element'}}">
<image class="wxEmoji" src="{{item.baseSrc}}{{item.text}}" />
</block>
</block>
</view>
</template>
<!--入口模版-->
<template name="wxParse">
<block wx:for="{{wxParseData}}" wx:key="">
<template is="wxParse0" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse0">
<!--<template is="wxParse1" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-c="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</view>
</block>
<block wx:elif="{{item.tag == 'table'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse1" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse1">
<!--<template is="wxParse2" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse2" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse2" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse2" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse2" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse2" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse2">
<!--<template is="wxParse3" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse3" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse3" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse3" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse3" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse3" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse3">
<!--<template is="wxParse4" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse4" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse4" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse4" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse4" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse4" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse4">
<!--<template is="wxParse5" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse5" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse5" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse5" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse5" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse5" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse5">
<!--<template is="wxParse6" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse6" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse6" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse6" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse6" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse6" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse6">
<!--<template is="wxParse7" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse7" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse7" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse7" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse7" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse7" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse7">
<!--<template is="wxParse8" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse8" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse8" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse8" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse8" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse8" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse8">
<!--<template is="wxParse9" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse9" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse9" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse9" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse9" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse9" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse9">
<!--<template is="wxParse10" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse10" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse10" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse10" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse10" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse10" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse10">
<!--<template is="wxParse11" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse11" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse11" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse11" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse11" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse11" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
<!--循环模版-->
<template name="wxParse11">
<!--<template is="wxParse12" data="{{item}}" />-->
<!--判断是否是标签节点-->
<block wx:if="{{item.node == 'element'}}">
<block wx:if="{{item.tag == 'button'}}">
<button type="default" size="mini" >
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse12" data="{{item}}"/>
</block>
</button>
</block>
<!--li类型-->
<block wx:elif="{{item.tag == 'li'}}">
<view class="{{item.classStr}} wxParse-li">
<view class="{{item.classStr}} wxParse-li-inner">
<view class="{{item.classStr}} wxParse-li-text">
<view class="{{item.classStr}} wxParse-li-circle"></view>
</view>
<view class="{{item.classStr}} wxParse-li-text">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse12" data="{{item}}"/>
</block>
</view>
</view>
</view>
</block>
<!--video类型-->
<block wx:elif="{{item.tag == 'video'}}">
<template is="wxParseVideo" data="{{item}}"/>
</block>
<!--img类型-->
<block wx:elif="{{item.tag == 'img'}}">
<template is="wxParseImg" data="{{item}}"/>
</block>
<!--a类型-->
<block wx:elif="{{item.tag == 'a'}}">
<view bindtap="wxParseTagATap" class="wxParse-inline {{item.classStr}} wxParse-{{item.tag}}" data-src="{{item.attr.href}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse12" data="{{item}}"/>
</block>
</view>
</block>
<!--其他块级标签-->
<block wx:elif="{{item.tagType == 'block'}}">
<view class="{{item.classStr}} wxParse-{{item.tag}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse12" data="{{item}}"/>
</block>
</view>
</block>
<!--内联标签-->
<view wx:else class="{{item.classStr}} wxParse-{{item.tag}} wxParse-{{item.tagType}}" style="{{item.styleStr}}">
<block wx:for="{{item.nodes}}" wx:for-item="item" wx:key="">
<template is="wxParse12" data="{{item}}"/>
</block>
</view>
</block>
<!--判断是否是文本节点-->
<block wx:elif="{{item.node == 'text'}}">
<!--如果是,直接进行-->
<template is="WxEmojiView" data="{{item}}"/>
</block>
</template>
\ No newline at end of file
/**
* author: Di (微信小程序开发工程师)
* organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
* 垂直微信小程序开发交流社区
*
* github地址: https://github.com/icindy/wxParse
*
* for: 微信小程序富文本解析
* detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
*/
.wxParse{
margin: 0 5px;
font-family: Helvetica,sans-serif;
font-size: 28rpx;
color: #666;
line-height: 1.8;
}
view{
word-break:break-all; overflow:auto;
}
.wxParse-inline{
display: inline;
margin: 0;
padding: 0;
}
/*//标题 */
.wxParse-div{margin: 0;padding: 0;}
.wxParse-h1{ font-size:2em; margin: .67em 0 }
.wxParse-h2{ font-size:1.5em; margin: .75em 0 }
.wxParse-h3{ font-size:1.17em; margin: .83em 0 }
.wxParse-h4{ margin: 1.12em 0}
.wxParse-h5 { font-size:.83em; margin: 1.5em 0 }
.wxParse-h6{ font-size:.75em; margin: 1.67em 0 }
.wxParse-h1 {
font-size: 18px;
font-weight: 400;
margin-bottom: .9em;
}
.wxParse-h2 {
font-size: 16px;
font-weight: 400;
margin-bottom: .34em;
}
.wxParse-h3 {
font-weight: 400;
font-size: 15px;
margin-bottom: .34em;
}
.wxParse-h4 {
font-weight: 400;
font-size: 14px;
margin-bottom: .24em;
}
.wxParse-h5 {
font-weight: 400;
font-size: 13px;
margin-bottom: .14em;
}
.wxParse-h6 {
font-weight: 400;
font-size: 12px;
margin-bottom: .04em;
}
.wxParse-h1, .wxParse-h2, .wxParse-h3, .wxParse-h4, .wxParse-h5, .wxParse-h6, .wxParse-b, .wxParse-strong { font-weight: bolder }
.wxParse-i,.wxParse-cite,.wxParse-em,.wxParse-var,.wxParse-address{font-style:italic}
.wxParse-pre,.wxParse-tt,.wxParse-code,.wxParse-kbd,.wxParse-samp{font-family:monospace}
.wxParse-pre{white-space:pre}
.wxParse-big{font-size:1.17em}
.wxParse-small,.wxParse-sub,.wxParse-sup{font-size:.83em}
.wxParse-sub{vertical-align:sub}
.wxParse-sup{vertical-align:super}
.wxParse-s,.wxParse-strike,.wxParse-del{text-decoration:line-through}
/*wxparse-自定义个性化的css样式*/
/*增加video的css样式*/
.wxParse-strong,wxParse-s{display: inline}
.wxParse-a{
color: deepskyblue;
word-break:break-all;
overflow:auto;
}
.wxParse-video{
text-align: center;
margin: 10px 0;
}
.wxParse-video-video{
width:100%;
}
.wxParse-img{
background-color: #efefef;
overflow: hidden;
width:40px;
height: 40px;
}
.wxParse-blockquote {
margin: 0;
padding:10px 0 10px 5px;
font-family:Courier, Calibri,"宋体";
background:#f5f5f5;
border-left: 3px solid #dbdbdb;
}
.wxParse-code,.wxParse-wxxxcode-style{
display: inline;
background:#f5f5f5;
}
.wxParse-ul{
margin: 20rpx 10rpx;
}
.wxParse-li,.wxParse-li-inner{
display: flex;
align-items: baseline;
margin: 10rpx 0;
}
.wxParse-li-text{
align-items: center;
line-height: 20px;
}
.wxParse-li-circle{
display: inline-flex;
width: 5px;
height: 5px;
background-color: #333;
margin-right: 5px;
}
.wxParse-li-square{
display: inline-flex;
width: 10rpx;
height: 10rpx;
background-color: #333;
margin-right: 5px;
}
.wxParse-li-ring{
display: inline-flex;
width: 10rpx;
height: 10rpx;
border: 2rpx solid #333;
border-radius: 50%;
background-color: #fff;
margin-right: 5px;
}
/*.wxParse-table{
width: 100%;
height: 400px;
}
.wxParse-thead,.wxParse-tfoot,.wxParse-tr{
display: flex;
flex-direction: row;
}
.wxParse-th,.wxParse-td{
display: flex;
width: 580px;
overflow: auto;
}*/
.wxParse-u {
text-decoration: underline;
}
.wxParse-hide{
display: none;
}
.WxEmojiView{
align-items: center;
}
.wxEmoji{
width: 16px;
height:16px;
}
.wxParse-tr{
display: flex;
border-right:1px solid #e0e0e0;
border-bottom:1px solid #e0e0e0;
}
.wxParse-th,
.wxParse-td{
flex:1;
padding:5px;
font-size:28rpx;
border-left:1px solid #e0e0e0;
word-break: break-all;
}
.wxParse-td:last{
border-top:1px solid #e0e0e0;
}
.wxParse-th{
background:#f0f0f0;
border-top:1px solid #e0e0e0;
}
'use strict';
Component({
externalClasses: ['custom-class'],
/**
* 组件的属性列表
* 用于组件自定义设置
*/
properties: {
// 颜色状态
type: {
type: String,
value: ''
},
// 自定义颜色
color: {
type: String,
value: ''
},
// 左侧内容
leftText: {
type: String,
value: ''
},
// 右侧内容
rightText: {
type: String,
value: ''
}
}
});
\ No newline at end of file
<view class="custom-class zan-capsule zan-capsule--{{type}}">
<block wx:if="{{color}}">
<view class="zan-capsule__left" style="background: {{ color }}; border-color: {{ color }}">{{ leftText }}</view>
<view class="zan-capsule__right" style="color: {{ color }}; border-color: {{ color }}">{{ rightText }}</view>
</block>
<block wx:else>
<view class="zan-capsule__left">{{ leftText }}</view>
<view class="zan-capsule__right">{{ rightText }}</view>
</block>
</view>
\ No newline at end of file
.zan-capsule {
display: inline-block;
font-size: 12px;
vertical-align: middle;
line-height: 19px;
-webkit-transform: scale(0.83);
transform: scale(0.83);
}
.zan-capsule__left, .zan-capsule__right {
display: inline-block;
line-height: 17px;
height: 19px;
vertical-align: middle;
box-sizing: border-box;
}
.zan-capsule__left {
padding: 0 2px;
color: #fff;
background: #999;
border-radius: 2px 0 0 2px;
border: 1rpx solid #999;
}
.zan-capsule__right {
padding: 0 5px;
color: #999;
border-radius: 0 2px 2px 0;
border: 1rpx solid #999;
}
.zan-capsule--danger .zan-capsule__left {
color: #fff;
background: #f24544;
border-color: #f24544;
}
.zan-capsule--danger .zan-capsule__right {
color: #f24544;
border-color: #f24544;
}
// about.js
var app = getApp()
var util = require("../../utils/util.js");
var api = require("../../config/api.js");
Page({
/**
* 页面的初始数据
*/
data: {
load_statue: true,
shopInfo: {
name: '戈友商城',
address: '微信小程序搜索戈友商城',
// latitude: 31.201900,
// longitude: 121.587839,
// linkPhone: '021-xxxx-xxxx',
// qqNumber: '738696120'
},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
showLocation: function (e) {
var that = this
wx.openLocation({
latitude: that.data.shopInfo.latitude,
longitude: that.data.shopInfo.longitude,
name: that.data.shopInfo.name,
address: that.data.shopInfo.address,
})
},
callPhone: function (e) {
var that = this
wx.makePhoneCall({
phoneNumber: that.data.shopInfo.linkPhone,
})
},
reLoad: function (e) {
this.loadShopInfo();
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view class="container">
<view class="about-item">
<view class="item-left">
<label>项目名称: </label>
<text>{{shopInfo.name}}</text>
</view>
</view>
<view class="about-item">
<view class="item-left">
<label>项目地址: </label>
<text>{{shopInfo.address}}</text>
</view>
<view class="item-right" bindtap="showLocation">
<image src="/static/images/ico-addr.png" class="right-icon"></image>
</view>
</view>
<view class="about-item">
<view class="item-left">
<label>电话号码: </label>
<text>{{shopInfo.linkPhone}}</text>
</view>
<view class="item-right" bindtap="callPhone">
<image src="/static/images/telephone.png" class="right-icon"></image>
</view>
</view>
<view class="about-item">
<view class="item-left">
<label>交流群: </label>
<text>{{shopInfo.qqNumber}}</text>
</view>
<view class="item-right">
<image src="/static/images/mobile.png" class="right-icon"></image>
</view>
</view>
</view>
\ No newline at end of file
/* about.wxss */
page{
height: 100%;
background-color: #F2f2f2;
}
.page-view{
height: 100%;
}
.banner-image{
width: 100%;
height: 350rpx;
background: #ee1;
margin-bottom: 30rpx;
border-bottom: solid #f2f2f2 0.5dp;
}
.about-item{
background: white;
border-top: solid #f2f2f2 0.5rpx;
border-bottom: solid #f2f2f2 0.5rpx;
width: 100%;
height: 100rpx;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.item-left{
font-size: 32rpx;
margin-left: 15rpx;
margin-top: auto;
margin-bottom: auto;
}
.item-right{
margin-right: 15rpx;
margin-top: auto;
margin-bottom: auto;
}
.right-icon{
width: 40rpx;
height: 40rpx;
}
\ No newline at end of file
const util = require('../../utils/util.js');
const api = require('../../config/api.js');
const user = require('../../utils/user.js');
//获取应用实例
const app = getApp();
Page({
data: {
// newGoods: [],
// hotGoods: [],
// topics: [],
// brands: [],
groupons: [], //商品列表信息
campaign:{}, //活动信息
isOver:true, //活动是否结束
// floorGoods: [],
// banner: [],
// channel: [],
// coupon: [],
relatedGoods:[] //推荐商品
},
onShareAppMessage: function() {
return {
title: this.data.campaign.name,
desc: this.data.campaign.desc,
path: '/pages/activity/activity',
imageUrl:this.data.campaign.promotePictures
}
},
onPullDownRefresh() {
this.getIndexData();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getIndexData: function(id) {
let that = this;
util.request(api.ActivityGoodsList,{campaignId:id}).then(function(res) { //IndexUrl
if (res.errno === 0) {
that.setData({
// newGoods: res.data.newGoodsList,//新品
// hotGoods: res.data.hotGoodsList,//人气
// topics: res.data.topicList,
// brands: res.data.brandList,
// floorGoods: res.data.floorGoodsList,
// banner: res.data.banner, //轮播图
groupons: res.data.items, //团购
campaign:res.data.campaign //活动信息
// channel: res.data.channel, //户外分类
// coupon: res.data.couponList
});
wx.setNavigationBarTitle({
title:that.data.campaign.name
})
var end = new Date(res.data.campaign.endTime).getTime();
var now =new Date().getTime();
if (end < now){ //判断活动是否过期
that.setData({
isOver:false
})
}
}
});
},
onLoad: function(options) {
console.log(options);
// 页面初始化 options为页面跳转所带来的参数
if (options.scene) {
//这个scene的值存在则证明首页的开启来源于朋友圈分享的图,同时可以通过获取到的goodId的值跳转导航到对应的详情页
var scene = decodeURIComponent(options.scene);
console.log("scene:" + scene);
let info_arr = [];
info_arr = scene.split(',');
let _type = info_arr[0];
let id = info_arr[1];
if (_type == 'goods') {
wx.navigateTo({
url: '../goods/goods?id=' + id
});
} else if (_type == 'groupon') {
wx.navigateTo({
url: '../goods/goods?grouponId=' + id
});
} else {
wx.navigateTo({
url: '../index2/index2'
});
}
}
// 页面初始化 options为页面跳转所带来的参数
if (options.grouponId) {
//这个pageId的值存在则证明首页的开启来源于用户点击来首页,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?grouponId=' + options.grouponId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.goodId) {
//这个goodId的值存在则证明首页的开启来源于分享,同时可以通过获取到的goodId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?id=' + options.goodId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.orderId) {
//这个orderId的值存在则证明首页的开启来源于订单模版通知,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../ucenter/orderDetail/orderDetail?id=' + options.orderId
});
}
this.getIndexData(options.link);
//this.getBanner();
//this.getrelatedGoods();
},
// getBanner: function() {
// let that = this;
// util.request(api.GoodsHot).then(function(res) {
// if (res.errno === 0) {
// that.setData({
// bannerInfo: res.data.bannerInfo,
// });
// }
// });
// },
getrelatedGoods: function() { //id为商品id???????????????????此页面是活动跳过来的,没有商品ID
let that = this;
util.request(api.GoodsRelated,{id:1181012}).then(function(res) {
if (res.errno === 0) {
that.setData({
relatedGoods: res.data.goodsList,
});
}
});
},
goGoods:function(e){
console.log(e);
if(e.currentTarget.dataset.member==0){
wx.showToast({
title: "该货品已经售罄",
icon:'none'
})
}else{
wx.navigateTo({
url:`/pages/goods/goods?id=${e.currentTarget.dataset.id}`
})
}
//url="/pages/goods/goods?id={{item.goods.id}}"
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
getCoupon(e) {
if (!app.globalData.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
let couponId = e.currentTarget.dataset.id,
index = e.currentTarget.dataset.index,
that = this;
util.request(api.CouponReceive, {
couponId: couponId
}, 'POST').then(res => {
if (res.errno === 0) {
wx.showToast({
title: "领取成功"
})
let _coupon = that.data.coupon;
_coupon.splice(index, 1);
that.setData({
coupon: _coupon
})
}
else{
util.showErrorToast(res.errmsg);
}
})
},
})
\ No newline at end of file
{
"navigationBarTitleText": "",
"usingComponents": {
"zan-capsule": "../../lib/zanui-weapp/capsule/index"
}
}
\ No newline at end of file
<!--index.wxml-->
<view class="container">
<view class="a-section a-groupon" wx:if="{{isOver}}">
<view class="h">
<image class="img" src="{{campaign.promotePictures}}" ></image>
</view>
<view class="b">
<view class="item" wx:for="{{groupons}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<view class="box" style="height:100%" bindtap="goGoods" data-id="{{item.goods.id}}" data-member="{{item.stockNum}}">
<view >
<image class="img" src="{{item.goods.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<view class="header">
<text class="name">{{item.goods.name}}</text>
</view>
<text class="desc">{{item.goods.brief}}</text>
<view class="price">
<view class="retailPrice">
<!-- <text class='retailPrice-text'>限时价</text> -->
<text class='retailPrice-price'>¥{{item.goods.retailPrice}}</text>
<text class='retailPrice-price2' wx:if="{{item.goods.useScores > 0}}">+戈币:{{item.goods.useScores}}</text>
<text class="counterPrice">¥{{item.goods.counterPrice}}</text>
</view>
</view>
</view>
<view class='bottom'>
<view class='progress-box'>
<progress class='progress' percent="{{item.stockNum < 100 ? (100-item.stockNum) : (item.stockNum >= 100 && item.stockNum < 1000 ? (1000-item.stockNum)*100 / 1000 : 0 )}}" color="red" stroke-width="19" activeColor="#FBE2E6" backgroundColor="#ffffff" />
<text class='progress-text'>已售{{item.stockNum < 100 ? (100-item.stockNum) : (item.stockNum >=100 && item.stockNum < 1000 ? (1000-item.stockNum)*100 / 1000 : 0 )}}%</text>
</view>
<view class="{{item.stockNum==0 ? 'gray' :'grab'}}">{{item.stockNum==0 ? '已抢完': '马上抢'}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="container2" wx:else>
<image class="over" src="../../static/images/activityOver.png" />
本轮活动已结束
</view>
<!-- 大家都在看 -->
<!-- wx:if="{{relatedGoods.length > 0}}" -->
<!-- <view class="related-goods" >
<view class="h">
<view class="line"></view>
<text class="title">大家都在看</text>
</view>
<view class="b">
<view class="item" wx:for="{{relatedGoods}}" wx:key="id">
<navigator url="/pages/goods/goods?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<text class="name">{{item.name}}</text>
<text class="price">¥{{item.retailPrice}}</text>
</navigator>
</view>
</view>
</view> -->
<view class='load-bottom'>
<view class="line"></view>
<text class="text">我是有底线的</text>
<view class="line"></view>
</view>
</view>
page {
background: #F4F4F4;
}
.container2{
text-align:center;
font-size:36rpx;
color:rgba(126,126,126,1);
background-color:#fff;
margin-bottom:20rpx;
padding-bottom:50rpx;
}
.over{
margin:0rpx auto 30rpx auto;
width:400rpx;
height:300rpx;
display: block;
}
.backIndex{
width:470rpx;
height:90rpx;
line-height: 90rpx;
text-align:center;
border:1rpx solid #FF1B40;
border-radius: 40rpx;
margin:30rpx auto;
color:#FF1B40;
}
.search {
height: 88rpx;
width: 100%;
padding: 0 30rpx;
background: #fff;
display: flex;
align-items: center;
}
.search .input {
width:706rpx;
height: 64rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
border: 2rpx solid #FF1B40;
background: #fff;
}
.search .icon {
margin-left: 16rpx;
width: 28rpx;
height: 28rpx;
}
.search .txt {
height: 42rpx;
line-height: 42rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(131,131,131,1);
margin-left: 15rpx;
}
.banner {
width: 750rpx;
height: 368rpx;
}
.banner image {
width: 100%;
height: 368rpx;
}
.m-menu {
background: #fff;
display: flex;
align-items: center;
flex-wrap: wrap;
padding-bottom: 0rpx;
padding-top: 25rpx;
}
.m-menu .item {
width: 150rpx;
height: 172rpx;
}
.m-menu image {
display: block;
width: 100rpx;
height: 100rpx;
margin: 0 auto;
margin-bottom: 12rpx;
}
.m-menu text {
display: block;
font-size: 24rpx;
text-align: center;
margin: 0 auto;
line-height: 1;
color: #333;
}
.a-section {
width: 750rpx;
height: auto;
overflow: hidden;
background: #fff;
color: #333;
}
.a-section .h {
/* display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center; */
height: auto
}
.a-section .h .img{
width:100%;
height:250rpx;
display: block;
}
.a-section .h .txt {
/* font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
float: left; */
}
.popular-box {
width: 100%;
}
.more-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
}
.popular-navigator {
width: 698rpx;
margin: 0 auto;
overflow: hidden;
}
.more-icon {
width: 12rpx;
height: 22rpx;
margin-left: 12rpx;
}
.more {
display: flex;
align-items: center;
float: right;
margin-top: 2rpx;
}
.a-brand .b {
width: 698rpx;
height: auto;
overflow: hidden;
position: relative;
margin: 0 auto;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.a-brand .wrap {
position: relative;
}
.a-brand .img {
position: absolute;
left: 0;
top: 0;
}
.a-brand .mt {
padding: 10rpx 0;
background: rgba(240,246,251,0.6);
position: absolute;
z-index: 2;
left: 0;
top: 0;
}
.a-brand .mt .brand {
width: 342rpx;
text-align: center;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
display: block;
}
.a-brand .mt .price, .a-brand .mt .unit {
width: 342rpx;
display: block;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.a-brand .item-1 {
float: left;
width: 342rpx;
height: 260rpx;
overflow: hidden;
border-top: 1rpx solid #fff;
margin-left: 1rpx;
margin-top: 12rpx;
}
.a-brand .item-1:nth-of-type(1), .a-brand .item-1:nth-of-type(2) {
margin-top: 0;
}
.a-brand .item-1 .img {
width: 342rpx;
height: 260rpx;
}
.a-coupon {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-coupon .b .item {
position: relative;
height: 200rpx;
width: 698rpx;
margin-bottom: 10rpx;
margin-left: 30rpx;
margin-right: 30rpx;
padding-top: 30rpx;
}
.a-coupon .b .coupon-bg {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 4.5rpx;
z-index: 200;
}
.a-coupon .b .tag {
height: 32rpx;
background: #a48143;
padding-left: 16rpx;
padding-right: 16rpx;
position: absolute;
left: 20rpx;
color: #fff;
top: 20rpx;
font-size: 20rpx;
text-align: center;
line-height: 32rpx;
}
.a-coupon .b .content {
width: 689rpx;
height: 193rpx;
display: flex;
flex-direction: row;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
}
.a-coupon .b .content .left {
width: 204rpx;
float: left;
}
.discount {
width: 204rpx;
display: flex;
align-items:flex-end;
justify-content: center;
margin-top: 30rpx;
}
.discount-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
color:rgba(255,34,70,1);
display: block;
margin-bottom: 15rpx;
margin-right: 5rpx;
}
.discount-num {
font-size:60rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(255,34,70,1);
}
.a-coupon .min {
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
text-align: center;
}
.coupon-main-right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.coupon-main-right .name {
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 37rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.coupon-main-right .time {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
margin-left: 37rpx;
color:rgba(110,110,110,1);
}
.coupon-main-right .use {
width: 126rpx;
border-radius:50rpx;
background: #FF1B40;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color: #fff;
text-align: center;
line-height: 50rpx;
position: absolute;
right: 40rpx;
top: 70rpx;
}
.a-groupon {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-groupon .b .item {
border-top: 1rpx solid rgba(239,239,239,1);
height: 308rpx;
width: 750rpx;
}
.a-groupon .b .img {
float: left;
width: 240rpx;
height: 240rpx;
margin-left: 38rpx;
margin-top: 33rpx;
}
.a-groupon .b .right {
float: left;
height: 244rpx;
width: 450rpx;
padding-left: 20rpx;
}
.a-groupon .b .text {
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 204rpx;
width: 476rpx;
}
.a-groupon .b .name {
width: 430rpx;
float: left;
display: block;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
overflow: hidden;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-groupon .capsule-tag {
float: right;
padding-right: 0rpx;
padding-top: 8rpx;
}
.a-groupon .zan-capsule + .zan-capsule {
margin-left: 10px;
}
.a-groupon .b .desc {
width: 430rpx;
display: block;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 10rpx;
}
.a-groupon .b .price {
height: 60rpx;
width: 476rpx;
color: #ab956d;
line-height: 40rpx;
font-size: 33rpx;
display: flex;
position: relative;
}
.a-groupon .b .retailPrice {
display: flex;
align-items:flex-end;
margin-top: 10rpx;
height: 50rpx;
}
.a-groupon .b .counterPrice {
text-decoration: line-through;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
display: block;
height:35rpx;
margin-left: 20rpx;
margin-bottom: 5rpx;
}
.a-groupon .bottom {
position: relative;
overflow: hidden;
display: flex;
justify-content: space-between;
align-items: center;
}
.a-groupon .progress-box {
width: 197rpx;
position: relative;
}
.a-groupon .progress {
width: 197rpx;
border-radius:20rpx;
border:2rpx solid rgba(233,69,68,1);
overflow:hidden;
}
.a-groupon .progress-text {
width: 197rpx;
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
position: absolute;
top: 50%;
left: 0;
z-index: 1000;
text-align: center;
transform: translateY(-50%);
}
.a-groupon .grab {
width:160rpx;
line-height:50rpx;
background:#FF1B40;
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:rgba(255,255,255,1);
margin-right: 15rpx;
}
.a-groupon .gray {
width:160rpx;
line-height:50rpx;
background:rgba(134,133,134,1);
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:rgba(255,255,255,1);
margin-right: 15rpx;
}
.retailPrice-text {
height:35rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
display:block;
margin-bottom: 5rpx;
}
.retailPrice-price {
/* height: 28rpx; */
display:block;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
height:40rpx;
}
.retailPrice-price2 {
/* height: 28rpx; */
display:block;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
height:40rpx;
}
.a-new .b {
width: 698rpx;
height: auto;
overflow: hidden;
padding-bottom: 31rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.a-new .b .item {
width: 216rpx;
margin-top: 10rpx;
}
.a-new .b .item-b {
margin-left: 42rpx;
}
.a-new .b .img {
width: 216rpx;
height: 216rpx;
}
.a-new .b .name {
text-align: center;
display: block;
width: 216rpx;
height: 35rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
overflow: hidden;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-new .b .price {
display: block;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.a-popular {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-popular .b {
width: 698rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
padding-bottom: 36rpx;
}
.a-popular .b .item {
height: 280rpx;
width: 698rpx;
background:rgba(254,239,223,0.8);
margin: 0 auto 19rpx;
border-radius:2rpx;
}
.a-popular .b .a-popular-small {
height: 280rpx;
width: 220rpx;
border-radius:2rpx;
background: #fff;
}
.a-popular .b .img {
float: left;
width: 280rpx;
height: 280rpx;
}
.a-popular .b .a-popular-small .img {
width: 220rpx;
height: 220rpx;
}
.a-popular .b .right {
float: left;
height: 264rpx;
width:397rpx;
padding-left: 20rpx;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.a-popular .b .a-popular-small .right {
display: block;
width:230rpx;
height: 100rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding: 0;
}
.a-popular .b .text {
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 264rpx;
width: 456rpx;
}
.a-popular .b .a-popular-small .text {
display: block;
width: 220rpx;
height: 100rpx;
}
.a-popular .b .name {
width:377rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-popular .b .a-popular-small .name {
width:220rpx;
display: block;
font-size:24rpx;
text-align: center;
}
.a-popular .b .desc {
width:377rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-top: 10rpx;
}
.a-popular .b .price {
width:377rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
margin-top: 10rpx;
}
.a-popular .b .a-popular-small .price {
width: 100%;
text-align: center;
display:block;
font-size: 24rpx;
}
.a-topic .b {
height: 430rpx;
width: 750rpx;
padding: 0 0 48rpx 0;
}
.a-topic .b .list {
height: 430rpx;
width: 750rpx;
white-space: nowrap;
}
.a-topic .b .item {
display: inline-block;
width: 476rpx;
margin-left: 30rpx;
overflow: hidden;
}
.a-topic .b .item:last-child {
margin-right: 30rpx;
}
.a-topic .b .img {
height: 278rpx;
width: 476rpx;
margin-bottom: 10rpx;
}
.a-topic .b .np {
margin-bottom: 5rpx;
color: #333;
font-size: 30rpx;
}
.a-topic .b .np .name{
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.a-topic .b .np .price {
display: block;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.a-topic .b .desc {
display: block;
height: 30rpx;
color: #999;
font-size: 24rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.good-grid {
width: 750rpx;
height: auto;
overflow: hidden;
}
.good-grid .h {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
height: 130rpx;
font-size: 33rpx;
color: #333;
}
.good-grid .b {
width: 750rpx;
padding: 0 6.25rpx;
height: auto;
overflow: hidden;
}
.good-grid .b .item {
float: left;
background: #fff;
width: 365rpx;
margin-bottom: 6.25rpx;
height: 452rpx;
overflow: hidden;
text-align: center;
}
.good-grid .b .item .a {
height: 452rpx;
width: 100%;
}
.good-grid .b .item-b {
margin-left: 6.25rpx;
}
.good-grid .item .img {
margin-top: 20rpx;
width: 302rpx;
height: 302rpx;
}
.good-grid .item .name {
display: block;
width: 365.625rpx;
padding: 0 20rpx;
overflow: hidden;
height: 35rpx;
margin: 11.5rpx 0 22rpx 0;
text-align: center;
font-size: 30rpx;
color: #333;
}
.good-grid .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
color: #ab956d;
}
.good-grid .t {
height: 100rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.load-bottom {
background: #F4F4F4;
width: 100%;
height: 59rpx;
display: flex;
justify-content: center;
align-items: center;
}
.load-bottom .line {
width:51rpx;
border-bottom:1rpx solid rgba(198,196,196,1);
}
.load-bottom .text {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(198,196,196,1);
margin-left: 17rpx;
margin-right: 17rpx;
}
/* 大家都在看 */
.related-goods {
width: 750rpx;
height: auto;
overflow: hidden;
padding-bottom: 80rpx;
}
.related-goods .h {
position: relative;
height: 145.5rpx;
width: 750rpx;
padding: 56.25rpx 0;
background: #fff;
text-align: center;
border-bottom: 1px solid #f4f4f4;
}
.related-goods .h .line {
display: inline-block;
position: absolute;
top: 72rpx;
left: 0;
z-index: 2;
height: 1px;
margin-left: 225rpx;
width: 300rpx;
background: #ccc;
}
.related-goods .h .title {
display: inline-block;
position: absolute;
top: 56.125rpx;
left: 0;
z-index: 3;
height: 33rpx;
margin-left: 285rpx;
width: 180rpx;
background: #fff;
}
.related-goods .b {
width: 750rpx;
height: auto;
overflow: hidden;
}
.related-goods .b .item {
float: left;
background: #fff;
width: 375rpx;
height: auto;
overflow: hidden;
text-align: center;
padding: 15rpx 31.25rpx;
border-right: 1px solid #f4f4f4;
border-bottom: 1px solid #f4f4f4;
}
.related-goods .item .img {
width: 311.45rpx;
height: 311.45rpx;
}
.related-goods .item .name {
display: block;
width: 311.45rpx;
margin: 5rpx 0 5rpx 0;
text-align: center;
overflow: hidden;
font-size: 30rpx;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.related-goods .item .price {
display: block;
width: 311.45rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
color: #E31436;
}
var api = require('../../../config/api.js');
var util = require('../../../utils/util.js');
var user = require('../../../utils/user.js');
var app = getApp();
Page({
data: {
username: '',
password: '',
code: '',
loginErrorCount: 0
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
accountLogin: function() {
var that = this;
if (this.data.password.length < 1 || this.data.username.length < 1) {
wx.showModal({
title: '错误信息',
content: '请输入用户名和密码',
confirmColor: '#ED0E1B',
showCancel: false
});
return false;
}
wx.request({
url: api.AuthLoginByAccount,
data: {
username: that.data.username,
password: that.data.password
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function(res) {
if (res.data.errno == 0) {
that.setData({
loginErrorCount: 0
});
app.globalData.hasLogin = true;
wx.setStorageSync('userInfo', res.data.data.userInfo);
wx.setStorage({
key: "token",
data: res.data.data.token,
success: function() {
wx.switchTab({
url: '/pages/ucenter/index/index'
});
}
});
} else {
that.setData({
loginErrorCount: that.data.loginErrorCount + 1
});
app.globalData.hasLogin = false;
util.showErrorToast('账户登录失败');
}
}
});
},
bindUsernameInput: function(e) {
this.setData({
username: e.detail.value
});
},
bindPasswordInput: function(e) {
this.setData({
password: e.detail.value
});
},
bindCodeInput: function(e) {
this.setData({
code: e.detail.value
});
},
clearInput: function(e) {
switch (e.currentTarget.id) {
case 'clear-username':
this.setData({
username: ''
});
break;
case 'clear-password':
this.setData({
password: ''
});
break;
case 'clear-code':
this.setData({
code: ''
});
break;
}
}
})
\ No newline at end of file
{
"navigationBarTitleText": "账号登录"
}
\ No newline at end of file
<view class="container">
<view class="form-box">
<view class="form-item">
<input class="username" value="{{username}}" bindinput="bindUsernameInput" placeholder="账号"/>
<image wx:if="{{ username.length > 0 }}" id="clear-username" class="clear" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<view class="form-item">
<input class="password" value="{{password}}" password bindinput="bindPasswordInput" placeholder="密码"/>
<image class="clear" id="clear-password" wx:if="{{ password.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<!-- <view class="form-item-code" wx-if="{{loginErrorCount >= 3}}">
<view class="form-item code-item">
<input class="code" value="{{code}}" bindinput="bindCodeInput" placeholder="验证码"/>
<image class="clear" id="clear-code" wx:if="{{ code.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<image class="code-img" src="https://dl.reg.163.com/cp?pd=yanxuan_web&pkid=SkeBZeG&random=1489903563234"></image>
</view> -->
<button class="login-btn" bindtap="accountLogin">账号登录</button>
<view class="form-item-text">
<navigator url="/pages/auth/register/register" class="register">注册账号</navigator>
<navigator url="/pages/auth/reset/reset" class="reset">忘记密码</navigator>
</view>
</view>
</view>
\ No newline at end of file
.form-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
background: #fff;
}
.form-item {
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
}
.form-item .username, .form-item .password, .form-item .code {
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #333;
font-size: 30rpx;
}
.form-item-code {
margin-top: 32rpx;
height: auto;
overflow: hidden;
width: 100%;
}
.form-item-code .form-item {
float: left;
width: 350rpx;
}
.form-item-code .code-img {
float: right;
margin-top: 4rpx;
height: 88rpx;
width: 236rpx;
}
.form-item .clear {
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.login-btn {
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(255,255,255,1);
text-align: center;
margin: 40rpx auto;
}
.form-item-text {
height: 35rpx;
width: 100%;
}
.form-item-text .register {
display: block;
height: 34rpx;
float: left;
font-size: 28rpx;
}
.form-item-text .reset {
display: block;
height: 34rpx;
float: right;
font-size: 28rpx;
}
var api = require('../../../config/api.js');
var util = require('../../../utils/util.js');
var user = require('../../../utils/user.js');
var app = getApp();
Page({
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
wxLogin: function(e) {
console.log(e)
if (e.detail.userInfo == undefined) {
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
return;
}
user.checkLogin().catch(() => {
wx.showLoading({
title: '登录中,请稍后',
mask: true
})
user.loginByWeixin(e.detail.userInfo).then(res => {
app.globalData.hasLogin = true;
if (getCurrentPages().length>1) {
wx.navigateBack({
delta: 1
})
} else {
wx.reLaunch({
url: '/pages/ucenter/index/index',
})
}
wx.hideLoading();
}).catch((err) => {
console.log(err)
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
});
});
},
accountLogin: function() {
wx.navigateTo({
url: "/pages/auth/accountLogin/accountLogin"
});
}
})
\ No newline at end of file
{
"navigationBarTitleText": "登录"
}
\ No newline at end of file
<view class="container">
<view class="login-box">
<button open-type="getUserInfo" class="wx-login-btn" bindgetuserinfo="wxLogin">微信直接登录</button>
<button class="account-login-btn" bindtap="accountLogin">账号登录</button>
</view>
</view>
\ No newline at end of file
.login-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 200rpx;
background: #fff;
}
.wx-login-btn {
width:400rpx;
line-height:70rpx;
border: 2rpx solid #FF1B40;
color: #FF1B40;
border-radius:35px;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
text-align: center;
margin: 40rpx auto;
background: none;
}
.account-login-btn {
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:35px;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(255,255,255,1);
text-align: center;
margin: 40rpx auto;
border: none;
}
.account-login-btn::after,.wx-login-btn::after {
border: none;
border-radius: 0;
}
var api = require('../../../config/api.js');
var check = require('../../../utils/check.js');
var app = getApp();
Page({
data: {
username: '',
password: '',
confirmPassword: '',
mobile: '',
code: '',
time: 60,
timeActive: false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
sendCode: function() {
let that = this;
if (this.data.timeActive) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: `请${this.data.time}s获取验证码`,
showCancel: false
});
return false;
}
if (this.data.mobile.length == 0) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '手机号不能为空',
showCancel: false
});
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '手机号输入不正确',
showCancel: false
});
return false;
}
wx.request({
url: api.AuthRegisterCaptcha,
data: {
mobile: that.data.mobile
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function(res) {
if (res.data.errno == 0) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '发送成功',
content: '验证码已发送',
showCancel: false
});
that.setData({
timeActive: true
})
that.currentTime();
} else {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
});
},
currentTime: function() {
let that = this;
let currentTime = this.data.time;
let interval = setInterval(function () {
currentTime--;
that.setData({
time: currentTime
})
if (currentTime <= 0) {
clearInterval(interval)
that.setData({
timeActive: false,
time: 60
})
}
}, 1000)
},
requestRegister: function(wxCode) {
let that = this;
wx.request({
url: api.AuthRegister,
data: {
username: that.data.username,
password: that.data.password,
mobile: that.data.mobile,
code: that.data.code,
wxCode: wxCode
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function(res) {
if (res.data.errno == 0) {
app.globalData.hasLogin = true;
wx.setStorageSync('userInfo', res.data.data.userInfo);
wx.setStorage({
key: "token",
data: res.data.data.token,
success: function() {
wx.switchTab({
url: '/pages/ucenter/index/index'
});
}
});
} else {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
});
},
startRegister: function() {
var that = this;
if (this.data.username.length < 2) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '用户名不得少于2位',
showCancel: false
});
return false;
}
if (this.data.password.length < 6 ) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '密码不得少于6位',
showCancel: false
});
return false;
}
if (this.data.password != this.data.confirmPassword) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '确认密码不一致',
showCancel: false
});
return false;
}
if (this.data.mobile.length == 0 || this.data.code.length == 0) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '手机号和验证码不能为空',
showCancel: false
});
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '手机号输入不正确',
showCancel: false
});
return false;
}
wx.login({
success: function(res) {
if (!res.code) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: '注册失败',
showCancel: false
});
}
that.requestRegister(res.code);
}
});
},
bindUsernameInput: function(e) {
this.setData({
username: e.detail.value
});
},
bindPasswordInput: function(e) {
this.setData({
password: e.detail.value
});
},
bindConfirmPasswordInput: function(e) {
this.setData({
confirmPassword: e.detail.value
});
},
bindMobileInput: function(e) {
this.setData({
mobile: e.detail.value
});
},
bindCodeInput: function(e) {
this.setData({
code: e.detail.value
});
},
clearInput: function(e) {
switch (e.currentTarget.id) {
case 'clear-username':
this.setData({
username: ''
});
break;
case 'clear-password':
this.setData({
password: ''
});
break;
case 'clear-confirm-password':
this.setData({
confirmPassword: ''
});
break;
case 'clear-mobile':
this.setData({
mobile: ''
});
break;
case 'clear-code':
this.setData({
code: ''
});
break;
}
}
})
\ No newline at end of file
{
"navigationBarTitleText": "注册"
}
\ No newline at end of file
<view class="container">
<view class="form-box">
<view class="form-item">
<input class="username" value="{{username}}" bindinput="bindUsernameInput" placeholder="用户名" auto-focus/>
<!-- <image wx:if="{{ username.length > 0 }}" id="clear-username" class="clear" src="/static/images/clear_input.png" catchtap="clearInput"></image> -->
</view>
<view class="form-item">
<input class="password" value="{{password}}" password bindinput="bindPasswordInput" placeholder="密码" />
<!-- <image class="clear" id="clear-password" wx:if="{{ password.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>/ -->
</view>
<view class="form-item">
<input class="password" value="{{confirmPassword}}" password bindinput="bindConfirmPasswordInput" placeholder="确认密码" />
<!-- <image class="clear" id="clear-confirm-password" wx:if="{{ confirmPassword.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image> -->
</view>
<view class="form-item">
<input class="mobile" value="{{mobile}}" bindinput="bindMobileInput" type='number' maxlength='11' placeholder="手机号" />
<!-- <image wx:if="{{ mobile.length > 0 }}" id="clear-mobile" class="clear" src="/static/images/clear_input.png" catchtap="clearInput"></image> -->
</view>
<view class="form-item-code">
<view class="form-item code-item">
<input class="code" value="{{code}}" bindinput="bindCodeInput" placeholder="验证码" />
<!-- <image class="clear" id="clear-code" wx:if="{{ code.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image> -->
</view>
<view class="code-btn {{timeActive&&'code-btn-gray'}}" bindtap="sendCode">{{timeActive? time+'s后重发':'获取验证码'}}</view>
</view>
<button class="register-btn" bindtap="startRegister">注册</button>
</view>
</view>
\ No newline at end of file
.form-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
background: #fff;
}
.form-item {
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
margin-top:32rpx;
}
.form-item .username, .form-item .password, .form-item .mobile, .form-item .code {
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #333;
font-size: 30rpx;
}
.form-item-code {
overflow:hidden;
width:100%;
display:flex;
align-items:center;
margin-top:32rpx;
}
.form-item-code .form-item {
float: left;
flex: 1;
margin-top: 0;
}
.form-item-code .code-btn {
float: right;
width:160rpx;
line-height:50rpx;
border:2rpx solid #FF1B40;
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
margin-top: 28rpx;
}
.form-item-code .code-btn-gray {
border:2rpx solid #d9d9d9;
color:#d9d9d9;
}
.form-item .clear {
position: absolute;
top: 30rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.register-btn {
margin: 40rpx auto;
color: #fff;
font-size: 30rpx;
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:40rpx;
border: none;
}
.register-btn::after{
border: none;
border-radius: 0;
}
var api = require('../../../config/api.js');
var check = require('../../../utils/check.js');
var app = getApp();
Page({
data: {
mobile: '',
code: '',
password: '',
confirmPassword: '',
time: 60,
timeActive: false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
sendCode: function() {
let that = this;
if (this.data.timeActive) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: `请${this.data.time}s获取验证码`,
showCancel: false
});
return false;
}
wx.request({
url: api.AuthRegisterCaptcha,
data: {
mobile: that.data.mobile
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function(res) {
if (res.data.errno == 0) {
wx.showModal({
confirmColor: '#ED0E1B',
title: '发送成功',
content: '验证码已发送',
showCancel: false
});
that.setData({
timeActive: true
})
that.currentTime();
} else {
wx.showModal({
confirmColor: '#ED0E1B',
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
});
},
currentTime: function () {
let that = this;
let currentTime = this.data.time;
let interval = setInterval(function () {
currentTime--;
that.setData({
time: currentTime
})
if (currentTime <= 0) {
clearInterval(interval)
that.setData({
timeActive: false,
time: 60
})
}
}, 1000)
},
startReset: function() {
var that = this;
if (this.data.mobile.length == 0 || this.data.code.length == 0) {
wx.showModal({
title: '错误信息',
confirmColor: '#ED0E1B',
content: '手机号和验证码不能为空',
showCancel: false
});
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
wx.showModal({
title: '错误信息',
confirmColor: '#ED0E1B',
content: '手机号输入不正确',
showCancel: false
});
return false;
}
if (this.data.password.length < 2) {
wx.showModal({
title: '错误信息',
confirmColor: '#ED0E1B',
content: '用户名不得少于2位',
showCancel: false
});
return false;
}
if (this.data.password != this.data.confirmPassword) {
wx.showModal({
title: '错误信息',
confirmColor: '#ED0E1B',
content: '确认密码不一致',
showCancel: false
});
return false;
}
wx.request({
url: api.AuthReset,
data: {
mobile: that.data.mobile,
code: that.data.code,
password: that.data.password
},
method: 'POST',
header: {
'content-type': 'application/json'
},
success: function(res) {
if (res.data.errno == 0) {
wx.navigateBack();
} else {
wx.showModal({
title: '密码重置失败',
confirmColor: '#ED0E1B',
content: res.data.errmsg,
showCancel: false
});
}
}
});
},
bindPasswordInput: function(e) {
this.setData({
password: e.detail.value
});
},
bindConfirmPasswordInput: function(e) {
this.setData({
confirmPassword: e.detail.value
});
},
bindMobileInput: function(e) {
this.setData({
mobile: e.detail.value
});
},
bindCodeInput: function(e) {
this.setData({
code: e.detail.value
});
},
clearInput: function(e) {
switch (e.currentTarget.id) {
case 'clear-password':
this.setData({
password: ''
});
break;
case 'clear-confirm-password':
this.setData({
confirmPassword: ''
});
break;
case 'clear-mobile':
this.setData({
mobile: ''
});
break;
case 'clear-code':
this.setData({
code: ''
});
break;
}
}
})
\ No newline at end of file
{
"navigationBarTitleText": "密码重置"
}
\ No newline at end of file
<view class="container">
<view class="form-box">
<view class="form-item">
<input class="mobile" value="{{mobile}}" maxlength='11' type='number' bindinput="bindMobileInput" placeholder="手机号" />
<image wx:if="{{ mobile.length > 0 }}" id="clear-mobile" class="clear" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<view class="form-item-code">
<view class="form-item code-item">
<input class="code" value="{{code}}" bindinput="bindCodeInput" placeholder="验证码" />
<image class="clear" id="clear-code" wx:if="{{ code.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<view class="code-btn {{timeActive&&'code-btn-gray'}}" bindtap="sendCode">{{timeActive? time+'s后重发':'获取验证码'}}</view>
</view>
<view class="form-item">
<input class="password" value="{{password}}" password bindinput="bindPasswordInput" placeholder="密码" />
<image class="clear" id="clear-password" wx:if="{{ password.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<view class="form-item">
<input class="password" value="{{confirmPassword}}" password bindinput="bindConfirmPasswordInput" placeholder="确认密码" />
<image class="clear" id="clear-confirm-password" wx:if="{{ confirmPassword.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearInput"></image>
</view>
<button class="reset-btn" bindtap="startReset">密码重置</button>
</view>
</view>
\ No newline at end of file
.form-box {
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
background: #fff;
}
.form-item {
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
margin-top:32rpx;
}
.form-item .mobile, .form-item .password, .form-item .code {
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #333;
font-size: 30rpx;
}
.form-item-code {
overflow:hidden;
width:100%;
display:flex;
align-items:center;
margin-top:32rpx;
}
.form-item-code .form-item {
float: left;
flex: 1;
margin-top: 0;
}
.form-item-code .code-btn {
float: right;
width:160rpx;
line-height:50rpx;
border:2rpx solid #FF1B40;
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
margin-top: 28rpx;
}
.form-item-code .code-btn-gray {
border:2rpx solid #d9d9d9;
color:#d9d9d9;
}
.form-item .clear {
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.reset-btn {
margin: 40rpx auto;
color: #fff;
font-size: 30rpx;
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:40rpx;
border: none;
}
.reset-btn::after{
border: none;
border-radius: 0;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
brandList: [],
page: 1,
size: 10,
totalPages: 1
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.getBrandList();
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.getBrandList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getBrandList: function() {
wx.showLoading({
title: '加载中...',
});
let that = this;
util.request(api.BrandList, {
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
that.setData({
brandList: that.data.brandList.concat(res.data.brandList),
totalPages: res.data.totalPages
});
}
that.configList(res.data.brandList)
wx.hideLoading();
});
},
configList(brandList) {
for(let i=0; i<brandList.length; i++) {
brandList[i].nodes = this.configNode(brandList[i].desc);
}
this.setData({
brandList
})
},
configNode(desc) {
let _tempDesc = desc.split('|'),
_tempNodes = [];
for (let i = 0; i < _tempDesc.length; i++) {
let _tempObj = {
name: 'div',
attrs: {
class: 'div_class',
style: 'color: #666666; font-size: 30rpx; margin-left:31rpx;'
},
children: [{
type: 'text',
text: ""
}]
};
_tempObj.children[0].text = _tempDesc[i];
_tempNodes.push(_tempObj);
}
return _tempNodes
},
onReachBottom() {
if (this.data.totalPages > this.data.page) {
this.setData({
page: this.data.page + 1
});
} else {
return false;
}
this.getBrandList();
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "品牌制造商"
}
\ No newline at end of file
<view class="container">
<view class="brand-list">
<navigator url="../brandDetail/brandDetail?id={{item.id}}" class="item" wx:for="{{brandList}}" wx:key="id" hover-class='none'>
<view class="img-bg">
<image src="{{item.picUrl}}"></image>
</view>
<view class="txt-box">
<view class="line">
<text class="name" wx:if="{{item.name}}">{{item.name}}</text>
<text class="price" wx:if="{{item.floorPrice}}">¥{{item.floorPrice}}元起</text>
</view>
<rich-text class="desc" nodes="{{item.nodes}}"></rich-text>
</view>
</navigator>
</view>
</view>
\ No newline at end of file
.container {
background: #fff;
}
.brand-list .item {
display: block;
width: 750rpx;
/* height: 416rpx; */
padding-bottom: 20rpx;
position: relative;
margin-bottom: 4rpx;
}
.brand-list .item .img-bg {
width: 730rpx;
height: 303rpx;
overflow: hidden;
padding: 0 10rpx;
}
.brand-list .item .img-bg image {
width: 730rpx;
height: 303rpx;
}
.brand-list .item .txt-box {
width: 698rpx;
margin: 0 auto;
}
.brand-list .item .line {
height: 63rpx;
line-height: 63rpx;
margin-top: 10rpx;
}
.brand-list .item .line .name {
font-size:30rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(51,51,51,1);
}
.price {
color: #FF2246;
font-weight: 500;
margin-left: 20rpx;
}
.desc {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.brand-list .item .line .s {
padding: 0 10rpx;
font-size: 40rpx;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
id: 0,
brand: {},
goodsList: [],
page: 1,
size: 100,
nodes: []
},
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
var that = this;
that.setData({
id: parseInt(options.id)
});
this.getBrand();
},
getBrand: function () {
let that = this;
util.request(api.BrandDetail, {
id: that.data.id
}).then(function (res) {
if (res.errno === 0) {
that.setData({
brand: res.data.brand
});
that.configNode(res.data.brand.desc);
that.getGoodsList();
}
});
},
configNode(desc) {
let _tempDesc = desc.split('|'),
_tempNodes = [];
for(let i=0; i<_tempDesc.length;i++) {
let _tempObj = {
name: 'div',
attrs: {
class: 'div_class',
style: 'color: #666666; font-size: 30rpx; margin-left:31rpx;'
},
children: [{
type: 'text',
text: ""
}]
};
_tempObj.children[0].text = _tempDesc[i];
_tempNodes.push(_tempObj);
}
this.setData({
nodes: _tempNodes
})
},
getGoodsList() {
var that = this;
util.request(api.GoodsList, {
brandId: that.data.id,
page: that.data.page,
size: that.data.size
})
.then(function (res) {
if (res.errno === 0) {
that.setData({
goodsList: res.data.goodsList
});
}
});
},
onReady: function () {
// 页面渲染完成
},
onShow: function () {
// 页面显示
},
onHide: function () {
// 页面隐藏
},
onUnload: function () {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "品牌商详情"
}
\ No newline at end of file
<view class="container">
<view class="brand-info">
<view class="name">
<image class="img" src="{{brand.picUrl}}" background-size="cover"></image>
<view class="info-box">
<!-- <view class="info">
<text class="txt">{{brand.name}}</text>
<text class="line"></text>
</view> -->
</view>
</view>
<rich-text class="desc" nodes="{{nodes}}"></rich-text>
<!-- <view class="desc">
{{brand.desc}}
</view> -->
</view>
<view class="cate-item">
<view class="b">
<block wx:for="{{goodsList}}" wx:key="id" wx:for-index="iindex" wx:for-item="iitem">
<navigator class="item {{iindex % 2 == 0 ? 'item-b' : ''}}" url="../goods/goods?id={{iitem.id}}">
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</block>
</view>
</view>
</view>
\ No newline at end of file
page {
background: #f4f4f4;
}
.brand-info {
padding-bottom: 20rpx;
background: #fff;
}
.brand-info .name {
width: 100%;
height: 290rpx;
position: relative;
}
.brand-info .img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 290rpx;
}
.brand-info .info-box {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 290rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.brand-info .info {
display: block;
}
.brand-info .txt {
/* display: block; */
line-height: 37.5rpx;
font-size: 37.5rpx;
color: #fff;
background: rgba(0, 0, 0, 0.5);
padding: 10rpx 20rpx;
border-radius: 5rpx;
display: none;
}
.brand-info .line {
margin: 0 auto;
margin-top: 16rpx;
display: block;
height: 2rpx;
width: 145rpx;
background: #fff;
}
.brand-info .desc {
background: #fff;
width: 100%;
height: auto;
overflow: hidden;
font-size: 30rpx;
color: #666;
line-height: 41.5rpx;
/* text-align: center; */
padding: 40rpx 0;
}
.brand-info .desc .div_class {
padding: 0 31rpx;
margin: 0 auto;
background: #fff;
text-align:justify;
}
.cate-item .b {
width: 750rpx;
height: auto;
overflow: hidden;
border-top: 1rpx solid #f4f4f4;
margin-top: 20rpx;
}
.cate-item .b .item {
float: left;
background: #fff;
width: 375rpx;
padding-bottom: 33.333rpx;
border-bottom: 1rpx solid #f4f4f4;
height: auto;
overflow: hidden;
text-align: center;
}
.cate-item .b .item-b {
border-right: 1rpx solid #f4f4f4;
}
.cate-item .item .img {
margin-top: 10rpx;
width: 302rpx;
height: 302rpx;
}
.cate-item .item .name {
display: block;
width: 365.625rpx;
line-height: 35rpx;
padding: 0 20rpx;
overflow: hidden;
margin: 5rpx 0 5rpx 0;
text-align: center;
font-size: 30rpx;
color: #333;
}
.cate-item .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
color: #b4282d;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var user = require('../../utils/user.js');
var app = getApp();
Page({
data: {
cartGoods: [],
cartTotal: {
"goodsCount": 0,
"goodsAmount": 0.00,
"checkedGoodsCount": 0,
"checkedGoodsAmount": 0.00
},
isEditCart: false,
checkedAllStatus: true,
editCartList: [],
hasLogin: false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
},
onReady: function() {
// 页面渲染完成
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getCartList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
onShow: function() {
// 页面显示
if (app.globalData.hasLogin) {
this.getCartList();
}
this.setData({
hasLogin: app.globalData.hasLogin
});
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
goLogin() {
wx.navigateTo({
url: "/pages/auth/login/login"
});
},
getCartList: function() {
let that = this;
util.request(api.CartList).then(function(res) {
if (res.errno === 0) {
that.setData({
cartGoods: res.data.cartList,
cartTotal: res.data.cartTotal
});
that.setData({
checkedAllStatus: that.isCheckedAll()
});
}
});
},
isCheckedAll: function() {
//判断购物车商品已全选
return this.data.cartGoods.every(function(element, index, array) {
console.log(element)
if (element.checked == true) {
return true;
} else {
return false;
}
});
},
doCheckedAll: function() {
let checkedAll = this.isCheckedAll()
this.setData({
checkedAllStatus: this.isCheckedAll()
});
},
checkedItem: function(event) {
let itemIndex = event.target.dataset.itemIndex;
let that = this;
let productIds = [];
productIds.push(that.data.cartGoods[itemIndex].productId);
if (!this.data.isEditCart) {
util.request(api.CartChecked, {
productIds: productIds,
isChecked: that.data.cartGoods[itemIndex].checked ? 0 : 1
}, 'POST').then(function(res) {
if (res.errno === 0) {
that.setData({
cartGoods: res.data.cartList,
cartTotal: res.data.cartTotal
});
}
that.setData({
checkedAllStatus: that.isCheckedAll()
});
});
} else {
//编辑状态
let tmpCartData = this.data.cartGoods.map(function(element, index, array) {
if (index == itemIndex) {
element.checked = !element.checked;
}
return element;
});
that.setData({
cartGoods: tmpCartData,
checkedAllStatus: that.isCheckedAll(),
'cartTotal.checkedGoodsCount': that.getCheckedGoodsCount()
});
}
},
//手指触摸动作开始 记录起点X坐标
touchstart: function(e) {
//开始触摸时 重置所有删除
let data = app.touch._touchstart(e, this.data.cartGoods)
console.log(data)
this.setData({
cartGoods: data
})
},
//滑动事件处理
touchmove: function(e) {
let data = app.touch._touchmove(e, this.data.cartGoods)
this.setData({
cartGoods: data
})
},
getCheckedGoodsCount: function() {
let checkedGoodsCount = 0;
this.data.cartGoods.forEach(function(v) {
if (v.checked === true) {
checkedGoodsCount += v.number;
}
});
console.log(checkedGoodsCount);
return checkedGoodsCount;
},
checkedAll: function() {
let that = this;
if (!this.data.isEditCart) {
var productIds = this.data.cartGoods.map(function(v) {
return v.productId;
});
util.request(api.CartChecked, {
productIds: productIds,
isChecked: that.isCheckedAll() ? 0 : 1
}, 'POST').then(function(res) {
if (res.errno === 0) {
console.log(res.data);
that.setData({
cartGoods: res.data.cartList,
cartTotal: res.data.cartTotal
});
}
that.setData({
checkedAllStatus: that.isCheckedAll()
});
});
} else {
//编辑状态
let checkedAllStatus = that.isCheckedAll();
let tmpCartData = this.data.cartGoods.map(function(v) {
v.checked = !checkedAllStatus;
return v;
});
that.setData({
cartGoods: tmpCartData,
checkedAllStatus: that.isCheckedAll(),
'cartTotal.checkedGoodsCount': that.getCheckedGoodsCount()
});
}
},
editCart: function() {
var that = this;
if (this.data.isEditCart) {
this.getCartList();
this.setData({
isEditCart: !this.data.isEditCart
});
} else {
//编辑状态
let tmpCartList = this.data.cartGoods.map(function(v) {
v.checked = false;
return v;
});
this.setData({
editCartList: this.data.cartGoods,
cartGoods: tmpCartList,
isEditCart: !this.data.isEditCart,
checkedAllStatus: that.isCheckedAll(),
'cartTotal.checkedGoodsCount': that.getCheckedGoodsCount()
});
}
},
updateCart: function(productId, goodsId, number, id) {
let that = this;
util.request(api.CartUpdate, {
productId: productId,
goodsId: goodsId,
number: number,
id: id
}, 'POST').then(function(res) {
that.setData({
checkedAllStatus: that.isCheckedAll()
});
that.getCartList();
});
},
cutNumber: function(event) {
let itemIndex = event.target.dataset.itemIndex;
let cartItem = this.data.cartGoods[itemIndex];
let number = (cartItem.number - 1 > 1) ? cartItem.number - 1 : 1;
cartItem.number = number;
this.setData({
cartGoods: this.data.cartGoods,
});
this.updateCart(cartItem.productId, cartItem.goodsId, number, cartItem.id);
},
addNumber: function(event) {
let itemIndex = event.target.dataset.itemIndex;
let cartItem = this.data.cartGoods[itemIndex];
let number = cartItem.number + 1;
cartItem.number = number;
this.setData({
cartGoods: this.data.cartGoods
});
this.updateCart(cartItem.productId, cartItem.goodsId, number, cartItem.id);
},
checkoutOrder: function() {
//获取已选择的商品
let that = this;
var checkedGoods = this.data.cartGoods.filter(function(element, index, array) {
if (element.checked == true) {
return true;
} else {
return false;
}
});
if (checkedGoods.length <= 0) {
return false;
}
// storage中设置了cartId,则是购物车购买
try {
wx.setStorageSync('cartId', 0);
wx.navigateTo({
url: '/pages/checkout/checkout'
})
} catch (e) {}
},
deleteCart: function() {
//获取已选择的商品
let that = this;
let productIds = this.data.cartGoods.filter(function(element, index, array) {
if (element.checked == true) {
return true;
} else {
return false;
}
});
if (productIds.length <= 0) {
return false;
}
productIds = productIds.map(function(element, index, array) {
if (element.checked == true) {
return element.productId;
}
});
that.deletePost(productIds);
},
/**
* 滑动点击删除
*/
touchDelete: function(e) {
let productId = e.currentTarget.dataset.productId;
this.deletePost([productId]);
},
deletePost: function(productIds) {
console.log('productIds', productIds)
let that = this;
util.request(api.CartDelete, {
productIds: productIds
}, 'POST').then(function(res) {
if (res.errno === 0) {
console.log(res.data);
let cartList = res.data.cartList.map(v => {
// v.checked = false;
return v;
});
that.setData({
cartGoods: cartList,
cartTotal: res.data.cartTotal
});
}
that.setData({
checkedAllStatus: that.isCheckedAll()
});
});
},
gotoDetail(e) {
wx.navigateTo({
url: '../goods/goods?id=' + e.currentTarget.dataset.id
});
},
/**
* 去逛逛回到首页
*/
goHome() {
wx.switchTab({
url: '/pages/index2/index2'
})
},
//添加收藏
addCollectOrNot: function(e) {
let that = this;
util.request(api.CollectAddOrDelete, {
type: 0,
valueId: e.currentTarget.dataset.goodsId
}, "POST")
.then(function(res) {
let _res = res;
if (_res.errno == 0) {
let _mesg = ''
if (_res.data.type == 'add') {
_mesg = '已添加到我的收藏'
wx.showToast({
icon: 'none',
title: _mesg
});
that.deletePost([e.currentTarget.dataset.productId]);
} else {
that.addCollectOrNot(e);
}
} else {
wx.showToast({
image: '/static/images/icon_error.png',
title: _res.errmsg,
mask: true
});
}
});
}
})
\ No newline at end of file
{
"backgroundColor": "#f4f4f4",
"navigationBarTitleText": "购物车"
}
\ No newline at end of file
<view class="container">
<view class="no-login" wx:if="{{!hasLogin}}">
<view class="c">
<image src="/static/images/cart-icon.png" />
<!-- <text>还没有登录</text> -->
<button class="login-btn" bindtap="goLogin">去登录</button>
</view>
</view>
<view class='login' wx:else>
<!-- <view class="service-policy">
<view class="item">30天无忧退货</view>
<view class="item">48小时快速退款</view>
<view class="item">满88元免邮费</view>
</view> -->
<view class="no-cart" wx:if="{{cartGoods.length <= 0}}">
<view class="c">
<image src="/static/images/cart-icon.png" />
<view class="no-cart-btn" bindtap='goHome'>现在去逛逛</view>
</view>
</view>
<view class="cart-view" wx:else>
<view class='shop-editor'>
<view class="checkbox {{checkedAllStatus ? 'checked' : ''}}" bindtap="checkedAll">全选({{cartTotal.checkedGoodsCount}})</view>
<view class="{{!isEditCart ? 'edit' : 'sure'}}" bindtap="editCart">{{!isEditCart ? '编辑' : '完成'}}</view>
<view class="delete" bindtap="deleteCart" wx:if="{{isEditCart}}">删除({{cartTotal.checkedGoodsCount}})</view>
</view>
<view class="list">
<view class="group-item">
<view class="goods">
<view class="item edit {{item.isTouchMove ? 'touch-move-active' : ''}}" wx:for="{{cartGoods}}" bindtap='gotoDetail' wx:key="id" bindtouchstart="touchstart" bindtouchmove="touchmove" data-index="{{index}}" data-id="{{item.goodsId}}">
<view class='content'>
<view class='checkbox-main' catchtap="checkedItem" data-item-index="{{index}}">
<view class="checkbox {{item.checked ? 'checked' : ''}}" data-item-index="{{index}}" ></view>
</view>
<view class="cart-goods">
<image class="img" src="{{item.picUrl}}"></image>
<view class="info">
<view class="t">
<text class="name">{{item.goodsName}}{{item.isTouchMove}}</text>
<!-- <text class="num">x{{item.number}}</text> -->
</view>
<!-- <view class="attr">{{ isEditCart ? '已选择:' : ''}}{{item.goodsSpecificationValues||''}}</view> -->
<view class="b">
<text class="price">¥{{item.price}} <text wx:if="{{item.useScores}}" class="g-bi">+{{item.useScores}}戈币</text></text>
<view class="selnum">
<view class="cut" catchtap="cutNumber" data-item-index="{{index}}">-</view>
<input value="{{item.number}}" class="number" disabled="true" type="number" />
<view class="add" catchtap="addNumber" data-item-index="{{index}}">+</view>
</view>
</view>
</view>
</view>
</view>
<view class="touch-menu">
<view class="del collection" catchtap="addCollectOrNot" data-goods-id="{{item.goodsId}}" data-product-id="{{item.productId}}"><text>移入</text><text>收藏夹</text></view>
<view class="del" catchtap="touchDelete" data-product-id="{{item.productId}}">删除</view>
</view>
</view>
</view>
</view>
</view>
<view class="cart-bottom">
<view class='total-all'>
<view class="total">总计:{{'¥'+cartTotal.checkedGoodsAmount}}</view>
<view class="discount">金额:{{'¥'+cartTotal.checkedGoodsAmount}} 优惠:¥-0.00</view>
</view>
<view class='action_btn_area'>
<view class="checkout" bindtap="checkoutOrder">提交({{cartTotal.checkedGoodsCount}})</view>
</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
min-height: 100%;
background: #fff;
}
.container {
background: #fff;
width: 100%;
height: auto;
min-height: 100%;
overflow: hidden;
}
.service-policy {
width: 750rpx;
height: 73rpx;
background: #f4f4f4;
padding: 0 31.25rpx;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: space-between;
}
.service-policy .item {
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/servicePolicyRed-518d32d74b.png) 0 center no-repeat;
background-size: 10rpx;
padding-left: 15rpx;
display: flex;
align-items: center;
font-size: 25rpx;
color: #666;
}
.no-login {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-login .c {
width: 100%;
height: auto;
margin-top: 50rpx;
}
.no-login .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 362rpx;
height: 392rpx;
}
.no-login .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 59rpx;
line-height: 29rpx;
text-align: center;
font-size: 35rpx;
color: #999;
}
.no-login .login-btn {
width:362rpx;
line-height:94rpx;
border:2rpx solid rgba(227,20,54,1);
border-radius:4rpx;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(227,20,54,1);
text-align: center;
margin: 15px auto;
box-sizing: border-box;
background: none;
}
.no-cart {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-cart .c {
width: 100%;
height: auto;
margin-top: 50rpx;
}
.no-cart .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 362rpx;
height: 392rpx;
}
.no-cart .c .no-cart-btn {
width:362rpx;
line-height:94rpx;
border:2rpx solid rgba(227,20,54,1);
border-radius:4rpx;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(227,20,54,1);
text-align: center;
margin: 15px auto;
box-sizing: border-box;
}
.no-cart .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 29rpx;
line-height: 29rpx;
text-align: center;
font-size: 29rpx;
color: #999;
}
.cart-view {
width: 100%;
height: auto;
overflow: hidden;
}
.shop-editor {
height: 80rpx;
background: #fff;
width: 100%;
display: flex;
align-items: center;
border-bottom: 2rpx solid rgba(239,239,239,1);
}
.shop-editor .checkbox {
flex: 1;
height: 34rpx;
padding-left: 60rpx;
line-height: 34rpx;
font-size:24rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.shop-editor .edit {
width: 100rpx;
line-height:40rpx;
border:1px solid #FF1B40;
border-radius:24px;
color: #FF1B40;
font-size: 24rpx;
font-weight: 400;
text-align: center;
margin-right: 20rpx;
}
.shop-editor .sure {
width: 100rpx;
line-height:40rpx;
border:1px solid #FF1B40;
border-radius:24px;
color: #FF1B40;
font-size: 24rpx;
font-weight: 400;
text-align: center;
margin-right: 20rpx;
}
.shop-editor .delete {
width: 100rpx;
line-height:40rpx;
border:1px solid #6E6E6E;
border-radius:24px;
color: #6E6E6E;
font-size: 24rpx;
font-weight: 400;
text-align: center;
margin-right: 20rpx;
}
.cart-view .list {
height: auto;
width: 100%;
overflow: hidden;
margin-bottom: 120rpx;
}
.cart-view .group-item {
height: auto;
width: 100%;
background: #fff;
margin-bottom: 18rpx;
}
.cart-view .item {
height: 164rpx;
display: flex;
justify-content: space-between;
width: 100%;
overflow: hidden;
border-bottom: 1px solid #f4f4f4;
}
.cart-view .content{
width: 100%;
height: 164rpx;
transition: all 0.4s;
transform: translateX(180rpx);
margin-right: 0;
margin-left: -180rpx;
}
.touch-menu {
display: flex;
width:180rpx;
transform: translateX(180rpx);
transition: all 0.4s;
overflow: hidden;
}
.cart-view .del {
background-color: #FF1B40;
width:91rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #fff;
box-sizing: border-box;
font-size: 22rpx;
font-weight: 500;
}
.cart-view .collection {
background-color: rgb(233, 145, 64);
}
.collection text {
font-size: 22rpx;
color: #fff;
font-weight: 500;
}
.touch-move-active .content, .touch-move-active .touch-menu {
transform: translateX(0);
}
.checkbox-main {
float: left;
height: 170rpx;
width: 70rpx;
}
.checkbox {
height: 34rpx;
width: 34rpx;
margin: 65rpx 18rpx 65rpx 26rpx;
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/checkbox-0e09baa37e.png) no-repeat;
background-size: 34rpx;
}
.checkbox.checked {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAMAAACf4xmcAAAAZlBMVEUAAADjFDbmFjbjFDbjFjTkFDbjFTbjFDbjEzbjFDbjFDbhEzXkFDbkFDblEzfjFDbjFDfjFDbjFDbjGjnjFDbjFDbiEzXpEDjjFDbiGTrgEDPjEzXiFjXiFTbjFDbjFDbjFDbjFDZ8j12QAAAAIXRSTlMA+wjGXasuHQrTyWDArhLe3M+lB+nmoZmXb2taTUv0aIPfYCm5AAABAklEQVQ4y52U6bKDIAxG4eIKXrXazW72e/+XrFUpjYCMPb/IeCaACWG/kFyOoj4canG8JD4nUwXHB16ozGXddliwu1lSeYKDU0mtVMKJTImVw0P+5WUCXoS5yBkrnLV1xyr3yWrzdS1vRy2Cm7qYF9Goec7/X7J+qooY68jd1h9j2WOq27u+nddi/Rx0w7rxWpHepxkCGbQgh6jS/aCemImphWoI99PykegvloX9l5aO37R15aBaRc9Dc5lNJTlR35Bc5goNiMdILvNDOhDP5DJ0i2LFrcviybL0ccmUVWNhN1JVwEJtaMtwk294MuEHuO05h4dDeNRsGVzhMRgeqj/wAkr+cmD99DRLAAAAAElFTkSuQmCC) no-repeat;
background-size: 34rpx;
}
.cart-view .item .cart-goods {
float: left;
height: 164rpx;
width: 672rpx;
}
.cart-view .item .img {
float: left;
height: 125rpx;
width: 125rpx;
margin: 19.5rpx 18rpx 19.5rpx 0;
}
.cart-view .item .info {
float: left;
height: 125rpx;
width: 503rpx;
margin: 29.5rpx 26rpx 19.5rpx 0;
}
.cart-view .item .t {
margin: 8rpx 0;
height: 28rpx;
font-size: 25rpx;
color: #333;
overflow: hidden;
}
.cart-view .item .name {
height: 28rpx;
max-width: 310rpx;
line-height: 28rpx;
overflow: hidden;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.cart-view .item .num {
height: 28rpx;
max-width: 310rpx;
line-height: 28rpx;
overflow: hidden;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
float: right;
}
.cart-view .item .attr {
margin-bottom: 17rpx;
height: 24rpx;
line-height: 24rpx;
font-size: 22rpx;
color: #666;
overflow: hidden;
}
.cart-view .item .b {
height: 46rpx;
overflow: hidden;
display: flex;
align-items: center;
margin-top: 15rpx;
}
.cart-view .item .price {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
line-height:34rpx;
float: left;
}
.cart-view .item .g-bi {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
line-height:34rpx;
}
.cart-view .item .open {
height: 28rpx;
width: 150rpx;
display: block;
float: right;
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/arrowDown-d48093db25.png) right center no-repeat;
background-size: 25rpx;
font-size: 25rpx;
color: #333;
}
.cart-view .item.edit .t {
/* display: none; */
}
.cart-view .item.edit .attr {
text-align: right;
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/arrow-right1-e9828c5b35.png) right center no-repeat;
padding-right: 25rpx;
background-size: 12rpx 20rpx;
margin-bottom: 24rpx;
height: 39rpx;
line-height: 39rpx;
font-size: 24rpx;
color: #999;
overflow: hidden;
}
.cart-view .item.edit .b {
display: flex;
height: 46rpx;
/* height: 52rpx; */
overflow: hidden;
}
.cart-view .item.edit .price {
line-height: 52rpx;
height: 52rpx;
flex: 1;
}
.cart-view .item .selnum {
display: none;
}
.cart-view .item.edit .selnum {
line-height: 46rpx;
/* border: 1rpx solid #ccc; */
display: flex;
}
.selnum .cut {
width:46rpx;
text-align: center;
line-height: 46rpx;
background:rgba(240,240,240,1);
}
.selnum .number {
width: 84rpx;
height: 100%;
text-align: center;
line-height: 68.75rpx;
float: left;
}
.selnum .add {
width:46rpx;
text-align: center;
line-height: 46rpx;
background:#FF1B40;
color:#fff;
}
.cart-view .group-item .header {
width: 100%;
height: 94rpx;
line-height: 94rpx;
padding: 0 26rpx;
border-bottom: 1px solid #f4f4f4;
}
.cart-view .promotion .icon {
display: inline-block;
height: 24rpx;
width: 15rpx;
}
.cart-view .promotion {
margin-top: 25.5rpx;
float: left;
height: 43rpx;
width: 480rpx;
/*margin-right: 84rpx;*/
line-height: 43rpx;
font-size: 0;
}
.cart-view .promotion .tag {
border: 1px solid #f48f18;
height: 37rpx;
line-height: 31rpx;
padding: 0 9rpx;
margin-right: 10rpx;
color: #f48f18;
font-size: 24.5rpx;
}
.cart-view .promotion .txt {
height: 43rpx;
line-height: 43rpx;
padding-right: 10rpx;
color: #333;
font-size: 29rpx;
overflow: hidden;
}
.cart-view .get {
margin-top: 18rpx;
float: right;
height: 58rpx;
padding-left: 14rpx;
border-left: 1px solid #d9d9d9;
line-height: 58rpx;
font-size: 29rpx;
color: #333;
}
.cart-bottom {
position: fixed;
bottom: 0;
left: 0;
height: 100rpx;
width: 100%;
background: #fff;
display: flex;
border-top:1rpx solid rgba(217,217,217,1);
}
.cart-bottom .total-all {
height: 100%;
flex: 1;
padding-left: 20rpx;
display: flex;
justify-content: center;
flex-direction: column;
}
.cart-bottom .total {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.cart-bottom .discount {
font-size:20rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:rgba(110,110,110,1);
}
.cart-bottom .delete {
text-align: center;
width: 180rpx;
height: 80rpx;
line-height: 82rpx;
padding: 0;
margin: 0;
margin-left: -5rpx;
padding-right: 25rpx;
font-size: 25rpx;
color: #f4f4f4;
/* text-align: center; */
border-top-left-radius: 0rpx;
border-bottom-left-radius: 0rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #9a9ba1 0%, #ae8b9c 100%);
}
.cart-bottom .checkout {
height: 100rpx;
width: 210rpx;
text-align: center;
line-height: 100rpx;
font-size: 29rpx;
background: #b4282d;
color: #fff;
}
.action_btn_area {
/* border: 1px solid #333; */
position: absolute;
display: flex;
justify-content: center;
align-items: center;
right: 0;
top: 0;
height: 100rpx;
}
.action_btn_area .edit {
width: 140rpx;
/* border: 1px solid #000; */
height: 80rpx;
line-height: 82rpx;
padding: 0;
margin: 0;
margin-right: 5rpx;
text-align: center;
/* padding-left: 25rpx; */
font-size: 25rpx;
color: #f4f4f4;
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
/* background-image: linear-gradient(to right, #ff7701 100%); */
background-image: linear-gradient(to right, #ab956d 0%, #ab956d 100%);
}
.action_btn_area .checkout {
width: 210rpx;
height: 100%;
background:#FF1B40;
color: #fff;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
}
.action_btn_area .delete {
width: 140rpx;
/* border: 1px solid #000; */
height: 80rpx;
line-height: 82rpx;
padding: 0;
margin: 0;
margin-right: 5rpx;
text-align: center;
padding-left: -5rpx;
font-size: 25rpx;
color: #f4f4f4;
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #9a9ba1 0%, #9a9ba1 100%);
}
.action_btn_area .sure {
text-align: center;
width: 140rpx;
height: 80rpx;
line-height: 82rpx;
padding: 0;
margin: 0;
margin-right: 10rpx;
padding-left: -5rpx;
font-size: 25rpx;
color: #f4f4f4;
/* text-align: center; */
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #ab956d 0%, #ab956d 100%);
/* background-image: linear-gradient(to right, #ff7701 0%, #fe4800 100%); */
}
.auth_btn {
position: fixed;
top: 55vh;
left: 10vw;
width: 80vw;
height: 96rpx;
line-height: 96rpx;
font-size: 25rpx;
color: #f4f4f4;
/* text-align: center; */
border-top-left-radius: 50rpx;
border-bottom-left-radius: 50rpx;
border-top-right-radius: 50rpx;
border-bottom-right-radius: 50rpx;
letter-spacing: 3rpx;
background-image: linear-gradient(to right, #8baaaa 0%, #9a9ba1 100%);
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
categoryList: [],
currentCategory: {},
currentSubCategoryList: {},
scrollLeft: 0,
scrollTop: 0,
goodsCount: 0,
scrollHeight: 0
},
onLoad: function(options) {
this.getCatalog();
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getCatalog();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getCatalog: function() {
//CatalogList
let that = this;
wx.showLoading({
title: '加载中...',
});
util.request(api.CatalogList).then(function(res) {
that.setData({
categoryList: res.data.categoryList,
currentCategory: res.data.currentCategory,
currentSubCategoryList: res.data.currentSubCategory
});
wx.hideLoading();
});
util.request(api.GoodsCount).then(function(res) {
that.setData({
goodsCount: res.data.goodsCount
});
});
},
getCurrentCategory: function(id) {
let that = this;
util.request(api.CatalogCurrent, {
id: id
})
.then(function(res) {
that.setData({
currentCategory: res.data.currentCategory,
currentSubCategoryList: res.data.currentSubCategory
});
});
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
switchCate: function(event) {
var that = this;
var currentTarget = event.currentTarget;
if (this.data.currentCategory.id == event.currentTarget.dataset.id) {
return false;
}
this.getCurrentCategory(event.currentTarget.dataset.id);
}
})
\ No newline at end of file
{
"navigationBarTitleText": "分类"
}
\ No newline at end of file
<view class="container">
<view class="search">
<navigator url="/pages/search/search" class="input" hover-class='none'>
<image class="icon" src="/static/images/search-red.png"></image>
<text class="txt">商品搜索, 共{{goodsCount}}款好物</text>
</navigator>
</view>
<view class="catalog">
<scroll-view class="nav" scroll-y="true">
<view class="item {{ currentCategory.id == item.id ? 'active' : ''}}" wx:for="{{categoryList}}" wx:key="id" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchCate">{{item.name}}</view>
</scroll-view>
<scroll-view class="cate" scroll-y="true">
<navigator url="url" class="banner">
<image class="image" src="{{currentCategory.picUrl}}"></image>
<view class="txt">{{currentCategory.frontName}}</view>
</navigator>
<view class="hd">
<!-- <text class="line"></text> -->
<text class="txt">{{currentCategory.name}}分类</text>
<!-- <text class="line"></text> -->
</view>
<view class="bd">
<navigator url="/pages/category/category?id={{item.id}}" class="item {{(index+1) % 3 == 0 ? 'last' : ''}}" wx:key="id" wx:for="{{currentSubCategoryList}}">
<image class="icon" src="{{item.picUrl}}"></image>
<text class="txt">{{item.name}}</text>
</navigator>
</view>
</scroll-view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
}
.container {
background: #f9f9f9;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
}
.search {
height: 88rpx;
width: 100%;
padding: 0 30rpx;
background: #fff;
display: flex;
align-items: center;
}
.search .input {
width:706rpx;
height: 64rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
border: 2rpx solid #FF1B40;
background: #fff;
}
.search .icon {
margin-left: 16rpx;
width: 28rpx;
height: 28rpx;
}
.search .txt {
height: 42rpx;
line-height: 42rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(131,131,131,1);
margin-left: 15rpx;
}
.catalog {
flex: 1;
width: 100%;
background: #fff;
display: flex;
border-top: 1px solid #fafafa;
}
.catalog .nav {
width: 162rpx;
height: 100%;
margin-top: 20rpx;
}
.catalog .nav .item {
text-align: center;
line-height: 90rpx;
width: 162rpx;
height: 90rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.catalog .nav .item.active {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#E31436;
}
.catalog .cate {
border-left: 1px solid #fafafa;
flex: 1;
height: 100%;
padding: 0 30rpx 0 30rpx;
}
.banner {
display: block;
height: 222rpx;
width: 100%;
position: relative;
}
.banner .image {
position: absolute;
top: 30rpx;
left: 0;
border-radius: 4rpx;
height: 192rpx;
width: 100%;
}
.banner .txt {
position: absolute;
top: 30rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
left: 0;
height: 192rpx;
line-height: 192rpx;
width: 100%;
}
.catalog .hd {
height: 88rpx;
width: 100%;
display: flex;
align-items: center;
}
.catalog .hd .txt {
font-size: 24rpx;
text-align: center;
color: #333;
padding: 0 10rpx;
width: auto;
font-family:PingFangSC-Medium;
font-weight:500;
}
.catalog .hd .line {
width: 40rpx;
height: 1px;
background: #d9d9d9;
}
.catalog .bd {
height: auto;
width: 100%;
overflow: hidden;
}
.catalog .bd .item {
display: block;
float: left;
height: 216rpx;
width: 144rpx;
margin-right: 34rpx;
}
.catalog .bd .item.last {
margin-right: 0;
}
.catalog .bd .item .icon {
height: 144rpx;
width: 144rpx;
border-radius: 80rpx;
}
.catalog .bd .item .txt {
display: block;
text-align: center;
font-size: 24rpx;
height: 72rpx;
width: 144rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
navList: [],
goodsList: [],
id: 0,
currentCategory: {},
scrollLeft: 0,
scrollTop: 0,
scrollHeight: 0,
page: 1,
size: 100
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
var that = this;
if (options.id) {
that.setData({
id: parseInt(options.id)
});
}
wx.getSystemInfo({
success: function(res) {
that.setData({
scrollHeight: res.windowHeight
});
}
});
this.getCategoryInfo();
},
onPullDownRefresh() {
this.getCategoryInfo();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getCategoryInfo: function() {
let that = this;
util.request(api.GoodsCategory, {
id: this.data.id
})
.then(function(res) {
if (res.errno == 0) {
that.setData({
navList: res.data.brotherCategory,
currentCategory: res.data.currentCategory
});
wx.setNavigationBarTitle({
title: res.data.parentCategory.name
})
// 当id是L1分类id时,这里需要重新设置成L1分类的一个子分类的id
if (res.data.parentCategory.id == that.data.id) {
that.setData({
id: res.data.currentCategory.id
});
}
//nav位置
let currentIndex = 0;
let navListCount = that.data.navList.length;
for (let i = 0; i < navListCount; i++) {
currentIndex += 1;
if (that.data.navList[i].id == that.data.id) {
break;
}
}
if (currentIndex > navListCount / 2 && navListCount > 5) {
that.setData({
scrollLeft: currentIndex * 60
});
}
that.getGoodsList();
} else {
//显示错误信息
}
});
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
getGoodsList: function() {
var that = this;
util.request(api.GoodsList, {
categoryId: that.data.id,
page: that.data.page,
size: that.data.size
})
.then(function(res) {
that.setData({
goodsList: res.data.goodsList,
});
});
},
onUnload: function() {
// 页面关闭
},
switchCate: function(event) {
if (this.data.id == event.currentTarget.dataset.id) {
return false;
}
var that = this;
var clientX = event.detail.x;
var currentTarget = event.currentTarget;
if (clientX < 60) {
that.setData({
scrollLeft: currentTarget.offsetLeft - 60
});
} else if (clientX > 330) {
that.setData({
scrollLeft: currentTarget.offsetLeft
});
}
this.setData({
id: event.currentTarget.dataset.id
});
this.getCategoryInfo();
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view class="container">
<view class="cate-nav">
<scroll-view scroll-x="true" class="cate-nav-body" style="width: 750rpx;" scroll-left="{{scrollLeft}}">
<view wx:for="{{navList}}" class="item {{ id == item.id ? 'active' : ''}}" wx:key="id" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchCate">
<view class="name">{{item.name}}</view>
</view>
</scroll-view>
</view>
<scroll-view scroll-y="true" scroll-top="{{scrollTop}}" style="height:{{scrollHeight}};">
<view class="cate-item">
<!-- <view class="h">
<text class="name">{{currentCategory.name}}</text>
<text class="desc">{{currentCategory.frontName}}</text>
</view> -->
<view class="b">
<navigator class="item {{(iindex + 1) % 2 == 0 ? 'item-b' : ''}}" url="/pages/goods/goods?id={{iitem.id}}" wx:for="{{goodsList}}" wx:key="id" wx:for-item="iitem" wx:for-index="iindex">
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</view>
</view>
</scroll-view>
</view>
\ No newline at end of file
.container {
background: #f9f9f9;
}
.cate-nav {
position: fixed;
left: 0;
top: 0;
z-index: 1000;
}
.cate-nav-body {
height: 84rpx;
white-space: nowrap;
background: #fff;
border-top: 1px solid rgba(0, 0, 0, 0.15);
overflow: hidden;
}
.cate-nav .item {
display: inline-block;
height: 84rpx;
min-width: 130rpx;
padding: 0 15rpx;
}
.cate-nav .item .name {
display: block;
height: 84rpx;
padding: 0 20rpx;
line-height: 84rpx;
color: #111111;
font-size:28rpx;
font-weight:400;
width: auto;
font-family:PingFangSC-Regular;
}
.cate-nav .item.active .name {
font-size:28rpx;
color:rgba(17,17,17,1);
border-bottom: 4rpx solid #FF2246;
/* color: #ab956d;
border-bottom: 2px solid #ab956d; */
}
.cate-item {
margin-top: 94rpx;
height: auto;
overflow: hidden;
}
.cate-item .h {
height: 145rpx;
width: 750rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cate-item .h .name {
display: block;
height: 35rpx;
margin-bottom: 18rpx;
font-size: 30rpx;
color: #333;
}
.cate-item .h .desc {
display: block;
height: 24rpx;
font-size: 24rpx;
color: #999;
}
.cate-item .b {
width: 750rpx;
padding: 0 6.25rpx;
height: auto;
overflow: hidden;
}
.cate-item .b .item {
float: left;
background: #fff;
width: 365rpx;
margin-bottom: 6.25rpx;
padding-bottom: 33.333rpx;
height: auto;
overflow: hidden;
text-align: center;
}
.cate-item .b .item-b {
margin-left: 6.25rpx;
}
.cate-item .item .img {
width: 302rpx;
height: 302rpx;
}
.cate-item .item .name {
display: block;
width: 365.625rpx;
height: 35rpx;
margin: 11.5rpx 0 22rpx 0;
text-align: center;
overflow: hidden;
padding: 0 20rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
white-space: nowrap;
text-overflow: ellipsis;
}
.cate-item .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
checkedGoodsList: [],
checkedAddress: {},
availableCouponLength: 0, // 可用的优惠券数量
goodsTotalPrice: 0.00, //商品总价
freightPrice: 0.00, //快递费
totalSendScores: 0, // 赠送戈币
totalUseScores: 0, // 消费戈币
couponPrice: 0.00, //优惠券的价格
grouponPrice: 0.00, //团购优惠价格
orderTotalPrice: 0.00, //订单总价
actualPrice: 0.00, //实际需要支付的总价
cartId: 0,
addressId: 0,
couponId: 0,
message: '',
grouponLinkId: 0, //参与的团购,如果是发起则为0
grouponRulesId: 0 //团购规则ID
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
},
//获取checkou信息
getCheckoutInfo: function() {
let that = this;
util.request(api.CartCheckout, {
cartId: that.data.cartId,
addressId: that.data.addressId,
couponId: that.data.couponId,
grouponRulesId: that.data.grouponRulesId
}).then(function(res) {
console.log('res====>', res)
if (res.errno === 0) {
that.setData({
checkedGoodsList: res.data.checkedGoodsList,
checkedAddress: res.data.checkedAddress,
availableCouponLength: res.data.availableCouponLength,
actualPrice: res.data.actualPrice,
couponPrice: res.data.couponPrice,
grouponPrice: res.data.grouponPrice,
freightPrice: res.data.freightPrice,
goodsTotalPrice: res.data.goodsTotalPrice,
totalUseScores: res.data.totalUseScores,
totalSendScores: res.data.totalSendScores,
orderTotalPrice: res.data.orderTotalPrice,
addressId: res.data.addressId,
couponId: res.data.couponId,
grouponRulesId: res.data.grouponRulesId,
});
}
wx.hideLoading();
});
},
selectAddress() {
wx.navigateTo({
url: '/pages/ucenter/address/address',
})
},
selectCoupon() {
wx.navigateTo({
url: '/pages/ucenter/couponSelect/couponSelect',
})
},
bindMessageInput: function(e) {
this.setData({
message: e.detail.value
});
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
wx.showLoading({
title: '加载中...',
});
try {
var cartId = wx.getStorageSync('cartId');
if (cartId) {
this.setData({
'cartId': cartId
});
}
var addressId = wx.getStorageSync('addressId');
if (addressId) {
this.setData({
'addressId': addressId
});
}
var couponId = wx.getStorageSync('couponId');
if (couponId) {
this.setData({
'couponId': couponId
});
}
var grouponRulesId = wx.getStorageSync('grouponRulesId');
if (grouponRulesId) {
this.setData({
'grouponRulesId': grouponRulesId
});
}
var grouponLinkId = wx.getStorageSync('grouponLinkId');
if (grouponLinkId) {
this.setData({
'grouponLinkId': grouponLinkId
});
}
} catch (e) {
// Do something when catch error
console.log(e);
}
this.getCheckoutInfo();
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
submitOrder: function() {
let that = this;
if (this.data.addressId <= 0) {
util.showErrorToast('请选择收货地址');
return false;
}
util.request(api.OrderSubmit, {
cartId: this.data.cartId,
addressId: this.data.addressId,
couponId: this.data.couponId,
message: this.data.message,
grouponRulesId: this.data.grouponRulesId,
grouponLinkId: this.data.grouponLinkId
}, 'POST').then(res => {
if (res.errno === 0) {
// 下单成功,重置couponId
try {
wx.setStorageSync('couponId', 0);
} catch (error) {
}
const orderId = res.data.orderId;
util.request(api.OrderPrepay, {
orderId: orderId
}, 'POST').then(function(res) {
if (res.errno === 0) {
const payParam = res.data;
console.log("支付过程开始");
if (that.data.goodsTotalPrice>0) {
wx.requestPayment({
'timeStamp': payParam.timeStamp,
'nonceStr': payParam.nonceStr,
'package': payParam.wxPackage,
'signType': payParam.signType,
'paySign': payParam.paySign,
'success': function(res) {
console.log("支付过程成功");
wx.redirectTo({
url: '/pages/payResult/payResult?status=1&orderId=' + orderId
});
},
'fail': function(res) {
console.log("支付过程失败");
wx.redirectTo({
url: '/pages/payResult/payResult?status=0&orderId=' + orderId
});
},
'complete': function(res) {
console.log("支付过程结束")
}
});
} else {
wx.redirectTo({
url: '/pages/payResult/payResult?status=1&orderId=' + orderId
});
}
} else {
if (res.errno == 710) {
wx.redirectTo({
url: '/pages/payResult/payResult?status=0&orderId=' + orderId + "&success=0"
});
return;
}
wx.redirectTo({
url: '/pages/payResult/payResult?status=0&orderId=' + orderId
});
}
});
} else {
wx.redirectTo({
url: '/pages/payResult/payResult?status=0&orderId=' + orderId
});
}
});
}
});
\ No newline at end of file
{
"navigationBarTitleText": "填写订单"
}
\ No newline at end of file
<view class="container">
<view class="address-box">
<view class="address-item" bindtap="selectAddress" wx:if="{{checkedAddress.id > 0}}">
<view class="l">
<text class="name">{{checkedAddress.name}}</text>
<text class="default" wx:if="{{checkedAddress.isDefault}}">默认</text>
</view>
<view class="m">
<text class="mobile">{{checkedAddress.mobile}}</text>
<text class="address">{{checkedAddress.address}}</text>
</view>
<view class="r">
<image src="/static/images/address_right.png"></image>
</view>
</view>
<view class="address-item address-empty" bindtap="selectAddress" wx:else>
<view class="m">
还没有收货地址,去添加
</view>
<view class="r">
<image src="/static/images/address_right.png"></image>
</view>
</view>
</view>
<view class="coupon-box">
<view class="coupon-item" bindtap="selectCoupon">
<view class="l" wx:if="{{couponId == 0}}">
<text class="name">没有可用的优惠券</text>
<text class="txt">0张</text>
</view>
<view class="l" wx:elif="{{couponId == -1}}">
<text class="name">优惠券</text>
<text class="txt">{{availableCouponLength}}张</text>
</view>
<view class="l" wx:else>
<text class="name">优惠券</text>
<text class="txt">-¥{{couponPrice}}元</text>
</view>
<view class="r">
<image src="/static/images/address_right.png"></image>
</view>
</view>
</view>
<view class="order-box" wx:if="{{totalSendScores}}">
<view class="order-item" style='border: none;'>
<view class="l">
<text class="name">赠送戈币</text>
</view>
<view class="r">
<text class="txt">{{totalSendScores}}</text>
</view>
</view>
</view>
<view class="message-box">
<input class="message-item" bindinput="bindMessageInput" placeholder="如需要,请输入留言" value="{{message}}" />
</view>
<view class="order-box">
<view class="order-item">
<view class="l">
<text class="name">商品合计</text>
</view>
<view class="r">
<text class="txt">¥{{goodsTotalPrice}}元</text>
</view>
</view>
<view class="order-item">
<view class="l">
<text class="name">消费戈币</text>
</view>
<view class="r">
<text class="txt">{{totalUseScores}}</text>
</view>
</view>
<view class="order-item">
<view class="l">
<text class="name">运费</text>
</view>
<view class="r">
<text class="txt">¥{{freightPrice}}元</text>
</view>
</view>
<view class="order-item no-border">
<view class="l">
<text class="name">优惠券</text>
</view>
<view class="r">
<text class="txt">-¥{{couponPrice}}元</text>
</view>
</view>
</view>
<view class="goods-items">
<view class="item" wx:for="{{checkedGoodsList}}" wx:key="id">
<view class="img">
<image src="{{item.picUrl}}"></image>
</view>
<view class="info">
<view class="t">
<text class="name">{{item.goodsName}}</text>
<text class="number">x{{item.number}}</text>
</view>
<view class="m">{{item.specifications}}<text class='g-bi' wx:if="{{item.sendScores}}">(赠送{{item.sendScores}}戈币)</text></view>
<view class="b">¥{{item.price}} <text class='g-bi' wx:if="{{item.useScores}}">消费{{item.useScores}}戈币</text></view>
</view>
</view>
</view>
<view class="order-total">
<view class="l">实付:¥{{actualPrice}}</view>
<view class="r" bindtap="submitOrder">去付款</view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
background: #f4f4f4;
}
.address-box {
width: 100%;
height: 166.55rpx;
background: url('http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/address-bg-bd30f2bfeb.png') 0 0 repeat-x;
background-size: 62.5rpx 10.5rpx;
margin-bottom: 20rpx;
padding-top: 10.5rpx;
}
.address-item {
display: flex;
height: 155.55rpx;
background: #fff;
padding: 41.6rpx 0 41.6rpx 31.25rpx;
}
.address-item.address-empty {
line-height: 75rpx;
text-align: center;
}
.address-box .l {
width: 125rpx;
height: 100%;
}
.address-box .l .name {
margin-left: 6.25rpx;
margin-top: -7.25rpx;
display: block;
width: 125rpx;
height: 43rpx;
line-height: 43rpx;
font-size: 30rpx;
color: #333;
margin-bottom: 5rpx;
}
.address-box .l .default {
margin-left: 6.25rpx;
display: block;
width: 62rpx;
height: 33rpx;
border-radius: 5rpx;
border: 1px solid #E31436;
font-size: 20.5rpx;
text-align: center;
line-height: 29rpx;
color: #E31436;
}
.address-box .m {
flex: 1;
height: 72.25rpx;
color: #999;
}
.address-box .mobile {
display: block;
height: 29rpx;
line-height: 29rpx;
margin-bottom: 6.25rpx;
font-size: 30rpx;
color: #333;
}
.address-box .address {
display: block;
height: 37.5rpx;
line-height: 37.5rpx;
font-size: 25rpx;
color: #666;
}
.address-box .r {
width: 77rpx;
height: 77rpx;
display: flex;
justify-content: center;
align-items: center;
}
.address-box .r image {
width: 52.078rpx;
height: 52.078rpx;
}
.coupon-box {
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
}
.coupon-box .coupon-item {
width: 100%;
height: 108.3rpx;
overflow: hidden;
background: #fff;
display: flex;
padding-left: 31.25rpx;
}
.coupon-box .l {
flex: 1;
height: 43rpx;
line-height: 43rpx;
padding-top: 35rpx;
}
.coupon-box .l .name {
float: left;
font-size: 30rpx;
color: #666;
}
.coupon-box .l .txt {
float: right;
font-size: 30rpx;
color: #666;
}
.coupon-box .r {
margin-top: 15.5rpx;
width: 77rpx;
height: 77rpx;
display: flex;
justify-content: center;
align-items: center;
}
.coupon-box .r image {
width: 52.078rpx;
height: 52.078rpx;
}
.message-box {
margin-top: 20rpx;
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
}
.message-box .message-item {
height: 52.078rpx;
overflow: hidden;
background: #fff;
display: flex;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
padding-top: 26rpx;
}
.order-box {
margin-top: 20rpx;
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
}
.order-box .order-item {
height: 104.3rpx;
overflow: hidden;
background: #fff;
display: flex;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
padding-top: 26rpx;
border-bottom: 1px solid #d9d9d9;
}
.order-box .order-item .l {
float: left;
height: 52rpx;
width: 50%;
line-height: 52rpx;
overflow: hidden;
}
.order-box .order-item .r {
float: right;
text-align: right;
width: 50%;
height: 52rpx;
line-height: 52rpx;
overflow: hidden;
}
.order-box .order-item.no-border {
border-bottom: none;
}
.goods-items {
margin-top: 20rpx;
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
padding-left: 31.25rpx;
margin-bottom: 120rpx;
}
.goods-items .item {
height: 192rpx;
padding-right: 31.25rpx;
display: flex;
align-items: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.goods-items .item.no-border {
border-bottom: none;
}
.goods-items .item:last-child {
border-bottom: none;
}
.goods-items .img {
height: 145.83rpx;
width: 145.83rpx;
background-color: #f4f4f4;
margin-right: 20rpx;
}
.goods-items .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.goods-items .info {
flex: 1;
height: 145.83rpx;
padding-top: 5rpx;
}
.goods-items .t {
height: 33rpx;
line-height: 33rpx;
margin-bottom: 10rpx;
overflow: hidden;
font-size: 30rpx;
color: #333;
}
.goods-items .t .name {
display: block;
float: left;
}
.goods-items .t .number {
display: block;
float: right;
text-align: right;
}
.goods-items .m {
height: 29rpx;
overflow: hidden;
line-height: 29rpx;
margin-bottom: 25rpx;
font-size: 25rpx;
color: #666;
}
.g-bi {
height: 29rpx;
overflow: hidden;
line-height: 29rpx;
margin-bottom: 25rpx;
font-size: 25rpx;
color: #666;
}
.goods-items .b {
height: 41rpx;
overflow: hidden;
line-height: 41rpx;
font-size: 30rpx;
color: #333;
}
.order-total {
position: fixed;
left: 0;
bottom: 0;
height: 100rpx;
width: 100%;
display: flex;
}
.order-total .l {
flex: 1;
height: 100rpx;
line-height: 100rpx;
color: #E31436;
background: #fff;
font-size: 33rpx;
padding-left: 31.25rpx;
border-top: 1rpx solid rgba(0, 0, 0, 0.2);
border-bottom: 1rpx solid rgba(0, 0, 0, 0.2);
}
.order-total .r {
width: 233rpx;
height: 100rpx;
background: #E31436;
border: 1px solid #E31436;
line-height: 100rpx;
text-align: center;
color: #fff;
font-size: 30rpx;
}
var app = getApp();
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
comments: [],
allCommentList: [],
picCommentList: [],
type: 0,
valueId: 0,
showType: 0,
allCount: 0,
hasPicCount: 0,
allPage: 1,
picPage: 1,
size: 20
},
getCommentCount: function() {
let that = this;
util.request(api.CommentCount, {
valueId: that.data.valueId,
type: that.data.type
}).then(function(res) {
if (res.errno === 0) {
that.setData({
allCount: res.data.allCount,
hasPicCount: res.data.hasPicCount
});
}
});
},
getCommentList: function() {
let that = this;
util.request(api.CommentList, {
valueId: that.data.valueId,
type: that.data.type,
size: that.data.size,
page: (that.data.showType == 0 ? that.data.allPage : that.data.picPage),
showType: that.data.showType
}).then(function(res) {
if (res.errno === 0) {
if (that.data.showType == 0) {
that.setData({
allCommentList: that.data.allCommentList.concat(res.data.data),
allPage: res.data.currentPage,
comments: that.data.allCommentList.concat(res.data.data)
});
} else {
that.setData({
picCommentList: that.data.picCommentList.concat(res.data.data),
picPage: res.data.currentPage,
comments: that.data.picCommentList.concat(res.data.data)
});
}
}
});
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.setData({
type: options.type,
valueId: options.valueId
});
this.getCommentCount();
this.getCommentList();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
switchTab: function() {
let that = this;
if (that.data.showType == 0) {
that.setData({
allCommentList: [],
allPage: 1,
comments: [],
showType: 1
});
} else {
that.setData({
picCommentList: [],
picPage: 1,
comments: [],
showType: 0
});
}
this.getCommentList();
},
onReachBottom: function() {
console.log('onPullDownRefresh');
if (this.data.showType == 0) {
if (this.data.allCount / this.data.size < this.data.allPage) {
return false;
}
this.setData({
'allPage': this.data.allPage + 1
});
} else {
if (this.data.hasPicCount / this.data.size < this.data.picPage) {
return false;
}
this.setData({
'picPage': this.data.picPage + 1
});
}
this.getCommentList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "评价"
}
\ No newline at end of file
<view class="comments">
<view class="h">
<view class="item {{ showType == 0 ? 'active' : ''}}" bindtap="switchTab">
<view class="txt">全部({{allCount}})</view>
</view>
<view class="item {{ showType == 0 ? '' : 'active'}}" bindtap="switchTab">
<view class="txt">有图({{hasPicCount}})</view>
</view>
</view>
<view class="b">
<view class="item" wx:for="{{comments}}" wx:key="id">
<view class="info">
<view class="user">
<image src="{{item.userInfo.avatarUrl}}"></image>
<text>{{item.userInfo.nickname}}</text>
</view>
<view class="time">{{item.addTime}}</view>
</view>
<view class="comment">{{item.content}}</view>
<view class="imgs" wx:if="{{item.picList.length > 0}}">
<image class="img" wx:for="{{item.picList}}" wx:key="*this" wx:for-item="pitem" src="{{pitem}}"></image>
</view>
<view class="customer-service" wx:if="{{item.reply}}">
<text class="u">小商场回复:</text>
<text class="c">{{item.reply}}</text>
</view>
</view>
</view>
</view>
\ No newline at end of file
.comments {
width: 100%;
height: auto;
padding-left: 30rpx;
background: #fff;
margin: 20rpx 0;
}
.comments .h {
position: fixed;
left: 0;
top: 0;
z-index: 1000;
width: 100%;
display: flex;
background: #fff;
height: 84rpx;
border-bottom: 1rpx solid rgba(0, 0, 0, 0.15);
overflow: hidden;
}
.comments .h .item {
display: inline-block;
height:90rpx;
width: 50%;
padding: 0 15rpx;
text-align: center;
}
.comments .h .item .txt {
display: inline-block;
height: 82rpx;
padding: 0 20rpx;
line-height: 82rpx;
width: 100%;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(17,17,17,1);
}
.comments .h .item.active .txt {
border-bottom: 4rpx solid #E31436;
}
.comments .b {
margin-top: 85rpx;
height: auto;
width: 720rpx;
}
.comments .b.no-h {
margin-top: 0;
}
.comments .item {
height: auto;
width: 720rpx;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
padding-bottom: 25rpx;
}
.comments .info {
height: 127rpx;
width: 100%;
padding: 33rpx 0 27rpx 0;
}
.comments .user {
float: left;
width: auto;
height: 67rpx;
line-height: 67rpx;
font-size: 0;
}
.comments .user image {
float: left;
width: 67rpx;
height: 67rpx;
margin-right: 17rpx;
border-radius: 50%;
}
.comments .user text {
display: inline-block;
width: auto;
height: 66rpx;
overflow: hidden;
font-size: 29rpx;
line-height: 66rpx;
}
.comments .time {
display: block;
float: right;
width: auto;
height: 67rpx;
line-height: 67rpx;
color: #7f7f7f;
font-size: 25rpx;
margin-right: 30rpx;
}
.comments .comment {
width: 720rpx;
padding-right: 30rpx;
line-height: 45.8rpx;
font-size: 29rpx;
margin-bottom: 16rpx;
}
.comments .imgs {
width: 720rpx;
height: 150rpx;
margin-bottom: 25rpx;
}
.comments .imgs .img {
height: 150rpx;
width: 150rpx;
margin-right: 28rpx;
}
.comments .spec {
width: 720rpx;
height: 25rpx;
font-size: 24rpx;
color: #999;
}
.comments .spec .item {
color: #7f7f7f;
font-size: 25rpx;
}
.comments .customer-service {
width: 690rpx;
height: auto;
overflow: hidden;
margin-top: 23rpx;
background: rgba(0, 0, 0, 0.03);
padding: 21rpx;
}
.comments .customer-service .u {
font-size: 24rpx;
color: #333;
line-height: 37.5rpx;
}
.comments .customer-service .c {
font-size: 24rpx;
color: #999;
line-height: 37.5rpx;
}
// 上传组件 基于https://github.com/Tencent/weui-wxss/tree/master/src/example/uploader
var app = getApp();
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
orderId: 0,
type: 0,
valueId: 0,
orderGoods: {},
content: '',
stars: [0, 1, 2, 3, 4],
star: 5,
starText: '十分满意',
hasPicture: false,
picUrls: [],
files: []
},
chooseImage: function(e) {
if (this.data.files.length >= 5) {
util.showErrorToast('只能上传五张图片')
return false;
}
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.setData({
files: that.data.files.concat(res.tempFilePaths)
});
that.upload(res);
}
})
},
upload: function(res) {
var that = this;
const uploadTask = wx.uploadFile({
url: api.StorageUpload,
filePath: res.tempFilePaths[0],
name: 'file',
success: function(res) {
var _res = JSON.parse(res.data);
if (_res.errno === 0) {
var url = _res.data.url
that.data.picUrls.push(url)
that.setData({
hasPicture: true,
picUrls: that.data.picUrls
})
}
},
fail: function(e) {
wx.showModal({
title: '错误',
content: '上传失败',
showCancel: false
})
},
})
uploadTask.onProgressUpdate((res) => {
console.log('上传进度', res.progress)
console.log('已经上传的数据长度', res.totalBytesSent)
console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
})
},
previewImage: function(e) {
wx.previewImage({
current: e.currentTarget.id, // 当前显示图片的http链接
urls: this.data.files // 需要预览的图片http链接列表
})
},
selectRater: function(e) {
var star = e.currentTarget.dataset.star + 1;
var starText;
if (star == 1) {
starText = '很差';
} else if (star == 2) {
starText = '不太满意';
} else if (star == 3) {
starText = '满意';
} else if (star == 4) {
starText = '比较满意';
} else {
starText = '十分满意'
}
this.setData({
star: star,
starText: starText
})
},
onLoad: function(options) {
var that = this;
that.setData({
orderId: options.orderId,
type: options.type,
valueId: options.valueId
});
this.getOrderGoods();
},
getOrderGoods: function() {
let that = this;
util.request(api.OrderGoods, {
orderId: that.data.orderId,
goodsId: that.data.valueId
}).then(function(res) {
if (res.errno === 0) {
that.setData({
orderGoods: res.data,
});
}
});
},
onClose: function() {
wx.navigateBack();
},
onPost: function() {
let that = this;
if (!this.data.content) {
util.showErrorToast('请填写评论')
return false;
}
util.request(api.OrderComment, {
orderGoodsId: that.data.orderGoods.id,
content: that.data.content,
star: that.data.star,
hasPicture: that.data.hasPicture,
picUrls: that.data.picUrls
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '评论成功',
complete: function() {
wx.switchTab({
url: '/pages/ucenter/index/index'
})
}
})
}
});
},
bindInputValue(event) {
let value = event.detail.value;
//判断是否超过140个字符
if (value && value.length > 140) {
return false;
}
this.setData({
content: event.detail.value,
})
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "评价"
}
\ No newline at end of file
<view class="container">
<view class="post-comment">
<view class="goods">
<view class="img">
<image src="{{orderGoods.picUrl}}"></image>
</view>
<view class="info">
<view class="t">
<text class="name">{{orderGoods.goodsName}} x{{orderGoods.number}}</text>
</view>
<view class="attr">{{orderGoods.goodsSpecificationValues}}</view>
</view>
</view>
<view class="rater">
<text class="rater-title">评分</text>
<block wx:for="{{stars}}" wx:key="*this" wx:for-item="item">
<image src="/static/images/icon_collect_checked.png" bindtap="selectRater" data-star="{{item}}" wx:if="{{item < star}}"></image>
<image src="/static/images/icon_collect.png" bindtap="selectRater" data-star="{{item}}" wx:else></image>
</block>
<text class="rater-desc">{{starText}}</text>
</view>
<view class="input-box">
<textarea class="content" focus="true" bindinput="bindInputValue" maxlength="140" placeholder="留言经过筛选后,对所有人可见" />
<text class="count">{{140 - content.length}}</text>
</view>
<view class="weui-uploader">
<view class="weui-uploader__hd">
<view class="weui-uploader__title">图片上传</view>
<view class="weui-uploader__info">{{picUrls.length}}/{{files.length}}</view>
</view>
<view class="weui-uploader__bd">
<view class="weui-uploader__files" id="uploaderFiles">
<block wx:for="{{files}}" wx:key="*this">
<view class="weui-uploader__file" bindtap="previewImage" id="{{item}}">
<image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
</view>
<!-- <view class="weui-uploader__file weui-uploader__file_status" bindtap="previewImage" id="{{item}}">
<image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
<view class="weui-uploader__file-content">50%</view>
</view> -->
</block>
<view class="weui-uploader__input-box">
<view class="weui-uploader__input" bindtap="chooseImage"></view>
</view>
</view>
</view>
</view>
<view class="btns">
<view class="close" bindtap="onClose">取消</view>
<view class="post" bindtap="onPost">发表</view>
</view>
</view>
</view>
\ No newline at end of file
page, .container {
height: 100%;
background: #f4f4f4;
}
.post-comment {
width: 750rpx;
height: auto;
overflow: hidden;
padding: 30rpx;
background: #fff;
}
.post-comment .goods {
display: flex;
align-items: center;
height: 199rpx;
margin-left: 31.25rpx;
}
.post-comment .goods .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.post-comment .goods .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.post-comment .goods .info {
height: 145.83rpx;
flex: 1;
padding-left: 20rpx;
}
.post-comment .goods .name {
margin-top: 30rpx;
display: block;
height: 44rpx;
line-height: 44rpx;
color: #333;
font-size: 30rpx;
}
.post-comment .goods .number {
display: block;
height: 37rpx;
line-height: 37rpx;
color: #666;
font-size: 25rpx;
}
.post-comment .goods .status {
width: 105rpx;
color: #b4282d;
font-size: 25rpx;
}
.post-comment .rater {
display: flex;
flex-direction: row;
height: 55rpx;
}
.post-comment .rater .rater-title {
font-size: 29rpx;
padding-right: 10rpx;
}
.post-comment .rater image {
padding-left: 5rpx;
height: 50rpx;
width: 50rpx;
}
.post-comment .rater .rater-desc {
font-size: 29rpx;
padding-left: 10rpx;
}
.post-comment .input-box {
height: 337.5rpx;
width: 690rpx;
position: relative;
background: #fff;
}
.post-comment .input-box .content {
position: absolute;
top: 0;
left: 0;
display: block;
background: #fff;
font-size: 29rpx;
border: 5px solid #f4f4f4;
height: 300rpx;
width: 650rpx;
padding: 20rpx;
}
.post-comment .input-box .count {
position: absolute;
bottom: 20rpx;
right: 20rpx;
display: block;
height: 30rpx;
width: 50rpx;
font-size: 29rpx;
color: #999;
}
.post-comment .btns {
height: 108rpx;
}
.post-comment .close {
float: left;
height: 108rpx;
line-height: 108rpx;
text-align: left;
color: #666;
padding: 0 30rpx;
}
.post-comment .post {
float: right;
height: 108rpx;
line-height: 108rpx;
text-align: right;
padding: 0 30rpx;
}
.weui-uploader {
margin-top: 50rpx;
}
.weui-uploader__hd {
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding-bottom: 10px;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-uploader__title {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-uploader__info {
color: #b2b2b2;
}
.weui-uploader__bd {
margin-bottom: -4px;
margin-right: -9px;
overflow: hidden;
}
.weui-uploader__file {
float: left;
margin-right: 9px;
margin-bottom: 9px;
}
.weui-uploader__img {
display: block;
width: 79px;
height: 79px;
}
.weui-uploader__file_status {
position: relative;
}
.weui-uploader__file_status:before {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.weui-uploader__file-content {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
color: #fff;
}
.weui-uploader__input-box {
float: left;
position: relative;
margin-right: 9px;
margin-bottom: 9px;
width: 77px;
height: 77px;
border: 1px solid #d9d9d9;
}
.weui-uploader__input-box:after, .weui-uploader__input-box:before {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #d9d9d9;
}
.weui-uploader__input-box:before {
width: 2px;
height: 39.5px;
}
.weui-uploader__input-box:after {
width: 39.5px;
height: 2px;
}
.weui-uploader__input-box:active {
border-color: #999;
}
.weui-uploader__input-box:active:after, .weui-uploader__input-box:active:before {
background-color: #999;
}
.weui-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
couponList: [],
page: 1,
size: 10,
count: 0,
scrollTop: 0,
showPage: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getCouponList();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
getCouponList: function () {
let that = this;
that.setData({
scrollTop: 0,
showPage: false,
couponList: []
});
// 页面渲染完成
wx.showToast({
title: '加载中...',
icon: 'loading',
duration: 2000
});
util.request(api.CouponList, {
page: that.data.page,
size: that.data.size
}).then(function (res) {
if (res.errno === 0) {
that.setData({
scrollTop: 0,
couponList: res.data.data,
showPage: true,
count: res.data.count
});
}
wx.hideToast();
});
},
getCoupon(e) {
if (!app.globalData.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
let couponId = e.currentTarget.dataset.index
util.request(api.CouponReceive, {
couponId: couponId
}, 'POST').then(res => {
if (res.errno === 0) {
wx.showToast({
title: "领取成功"
})
}
else {
util.showErrorToast(res.errmsg);
}
})
},
nextPage: function (event) {
var that = this;
if (this.data.page > that.data.count / that.data.size) {
wx.showToast({
title: '-_-没有下一页了-_-',
icon: 'none'
})
return true;
}
that.setData({
page: that.data.page + 1
});
this.getCouponList();
},
prevPage: function (event) {
if (this.data.page <= 1) {
wx.showToast({
title: '-_-没有上一页了-_-',
icon: 'none'
})
return false;
}
var that = this;
that.setData({
page: that.data.page - 1
});
this.getCouponList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "优惠券专区"
}
\ No newline at end of file
<view class="container">
<scroll-view class="coupon-list" scroll-y="true" scroll-top="{{scrollTop}}">
<view class="item" wx:for="{{couponList}}" wx:for-index="index" wx:for-item="item" wx:key="id" bindtap="getCoupon" data-index="{{item.id}}">
<!-- <view class="tag">{{item.tag}}</view>
<view class="content">
<view class="left">
<view class="discount">{{item.discount}}元</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class="right">
<view class="name">{{item.name}}</view>
<view class="time" wx:if="{{item.days != 0}}">有效期:{{item.days}}天</view>
<view class="time" wx:else> 有效期:{{item.startTime}} - {{item.endTime}}</view>
</view>
</view>
<view class="condition">
<text class="txt">{{item.desc}}</text>
<image src="{{item.pic}}" class="icon"></image>
</view> -->
<image class='coupon-bg' src="/static/images/coupon-bg.png"></image>
<view class="content">
<view class="left">
<view class="discount">
<text class="discount-text">¥</text>
<text class="discount-num">{{item.discount}}</text>
</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class='coupon-main-right'>
<view class="name">{{item.name}}</view>
<view class="time" wx:if="{{item.startTime}}">{{item.startTime}} - </view>
<view class="time" wx:if="{{item.endTime}}">{{item.endTime}}</view>
<view class="time" wx:if="{{item.days}}">有效期:{{item.days}}天</view>
<view class="time" wx:if="{{item.desc}}">{{item.desc}}</view>
<view class='use' bindtap='gotoHome' bindtap="getCoupon" data-id="{{item.id}}" data-index="{{index}}">
领取
</view>
</view>
</view>
</view>
<view class="page" wx:if="{{showPage}}">
<view class="prev {{ page <= 1 ? 'disabled' : ''}}" bindtap="prevPage">上一页</view>
<view class="next {{ (count / size) < page ? 'disabled' : ''}}" bindtap="nextPage">下一页</view>
</view>
</scroll-view>
</view>
\ No newline at end of file
page {
background: #fff;
min-height: 100%;
}
.container {
background: #fff;
min-height: 100%;
padding-top: 30rpx;
}
.coupon-list {
width: 750rpx;
height: 100%;
overflow: hidden;
}
.item {
position: relative;
height: 200rpx;
width: 698rpx;
margin-bottom: 10rpx;
margin-left: 30rpx;
margin-right: 30rpx;
padding-top: 30rpx;
}
.coupon-bg {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 4.5rpx;
z-index: 200;
}
.content {
width: 689rpx;
height: 193rpx;
display: flex;
flex-direction: row;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
}
.content .left {
width: 204rpx;
float: left;
}
.discount {
width: 204rpx;
display: flex;
align-items:flex-end;
justify-content: center;
margin-top: 30rpx;
}
.discount-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
color:rgba(255,34,70,1);
display: block;
margin-bottom: 15rpx;
margin-right: 5rpx;
}
.discount-num {
font-size:60rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(255,34,70,1);
}
.min {
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
text-align: center;
}
.content .right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.coupon-main-right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.name {
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 37rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.time {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
margin-left: 37rpx;
color:rgba(110,110,110,1);
}
.use {
width: 126rpx;
border-radius:50rpx;
background: #FF1B40;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color: #fff;
text-align: center;
line-height: 50rpx;
position: absolute;
right: 40rpx;
top: 70rpx;
}
.condition {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 78rpx;
background: rgba(0, 0, 0, 0.08);
padding: 24rpx 40rpx;
display: flex;
flex-direction: row;
}
.condition .txt {
display: block;
height: 30rpx;
flex: 1;
overflow: hidden;
font-size: 24rpx;
line-height: 30rpx;
color: #fff;
}
.condition .icon {
margin-left: 30rpx;
width: 24rpx;
height: 24rpx;
}
.page {
width: 750rpx;
background: #fff;
margin-bottom: 20rpx;
display: flex;
justify-content: center;
}
.prev, .next {
width: 200rpx;
line-height: 60rpx;
font-size: 24rpx;
font-weight: 400;
color: #FF1B40;
border-radius: 50rpx;
border: 1rpx solid #FF1B40;
text-align: center;
}
.prev {
margin-right: 20rpx;
}
.page .disabled {
border:1rpx solid rgba(110,110,110,1);
color: rgba(110,110,110,1);
}
\ No newline at end of file
var app = getApp();
var WxParse = require('../../lib/wxParse/wxParse.js');
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var user = require('../../utils/user.js');
Page({
data: {
detailShow: true,
id: 0,
goods: {},
groupon: [], //该商品支持的团购规格
grouponLink: {}, //参与的团购
attribute: [],
issueList: [],
comment: [],
brand: {},
specificationList: [],
productList: [],
relatedGoods: [],
cartGoodsCount: 0,
userHasCollect: 0,
number: 1,
checkedSpecText: '规格数量选择',
tmpSpecText: '请选择规格数量',
temPicurl:'',
checkedSpecPrice: 0,
useScores: 0,
openAttr: false,
openShare: false,
noCollectImage: '/static/images/collect-icon.png',
hasCollectImage: '/static/images/collect-icon_selcet.png',
collectImage: '/static/images/collect-icon.png',
shareImage: '',
goodQrCodeImg: '',
goodQrCodeImgShow: false,
isGroupon: false, //标识是否是一个参团购买
soldout: false,
canWrite: false, //用户是否获取了保存相册的权限
},
stopPageScroll() {
return
},
/**
* 生成二维码
*/
qrcodeFn() {
let that = this;
console.log('/pages/index2/index2?goodId=' + that.data.id)
wx.request({
url: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx4359791c2e1f0be0&secret=57983271226db8ed6fe735323f3b6b30',
complete: function (tokenRes) {
console.log(">>>",tokenRes)
wx.request({
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + tokenRes.data.access_token,
method: 'POST',
data: {
scene: 'goods,'+that.data.id,
// 是否为Png,默认jpeg
// is_hyaline: true,
// 是否自动取色
auto_color: true,
page: 'pages/index2/index2',
},
responseType: 'arraybuffer',
complete: function (res) {
// that.base64src('data:image/png;base64,' + wx.arrayBufferToBase64(res.data))
that.setData({
goodQrCodeImg: 'data:image/png;base64,' + wx.arrayBufferToBase64(res.data),
goodQrCodeImgShow: true
})
// 自动复制到剪切板
// wx.setClipboardData({
// data: wx.arrayBufferToBase64(res.data),
// success(res) { }
// })
// console.log(wx.arrayBufferToBase64(res.data));
},
})
},
});
},
base64src (base64data) {
let that = this;
const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'tmp_base64src';
return new Promise((resolve, reject) => {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
reject(new Error('ERROR_BASE64SRC_PARSE'));
}
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
console.log(filePath)
that.setData({
goodQrCodeImg: filePath
})
});
},
viewImage(e) {
let that = this;
var aa = wx.getFileSystemManager();
console.log('that.data.goodQrCodeImg:', that.data.goodQrCodeImg)
aa.writeFile({
filePath: wx.env.USER_DATA_PATH + '/test.png',
data: that.data.goodQrCodeImg.slice(22),
encoding: 'base64',
success: res => {
wx.saveImageToPhotosAlbum({
filePath: wx.env.USER_DATA_PATH + '/test.png',
success: function (res) {
wx.showToast({
title: '保存成功',
})
},
fail: function (err) {
console.log(err)
}
})
console.log(res)
}, fail: err => {
console.log(err)
}
})
},
// 页面分享
onShareAppMessage: function() {
let that = this;
return {
title: that.data.goods.name,
imageUrl: that.data.shareImage,
desc: '唯爱与美食不可辜负',
path: '/pages/index2/index2?goodId=' + this.data.id
}
},
shareFriendOrCircle: function() {
//var that = this;
if (this.data.openShare === false) {
this.setData({
openShare: !this.data.openShare
});
} else {
return false;
}
},
handleSetting: function(e) {
var that = this;
// console.log(e)
if (!e.detail.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '警告',
content: '不授权无法保存',
showCancel: false
})
that.setData({
canWrite: false
})
} else {
wx.showToast({
title: '保存成功'
})
that.setData({
canWrite: true
})
}
},
// 保存分享图
saveShare: function() {
let that = this;
wx.downloadFile({
url: that.data.shareImage,
success: function(res) {
console.log(res)
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function(res) {
wx.showModal({
title: '存图成功',
content: '图片成功保存到相册了,可以分享到朋友圈了',
showCancel: false,
confirmText: '好的',
confirmColor: '#a78845',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
}
}
})
},
fail: function(res) {
console.log('fail')
}
})
},
fail: function() {
console.log('fail')
}
})
},
//从分享的团购进入
getGrouponInfo: function(grouponId) {
let that = this;
util.request(api.GroupOnJoin, {
grouponId: grouponId
}).then(function(res) {
if (res.errno === 0) {
that.setData({
grouponLink: res.data.groupon,
id: res.data.goods.id
});
//获取商品详情
that.getGoodsInfo();
}
});
},
// 获取商品信息
getGoodsInfo: function() {
let that = this;
util.request(api.GoodsDetail, {
id: that.data.id
}).then(function(res) {
if (res.errno === 0) {
let _specificationList = res.data.specificationList
// 如果仅仅存在一种货品,那么商品页面初始化时默认checked
if (_specificationList.length == 1) {
if (_specificationList[0].valueList.length == 1) {
_specificationList[0].valueList[0].checked = true
// 如果仅仅存在一种货品,那么商品价格应该和货品价格一致
// 这里检测一下
let _productPrice = res.data.productList[0].price;
let _goodsPrice = res.data.info.retailPrice;
if (_productPrice != _goodsPrice) {
console.error('商品数量价格和货品不一致');
}
that.setData({
checkedSpecText: _specificationList[0].valueList[0].value,
tmpSpecText: '已选择:' + _specificationList[0].valueList[0].value,
});
}
}
that.setData({
goods: res.data.info,
attribute: res.data.attribute,
issueList: res.data.issue,
comment: res.data.comment,
brand: res.data.brand,
specificationList: res.data.specificationList,
productList: res.data.productList,
userHasCollect: res.data.userHasCollect,
shareImage: res.data.shareImage || res.data.info.gallery[0],
checkedSpecPrice: res.data.info.retailPrice,
useScores: res.data.info.useScores,
groupon: res.data.groupon
});
//如果是通过分享的团购参加团购,则团购项目应该与分享的一致并且不可更改
if (that.data.isGroupon) {
let groupons = that.data.groupon;
for (var i = 0; i < groupons.length; i++) {
if (groupons[i].id != that.data.grouponLink.rulesId) {
groupons.splice(i, 1);
}
}
groupons[0].checked = true;
//重设团购规格
that.setData({
groupon: groupons
});
}
if (res.data.userHasCollect == 1) {
that.setData({
collectImage: that.data.hasCollectImage
});
} else {
that.setData({
collectImage: that.data.noCollectImage
});
}
WxParse.wxParse('goodsDetail', 'html', res.data.info.detail, that);
//获取推荐商品
that.getGoodsRelated();
// that.qrcodeFn();
}
});
},
// 获取推荐商品
getGoodsRelated: function() {
let that = this;
util.request(api.GoodsRelated, {
id: that.data.id
}).then(function(res) {
if (res.errno === 0) {
that.setData({
relatedGoods: res.data.goodsList,
});
}
});
},
// 团购选择
clickGroupon: function(event) {
let that = this;
//参与团购,不可更改选择
if (that.data.isGroupon) {
return;
}
let specName = event.currentTarget.dataset.name;
let specValueId = event.currentTarget.dataset.valueId;
let _grouponList = this.data.groupon;
for (let i = 0; i < _grouponList.length; i++) {
if (_grouponList[i].id == specValueId) {
if (_grouponList[i].checked) {
_grouponList[i].checked = false;
} else {
_grouponList[i].checked = true;
}
} else {
_grouponList[i].checked = false;
}
}
this.setData({
groupon: _grouponList,
});
},
// 规格选择
clickSkuValue: function(event) {
let that = this;
let specName = event.currentTarget.dataset.name;
let specValueId = event.currentTarget.dataset.valueId;
//判断是否可以点击
//TODO 性能优化,可在wx:for中添加index,可以直接获取点击的属性名和属性值,不用循环
let _specificationList = this.data.specificationList;
for (let i = 0; i < _specificationList.length; i++) {
if (_specificationList[i].name === specName) {
for (let j = 0; j < _specificationList[i].valueList.length; j++) {
if (_specificationList[i].valueList[j].id == specValueId) {
//如果已经选中,则反选
if (_specificationList[i].valueList[j].checked) {
_specificationList[i].valueList[j].checked = false;
} else {
_specificationList[i].valueList[j].checked = true;
this.setData({
temPicurl:_specificationList[i].valueList[j].picUrl
})
}
} else {
_specificationList[i].valueList[j].checked = false;
}
}
}
}
this.setData({
specificationList: _specificationList,
});
//重新计算spec改变后的信息
this.changeSpecInfo();
//重新计算哪些值不可以点击
},
//获取选中的团购信息
getCheckedGrouponValue: function() {
let checkedValues = {};
let _grouponList = this.data.groupon;
for (let i = 0; i < _grouponList.length; i++) {
if (_grouponList[i].checked) {
checkedValues = _grouponList[i];
}
}
return checkedValues;
},
//获取选中的规格信息
getCheckedSpecValue: function() {
let checkedValues = [];
let _specificationList = this.data.specificationList;
for (let i = 0; i < _specificationList.length; i++) {
let _checkedObj = {
name: _specificationList[i].name,
valueId: 0,
valueText: ''
};
for (let j = 0; j < _specificationList[i].valueList.length; j++) {
if (_specificationList[i].valueList[j].checked) {
_checkedObj.valueId = _specificationList[i].valueList[j].id;
_checkedObj.valueText = _specificationList[i].valueList[j].value;
}
}
checkedValues.push(_checkedObj);
}
return checkedValues;
},
//判断规格是否选择完整
isCheckedAllSpec: function() {
return !this.getCheckedSpecValue().some(function(v) {
if (v.valueId == 0) {
return true;
}
});
},
getCheckedSpecKey: function() {
let checkedValue = this.getCheckedSpecValue().map(function(v) {
return v.valueText;
});
return checkedValue;
},
// 规格改变时,重新计算价格及显示信息
changeSpecInfo: function() {
let checkedNameValue = this.getCheckedSpecValue();
//设置选择的信息
let checkedValue = checkedNameValue.filter(function(v) {
if (v.valueId != 0) {
return true;
} else {
return false;
}
}).map(function(v) {
return v.valueText;
});
if (checkedValue.length > 0) {
this.setData({
tmpSpecText: checkedValue.join(' ')
});
} else {
this.setData({
tmpSpecText: '请选择规格数量'
});
}
if (this.isCheckedAllSpec()) {
this.setData({
checkedSpecText: this.data.tmpSpecText
});
// 规格所对应的货品选择以后
let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
if (!checkedProductArray || checkedProductArray.length <= 0) {
this.setData({
soldout: true
});
console.error('规格所对应货品不存在');
return;
}
let checkedProduct = checkedProductArray[0];
debugger
if (checkedProduct.number > 0) {
this.setData({
checkedSpecPrice: checkedProduct.price,
soldout: false
});
} else {
this.setData({
checkedSpecPrice: this.data.goods.retailPrice,
soldout: true
});
}
} else {
this.setData({
checkedSpecText: '规格数量选择',
checkedSpecPrice: this.data.goods.retailPrice,
soldout: false
});
}
},
// 获取选中的产品(根据规格)
getCheckedProductItem: function(key) {
return this.data.productList.filter(function(v) {
if (v.specifications.toString() == key.toString()) {
return true;
} else {
return false;
}
});
},
onLoad: function(options) {
console.log(">>>options",options)
// 页面初始化 options为页面跳转所带来的参数
if (options.id) {
this.setData({
id: parseInt(options.id)
});
this.getGoodsInfo();
}
if (options.grouponId) {
this.setData({
isGroupon: true,
});
this.getGrouponInfo(options.grouponId);
}
let that = this;
wx.getSetting({
success: function (res) {
console.log(res)
//不存在相册授权
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success: function () {
that.setData({
canWrite: true
})
},
fail: function (err) {
that.setData({
canWrite: false
})
}
})
} else {
that.setData({
canWrite: true
});
}
}
})
},
onShow: function() {
// 页面显示
var that = this;
util.request(api.CartGoodsCount).then(function(res) {
if (res.errno === 0) {
that.setData({
cartGoodsCount: res.data
});
}
});
},
//添加或是取消收藏
addCollectOrNot: function() {
let that = this;
util.request(api.CollectAddOrDelete, {
type: 0,
valueId: this.data.id
}, "POST")
.then(function(res) {
let _res = res;
if (_res.errno == 0) {
if (_res.data.type == 'add') {
that.setData({
collectImage: that.data.hasCollectImage
});
} else {
that.setData({
collectImage: that.data.noCollectImage
});
}
} else {
wx.showToast({
image: '/static/images/icon_error.png',
title: _res.errmsg,
mask: true
});
}
});
},
//立即购买(先自动加入购物车)
addFast: function() {
var that = this;
if (this.data.openAttr == false) {
//打开规格选择窗口
this.setData({
openAttr: !this.data.openAttr
});
} else {
//提示选择完整规格
if (!this.isCheckedAllSpec()) {
wx.showToast({
image: '/static/images/icon_error.png',
title: '请选择完整规格'
});
return false;
}
//根据选中的规格,判断是否有对应的sku信息
let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
if (!checkedProductArray || checkedProductArray.length <= 0) {
//找不到对应的product信息,提示没有库存
wx.showToast({
image: '/static/images/icon_error.png',
title: '没有库存'
});
return false;
}
let checkedProduct = checkedProductArray[0];
//验证库存
if (checkedProduct.number <= 0) {
wx.showToast({
image: '/static/images/icon_error.png',
title: '没有库存'
});
return false;
}
//验证团购是否有效
let checkedGroupon = this.getCheckedGrouponValue();
//立即购买
util.request(api.CartFastAdd, {
goodsId: this.data.goods.id,
number: this.data.number,
productId: checkedProduct.id
}, "POST")
.then(function(res) {
if (res.errno == 0) {
// 如果storage中设置了cartId,则是立即购买,否则是购物车购买
try {
wx.setStorageSync('cartId', res.data);
wx.setStorageSync('grouponRulesId', checkedGroupon.id);
wx.setStorageSync('grouponLinkId', that.data.grouponLink.id);
wx.navigateTo({
url: '/pages/checkout/checkout'
})
} catch (e) {}
} else {
wx.showToast({
image: '/static/images/icon_error.png',
title: res.errmsg,
mask: true
});
}
});
}
},
//添加到购物车
addToCart: function() {
var that = this;
if (this.data.openAttr == false) {
//打开规格选择窗口
this.setData({
openAttr: !this.data.openAttr
});
} else {
//提示选择完整规格
if (!this.isCheckedAllSpec()) {
wx.showToast({
image: '/static/images/icon_error.png',
title: '请选择完整规格'
});
return false;
}
//根据选中的规格,判断是否有对应的sku信息
let checkedProductArray = this.getCheckedProductItem(this.getCheckedSpecKey());
if (!checkedProductArray || checkedProductArray.length <= 0) {
//找不到对应的product信息,提示没有库存
wx.showToast({
image: '/static/images/icon_error.png',
title: '没有库存'
});
return false;
}
let checkedProduct = checkedProductArray[0];
//验证库存
if (checkedProduct.number <= 0) {
wx.showToast({
image: '/static/images/icon_error.png',
title: '没有库存'
});
return false;
}
//添加到购物车
util.request(api.CartAdd, {
goodsId: this.data.goods.id,
number: this.data.number,
productId: checkedProduct.id
}, "POST")
.then(function(res) {
let _res = res;
if (_res.errno == 0) {
wx.showToast({
title: '添加成功'
});
that.setData({
openAttr: !that.data.openAttr,
cartGoodsCount: _res.data
});
if (that.data.userHasCollect == 1) {
that.setData({
collectImage: that.data.hasCollectImage
});
} else {
that.setData({
collectImage: that.data.noCollectImage
});
}
} else {
wx.showToast({
image: '/static/images/icon_error.png',
title: _res.errmsg,
mask: true
});
}
});
}
},
cutNumber: function() {
this.setData({
number: (this.data.number - 1 > 1) ? this.data.number - 1 : 1
});
},
addNumber: function() {
this.setData({
number: this.data.number + 1
});
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
switchAttrPop: function() {
if (this.data.openAttr == false) {
this.setData({
openAttr: !this.data.openAttr
});
}
},
closeAttr: function() {
this.setData({
openAttr: false,
});
},
closeShare: function() {
this.setData({
openShare: false,
});
},
openCartPage: function() {
wx.switchTab({
url: '/pages/cart/cart'
});
},
onReady: function() {
// 页面渲染完成
},
// 下拉刷新
onPullDownRefresh() {
this.setData({
detailShow: false
})
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getGoodsInfo();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
setTimeout(()=>{
this.setData({
detailShow: true
})
}, 100)
},
//根据已选的值,计算其它值的状态
setSpecValueStatus: function() {
},
})
\ No newline at end of file
{
"navigationBarTitleText": "商品详情"
}
\ No newline at end of file
<view class="container">
<!-- background-size="cover" -->
<swiper class="goodsimgs" indicator-dots="true" indicator-active-color="#E31436" autoplay="true" interval="3000" duration="1000">
<swiper-item wx:for="{{goods.gallery}}" wx:key="*this">
<image src="{{item}}" background-size="cover"></image>
</swiper-item>
</swiper>
<view class="share-pop-box" hidden="{{!openShare}}">
<view class="share-pop">
<view class="close" bindtap="closeShare">
<image class="icon" src="/static/images/icon_close.png"></image>
</view>
<view class='share-info'>
<button class="sharebtn" open-type="share" wx:if="{{!isGroupon}}">
<image class='sharebtn_image' src='/static/images/wechat.png'></image>
<view class='sharebtn_text'>分享给好友</view>
</button>
<!-- <button class="savesharebtn" open-type="openSetting" bindopensetting="handleSetting" wx:if="{{(!isGroupon) && (!canWrite)}}" >
<image class='sharebtn_image' src='/static/images/friend.png'></image>
<view class='sharebtn_text'>发朋友圈</view>
</button> -->
<!-- <button class="savesharebtn" bindtap="saveShare" wx:if="{{!isGroupon && canWrite}}">
<image class='sharebtn_image' src='/static/images/friend.png'></image>
<view class='sharebtn_text'>发朋友圈</view>
</button> -->
</view>
</view>
</view>
<view class="goods-info">
<view class="c">
<view class="price">
<view class="retailPrice">¥{{checkedSpecPrice}}</view>
<view class="retailPrice g-bi" wx:if="{{useScores}}">+{{useScores}}戈币</view>
<view class="counterPrice">¥{{goods.counterPrice}}</view>
<!-- 分享 -->
<view class='goods_name'>
<!-- <view class="goods_name_right" bindtap="shareFriendOrCircle"></view> -->
<button class="goods_name_right" open-type="share">
分享
</button>
</view>
</view>
<view class='goods_name_left'>{{goods.name}}</view>
<view class="desc" wx:if="{{goods.brief.length}}">{{goods.brief}}</view>
<view class="brand" wx:if="{{brand.name}}">
<navigator url="../brandDetail/brandDetail?id={{brand.id}}">
<text>{{brand.name}}</text>
</navigator>
</view>
</view>
</view>
<view class="section-nav section-attr" bindtap="switchAttrPop">
<view class="t">请选择规格数量</view>
<image class="i" src="/static/images/address_right.png" background-size="cover"></image>
</view>
<view class="comments" wx:if="{{comment.count > 0}}">
<view class="h">
<navigator url="/pages/comment/comment?valueId={{goods.id}}&type=0">
<text class="t">评价({{comment.count > 999 ? '999+' : comment.count}})</text>
<text class="i">查看全部</text>
</navigator>
</view>
<view class="b">
<view class="item" wx:for="{{comment.data}}" wx:key="id">
<view class="info">
<view class="user">
<image src="{{item.avatar}}"></image>
<text>{{item.nickname}}</text>
</view>
<view class="time">{{item.addTime}}</view>
</view>
<view class="content">
{{item.content}}
</view>
<view class="imgs" wx:if="{{item.picList.length > 0}}">
<image class="img" wx:for="{{item.picList}}" wx:key="*this" wx:for-item="iitem" src="{{iitem}} "></image>
</view>
</view>
</view>
</view>
<view class="goods-attr">
<view class="t">商品参数</view>
<view class="l">
<view class="item" wx:for="{{attribute}}" wx:key="name">
<text class="left">{{item.attribute}}</text>
<text class="right">{{item.value}}</text>
</view>
</view>
</view>
<view class="detail" wx:if="{{detailShow}}">
<import src="/lib/wxParse/wxParse.wxml" />
<template is="wxParse" data="{{wxParseData:goodsDetail.nodes}}" />
</view>
<view class="common-problem">
<view class="h">
<view class="line"></view>
<text class="title">常见问题</text>
</view>
<view class="b">
<view class="item" wx:for="{{issueList}}" wx:key="id">
<view class="question-box">
<text class="spot"></text>
<text class="question">{{item.question}}</text>
</view>
<view class="answer">
{{item.answer}}
</view>
</view>
</view>
</view>
<!-- <view class='good-qr-box'>
<image wx:if="{{goodQrCodeImgShow}}" src="{{goodQrCodeImg}}" class='good-qr-code' bindtap="viewImage"></image>
</view> -->
<!-- 大家都在看 -->
<view class="related-goods" wx:if="{{relatedGoods.length > 0}}">
<view class="h">
<view class="line"></view>
<text class="title">大家都在看</text>
</view>
<view class="b">
<view class="item" wx:for="{{relatedGoods}}" wx:key="id">
<navigator url="/pages/goods/goods?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<text class="name">{{item.name}}</text>
<text class="price">¥{{item.retailPrice}}</text>
</navigator>
</view>
</view>
</view>
</view>
<!-- 规格选择界面 -->
<view class="attr-pop-box" hidden="{{!openAttr}}" catchtouchmove='stopPageScroll'>
<view class="attr-pop">
<view class="close" bindtap="closeAttr">
<image class="icon" src="/static/images/icon_close.png"></image>
</view>
<view class="img-info">
<image class="img" src="{{temPicurl?temPicurl:goods.picUrl}}"></image>
<view class="info">
<view class="c">
<view class="p">¥{{checkedSpecPrice}}</view>
<view class="a">{{tmpSpecText}}</view>
</view>
</view>
</view>
<!-- 规格列表 -->
<view class="spec-con">
<view class="spec-item" wx:for="{{specificationList}}" wx:key="name">
<view class="name">{{item.name}}</view>
<view class="values">
<view class="value {{vitem.checked ? 'selected' : ''}}" bindtap="clickSkuValue" wx:for="{{item.valueList}}" wx:for-item="vitem" wx:key="{{vitem.id}}" data-value-id="{{vitem.id}}" data-name="{{vitem.specification}}" data-value='{{vitem.value}}'>{{vitem.value}}</view>
</view>
</view>
<view class="spec-con" wx:if="{{groupon.length > 0}}">
<view class="spec-item">
<view class="name">团购立减</view>
<view class="values">
<view class="value {{vitem.checked ? 'selected' : ''}}" bindtap="clickGroupon" wx:for="{{groupon}}" wx:for-item="vitem" wx:key="{{vitem.id}}" data-value-id="{{vitem.id}}" data-name="{{vitem.specification}}">¥{{vitem.discount}} ({{vitem.discountMember}}人)</view>
</view>
</view>
</view>
<!-- 数量 -->
<view class="number-item">
<view class="name">数量</view>
<view class="selnum">
<view class="cut" bindtap="cutNumber">-</view>
<input value="{{number}}" class="number" disabled="true" type="number" />
<view class="add" bindtap="addNumber">+</view>
</view>
</view>
</view>
</view>
</view>
<!-- 联系客服 -->
<!-- <view class="contact">
<contact-button style="opacity:0;position:absolute;" type="default-dark" session-from="weapp" size="27">
</contact-button>
</view> -->
<!-- 底部按钮 -->
<view class="bottom-btn">
<view class="l l-server">
<image bindtap="openCartPage" class="icon" src="/static/images/service-icon.png"></image>
<contact-button style="opacity:0;position:absolute;" type="default-dark" session-from="weapp" size="27">
</contact-button>
</view>
<view class="l l-collect" bindtap="addCollectOrNot" wx:if="{{!isGroupon}}">
<image class="icon" src="{{ collectImage }}"></image>
</view>
<view class="l l-cart" wx:if="{{!isGroupon}}">
<view class="box">
<text class="cart-count">{{cartGoodsCount}}</text>
<image bindtap="openCartPage" class="icon" src="/static/images/shop-icon-2.png"></image>
</view>
</view>
<view class="c" bindtap="addFast" wx:if="{{!soldout}}">{{isGroupon?'参加团购':'立即购买'}}</view>
<view class="r" bindtap="addToCart" wx:if="{{!soldout}}" wx:if="{{!isGroupon}}">加入购物车</view>
<view class="c" wx:if="{{soldout}}">商品已售空</view>
</view>
\ No newline at end of file
.container {
margin-bottom: 100rpx;
}
.good-qr-box {
width: 100%;
height: 300rpx;
display: flex;
align-items: center;
justify-content: center;
background:#fff;
}
.good-qr-code {
display: block;
width: 300rpx;
height: 300rpx;
margin: 10rpx auto;
}
.goodsimgs {
width: 750rpx;
height: 750rpx;
}
.goodsimgs image {
width: 750rpx;
height: 750rpx;
}
.commodity_screen {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
opacity: 0.2;
overflow: hidden;
z-index: 1000;
color: #fff;
}
.commodity_attr_box {
width: 100%;
overflow: hidden;
position: fixed;
bottom: 0;
left: 0;
z-index: 2000;
background: #fff;
padding-top: 20rpx;
}
/* .service-policy {
width: 750rpx;
height: 73rpx;
background: #f4f4f4;
padding: 0 31.25rpx;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: space-between;
}
.service-policy .item {
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/servicePolicyRed-518d32d74b.png) 0 center no-repeat;
background-size: 10rpx;
padding-left: 15rpx;
display: flex;
align-items: center;
font-size: 25rpx;
color: #666;
} */
.goods-info {
width: 750rpx;
overflow: hidden;
background: #fff;
}
.goods-info .c {
display: block;
width: 718.75rpx;
height: 100%;
margin-left: 31.25rpx;
padding: 18rpx 31.25rpx 38rpx 0;
}
.goods-info .c text {
display: block;
width: 687.5rpx;
text-align: left;
}
.goods_name {
margin-top: 20rpx;
position: absolute;
top: 0rpx;
right: 0rpx;
z-index: 7;
}
.goods_name_left {
font-size:30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.goods_name_right {
color: #FF1B40;
border-radius: 50rpx;
border: 1rpx solid #FF1B40;
text-align: center;
font-size: 24rpx;
background: none;
height:42rpx;
line-height:42rpx;
}
.goods-info .desc {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-top: 10rpx;
display: -webkit-box; /* 定义为自适应布局 */
word-break: break-all; /* 换行模式 */
text-overflow: ellipsis; /* 超出文字用省略号代替 */
overflow: hidden; /* 多出部分隐藏 */
-webkit-box-orient: vertical; /* 竖直方向的超出和隐藏 */
-webkit-line-clamp: 3; /* 设定行数为3 */
}
.goods-info .price {
height: 70rpx;
display: flex;
align-items: center;
position: relative;
}
.goods-info .counterPrice {
padding-left: 0rpx;
text-decoration: line-through;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-left: 12rpx;
margin-top: 10rpx;
}
.goods-info .retailPrice {
font-size:48rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:#FF1B40;
}
.goods-info .g-bi {
font-size:24rpx;
margin-top:10rpx;
margin-left: 5rpx;
}
.goods-info .brand {
margin-top: 23rpx;
min-height: 40rpx;
text-align: left;
}
.goods-info .brand text {
display: inline-block;
width: auto;
padding: 2px 30rpx 2px 10.5rpx;
line-height: 35.5rpx;
border: 1px solid #f48f18;
font-size: 25rpx;
color: #f48f18;
border-radius: 4px;
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/detailTagArrow-18bee52dab.png) 95% center no-repeat;
background-size: 10.75rpx 18.75rpx;
}
.section-nav {
width: 750rpx;
background: #fff;
margin-bottom: 20rpx;
margin-top: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.section-nav .t {
float: left;
width: 600rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
line-height:93rpx;
margin-left: 28rpx;
}
.section-nav .i {
float: right;
width: 52rpx;
height: 52rpx;
margin-right: 16rpx;
}
.section-act .t {
float: left;
display: flex;
align-items: center;
width: 600rpx;
height: 108rpx;
overflow: hidden;
line-height: 108rpx;
font-size: 29rpx;
color: #999;
margin-left: 31.25rpx;
}
.section-act .label {
color: #999;
}
.section-act .tag {
display: flex;
align-items: center;
padding: 0 10rpx;
border-radius: 3px;
height: 37rpx;
width: auto;
color: #f48f18;
overflow: hidden;
border: 1px solid #f48f18;
font-size: 25rpx;
margin: 0 10rpx;
}
.section-act .text {
display: flex;
align-items: center;
height: 37rpx;
width: auto;
overflow: hidden;
color: #f48f18;
font-size: 29rpx;
}
.comments {
width: 100%;
height: auto;
padding-left: 30rpx;
background: #fff;
margin: 20rpx 0;
}
.comments .h {
height: 102.5rpx;
line-height: 100.5rpx;
width: 718.75rpx;
padding-right: 16rpx;
border-bottom: 1px solid #d9d9d9;
}
.comments .h .t {
display: block;
float: left;
width: 50%;
font-size: 38.5rpx;
color: #333;
}
.comments .h .i {
display: block;
float: right;
width: 164rpx;
height: 100.5rpx;
line-height: 100.5rpx;
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/address-right-990628faa7.png) right center no-repeat;
background-size: 52rpx;
}
.comments .b {
height: auto;
width: 720rpx;
}
.comments .item {
height: auto;
width: 720rpx;
overflow: hidden;
}
.comments .info {
height: 127rpx;
width: 100%;
padding: 33rpx 0 27rpx 0;
}
.comments .user {
float: left;
width: auto;
height: 67rpx;
line-height: 67rpx;
font-size: 0;
}
.comments .user image {
float: left;
width: 67rpx;
height: 67rpx;
margin-right: 17rpx;
border-radius: 50%;
}
.comments .user text {
display: inline-block;
width: auto;
height: 66rpx;
overflow: hidden;
font-size: 29rpx;
line-height: 66rpx;
}
.comments .time {
display: block;
float: right;
width: auto;
height: 67rpx;
line-height: 67rpx;
color: #7f7f7f;
font-size: 25rpx;
margin-right: 30rpx;
}
.comments .content {
width: 720rpx;
padding-right: 30rpx;
line-height: 45.8rpx;
font-size: 29rpx;
margin-bottom: 24rpx;
}
.comments .imgs {
width: 720rpx;
height: auto;
margin-bottom: 25rpx;
}
.comments .imgs .img {
height: 150rpx;
width: 150rpx;
margin-right: 28rpx;
}
.comments .spec {
width: 720rpx;
padding-right: 30rpx;
line-height: 30rpx;
font-size: 24rpx;
color: #999;
margin-bottom: 30rpx;
}
.goods-attr {
width: 750rpx;
height: auto;
overflow: hidden;
padding: 0 31.25rpx 25rpx 31.25rpx;
background: #fff;
}
.goods-attr .t {
width: 687.5rpx;
height: 104rpx;
line-height: 104rpx;
font-size: 38.5rpx;
}
.goods-attr .item {
width: 687.5rpx;
height: 68rpx;
padding: 11rpx 20rpx;
margin-bottom: 11rpx;
background: #f7f7f7;
font-size: 38.5rpx;
}
.goods-attr .left {
float: left;
font-size: 25rpx;
width: 134rpx;
height: 45rpx;
line-height: 45rpx;
overflow: hidden;
color: #999;
}
.goods-attr .right {
float: left;
font-size: 36.5rpx;
margin-left: 20rpx;
width: 480rpx;
height: 45rpx;
line-height: 45rpx;
overflow: hidden;
color: #333;
}
.detail {
width: 750rpx;
height: auto;
overflow: hidden;
}
.detail image {
width: 750rpx;
display: block;
}
.common-problem {
width: 750rpx;
height: auto;
overflow: hidden;
}
.common-problem .h {
position: relative;
height: 145.5rpx;
width: 750rpx;
padding: 56.25rpx 0;
background: #fff;
text-align: center;
}
.common-problem .h .line {
display: inline-block;
position: absolute;
top: 72rpx;
left: 0;
z-index: 2;
height: 1px;
margin-left: 225rpx;
width: 300rpx;
background: #ccc;
}
.common-problem .h .title {
display: inline-block;
position: absolute;
top: 56.125rpx;
left: 0;
z-index: 3;
height: 33rpx;
margin-left: 285rpx;
width: 180rpx;
background: #fff;
}
.common-problem .b {
width: 750rpx;
height: auto;
overflow: hidden;
padding: 0rpx 30rpx;
background: #fff;
}
.common-problem .item {
height: auto;
overflow: hidden;
padding-bottom: 25rpx;
}
.common-problem .question-box .spot {
float: left;
display: block;
height: 8rpx;
width: 8rpx;
background: #b4282d;
border-radius: 50%;
margin-top: 11rpx;
}
.common-problem .question-box .question {
float: left;
line-height: 30rpx;
padding-left: 8rpx;
display: block;
font-size: 26rpx;
padding-bottom: 15rpx;
color: #303030;
}
.common-problem .answer {
line-height: 36rpx;
padding-left: 16rpx;
font-size: 26rpx;
color: #787878;
}
.related-goods {
width: 750rpx;
height: auto;
overflow: hidden;
padding-bottom: 80rpx;
}
.related-goods .h {
position: relative;
height: 145.5rpx;
width: 750rpx;
padding: 56.25rpx 0;
background: #fff;
text-align: center;
border-bottom: 1px solid #f4f4f4;
}
.related-goods .h .line {
display: inline-block;
position: absolute;
top: 72rpx;
left: 0;
z-index: 2;
height: 1px;
margin-left: 225rpx;
width: 300rpx;
background: #ccc;
}
.related-goods .h .title {
display: inline-block;
position: absolute;
top: 56.125rpx;
left: 0;
z-index: 3;
height: 33rpx;
margin-left: 285rpx;
width: 180rpx;
background: #fff;
}
.related-goods .b {
width: 750rpx;
height: auto;
overflow: hidden;
}
.related-goods .b .item {
float: left;
background: #fff;
width: 375rpx;
height: auto;
overflow: hidden;
text-align: center;
padding: 15rpx 31.25rpx;
border-right: 1px solid #f4f4f4;
border-bottom: 1px solid #f4f4f4;
}
.related-goods .item .img {
width: 311.45rpx;
height: 311.45rpx;
}
.related-goods .item .name {
display: block;
width: 311.45rpx;
margin: 5rpx 0 5rpx 0;
text-align: center;
overflow: hidden;
font-size: 30rpx;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.related-goods .item .price {
display: block;
width: 311.45rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
color: #E31436;
}
.bottom-btn {
position: fixed;
left: 0;
bottom: 0;
z-index: 10;
width: 750rpx;
height: 88rpx;
display: flex;
background: #fff;
}
.bottom-btn .l {
float: left;
height: 88rpx;
width: 94rpx;
border: 1px solid #f4f4f4;
display: flex;
align-items: center;
justify-content: center;
}
.bottom-btn .l.l-collect {
border-right: none;
border-left: none;
text-align: center;
width: 90rpx;
}
.bottom-btn .l.l-kefu {
position: relative;
height: 54rpx;
width: 63rpx;
}
.bottom-btn .l.l-cart .box {
position: relative;
height: 60rpx;
width: 60rpx;
margin-top: 4rpx;
}
.bottom-btn .l.l-cart .cart-count {
height: 28rpx;
width: 28rpx;
z-index: 10;
position: absolute;
top: 0;
right: 0;
background: #E31436;
text-align: center;
font-size: 18rpx;
color: #fff;
line-height: 28rpx;
border-radius: 50%;
}
.bottom-btn .l.l-cart .icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.bottom-btn .l.l-kefu .kefu-count {
height: 28rpx;
width: 28rpx;
z-index: 10;
position: absolute;
top: 0;
right: 0;
/* background: #b4282d; */
text-align: center;
font-size: 18rpx;
color: #fff;
line-height: 28rpx;
border-radius: 50%;
}
.bottom-btn .l.l-kefu .icon {
position: absolute;
top: 10rpx;
left: 0;
}
.bottom-btn .l .icon {
display: block;
height: 36rpx;
width: 38rpx;
}
.bottom-btn .l-server .icon {
width: 30rpx;
height: 34rpx;
}
.bottom-btn .c {
float: left;
border-top:1rpx solid #f4f4f4;
background: #fff;
height: 88rpx;
flex: 1;
text-align: center;
color: #333333;
display: flex;
align-items: center;
justify-content: center;
}
.bottom-btn .r {
border: 1px solid #E31436;
background: #E31436;
float: left;
height: 88rpx;
flex: 1;
text-align: center;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
@import "../../lib/wxParse/wxParse.wxss";
.attr-pop-box {
width: 100%;
height: 100%;
position: fixed;
background: rgba(0, 0, 0, 0.5);
z-index: 8;
bottom: 0;
/* display: none; */
}
.attr-pop {
width: 100%;
height: auto;
max-height: 780rpx;
padding: 31.25rpx;
background: #fff;
position: fixed;
z-index: 9;
bottom: 88rpx;
}
.attr-pop .close {
position: absolute;
width: 48rpx;
height: 48rpx;
right: 31.25rpx;
overflow: hidden;
top: 31.25rpx;
}
.attr-pop .close .icon {
width: 48rpx;
height: 48rpx;
}
.attr-pop .img-info {
width: 687.5rpx;
height: 177rpx;
overflow: hidden;
margin-bottom: 21.5rpx;
}
.attr-pop .img {
float: left;
height: 177rpx;
width: 177rpx;
margin-right: 31.25rpx;
}
.attr-pop .info {
float: left;
height: 177rpx;
display: flex;
align-items: center;
}
.attr-pop .p {
line-height: 33rpx;
font-size:24rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:#FF1B40;
}
.attr-pop .a {
height: 40rpx;
line-height: 40rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.spec-con {
width: 100%;
height: auto;
overflow: hidden;
}
.spec-con .name {
margin-bottom: 22rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.spec-con .values {
height: auto;
margin-bottom: 31.25rpx;
font-size: 0;
}
.spec-con .value {
display: inline-block;
padding: 0 35rpx;
line-height: 46rpx;
text-align: center;
margin-right: 25rpx;
margin-bottom: 16.5rpx;
border: 1px solid #333;
font-size: 25rpx;
color: #333;
border-radius: 30rpx;
}
.spec-con .value.disable {
border:2rpx solid rgba(182,182,182,1);
color:rgba(182,182,182,1);
}
.spec-con .value.selected {
border: 2rpx solid #E31436;
color: #E31436;
}
.number-item .selnum {
width: 322rpx;
display: flex;
align-items: center;
}
.number-item .cut {
width: 46rpx;
text-align: center;
line-height: 46rpx;
background:rgba(240,240,240,1);
}
.number-item .number {
width: 84rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(0,0,0,1);
}
.number-item .add {
width: 46rpx;
text-align: center;
line-height: 46rpx;
background: #E31436;
color: #fff;
}
.contact {
height: 100rpx;
width: 100rpx;
border-radius: 100%;
position: fixed;
bottom: 96rpx;
right: 10rpx;
font-size: 20rpx;
box-sizing: border-box;
background: url("https://litemall.oss-cn-shenzhen.aliyuncs.com/kefu.png") no-repeat center 21rpx;
background-size: 55rpx auto;
}
.share-pop-box {
width: 100%;
height: 100%;
position: fixed;
background: rgba(0, 0, 0, 0.5);
z-index: 8;
bottom: 0;
/* display: none; */
}
.share-pop {
width: 100%;
height: auto;
max-height: 780rpx;
padding: 31.25rpx;
background: #fff;
position: fixed;
z-index: 9;
bottom: 88rpx;
}
.share-pop .close {
position: absolute;
width: 48rpx;
height: 48rpx;
right: 31.25rpx;
top: 31.25rpx;
}
.share-pop .close .icon {
width: 48rpx;
height: 48rpx;
}
.share-pop .share-info {
width: 100%;
height: 225rpx;
overflow: hidden;
margin-bottom: 41.5rpx;
}
.sharebtn {
top: 75rpx;
left: 50%;
background: none !important;
font-size: 32rpx;
color: #fff !important;
border-radius: 0%;
width: 175rpx;
height: 150rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
float: left;
background: #fff;
border-bottom: 0px solid #fafafa;
margin-left: -88rpx;
}
.sharebtn::after {
border: none;
border-radius: 0%;
}
.savesharebtn {
top: 75rpx;
background: none !important;
font-size: 32rpx;
color: #fff !important;
border-radius: 0%;
width: 175rpx;
height: 150rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
float: right;
background: #fff;
border-bottom: 0px solid #fafafa;
margin-right: 15%;
}
.savesharebtn::after {
border: none;
border-radius: 0%;
}
.sharebtn_image {
/* border: 1px solid #757575; */
width: 128rpx;
height: 128rpx;
margin-top: 0rpx;
}
.sharebtn_text {
/* border: 1px solid #757575; */
width: 150rpx;
margin-bottom: 2rpx;
height: 20rpx;
line-height: 20rpx;
font-size: 20rpx;
color: #555;
}
.separate {
background: #e0e3da;
width: 100%;
height: 6rpx;
}
.wxParse-p {
font-size: 0 !important;
}
.wxParse-img {
display: block;
width: 750px;
border: none;
}
\ No newline at end of file
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
Page({
data: {
id: 0,
orderId: 0,
groupon: {},
linkGrouponId: 0,
joiners: [],
orderInfo: {},
orderGoods: [],
expressInfo: {},
flag: false,
handleOption: {}
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.setData({
id: options.id
});
this.getOrderDetail();
},
// 页面分享
onShareAppMessage: function() {
let that = this;
return {
title: '邀请团购',
desc: '唯爱与美食不可辜负',
path: '/pages/index2/index2?grouponId=' + this.data.linkGrouponId
}
},
shareGroupon: function() {
let that = this;
wx.showActionSheet({
itemList: ['分享给朋友', '分享到朋友圈'],
itemColor: '#333333',
success: function(res) {
if (res.tapIndex == 0) {
wx.showModal({
title: '提示',
content: '点击右上角 "..." 转发给朋友',
showCancel: false
});
} else if (res.tapIndex == 1) {
that.saveShare();
} else {
console.log(res.tapIndex);
}
},
fail: function(res) {
console.log(res.errMsg);
}
})
},
// 保存分享图
saveShare: function() {
let that = this;
wx.downloadFile({
url: that.data.groupon.shareUrl,
success: function(res) {
console.log(res)
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: function(res) {
wx.showModal({
title: '存图成功',
content: '图片成功保存到相册了,可以分享到朋友圈了',
showCancel: false,
confirmText: '好的',
confirmColor: '#a78845',
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
}
}
})
},
fail: function(res) {
console.log('fail')
}
})
},
fail: function() {
console.log('fail')
}
})
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getOrderDetail();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
//获取物流信息
getOrderExpress: function() {
let that = this;
util.request(api.ExpressQuery, {
expCode: that.data.orderInfo.expCode,
expNo: that.data.orderInfo.expNo
}, 'POST').then(function(res) {
if (res.errno === 0) {
that.setData({
expressInfo: res.data
});
}
});
},
expandDetail: function() {
let that = this;
this.setData({
flag: !that.data.flag
})
},
getOrderDetail: function() {
let that = this;
util.request(api.GroupOnDetail, {
grouponId: that.data.id
}).then(function(res) {
if (res.errno === 0) {
if (that.data.orderInfo.actualPrice > 0) {
that.setData({
joiners: res.data.joiners,
groupon: res.data.groupon,
linkGrouponId: res.data.linkGrouponId,
orderId: res.data.orderInfo.id,
orderInfo: res.data.orderInfo,
orderGoods: res.data.orderGoods,
handleOption: res.data.orderInfo.handleOption
});
} else {
wx.redirectTo({
url: '/pages/payResult/payResult?status=1&orderId=' + that.data.orderId
});
}
// 请求物流信息,仅当订单状态为发货时才请求
if (res.data.orderInfo.handleOption.confirm) {
that.getOrderExpress();
}
}
});
},
// “去付款”按钮点击效果
payOrder: function() {
let that = this;
util.request(api.OrderPrepay, {
orderId: that.data.orderId
}, 'POST').then(function(res) {
if (res.errno === 0) {
const payParam = res.data;
console.log("支付过程开始");
wx.requestPayment({
'timeStamp': payParam.timeStamp,
'nonceStr': payParam.nonceStr,
'package': payParam.wxPackage,
'signType': payParam.signType,
'paySign': payParam.paySign,
'success': function(res) {
console.log("支付过程成功");
util.redirect('/pages/ucenter/order/order');
},
'fail': function(res) {
console.log("支付过程失败");
util.showErrorToast('支付失败');
},
'complete': function(res) {
console.log("支付过程结束")
}
});
}
});
},
// “取消订单”点击效果
cancelOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要取消此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderCancel, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '取消订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “取消订单并退款”点击效果
refundOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要取消此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderRefund, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '取消订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “删除”点击效果
deleteOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要删除此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderDelete, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '删除订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “确认收货”点击效果
confirmOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确认收货?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderConfirm, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '确认收货成功!'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
});
\ No newline at end of file
{
"navigationBarTitleText": "团购详情"
}
\ No newline at end of file
<view class="container">
<view class="order-info">
<view class="item-a">下单时间:{{orderInfo.addTime}}</view>
<view class="item-b">订单编号:{{orderInfo.orderSn}}</view>
<view class="item-c">
<view class="l">实付:
<text class="cost">¥{{orderInfo.actualPrice}}</text>
</view>
<view class="r">
<view class="btn active" bindtap="shareGroupon">邀请参团</view>
</view>
</view>
</view>
<view class="menu-list-pro">
<view class="h">
<view class="label">参与团购 ( {{joiners.length}}人)</view>
<view class="status">查看全部</view>
</view>
<view class="menu-list-item" wx:for-items="{{joiners}}" wx:key="id" data-id="{{item.id}}">
<image class="icon" src="{{item.avatar}}"></image>
<text class="txt">{{item.nickname}}</text>
</view>
</view>
<view class="order-goods">
<view class="h">
<view class="label">商品信息</view>
<view class="status">{{orderInfo.orderStatusText}}</view>
</view>
<view class="goods">
<view class="item" wx:for="{{orderGoods}}" wx:key="id">
<view class="img">
<image src="{{item.picUrl}}"></image>
</view>
<view class="info">
<view class="t">
<text class="name">{{item.goodsName}}</text>
<text class="number">x{{item.number}}</text>
</view>
<view class="attr">{{item.goodsSpecificationValues}}</view>
<view class="price">¥{{item.retailPrice}}</view>
</view>
</view>
</view>
<view class="order-bottom">
<view class="address">
<view class="t">
<text class="name">{{orderInfo.consignee}}</text>
<text class="mobile">{{orderInfo.mobile}}</text>
</view>
<view class="b">{{orderInfo.address}}</view>
</view>
<view class="total">
<view class="t">
<text class="label">商品合计:</text>
<text class="txt">¥{{orderInfo.goodsPrice}}</text>
</view>
<view class="t">
<text class="label">运费:</text>
<text class="txt">¥{{orderInfo.freightPrice}}</text>
</view>
</view>
<view class="pay-fee">
<text class="label">实付:</text>
<text class="txt">¥{{orderInfo.actualPrice}}</text>
</view>
</view>
</view>
<!-- 物流信息,仅收货状态下可见 -->
<view class="order-express" bindtap="expandDetail" wx:if="{{ handleOption.confirm }}">
<view class="expand">
<view class="title">
<view class="t">快递公司:{{expressInfo.expName}}</view>
<view class="b">物流单号:{{expressInfo.expCode}}</view>
</view>
<image class="ti" src="/static/images/address_right.png" background-size="cover"></image>
</view>
<!-- <view class="order-express" > -->
<view class="traces" wx:for="{{expressInfo.Traces}}" wx:key="item" wx:for-item="iitem" wx:if="{{ flag }}">
<view class="trace">
<view class="acceptStation">{{iitem.AcceptStation}}</view>
<view class="acceptTime">{{iitem.AcceptTime}}</view>
</view>
</view>
</view>
<!-- </view> -->
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #f4f4f4;
}
.order-info {
padding-top: 25rpx;
background: #fff;
height: auto;
overflow: hidden;
}
.item-a {
padding-left: 31.25rpx;
height: 42.5rpx;
padding-bottom: 12.5rpx;
line-height: 30rpx;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.item-b {
padding-left: 31.25rpx;
height: 29rpx;
line-height: 29rpx;
margin-top: 12.5rpx;
margin-bottom: 41.5rpx;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.item-c {
margin-left: 31.25rpx;
border-top: 1px solid #f4f4f4;
height: 103rpx;
line-height: 103rpx;
}
.item-c .l {
float: left;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.item-c .r {
height: 103rpx;
float: right;
display: flex;
align-items: center;
padding-right: 16rpx;
}
.item-c .r .btn {
float: right;
}
.item-c .cost {
color: #FF1B40;
}
.item-c .btn {
width:102px;
line-height: 60rpx;
text-align: center;
display: block;
float: right;
margin: 0 15rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
}
.item-c .btn.active {
background: #FF1B40;
color: #fff;
}
.order-goods {
margin-top: 20rpx;
background: #fff;
}
.order-goods .h {
height: 93.75rpx;
line-height: 93.75rpx;
margin-left: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
padding-right: 31.25rpx;
}
.order-goods .h .label {
float: left;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.order-goods .h .status {
float: right;
width:102px;
line-height: 60rpx;
text-align: center;
display: block;
margin: 0 15rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#fff;
}
.order-goods .item {
display: flex;
align-items: center;
height: 192rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-goods .item:last-child {
border-bottom: none;
}
.order-goods .item .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.order-goods .item .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.order-goods .item .info {
flex: 1;
height: 145.83rpx;
margin-left: 20rpx;
}
.order-goods .item .t {
margin-top: 8rpx;
height: 33rpx;
line-height: 33rpx;
margin-bottom: 10.5rpx;
}
.order-goods .item .t .name {
display: block;
float: left;
height: 33rpx;
line-height: 33rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .t .number {
display: block;
float: right;
height: 33rpx;
text-align: right;
line-height: 33rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .attr {
height: 29rpx;
line-height: 29rpx;
color: #666;
margin-bottom: 25rpx;
font-size: 25rpx;
}
.order-goods .item .price {
display: block;
float: left;
height: 30rpx;
line-height: 30rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .btn {
width:102px;
line-height: 60rpx;
text-align: center;
display: block;
float: right;
margin: 0 15rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
}
.order-goods .item .btn.active {
background: #FF1B40;
color: #fff;
}
.order-bottom {
margin-top: 20rpx;
padding-left: 31.25rpx;
height: auto;
overflow: hidden;
background: #fff;
}
.order-bottom .address {
height: 128rpx;
padding-top: 25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-bottom .address .t {
height: 35rpx;
line-height: 35rpx;
margin-bottom: 7.5rpx;
}
.order-bottom .address .name {
display: inline-block;
height: 35rpx;
width: 140rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .address .mobile {
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .address .b {
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .total {
height: 106rpx;
padding-top: 20rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-bottom .total .t {
height: 30rpx;
line-height: 30rpx;
margin-bottom: 7.5rpx;
display: flex;
}
.order-bottom .total .label {
width: 150rpx;
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.order-bottom .total .txt {
flex: 1;
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.order-bottom .pay-fee {
height: 81rpx;
line-height: 81rpx;
}
.order-bottom .pay-fee .label {
display: inline-block;
width: 140rpx;
color: #FF1B40;
}
.order-bottom .pay-fee .txt {
display: inline-block;
width: 140rpx;
color: #FF1B40;
}
.order-express {
margin-top: 20rpx;
width: 100%;
height: 100rpx;
background: #fff;
}
.order-express .expand {
/* margin-top: 20rpx; */
width: 100%;
height: 100rpx;
background: #fff;
/* border: 10rpx #FF1B40; */
}
.order-express .title {
float: left;
margin-bottom: 20rpx;
padding: 10rpx;
}
.order-express .ti {
float: right;
width: 52rpx;
height: 52rpx;
margin-right: 16rpx;
margin-top: 28rpx;
}
.order-express .t {
font-size: 29rpx;
margin-left: 10.25rpx;
color: #FF1B40;
}
.order-express .b {
font-size: 29rpx;
margin-left: 10.25rpx;
color: #FF1B40;
}
.order-express .traces {
padding: 17.5rpx;
background: #fff;
border-bottom: 1rpx solid #f1e6cdcc;
}
.order-express .trace {
padding-bottom: 17.5rpx;
padding-top: 17.5rpx;
background: #fff;
}
.order-express .acceptTime {
margin-top: 20rpx;
margin-right: 40rpx;
text-align: right;
font-size: 26rpx;
}
.order-express .acceptStation {
font-size: 26rpx;
}
.menu-list-pro {
margin-top: 20rpx;
overflow-x: scroll;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
height: 260rpx;
width: 100%;
border-bottom: 1rpx #cfc9ca;
background-color: #fff;
}
.menu-list-pro .h {
height: 93.75rpx;
line-height: 93.75rpx;
margin-left: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
padding-right: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.menu-list-pro .h .label {
float: left;
font-size: 30rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.menu-list-pro .h .status {
float: right;
width:102px;
line-height: 60rpx;
text-align: center;
display: block;
margin: 0 15rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#fff;
}
.menu-list-pro .menu-list-item {
display: block;
float: left;
height: 110rpx;
width: 80rpx;
margin-top: 30rpx;
margin-bottom: 30rpx;
margin-left: 40rpx;
}
.menu-list-pro .icon {
height: 80rpx;
width: 80rpx;
border-radius: 12rpx;
box-shadow: 0px 4rpx 4rpx 0px #cfc9ca;
}
.menu-list-pro .txt {
display: block;
float: left;
width: 80rpx;
margin-top: 5rpx;
font-size: 22rpx;
color: #FF1B40;
}
// pages/groupon/grouponList/grouponList.js
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
grouponList: [],
page: 1,
size: 10,
count: 0,
scrollTop: 0,
showPage: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getGrouponList();
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.getGrouponList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
},
getGrouponList: function() {
let that = this;
that.setData({
scrollTop: 0,
showPage: false,
grouponList: []
});
// 页面渲染完成
wx.showToast({
title: '加载中...',
icon: 'loading',
duration: 2000
});
util.request(api.GroupOnList, {
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
that.setData({
scrollTop: 0,
grouponList: res.data.data,
showPage: true,
count: res.data.count
});
}
wx.hideToast();
});
},
nextPage: function(event) {
var that = this;
if (this.data.page > that.data.count / that.data.size) {
wx.showToast({
title: '-_-没有下一页了-_-',
icon: 'none'
})
return true;
}
that.setData({
page: that.data.page + 1
});
this.getGrouponList();
},
prevPage: function(event) {
if (this.data.page <= 1) {
wx.showToast({
title: '-_-没有上一页了-_-',
icon: 'none'
})
return false;
}
var that = this;
that.setData({
page: that.data.page - 1
});
this.getGrouponList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "团购专区",
"usingComponents": {
"zan-capsule": "/lib/zanui-weapp/capsule/index"
}
}
\ No newline at end of file
<view class="container">
<scroll-view class="groupon-list" scroll-y="true" scroll-top="{{scrollTop}}">
<view class="item" wx:for="{{grouponList}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<navigator url="/pages/goods/goods?id={{item.goods.id}}" hover-class='none'>
<!-- <image class="img" src="{{item.goods.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<view class="header">
<text class="name">{{item.goods.name}}</text>
<view class="capsule-tag">
<zan-capsule color="#a78845" leftText="团购" rightText="{{item.groupon_member}}" />
</view>
</view>
<text class="desc">{{item.goods.brief}}</text>
<view class="price">
<view class="counterPrice">原价:¥{{item.goods.counterPrice}}</view>
<view class="retailPrice">现价:¥{{item.groupon_price}}</view>
</view>
</view>
</view> -->
<image class="img" src="{{item.goods.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<view class="header">
<text class="name">{{item.goods.name}}</text>
</view>
<text class="desc">{{item.goods.brief}}</text>
<view class="price">
<view class="retailPrice">
<text class='retailPrice-text'>限时价</text>
<text class='retailPrice-price'>¥{{item.groupon_price}}</text>
<text class="counterPrice">¥{{item.goods.counterPrice}}</text>
</view>
</view>
</view>
<view class='bottom'>
<view class='progress-box'>
<progress class='progress' percent="{{100-item.groupon_member}}" color="red" stroke-width="19" activeColor="#FBE2E6" backgroundColor="#ffffff" />
<text class='progress-text'>仅剩{{item.groupon_member}}件</text>
</view>
<view class="grab">马上抢</view>
</view>
</view>
</navigator>
</view>
<view class="page" wx:if="{{showPage}}">
<view class="prev {{ page <= 1 ? 'disabled' : ''}}" bindtap="prevPage">上一页</view>
<view class="next {{ (count / size) < page ? 'disabled' : ''}}" bindtap="nextPage">下一页</view>
</view>
</scroll-view>
</view>
\ No newline at end of file
page, .container {
width: 750rpx;
height: 100%;
overflow: hidden;
background: #fff;
}
.groupon-list {
width: 750rpx;
height: 100%;
overflow: hidden;
background: #fff;
}
.groupon-list .item {
border-top: 1rpx solid rgba(239,239,239,1);
height: 308rpx;
width: 750rpx;
}
.groupon-list .img {
float: left;
width: 240rpx;
height: 240rpx;
margin-left: 38rpx;
margin-top: 33rpx;
}
.groupon-list .right {
float: left;
height: 244rpx;
width: 450rpx;
padding-left: 20rpx;
}
.groupon-list .text {
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 204rpx;
width: 476rpx;
}
.groupon-list .name {
width: 430rpx;
float: left;
display: block;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
overflow: hidden;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.groupon-list .capsule-tag {
float: right;
padding-right: 0rpx;
padding-top: 8rpx;
}
.groupon-list .zan-capsule + .zan-capsule {
margin-left: 10px;
}
.groupon-list .desc {
width: 430rpx;
display: block;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 10rpx;
}
.groupon-list .price {
height: 60rpx;
width: 476rpx;
color: #ab956d;
line-height: 40rpx;
font-size: 33rpx;
display: flex;
position: relative;
}
.groupon-list .counterPrice {
text-decoration: line-through;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
display: block;
height:35rpx;
margin-left: 20rpx;
margin-bottom: 5rpx;
}
.groupon-list .retailPrice {
display: flex;
align-items:flex-end;
margin-top: 10rpx;
height: 50rpx;
}
.bottom {
position: relative;
overflow: hidden;
display: flex;
justify-content: space-between;
align-items: center;
}
.progress-box {
width: 197rpx;
position: relative;
}
.progress {
width: 197rpx;
border-radius:20rpx;
border:2rpx solid rgba(233,69,68,1);
overflow:hidden;
}
.progress-text {
width: 197rpx;
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
position: absolute;
top: 50%;
left: 0;
z-index: 1000;
text-align: center;
transform: translateY(-50%);
}
.grab {
width:160rpx;
line-height:50rpx;
background:#FF1B40;
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:rgba(255,255,255,1);
margin-right: 15rpx;
}
.retailPrice-text {
height:35rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
display:block;
margin-bottom: 5rpx;
}
.retailPrice-price {
/* height: 28rpx; */
display:block;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
height:40rpx;
}
.page {
width: 750rpx;
background: #fff;
margin-bottom: 20rpx;
display: flex;
justify-content: center;
}
.prev, .next {
width: 200rpx;
line-height: 60rpx;
font-size: 24rpx;
font-weight: 400;
color: #FF1B40;
border-radius: 50rpx;
border: 1rpx solid #FF1B40;
text-align: center;
}
.prev {
margin-right: 20rpx;
}
.page .disabled {
border:1rpx solid rgba(110,110,110,1);
color: rgba(110,110,110,1);
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
Page({
data: {
orderList: [],
showType: 0
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getOrderList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getOrderList() {
let that = this;
util.request(api.GroupOnMy, {
showType: that.data.showType
}).then(function(res) {
if (res.errno === 0) {
that.setData({
orderList: res.data.data
});
}
});
},
switchTab: function(event) {
let showType = event.currentTarget.dataset.index;
this.setData({
showType: showType
});
this.getOrderList();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
this.getOrderList();
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "我的团购",
"usingComponents": {
"zan-capsule": "../../../lib/zanui-weapp/capsule/index"
}
}
\ No newline at end of file
<view class="container">
<view class="orders-switch">
<view class="item {{ showType == 0 ? 'active' : ''}}" bindtap="switchTab" data-index='0'>
<view class="txt">发起的团购</view>
</view>
<view class="item {{ showType == 1 ? 'active' : ''}}" bindtap="switchTab" data-index='1'>
<view class="txt">参加的团购</view>
</view>
</view>
<view class="no-order" wx:if="{{orderList.length <= 0}}">
<view class="c">
<image src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>尚未参加任何团购</text>
</view>
</view>
<view class="orders">
<navigator url="../grouponDetail/grouponDetail?id={{item.id}}" class="order" open-type="navigate" wx:for="{{orderList}}" wx:key="id">
<view class="h">
<view class="l">订单编号:{{item.orderSn}}</view>
<view class="r">{{item.orderStatusText}}</view>
</view>
<view class="j">
<view class="l">团购立减:¥{{item.rules.discount}}</view>
<view class="r">参与时间:{{item.groupon.addTime}}</view>
</view>
<view class="i">
<view class="l">团购要求:{{item.rules.discountMember}}人</view>
<view class="r">当前参与:{{item.joinerCount}}</view>
</view>
<view class="goods" wx:for="{{item.goodsList}}" wx:key="id" wx:for-item="gitem">
<view class="img">
<image src="{{gitem.picUrl}}"></image>
</view>
<view class="info">
<text class="name">{{gitem.goodsName}}</text>
<text class="number">共{{gitem.number}}件商品</text>
</view>
<view class="status"></view>
</view>
<view class="b">
<view class="l">实付:¥{{item.actualPrice}}</view>
<view class="capsule-tag">
<zan-capsule color="#a78845" leftText="状态" rightText="{{item.joinerCount>=item.rules.discountMember?'已达成':'团购中'}}" />
</view>
<view class="capsule-tag">
<zan-capsule color="#a78845" leftText="发起" rightText="{{item.creator}}" wx:if="{{!item.isCreator}}" />
</view>
</view>
</navigator>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #f4f4f4;
}
.capsule-tag {
float: right;
/* padding-right: 10rpx; */
}
.zan-capsule + .zan-capsule {
margin-left: 5px;
}
.orders-switch {
width: 100%;
background: #fff;
height: 84rpx;
border-bottom: 1px solid #DCDADA;
}
.orders-switch .item {
display: inline-block;
height: 82rpx;
width: 50%;
padding: 0 15rpx;
text-align: center;
}
.orders-switch .item .txt {
display: inline-block;
height: 82rpx;
padding: 0 20rpx;
line-height: 82rpx;
width: 100%;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(17,17,17,1);
}
.orders-switch .item.active .txt {
border-bottom: 4rpx solid #E31436;
}
.no-order {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-order .c {
width: 100%;
height: auto;
margin-top: 200rpx;
}
.no-order .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
}
.no-order .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 29rpx;
line-height: 29rpx;
text-align: center;
font-size: 29rpx;
color: #999;
}
.orders {
height: auto;
width: 100%;
overflow: hidden;
}
.order {
margin-top: 20rpx;
background: #fff;
}
.order .h {
height: 83.3rpx;
line-height: 83.3rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order .h .l {
float: left;
color: #E31436;
font-size: 26rpx;
}
.order .h .r {
float: right;
color: #E31436;
font-size: 26rpx;
}
.order .i {
height: 56rpx;
line-height: 56rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order .i .l {
float: left;
color: #E31436;
font-size: 26rpx;
}
.order .i .r {
float: right;
color: #E31436;
font-size: 26rpx;
}
.order .j {
height: 56rpx;
line-height: 56rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
}
.order .j .l {
float: left;
font-size: 26rpx;
color: #E31436;
}
.order .j .r {
float: right;
color: #E31436;
font-size: 26rpx;
}
.order .goods {
display: flex;
align-items: center;
height: 199rpx;
margin-left: 31.25rpx;
}
.order .goods .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.order .goods .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.order .goods .info {
height: 145.83rpx;
flex: 1;
padding-left: 20rpx;
}
.order .goods .name {
margin-top: 30rpx;
display: block;
height: 44rpx;
line-height: 44rpx;
color: #333;
font-size: 30rpx;
}
.order .goods .number {
display: block;
height: 37rpx;
line-height: 37rpx;
color: #666;
font-size: 25rpx;
}
.order .goods .status {
width: 105rpx;
color: #E31436;
font-size: 25rpx;
}
.order .b {
height: 103rpx;
line-height: 103rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-top: 1px solid #f4f4f4;
font-size: 30rpx;
color: #333;
}
.order .b .l {
float: left;
}
.order .b .r {
float: right;
}
.order .b .btn {
margin-top: 19rpx;
height: 64.5rpx;
line-height: 64.5rpx;
text-align: center;
padding: 0 20rpx;
border-radius: 5rpx;
font-size: 28rpx;
color: #fff;
background: #E31436;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
bannerInfo: {
'imgUrl': '',
'name': ''
},
categoryFilter: false,
filterCategory: [],
goodsList: [],
categoryId: 0,
currentSortType: 'default',
currentSort: 'update_time',
currentSortOrder: 'desc',
page: 1,
size: 100
},
getBanner: function() {
let that = this;
util.request(api.GoodsHot).then(function(res) {
if (res.errno === 0) {
that.setData({
bannerInfo: res.data.bannerInfo,
});
}
});
},
getCategoryList: function() {
var that = this;
util.request(api.GoodsFilter, {
isHot: 1
})
.then(function(res) {
if (res.errno === 0) {
that.setData({
filterCategory: res.data.filterCategoryList,
});
}
});
},
getGoodsList: function() {
var that = this;
util.request(api.GoodsList, {
isHot: true,
page: that.data.page,
size: that.data.size,
order: that.data.currentSortOrder,
sort: that.data.currentSort,
categoryId: that.data.categoryId
})
.then(function(res) {
if (res.errno === 0) {
that.setData({
goodsList: res.data.goodsList,
filterCategory: res.data.filterCategoryList
});
}
});
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.getBanner();
this.getGoodsList();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
onPullDownRefresh() {
this.getBanner();
this.getGoodsList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
openSortFilter: function(event) {
let currentId = event.currentTarget.id;
switch (currentId) {
case 'categoryFilter':
this.setData({
categoryFilter: !this.data.categoryFilter,
currentSortType: 'category',
currentSort: 'add_time',
currentSortOrder: 'desc'
});
break;
case 'priceSort':
let tmpSortOrder = 'asc';
if (this.data.currentSortOrder == 'asc') {
tmpSortOrder = 'desc';
}
this.setData({
currentSortType: 'price',
currentSort: 'retail_price',
currentSortOrder: tmpSortOrder,
categoryFilter: false
});
this.getGoodsList();
break;
default:
//综合排序
this.setData({
currentSortType: 'default',
currentSort: 'add_time',
currentSortOrder: 'desc',
categoryFilter: false,
categoryId: 0,
});
this.getGoodsList();
}
},
selectCategory: function(event) {
let currentIndex = event.target.dataset.categoryIndex;
this.setData({
'categoryFilter': false,
'categoryId': this.data.filterCategory[currentIndex].id
});
this.getGoodsList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "人气推荐"
}
\ No newline at end of file
<view class="container">
<view class="brand-info">
<view class="name">
<image class="img" src="{{bannerInfo.imgUrl}}" background-size="cover"></image>
<view class="info-box">
<view class="info">
<text class="txt">{{bannerInfo.name}}</text>
<text class="line"></text>
</view>
</view>
</view>
</view>
<view class="sort">
<view class="sort-box">
<view class="item {{currentSortType == 'default' ? 'active' : ''}}" bindtap="openSortFilter" id="defaultSort">
<text class="txt">综合</text>
</view>
<view class="item by-price {{currentSortType == 'price' ? 'active' : ''}} {{currentSortOrder == 'asc' ? 'asc' : 'desc'}}" bindtap="openSortFilter" id="priceSort">
<text class="txt">价格</text>
</view>
<view class="item {{currentSortType == 'category' ? 'active' : ''}}" bindtap="openSortFilter" id="categoryFilter">
<text class="txt">分类</text>
</view>
</view>
<view class="sort-box-category" wx-if="{{categoryFilter}}">
<view class="item {{item.checked ? 'active' : ''}}" wx:for="{{filterCategory}}" wx:key="id" data-category-index="{{index}}" bindtap="selectCategory">{{item.name}}</view>
</view>
</view>
<view class="cate-item">
<view class="b">
<block wx:for="{{goodsList}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="id">
<navigator class="item {{iindex % 2 == 0 ? 'item-b' : '' }}" url="../goods/goods?id={{iitem.id}}" :hover-class='none'>
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</block>
</view>
</view>
</view>
\ No newline at end of file
page {
background: #fff;
}
.container {
background: #fff;
}
.brand-info .name {
width: 100%;
height: 250rpx;
position: relative;
}
.brand-info .img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 250rpx;
}
.brand-info .info-box {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 278rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.brand-info .info {
display: block;
}
.brand-info .txt {
display: block;
height: 40rpx;
font-size: 37.5rpx;
color: #fff;
}
.brand-info .line {
margin: 0 auto;
margin-top: 16rpx;
display: block;
height: 2rpx;
width: 145rpx;
background: #fff;
}
.sort {
position: relative;
background: #fff;
width: 100%;
height: 78rpx;
}
.sort-box {
background: #fff;
width: 100%;
height: 78rpx;
overflow: hidden;
padding: 0 30rpx;
display: flex;
border-bottom: 1px solid #d9d9d9;
}
.sort-box .item {
height: 78rpx;
line-height: 78rpx;
text-align: center;
flex: 1;
color: #333;
font-size: 30rpx;
}
.sort-box .item .txt {
display: block;
width: 100%;
height: 100%;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(0,0,0,1);
}
.sort-box .item.active .txt {
color:#FF1B40;
}
.sort-box .item.by-price {
background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/no-3127092a69.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.asc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/up-636b92c0a5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.desc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/down-95e035f3e5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box-category {
padding: 0 20rpx 20rpx 5rpx;
background: #fff;
width: 100%;
height: auto;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
display: flex;
justify-content: flex-start;
flex-direction: row;
flex-wrap: wrap;
}
.sort-box-category .item {
text-align: center;
padding: 0 16rpx;
border:1px solid #6E6E6E;
border-radius:4px;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#6E6E6E;
line-height:50rpx;
margin-left: 16rpx;
margin-top: 20rpx;
}
.sort-box-category .item.active {
border:1px solid rgba(255,34,70,1);
color:rgba(255,34,70,1);
}
.cate-item .b {
width: 750rpx;
height: auto;
overflow: hidden;
/* border-top: 1rpx solid #f4f4f4;
margin-top: 20rpx; */
}
.cate-item .b .item {
float: left;
background: #fff;
width: 346rpx;
padding-bottom: 33.333rpx;
/* border-bottom: 1rpx solid #f4f4f4; */
height: auto;
overflow: hidden;
margin-left: 18rpx;
margin-right: 9rpx;
}
.cate-item .b .item-b {
/* border-right: 1rpx solid #f4f4f4; */
}
.cate-item .item .img {
margin-top: 10rpx;
width: 346rpx;
height: 346rpx;
}
.cate-item .item .name {
display: block;
width: 365.625rpx;
height: 35rpx;
overflow: hidden;
margin: 10rpx 0;
text-align: center;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.cate-item .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
const util = require('../../utils/util.js');
const api = require('../../config/api.js');
const user = require('../../utils/user.js');
//获取应用实例
const app = getApp();
Page({
data: {
newGoods: [],
hotGoods: [],
topics: [],
brands: [],
groupons: [],
floorGoods: [],
banner: [],
channel: [],
coupon: [],
ad: []
},
onShareAppMessage: function() {
return {
title: '戈友商城',
desc: '戈友商城',
path: '/pages/index2/index2'
}
},
onPullDownRefresh() {
this.getIndexData();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getIndexData: function() {
let that = this;
util.request(api.IndexUrl).then(function(res) {
if (res.errno === 0) {
that.setData({
newGoods: res.data.newGoodsList,//新品
hotGoods: res.data.hotGoodsList,//人气
topics: res.data.topicList,
brands: res.data.brandList,
floorGoods: res.data.floorGoodsList,
// banner: res.data.banner, //轮播图
groupons: res.data.grouponList,
channel: res.data.channel, //户外分类
coupon: res.data.couponList
});
that.getAdBanner(res.data.banner)
}
});
},
getAdBanner(data) {
let _ad = [],
_banner = [];
for (let i = 0; i < data.length; i++) {
if (data[i].position === 2) {
_ad.push(data[i]);
} else {
_banner.push(data[i])
}
}
this.setData({
banner: _banner,
ad: _ad
})
},
goActivity:function(e){
var name=e.target.dataset.name,
link = e.target.dataset.link;
if (link.indexOf('pages')>-1){
wx.navigateTo({
url: link
});
} else {
wx.navigateTo({
url: `../activity/activity?name=${name}&link=${link}`
});
}
},
onLoad: function(options) {
console.log("options",options);
// 页面初始化 options为页面跳转所带来的参数
if (options.scene) {
//这个scene的值存在则证明首页的开启来源于朋友圈分享的图,同时可以通过获取到的goodId的值跳转导航到对应的详情页
var scene = decodeURIComponent(options.scene);
console.log("scene:" + scene);
let info_arr = [];
info_arr = scene.split(',');
let _type = info_arr[0];
let id = info_arr[1];
if (_type == 'goods') {
wx.navigateTo({
url: '../goods/goods?id=' + id
});
} else if (_type == 'groupon') {
wx.navigateTo({
url: '../goods/goods?grouponId=' + id
});
} else {
wx.navigateTo({
url: '../index2/index2'
});
}
}
// 页面初始化 options为页面跳转所带来的参数
if (options.grouponId) {
//这个pageId的值存在则证明首页的开启来源于用户点击来首页,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?grouponId=' + options.grouponId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.goodId) {
//这个goodId的值存在则证明首页的开启来源于分享,同时可以通过获取到的goodId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?id=' + options.goodId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.orderId) {
//这个orderId的值存在则证明首页的开启来源于订单模版通知,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../ucenter/orderDetail/orderDetail?id=' + options.orderId
});
}
this.getIndexData();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
getCoupon(e) {
if (!app.globalData.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
let couponId = e.currentTarget.dataset.id,
index = e.currentTarget.dataset.index,
that = this;
util.request(api.CouponReceive, {
couponId: couponId
}, 'POST').then(res => {
if (res.errno === 0) {
wx.showToast({
title: "领取成功"
})
let _coupon = that.data.coupon;
_coupon.splice(index, 1);
that.setData({
coupon: _coupon
})
}
else{
util.showErrorToast(res.errmsg);
}
})
},
openImgCloseFun() {
this.setData({
ad: []
})
},
openImgFun() {
wx.navigateTo({
url: this.data.ad[0].link,
})
// this.setData({
// 'openData.openImgShow': false
// })
}
})
\ No newline at end of file
{
"navigationBarTitleText": "首页",
"usingComponents": {
"zan-capsule": "../../lib/zanui-weapp/capsule/index"
}
}
\ No newline at end of file
<!--index.wxml-->
<view class="container">
<view class="search">
<navigator url="/pages/search/search" class="input" hover-class='none'>
<image class="icon" src="/static/images/search-red.png"></image>
<text class="txt">商品搜索</text>
</navigator>
</view>
<swiper class="banner" indicator-dots="true" indicator-active-color="#E31436" autoplay="true" interval="3000" duration="1000">
<swiper-item wx:for="{{banner}}" wx:key="id">
<!-- <navigator hover-class="none" url="{{item.link}}"> -->
<image src="{{item.url}}" background-size="cover" data-name="{{item.name}}" data-link="{{item.link}}" bindtap="goActivity"></image>
<!-- </navigator> -->
</swiper-item>
</swiper>
<view class="m-menu">
<navigator hover-class="none" class="item" url="/pages/category/category?id={{item.id}}" wx:for="{{channel}}" wx:key="id">
<image src="{{item.iconUrl}}" background-size="cover"></image>
<text>{{item.name}}</text>
</navigator>
</view>
<view class="a-section a-popular" wx:if="{{hotGoods.length > 0}}">
<view class="h">
<view class="popular-box">
<navigator hover-class="none" url="../hotGoods/hotGoods" class='popular-navigator'>
<text class="txt">人气推荐</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
</view>
<view class="b">
<view wx:for="{{hotGoods}}" wx:for-index="index" wx:for-item="item" wx:key="id" class="item {{index>0?'a-popular-small':''}}" wx:if="{{index<4}}">
<navigator hover-class="none" url="/pages/goods/goods?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<text class="name">{{item.name}}</text>
<text class="desc" wx:if="{{index<1}}">{{item.brief}}</text>
<text class="price">¥{{item.retailPrice}}</text>
</view>
</view>
</navigator>
</view>
</view>
</view>
<view class="a-section a-new" wx:if="{{newGoods.length > 0}}">
<view class="h">
<view class="popular-box">
<navigator hover-class="none" url="../newGoods/newGoods" class='popular-navigator'>
<text class="txt">新品首发</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
</view>
<view class="b">
<view class="item" wx:for="{{newGoods}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<navigator hover-class="none" url="../goods/goods?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<text class="name">{{item.name}}</text>
<text class="price">¥{{item.retailPrice}}</text>
</navigator>
</view>
</view>
</view>
<view class="a-section a-coupon" wx:if="{{coupon.length > 0}}">
<view class="h">
<view class="title">
<view>
<navigator hover-class="none" url="/pages/coupon/coupon" class='popular-navigator'>
<text class="txt">优惠券</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
</view>
</view>
<view wx:if="{{coupon.length>0}}" class="b">
<view class="item" wx:for="{{coupon}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<image class='coupon-bg' src="/static/images/coupon-bg.png"></image>
<!-- <view class="tag">{{item.tag}}</view> -->
<view class="content">
<view class="left">
<view class="discount">
<text class="discount-text">¥</text>
<text class="discount-num">{{item.discount}}</text>
</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class='coupon-main-right'>
<view class="name">{{item.name}}</view>
<view class="time" wx:if="{{item.startTime}}">{{item.startTime}} - </view>
<view class="time" wx:if="{{item.startTime}}">{{item.endTime}}</view>
<view class='use' bindtap='gotoHome' bindtap="getCoupon" data-id="{{item.id}}" data-index="{{index}}">
领取
</view>
</view>
</view>
</view>
</view>
</view>
<view class="a-section a-groupon" wx:if="{{groupons.length > 0}}">
<view class="h">
<view class="title">
<view>
<navigator hover-class="none" url="/pages/groupon/grouponList/grouponList" class='popular-navigator'>
<text class="txt">团购专区</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
</view>
</view>
<view class="b">
<view class="item" wx:for="{{groupons}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<navigator hover-class="none" url="/pages/goods/goods?id={{item.goods.id}}">
<image class="img" src="{{item.goods.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<view class="header">
<text class="name">{{item.goods.name}}</text>
</view>
<text class="desc">{{item.goods.brief}}</text>
<view class="price">
<view class="retailPrice">
<text class='retailPrice-text'>限时价</text>
<text class='retailPrice-price'>¥{{item.groupon_price}}</text>
<text class="counterPrice">¥{{item.goods.counterPrice}}</text>
</view>
</view>
</view>
<view class='bottom'>
<view class='progress-box'>
<progress class='progress' percent="{{100-item.groupon_member}}" color="red" stroke-width="19" activeColor="#FBE2E6" backgroundColor="#ffffff" />
<text class='progress-text'>仅剩{{item.groupon_member}}件</text>
</view>
<view class="grab">马上抢</view>
</view>
</view>
</navigator>
</view>
</view>
</view>
<view class="a-section a-brand" wx:if="{{brands.length > 0}}">
<view class="h">
<navigator hover-class="none" url="../brand/brand" class='popular-navigator'>
<text class="txt">品牌制造商直供</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
<view class="b">
<view class="item item-1" wx:for="{{brands}}" wx:key="id">
<navigator hover-class="none" url="/pages/brandDetail/brandDetail?id={{item.id}}">
<view class="wrap">
<image class="img" src="{{item.picUrl}}" ></image>
<view class="mt">
<text class="brand" wx:if="{{item.name}}">{{item.name}}</text>
<text class="price" wx:if="{{item.floorPrice}}">{{item.floorPrice}}元起</text>
</view>
</view>
</navigator>
</view>
</view>
</view>
<view class="a-section a-topic" wx:if="{{topics.length > 0}}">
<view class="h">
<view>
<navigator hover-class="none" url="/pages/topic/topic" class='popular-navigator'>
<text class="txt">专题精选</text>
<view class='more'>
<text class='more-text'>更多</text>
<image class='more-icon' src="/static/images/ucenter-more.png"></image>
</view>
</navigator>
</view>
</view>
<view class="b">
<scroll-view scroll-x class="list">
<view class="item" wx:for="{{topics}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<navigator hover-class="none" url="../topicDetail/topicDetail?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<view class="np">
<text class="name">{{item.title}}</text>
<text class="price" wx:if="{{item.price}}">{{item.price}}元起</text>
</view>
<text class="desc">{{item.subtitle}}</text>
</navigator>
</view>
</scroll-view>
</view>
</view>
<view class='load-bottom'>
<view class="line"></view>
<text class="text">我是有底线的</text>
<view class="line"></view>
</view>
<view class="open-img" wx:if="{{ad.length}}" catchtouchmove='true'>
<image class='open-img-main' src='{{ad[0].url}}' bindtap='openImgFun'></image>
<image class='open-img-close' src='/static/images/open-close.png' bindtap='openImgCloseFun'></image>
</view>
<!-- <view class="good-grid" wx:for="{{floorGoods}}" wx:key="id">
<view class="h">
<text>{{item.name}}</text>
</view>
<view class="b">
<block wx:for="{{item.goodsList}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="id">
<view class="item {{iindex % 2 == 0 ? '' : 'item-b'}}">
<navigator hover-class="none" url="../goods/goods?id={{iitem.id}}" class="a">
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</view>
</block>
</view> -->
<!-- <navigator hover-class="none" url="/pages/category/category?id={{item.id}}" class="t">
<view class="txt">{{'更多'+item.name+'好物 >'}}</view>
</navigator>
</view> -->
</view>
\ No newline at end of file
page {
background: #F4F4F4;
}
.search {
height: 88rpx;
width: 100%;
padding: 0 30rpx;
background: #fff;
display: flex;
align-items: center;
}
.search .input {
width:706rpx;
height: 64rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
border: 2rpx solid #FF1B40;
background: #fff;
}
.search .icon {
margin-left: 16rpx;
width: 28rpx;
height: 28rpx;
}
.search .txt {
height: 42rpx;
line-height: 42rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(131,131,131,1);
margin-left: 15rpx;
}
.banner {
width: 750rpx;
height: 368rpx;
}
.banner image {
width: 100%;
height: 368rpx;
}
.m-menu {
background: #fff;
display: flex;
align-items: center;
flex-wrap: wrap;
padding-bottom: 0rpx;
padding-top: 25rpx;
}
.m-menu .item {
width: 150rpx;
height: 172rpx;
}
.m-menu image {
display: block;
width: 100rpx;
height: 100rpx;
margin: 0 auto;
margin-bottom: 12rpx;
}
.m-menu text {
display: block;
font-size: 24rpx;
text-align: center;
margin: 0 auto;
line-height: 1;
color: #333;
}
.a-section {
width: 750rpx;
height: auto;
overflow: hidden;
background: #fff;
color: #333;
margin-top: 20rpx;
}
.a-section .h {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
height: 96rpx;
}
.a-section .h .txt {
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
float: left;
}
.popular-box {
width: 100%;
}
.more-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
}
.popular-navigator {
width: 698rpx;
margin: 0 auto;
overflow: hidden;
}
.more-icon {
width: 12rpx;
height: 22rpx;
margin-left: 12rpx;
}
.more {
display: flex;
align-items: center;
float: right;
margin-top: 2rpx;
}
.a-brand .b {
width: 698rpx;
height: auto;
overflow: hidden;
position: relative;
margin: 0 auto;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.a-brand .wrap {
position: relative;
}
.a-brand .b .wrap .img {
position:absolute;
left:0;
top:40rpx;
width:342rpx;
height:140rpx;
}
.a-brand .mt {
padding: 10rpx 0;
background: rgba(240,246,251,0.6);
position: absolute;
z-index: 2;
left: 0;
top: 0;
}
.a-brand .mt .brand {
width: 342rpx;
text-align: center;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(25,24,24,1);
display: block;
}
.a-brand .mt .price, .a-brand .mt .unit {
width: 342rpx;
display: block;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.a-brand .item-1 {
float: left;
width: 342rpx;
height: 260rpx;
overflow: hidden;
border-top: 1rpx solid #fff;
margin-left: 1rpx;
margin-top: 12rpx;
}
.a-brand .item-1:nth-of-type(1), .a-brand .item-1:nth-of-type(2) {
margin-top: 0;
}
.a-brand .item-1 .img {
width: 342rpx;
height: 260rpx;
}
.a-coupon {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-coupon .b .item {
position: relative;
height: 200rpx;
width: 698rpx;
margin-bottom: 10rpx;
margin-left: 30rpx;
margin-right: 30rpx;
padding-top: 30rpx;
}
.a-coupon .b .coupon-bg {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 4.5rpx;
z-index: 200;
}
.a-coupon .b .tag {
height: 32rpx;
background: #a48143;
padding-left: 16rpx;
padding-right: 16rpx;
position: absolute;
left: 20rpx;
color: #fff;
top: 20rpx;
font-size: 20rpx;
text-align: center;
line-height: 32rpx;
}
.a-coupon .b .content {
width: 689rpx;
height: 193rpx;
display: flex;
flex-direction: row;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
}
.a-coupon .b .content .left {
width: 204rpx;
float: left;
}
.discount {
width: 204rpx;
display: flex;
align-items:flex-end;
justify-content: center;
margin-top: 30rpx;
}
.discount-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
color:rgba(255,34,70,1);
display: block;
margin-bottom: 15rpx;
margin-right: 5rpx;
}
.discount-num {
font-size:60rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(255,34,70,1);
}
.a-coupon .min {
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
text-align: center;
}
.coupon-main-right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.coupon-main-right .name {
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 37rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.coupon-main-right .time {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
margin-left: 37rpx;
color:rgba(110,110,110,1);
}
.coupon-main-right .use {
width: 126rpx;
border-radius:50rpx;
background: #FF1B40;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color: #fff;
text-align: center;
line-height: 50rpx;
position: absolute;
right: 40rpx;
top: 70rpx;
}
.a-groupon {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-groupon .b .item {
border-top: 1rpx solid rgba(239,239,239,1);
height: 308rpx;
width: 750rpx;
}
.a-groupon .b .img {
float: left;
width: 240rpx;
height: 240rpx;
margin-left: 38rpx;
margin-top: 33rpx;
}
.a-groupon .b .right {
float: left;
height: 244rpx;
width: 450rpx;
padding-left: 20rpx;
}
.a-groupon .b .text {
flex: 1;
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 204rpx;
width: 476rpx;
}
.a-groupon .b .name {
width: 430rpx;
float: left;
display: block;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
overflow: hidden;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-groupon .capsule-tag {
float: right;
padding-right: 0rpx;
padding-top: 8rpx;
}
.a-groupon .zan-capsule + .zan-capsule {
margin-left: 10px;
}
.a-groupon .b .desc {
width: 430rpx;
display: block;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 10rpx;
}
.a-groupon .b .price {
height: 60rpx;
width: 476rpx;
color: #ab956d;
line-height: 40rpx;
font-size: 33rpx;
display: flex;
position: relative;
}
.a-groupon .b .retailPrice {
display: flex;
align-items:flex-end;
margin-top: 10rpx;
height: 50rpx;
}
.a-groupon .b .counterPrice {
text-decoration: line-through;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
display: block;
height:35rpx;
margin-left: 20rpx;
margin-bottom: 5rpx;
}
.a-groupon .bottom {
position: relative;
overflow: hidden;
display: flex;
justify-content: space-between;
align-items: center;
}
.a-groupon .progress-box {
width: 197rpx;
position: relative;
}
.a-groupon .progress {
width: 197rpx;
border-radius:20rpx;
border:2rpx solid rgba(233,69,68,1);
overflow:hidden;
}
.a-groupon .progress-text {
width: 197rpx;
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
position: absolute;
top: 50%;
left: 0;
z-index: 1000;
text-align: center;
transform: translateY(-50%);
}
.a-groupon .grab {
width:160rpx;
line-height:50rpx;
background:#FF1B40;
border-radius:30rpx;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:rgba(255,255,255,1);
margin-right: 15rpx;
}
.retailPrice-text {
height:35rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
display:block;
margin-bottom: 5rpx;
}
.retailPrice-price {
/* height: 28rpx; */
display:block;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
height:40rpx;
}
.a-new .b {
width: 698rpx;
height: auto;
overflow: hidden;
padding-bottom: 31rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.a-new .b .item {
width: 216rpx;
margin-top: 10rpx;
}
.a-new .b .item-b {
margin-left: 42rpx;
}
.a-new .b .img {
width: 216rpx;
height: 216rpx;
}
.a-new .b .name {
text-align: center;
display: block;
width: 216rpx;
height: 35rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
overflow: hidden;
color: #333;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-new .b .price {
display: block;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.a-popular {
width: 750rpx;
height: auto;
overflow: hidden;
}
.a-popular .b {
width: 698rpx;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
padding-bottom: 36rpx;
}
.a-popular .b .item {
height: 280rpx;
width: 698rpx;
background:rgba(254,239,223,0.8);
margin: 0 auto 19rpx;
border-radius:2rpx;
}
.a-popular .b .a-popular-small {
height: 280rpx;
width: 220rpx;
border-radius:2rpx;
background: #fff;
}
.a-popular .b .img {
float: left;
width: 280rpx;
height: 280rpx;
}
.a-popular .b .a-popular-small .img {
width: 220rpx;
height: 220rpx;
}
.a-popular .b .right {
float: left;
height: 264rpx;
width:397rpx;
padding-left: 20rpx;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.a-popular .b .a-popular-small .right {
display: block;
width:230rpx;
height: 100rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding: 0;
}
.a-popular .b .text {
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 264rpx;
width: 456rpx;
}
.a-popular .b .a-popular-small .text {
display: block;
width: 220rpx;
height: 100rpx;
}
.a-popular .b .name {
width:377rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.a-popular .b .a-popular-small .name {
width:220rpx;
display: block;
font-size:24rpx;
text-align: center;
}
.a-popular .b .desc {
width:377rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-top: 10rpx;
}
.a-popular .b .price {
width:377rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
margin-top: 10rpx;
}
.a-popular .b .a-popular-small .price {
width: 100%;
text-align: center;
display:block;
font-size: 24rpx;
}
.a-topic .b {
height: 430rpx;
width: 750rpx;
padding: 0 0 48rpx 0;
}
.a-topic .b .list {
height: 430rpx;
width: 750rpx;
white-space: nowrap;
}
.a-topic .b .item {
display: inline-block;
width: 476rpx;
margin-left: 30rpx;
overflow: hidden;
}
.a-topic .b .item:last-child {
margin-right: 30rpx;
}
.a-topic .b .img {
height: 278rpx;
width: 476rpx;
margin-bottom: 10rpx;
}
.a-topic .b .np {
margin-bottom: 5rpx;
color: #333;
font-size: 30rpx;
}
.a-topic .b .np .name{
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.a-topic .b .np .price {
display: block;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.a-topic .b .desc {
display: block;
height: 30rpx;
color: #999;
font-size: 24rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.good-grid {
width: 750rpx;
height: auto;
overflow: hidden;
}
.good-grid .h {
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: center;
height: 130rpx;
font-size: 33rpx;
color: #333;
}
.good-grid .b {
width: 750rpx;
padding: 0 6.25rpx;
height: auto;
overflow: hidden;
}
.good-grid .b .item {
float: left;
background: #fff;
width: 365rpx;
margin-bottom: 6.25rpx;
height: 452rpx;
overflow: hidden;
text-align: center;
}
.good-grid .b .item .a {
height: 452rpx;
width: 100%;
}
.good-grid .b .item-b {
margin-left: 6.25rpx;
}
.good-grid .item .img {
margin-top: 20rpx;
width: 302rpx;
height: 302rpx;
}
.good-grid .item .name {
display: block;
width: 365.625rpx;
padding: 0 20rpx;
overflow: hidden;
height: 35rpx;
margin: 11.5rpx 0 22rpx 0;
text-align: center;
font-size: 30rpx;
color: #333;
}
.good-grid .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
color: #ab956d;
}
.good-grid .t {
height: 100rpx;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.load-bottom {
background: #F4F4F4;
width: 100%;
height: 59rpx;
display: flex;
justify-content: center;
align-items: center;
}
.load-bottom .line {
width:51rpx;
border-bottom:1rpx solid rgba(198,196,196,1);
}
.load-bottom .text {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(198,196,196,1);
margin-left: 17rpx;
margin-right: 17rpx;
}
.open-img {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.open-img-main {
width: 620rpx;
height: 720rpx;
display: block;
}
.open-img-close {
width: 64rpx;
height: 64rpx;
margin-top: 55rpx;
}
\ No newline at end of file
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
//获取应用实例
const app = getApp();
Page({
data: {
searchStatus:false,
historyKeyword:'',
keywrod: '',
page: 1,
size: 10,
count: 0,
currentSortOrder: 'desc',
currentSortType: 'default',
currentSort: 'update_time',
categoryId: 0,
goodsList: [],
categoryList: [],
currentCategory: {},
currentSubCategoryList: {},
scrollLeft: 0,
scrollTop: 0,
goodsCount: 0,
scrollHeight: 0,
searchEscShow: false
},
getCatalog: function () {
//CatalogList
let that = this;
wx.showLoading({
title: '加载中...',
});
util.request(api.CatalogList).then(function (res) {
that.setData({
categoryList: res.data.categoryList,
currentCategory: res.data.currentCategory,
currentSubCategoryList: res.data.currentSubCategory
});
wx.hideLoading();
});
util.request(api.GoodsCount).then(function (res) {
that.setData({
goodsCount: res.data.goodsCount
});
});
},
getCurrentCategory: function (id) {
let that = this;
util.request(api.CatalogCurrent, {
id: id
})
.then(function (res) {
that.setData({
currentCategory: res.data.currentCategory,
currentSubCategoryList: res.data.currentSubCategory
});
});
},
switchCate: function (event) {
var that = this;
var currentTarget = event.currentTarget;
if (this.data.currentCategory.id == event.currentTarget.dataset.id) {
return false;
}
this.getCurrentCategory(event.currentTarget.dataset.id);
},
onShareAppMessage: function () {
return {
title: '戈友商城',
desc: '戈友商城',
path: '/pages/index2/index2'
}
},
// type 1 为加载更多 0 为刷新
getGoodsList(type) {
var that = this;
util.request(api.GoodsList, {
isHot: true,
page: that.data.page,
size: that.data.size,
order: that.data.currentSortOrder,
sort: that.data.currentSort,
categoryId: that.data.categoryId
})
.then(function (res) {
wx.stopPullDownRefresh();
if (res.errno === 0) {
console.log(res.data)
if (type == 1) {
let goodsList = that.data.goodsList;
goodsList = goodsList.concat(res.data.goodsList);
that.setData({
count: res.data.count,
goodsList
});
} else {
that.setData({
count: res.data.count,
goodsList: res.data.goodsList
});
}
}
});
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
console.log("下拉刷新")
let that = this;
that.setData({
page: 1,
})
that.getGoodsList(0);
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
console.log("上拉加载")
let that = this,
page = this.data.page,
count = this.data.count;
if (page * 10 > count) {
wx.showToast({
icon: 'none',
title: '更多精品尽在分类',
})
} else {
that.setData({
loading: true, //把"上拉加载"的变量设为false,显示
page: page + 1
})
// 上拉获取更多数据
that.getGoodsList(1);
}
},
/**
* 点击取消的时候
*/
hideSearch(){
console.log(222)
this.getSearchKeyword();
this.setData({
searchEscShow: false,
searchStatus:false
})
this.getGoodsList();
},
/**
* 输入框获取焦点的时候
*/
searchFocus() {
this.getSearchKeyword()
this.setData({
searchEscShow: true,
searchStatus:false
})
console.log("输入框获取了焦点")
},
/**
* 输入框失去焦点的时候
*/
searchChange() {
console.log("输入框失去了焦点")
},
clearKeyword: function () {
this.getSearchKeyword();
this.setData({
keyword: '',
searchStatus: false,
searchEscShow: true
});
},
/**
* 搜索
*/
onKeywordConfirm(event) {
console.log(event.detail.value)
this.getSearchResult(event.detail.value);
},
getSearchResult(keyWord){
let type=''
var that = this;
util.request(api.GoodsList, {
keyword: keyWord,
isHot: true,
page: that.data.page,
size: that.data.size,
order: that.data.currentSortOrder,
sort: that.data.currentSort,
categoryId: that.data.categoryId
})
.then(function (res) {
wx.stopPullDownRefresh();
if (res.errno === 0) {
console.log(res.data)
// let goodsList = that.data.goodsList;
// goodsList = goodsList.concat(res.data.goodsList);
if (res.data.goodsList.length===0){
console.log(22222222222222222)
that.setData({
searchStatus: true,
searchEscShow: false,
count: res.data.count,
goodsList: res.data.goodsList
})
}else{
console.log(33333333333333333333)
that.setData({
searchEscShow: false,
count: res.data.count,
goodsList: res.data.goodsList
})
}
// that.setData({
// });
}
});
},
/**
* 输入框改变
*/
inputChange: function (e) {
this.setData({
keyword: e.detail.value
});
},
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
console.log("options", options);
// 页面初始化 options为页面跳转所带来的参数
if (options.scene) {
//这个scene的值存在则证明首页的开启来源于朋友圈分享的图,同时可以通过获取到的goodId的值跳转导航到对应的详情页
var scene = decodeURIComponent(options.scene);
console.log("scene:" + scene);
let info_arr = [];
info_arr = scene.split(',');
let _type = info_arr[0];
let id = info_arr[1];
if (_type == 'goods') {
wx.navigateTo({
url: '../goods/goods?id=' + id
});
} else if (_type == 'groupon') {
wx.navigateTo({
url: '../goods/goods?grouponId=' + id
});
} else {
wx.navigateTo({
url: '../index2/index2'
});
}
}
// 页面初始化 options为页面跳转所带来的参数
if (options.grouponId) {
//这个pageId的值存在则证明首页的开启来源于用户点击来首页,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?grouponId=' + options.grouponId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.goodId) {
//这个goodId的值存在则证明首页的开启来源于分享,同时可以通过获取到的goodId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../goods/goods?id=' + options.goodId
});
}
// 页面初始化 options为页面跳转所带来的参数
if (options.orderId) {
//这个orderId的值存在则证明首页的开启来源于订单模版通知,同时可以通过获取到的pageId的值跳转导航到对应的详情页
wx.navigateTo({
url: '../ucenter/orderDetail/orderDetail?id=' + options.orderId
});
}
this.getGoodsList();
this.getCatalog();
},
onShow:function(){
this.setData({
searchEscShow:false
})
},
//查询历史记录
getSearchKeyword() {
let that = this;
util.request(api.SearchIndex).then(function (res) {
if (res.errno === 0) {
console.log(res.data.historyKeywordList)
that.setData({
historyKeyword: res.data.historyKeywordList,
// defaultKeyword: res.data.defaultKeyword,
// hotKeyword: res.data.hotKeywordList
});
}
});
},
//点击历史记录
onKeywordTap: function (event) {
this.getSearchResult(event.target.dataset.keyword);
this.setData({
keyword:event.target.dataset.keyword
})
},
clearHistory:function(){
this.setData({
historyKeyword: []
})
util.request(api.SearchClearHistory, {}, 'POST')
.then(function(res) {
console.log('清除成功');
});
}
})
\ No newline at end of file
{
"navigationBarTitleText": "首页",
"usingComponents": {
"zan-capsule": "../../lib/zanui-weapp/capsule/index"
}
}
\ No newline at end of file
<!--index.wxml-->
<view class="container">
<view class="search">
<view class="input">
<image class="icon" src="/static/images/search-red.png"></image>
<input class='search-input' value="{{keyword}}" placeholder='商品搜索' confirm-type="search" bindfocus="searchFocus" bindchange="searchChange" bindinput="inputChange" bindconfirm="onKeywordConfirm"></input>
<image class="del" wx:if="{{keyword}}" bindtap="clearKeyword" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/clearIpt-f71b83e3c2.png"></image>
</view>
<view class='search-esc' wx:if="{{searchEscShow}}" catchtap="hideSearch">
取消
</view>
</view>
<view class='lists'>
<view class='list' wx:for="{{goodsList}}" wx:for-index="index" wx:for-item="item" wx:key="{{index}}">
<navigator url="../goods/goods?id={{item.id}}" :hover-class='none'>
<view class="{{item.stockNum==0 ? 'dimback' : ''}}">
<image class='pic {{item.stockNum==0 ? "dim" : ""}}' mode="scaleToFill" src='{{item.picUrl}}'></image>
</view>
<view class='name'>{{item.name}}</view>
<view class='brief'>{{item.brief}}</view>
<view class='price'>
<view class='retail-retail'>¥{{item.retailPrice}}
<view class='retail-counter'>¥{{item.counterPrice}}</view>
</view>
<view class="retail-buied" wx:if="{{item.stockNum!=0}}">{{item.sellNum}}份已经售/限量{{item.stockNum+item.sellNum}}份</view>
<view class="retail-buied" wx:else>售罄</view>
</view>
</navigator>
</view>
</view>
<view class="catalog" wx:if="{{searchEscShow}}">
<view class="no-search">
<!-- wx:if="{{ !searchStatus}}" -->
<view class="search-keywords search-history" wx:if="{{ historyKeyword.length}}">
<!-- wx:if="{{!keyword && historyKeyword.length}}" -->
<view class="h">
<text class="title">历史记录</text>
<image class="icon" bindtap="clearHistory" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/del1-93f0a4add4.png"></image>
</view>
<view class="b">
<scroll-view scroll-x>
<view class="item" bindtap="onKeywordTap" hover-class="navigator-hover"data-keyword="{{item.keyword}}" wx:for="{{historyKeyword}}" wx:key="keyword">{{item.keyword}}</view>
</scroll-view>
<!-- data-keyword="{{item.keyword}}" wx:for="{{historyKeyword}}" wx:key="keyword" {{item.keyword}} -->
</view>
</view>
</view>
<view class="" style="display:flex">
<scroll-view class="nav" scroll-y="true">
<view class="item {{ currentCategory.id == item.id ? 'active' : ''}}" wx:for="{{categoryList}}" wx:key="id" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchCate">{{item.name}}</view>
</scroll-view>
<scroll-view class="cate" scroll-y="true">
<navigator url="url" class="banner">
<image class="image" src="{{currentCategory.picUrl}}"></image>
<view class="txt">{{currentCategory.frontName}}</view>
</navigator>
<view class="hd">
<!-- <text class="line"></text> -->
<text class="txt">{{currentCategory.name}}分类</text>
<!-- <text class="line"></text> -->
</view>
<view class="bd">
<navigator url="/pages/category/category?id={{item.id}}" class="item {{(index+1) % 3 == 0 ? 'last' : ''}}" wx:key="id" wx:for="{{currentSubCategoryList}}">
<image class="icon" src="{{item.picUrl}}"></image>
<text class="txt">{{item.name}}</text>
</navigator>
</view>
</scroll-view>
</view>
</view>
<view class="search-result-empty" wx:if="{{!goodsList.length && searchStatus}}">
<image class="icon" src="http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/noSearchResult-7572a94f32.png"></image>
<text class="text">您寻找的商品还未上架</text>
</view>
</view>
\ No newline at end of file
page {
background: #F4F4F4;
height: 100%;
}
.search {
height: 88rpx;
width: 100%;
padding: 0 30rpx;
background: #fff;
display: flex;
align-items: center;
position: fixed;
z-index:1000;
}
.search .input {
position: relative;
width:706rpx;
height: 64rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
border: 2rpx solid #FF1B40;
background: #fff;
}
.search .icon {
margin-left: 16rpx;
width: 28rpx;
height: 28rpx;
}
.search .del {
position: absolute;
top: 3rpx;
right: 10rpx;
width: 53rpx;
height: 53rpx;
z-index: 10;
}
.search-input {
height: 42rpx;
line-height: 42rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(131,131,131,1);
margin-left: 15rpx;
width: 500rpx;
}
.search-esc {
font-size: 26rpx;
width: 100rpx;
height: 100rpx;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
margin-left: 20rpx;
}
.lists {
width: 100%;
background: #fff;
padding-top: 100rpx;
}
.list {
width: 100%;
padding-bottom: 10rpx;
border-bottom: 14rpx solid #F4F4F4;
}
.pic {
width: 100%;
height: 700rpx;
}
.name {
width: 96%;
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin: 10rpx auto;
}
.brief {
width: 96%;
margin: 10rpx auto;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.price {
display: flex;
align-items: center;
margin-left: 20rpx;
margin-bottom: 5rpx;
justify-content: space-between;
}
.retail-retail {
color: #E31436;
font-size:32rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
display:flex;
align-items:center;
}
.retail-counter {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-left: 17rpx;
text-decoration: line-through;
}
.retail-buied {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
margin-right: 17rpx;
}
.catalog {
position: fixed;
top: 90rpx;
bottom: 0;
right: 0;
left: 0;
z-index: 1000;
background: #fff;
/* display: flex; */
border-top: 1px solid #fafafa;
}
.catalog .nav {
width: 162rpx;
height: 100%;
margin-top: 20rpx;
}
.catalog .nav .item {
text-align: center;
line-height: 90rpx;
width: 162rpx;
height: 90rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.catalog .nav .item.active {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#E31436;
}
.catalog .cate {
border-left: 1px solid #fafafa;
flex: 1;
height: 100%;
padding: 0 30rpx 0 30rpx;
}
.banner {
display: block;
height: 222rpx;
width: 100%;
position: relative;
}
.banner .image {
position: absolute;
top: 30rpx;
left: 0;
border-radius: 4rpx;
height: 192rpx;
width: 100%;
}
.banner .txt {
position: absolute;
top: 30rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
left: 0;
height: 192rpx;
line-height: 192rpx;
width: 100%;
}
.catalog .hd {
height: 88rpx;
width: 100%;
display: flex;
align-items: center;
}
.catalog .hd .txt {
font-size: 24rpx;
text-align: center;
color: #333;
padding: 0 10rpx;
width: auto;
font-family:PingFangSC-Medium;
font-weight:500;
}
.catalog .hd .line {
width: 40rpx;
height: 1px;
background: #d9d9d9;
}
.catalog .bd {
height: auto;
width: 100%;
overflow: hidden;
}
.catalog .bd .item {
display: block;
float: left;
height: 216rpx;
width: 144rpx;
margin-right: 34rpx;
}
.catalog .bd .item.last {
margin-right: 0;
}
.catalog .bd .item .icon {
height: 144rpx;
width: 144rpx;
border-radius: 80rpx;
}
.catalog .bd .item .txt {
display: block;
text-align: center;
font-size: 24rpx;
height: 72rpx;
width: 144rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.no-search {
height: auto;
overflow: hidden;
/* margin-top: 91rpx; */
}
.search-keywords {
background: #fff;
width: 750rpx;
height: auto;
overflow: hidden;
margin-bottom: 20rpx;
border-bottom: 1rpx solid black;
}
.search-keywords .h {
padding: 0 31.25rpx;
height: 93rpx;
line-height: 93rpx;
width: 100%;
color: #999;
font-size: 29rpx;
}
.search-keywords .title {
display: block;
width: 120rpx;
float: left;
}
.search-keywords .icon {
margin-top: 19rpx;
float: right;
display: block;
margin-left: 511rpx;
height: 55rpx;
width: 55rpx;
}
.search-keywords .b {
width: 750rpx;
height: auto;
overflow: hidden;
padding-left: 31.25rpx;
white-space: nowrap;
}
.search-keywords .item {
display: inline-block;
width: auto;
line-height: 40rpx;
padding: 0 15rpx;
border: 1px solid #999;
margin: 0 31.25rpx 31.25rpx 0;
font-size: 24rpx;
color: #333;
border-radius: 30rpx;
}
.search-keywords .item.active {
color: #FF1B40;
border: 2rpx solid #FF1B40;
}
.search-result-empty {
width: 100%;
height: 100%;
padding-top: 300rpx;
}
.search-result-empty .icon {
margin: 0 auto;
display: block;
width: 240rpx;
height: 240rpx;
}
.search-result-empty .text {
display: block;
width: 100%;
height: 40rpx;
font-size: 28rpx;
text-align: center;
color: #999;
}
.dimback{
background: #000
}
.dim{
opacity:0.6; filter: alpha(opacity=60)
}
\ No newline at end of file
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
bannerInfo: {
'imgUrl': '',
'name': ''
},
categoryFilter: false,
filterCategory: [],
goodsList: [],
categoryId: 0,
currentSortType: 'default',
currentSort: 'add_time',
currentSortOrder: 'desc',
page: 1,
size: 100
},
getBanner: function() {
let that = this;
util.request(api.GoodsNew).then(function(res) {
if (res.errno === 0) {
that.setData({
bannerInfo: res.data.bannerInfo,
});
}
});
},
getGoodsList: function() {
var that = this;
util.request(api.GoodsList, {
isNew: true,
page: that.data.page,
size: that.data.size,
order: that.data.currentSortOrder,
sort: that.data.currentSort,
categoryId: that.data.categoryId
})
.then(function(res) {
if (res.errno === 0) {
that.setData({
goodsList: res.data.goodsList,
filterCategory: res.data.filterCategoryList
});
}
});
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.getBanner();
this.getGoodsList();
},
onPullDownRefresh() {
this.getBanner();
this.getGoodsList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
openSortFilter: function(event) {
let currentId = event.currentTarget.id;
switch (currentId) {
case 'categoryFilter':
this.setData({
categoryFilter: !this.data.categoryFilter,
currentSortType: 'category',
currentSort: 'add_time',
currentSortOrder: 'desc'
});
break;
case 'priceSort':
let tmpSortOrder = 'asc';
if (this.data.currentSortOrder == 'asc') {
tmpSortOrder = 'desc';
}
this.setData({
currentSortType: 'price',
currentSort: 'retail_price',
currentSortOrder: tmpSortOrder,
categoryFilter: false
});
this.getGoodsList();
break;
default:
//综合排序
this.setData({
currentSortType: 'default',
currentSort: 'add_time',
currentSortOrder: 'desc',
categoryFilter: false,
categoryId: 0
});
this.getGoodsList();
}
},
selectCategory: function(event) {
let currentIndex = event.target.dataset.categoryIndex;
this.setData({
'categoryFilter': false,
'categoryId': this.data.filterCategory[currentIndex].id
});
this.getGoodsList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "新品首发"
}
\ No newline at end of file
<view class="container">
<view class="brand-info">
<view class="name">
<image class="img" src="{{bannerInfo.imgUrl}}" background-size="cover"></image>
<view class="info-box">
<view class="info">
<text class="txt">{{bannerInfo.name}}</text>
<text class="line"></text>
</view>
</view>
</view>
</view>
<view class="sort">
<view class="sort-box">
<view class="item {{currentSortType == 'default' ? 'active' : ''}}" bindtap="openSortFilter" id="defaultSort">
<text class="txt">综合</text>
</view>
<view class="item by-price {{currentSortType == 'price' ? 'active' : ''}} {{currentSortOrder == 'asc' ? 'asc' : 'desc'}}" bindtap="openSortFilter" id="priceSort">
<text class="txt">价格</text>
</view>
<view class="item {{currentSortType == 'category' ? 'active' : ''}}" bindtap="openSortFilter" id="categoryFilter">
<text class="txt">分类</text>
</view>
</view>
<view class="sort-box-category" wx-if="{{categoryFilter}}">
<view class="item {{item.checked ? 'active' : ''}}" wx:for="{{filterCategory}}" wx:key="id" data-category-index="{{index}}" bindtap="selectCategory">{{item.name}}</view>
</view>
</view>
<view class="cate-item">
<view class="b">
<block wx:for="{{goodsList}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="id">
<navigator class="item {{iindex % 2 == 0 ? 'item-b' : '' }}" url="../goods/goods?id={{iitem.id}}">
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</block>
</view>
</view>
</view>
\ No newline at end of file
page {
background: #fff;
}
.container {
background: #fff;
}
.brand-info .name {
width: 100%;
height: 250rpx;
position: relative;
}
.brand-info .img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 250rpx;
}
.brand-info .info-box {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 278rpx;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.brand-info .info {
display: block;
}
.brand-info .txt {
display: block;
height: 40rpx;
font-size: 37.5rpx;
color: #fff;
}
.brand-info .line {
margin: 0 auto;
margin-top: 16rpx;
display: block;
height: 2rpx;
width: 145rpx;
background: #fff;
}
.sort {
position: relative;
background: #fff;
width: 100%;
height: 78rpx;
}
.sort-box {
background: #fff;
width: 100%;
height: 78rpx;
overflow: hidden;
padding: 0 30rpx;
display: flex;
border-bottom: 1px solid #d9d9d9;
}
.sort-box .item {
height: 78rpx;
line-height: 78rpx;
text-align: center;
flex: 1;
color: #333;
font-size: 30rpx;
}
.sort-box .item .txt {
display: block;
width: 100%;
height: 100%;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(0,0,0,1);
}
.sort-box .item.active .txt {
color:#FF1B40;
}
.sort-box .item.by-price {
background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/no-3127092a69.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.asc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/up-636b92c0a5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.desc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/down-95e035f3e5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box-category {
padding: 0 20rpx 20rpx 5rpx;
background: #fff;
width: 100%;
height: auto;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
display: flex;
justify-content: flex-start;
flex-direction: row;
flex-wrap: wrap;
}
.sort-box-category .item {
text-align: center;
padding: 0 16rpx;
border:1px solid #6E6E6E;
border-radius:4px;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#6E6E6E;
line-height:50rpx;
margin-left: 16rpx;
margin-top: 20rpx;
}
.sort-box-category .item.active {
border:1px solid rgba(255,34,70,1);
color:rgba(255,34,70,1);
}
.cate-item .b {
width: 750rpx;
height: auto;
overflow: hidden;
/* border-top: 1rpx solid #f4f4f4;
margin-top: 20rpx; */
}
.cate-item .b .item {
float: left;
background: #fff;
width: 346rpx;
padding-bottom: 33.333rpx;
/* border-bottom: 1rpx solid #f4f4f4; */
height: auto;
overflow: hidden;
margin-left: 18rpx;
margin-right: 9rpx;
}
.cate-item .b .item-b {
/* border-right: 1rpx solid #f4f4f4; */
}
.cate-item .item .img {
margin-top: 10rpx;
width: 346rpx;
height: 346rpx;
}
.cate-item .item .name {
display: block;
width: 365.625rpx;
height: 35rpx;
overflow: hidden;
margin: 10rpx 0;
text-align: center;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.cate-item .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp();
Page({
data: {
status: false,
orderId: 0,
success:false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.setData({
orderId: options.orderId,
status: options.status === '1' ? true : false,
success: options.success === '0' ? true : false
})
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
payOrder() {
let that = this;
// 模拟支付成功,同理,后台也仅仅是返回一个成功的消息而已
// wx.showModal({
// title: '目前不能微信支付',
// content: '点击确定模拟支付成功,点击取消模拟未支付成功',
// success: function (res) {
// if (res.confirm) {
// util.request(api.OrderPrepay, { orderId: that.data.orderId }, 'POST').then(res => {
// if (res.errno === 0) {
// that.setData({
// status: true
// });
// }
// else {
// util.showErrorToast('支付失败');
// }
// });
// }
// else if (res.cancel) {
// util.showErrorToast('支付失败');
// }
// }
// });
util.request(api.OrderPrepay, {
orderId: that.data.orderId
}, 'POST').then(function(res) {
if (res.errno === 0) {
const payParam = res.data;
console.log("支付过程开始")
wx.requestPayment({
'timeStamp': payParam.timeStamp,
'nonceStr': payParam.nonceStr,
'package': payParam.wxPackage,
'signType': payParam.signType,
'paySign': payParam.paySign,
'success': function(res) {
console.log("支付过程成功")
that.setData({
status: true
});
},
'fail': function(res) {
console.log("支付过程失败")
util.showErrorToast('支付失败');
},
'complete': function(res) {
console.log("支付过程结束")
}
});
}
});
}
})
\ No newline at end of file
{
"navigationBarTitleText": "付款结果",
"navigationBarBackgroundColor": "#fafafa"
}
\ No newline at end of file
<view class="container">
<view class="pay-result" wx:if='{{!success}}'>
<view class="success" wx:if="{{status}}">
<view class="msg">付款成功</view>
<view class="btns">
<navigator class="btn btn-border" url="/pages/ucenter/order/order?tab=2" open-type="redirect">查看订单</navigator>
<navigator class="btn" url="/pages/index2/index2" open-type="switchTab">继续逛</navigator>
</view>
</view>
<view class="error" wx:if="{{!status}}">
<view class="msg">付款失败</view>
<view class="tips">
<view class="p">请在
<text class="time">半小时</text> 内完成付款</view>
<view class="p">否则订单将会被系统取消</view>
</view>
<view class="btns">
<navigator class="btn btn-border" url="/pages/ucenter/order/order?tab=1" open-type="redirect">查看订单</navigator>
<view class="btn" bindtap='payOrder'>重新付款</view>
</view>
</view>
</view>
<view class='customer pay-result' wx:if='{{success}}'>
<view class="p">抱歉,您的账户积分不足购买此商品!</view>
<button open-type="contact" class="btn">联系客服</button>
</view>
</view>
\ No newline at end of file
page {
min-height: 100%;
width: 100%;
background: #fff;
}
.container {
height: 100%;
background: #fff;
}
.pay-result {
background: #fff;
}
.pay-result .msg {
text-align: center;
margin: 100rpx auto;
color: #FF1B40;
font-size: 36rpx;
}
.pay-result .btns {
display: flex;
align-items: center;
justify-content: center;
}
.pay-result .btn {
text-align: center;
margin: 0 20rpx;
width: 200rpx;
line-height: 60rpx;
color: #fff;
background: #FF1B40;
border-radius: 50rpx;
box-sizing: border-box;
}
.pay-result .btn-border {
border: 2rpx solid #FF1B40;
color: #FF1B40;
background: #fff;
}
.pay-result .error .msg {
color: #FF1B40;
margin-bottom: 60rpx;
}
.pay-result .error .tips {
color: #7f7f7f;
margin-bottom: 70rpx;
}
.pay-result .error .tips .p {
font-size: 24rpx;
line-height: 42rpx;
text-align: center;
}
.pay-result .error .tips .p {
line-height: 42rpx;
text-align: center;
}
.customer .p{
text-align:center;
margin-top:25%;
font-size:28rpx;
}
.customer .btn{
margin:20rpx auto;
font-size:26rpx;
}
\ No newline at end of file
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp()
Page({
data: {
keywrod: '',
searchStatus: false,
goodsList: [],
helpKeyword: [],
historyKeyword: [],
categoryFilter: false,
currentSort: 'name',
currentSortType: 'default',
currentSortOrder: 'desc',
filterCategory: [],
defaultKeyword: {},
hotKeyword: [],
page: 1,
size: 20,
categoryId: 0
},
//事件处理函数
closeSearch: function() {
wx.navigateBack()
},
clearKeyword: function() {
this.setData({
keyword: '',
searchStatus: false
});
},
onLoad: function() {
this.getSearchKeyword();
},
onPullDownRefresh() {
this.getSearchKeyword();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getSearchKeyword() {
let that = this;
util.request(api.SearchIndex).then(function(res) {
if (res.errno === 0) {
that.setData({
historyKeyword: res.data.historyKeywordList,
defaultKeyword: res.data.defaultKeyword,
hotKeyword: res.data.hotKeywordList
});
}
});
},
inputChange: function(e) {
this.setData({
keyword: e.detail.value,
searchStatus: false
});
if (e.detail.value) {
this.getHelpKeyword();
}
},
getHelpKeyword: function() {
let that = this;
util.request(api.SearchHelper, {
keyword: that.data.keyword
}).then(function(res) {
if (res.errno === 0) {
that.setData({
helpKeyword: res.data
});
}
});
},
inputFocus: function() {
this.setData({
searchStatus: false,
goodsList: []
});
if (this.data.keyword) {
this.getHelpKeyword();
}
},
clearHistory: function() {
this.setData({
historyKeyword: []
})
util.request(api.SearchClearHistory, {}, 'POST')
.then(function(res) {
console.log('清除成功');
});
},
getGoodsList: function() {
let that = this;
util.request(api.GoodsList, {
keyword: that.data.keyword,
page: that.data.page,
size: that.data.size,
sort: that.data.currentSort,
order: that.data.currentSortOrder,
categoryId: that.data.categoryId
}).then(function(res) {
if (res.errno === 0) {
that.setData({
searchStatus: true,
categoryFilter: false,
goodsList: res.data.goodsList,
filterCategory: res.data.filterCategoryList
});
}
//重新获取关键词
that.getSearchKeyword();
});
},
onKeywordTap: function(event) {
this.getSearchResult(event.target.dataset.keyword);
},
getSearchResult(keyword) {
if (keyword === '') {
keyword = this.data.defaultKeyword.keyword;
}
this.setData({
keyword: keyword,
page: 1,
categoryId: 0,
goodsList: []
});
this.getGoodsList();
},
openSortFilter: function(event) {
let currentId = event.currentTarget.id;
switch (currentId) {
case 'categoryFilter':
this.setData({
categoryFilter: !this.data.categoryFilter,
currentSortType: 'category',
currentSort: 'add_time',
currentSortOrder: 'desc'
});
break;
case 'priceSort':
let tmpSortOrder = 'asc';
if (this.data.currentSortOrder == 'asc') {
tmpSortOrder = 'desc';
}
this.setData({
currentSortType: 'price',
currentSort: 'retail_price',
currentSortOrder: tmpSortOrder,
categoryFilter: false
});
this.getGoodsList();
break;
default:
//综合排序
this.setData({
currentSortType: 'default',
currentSort: 'name',
currentSortOrder: 'desc',
categoryFilter: false,
categoryId: 0,
});
this.getGoodsList();
}
},
selectCategory: function(event) {
let currentIndex = event.target.dataset.categoryIndex;
let filterCategory = this.data.filterCategory;
let currentCategory = null;
for (let key in filterCategory) {
if (key == currentIndex) {
filterCategory[key].selected = true;
currentCategory = filterCategory[key];
} else {
filterCategory[key].selected = false;
}
}
this.setData({
filterCategory: filterCategory,
categoryFilter: false,
categoryId: currentCategory.id,
page: 1,
goodsList: []
});
this.getGoodsList();
},
onKeywordConfirm(event) {
this.getSearchResult(event.detail.value);
}
})
\ No newline at end of file
{
"navigationBarTitleText": "搜索"
}
\ No newline at end of file
<scroll-view class="container" style="height: 100%;">
<view class="search-header">
<view class="input-box">
<image class="icon" src="/static/images/search-red.png"></image>
<input name="input" class="keywrod" focus="true" value="{{keyword}}" confirm-type="search" bindinput="inputChange" bindfocus="inputFocus" bindconfirm="onKeywordConfirm" placeholder="{{defaultKeyword.keyword}}" />
<image class="del" wx:if="{{keyword}}" bindtap="clearKeyword" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/clearIpt-f71b83e3c2.png"></image>
</view>
<view class="right" bindtap="closeSearch">取消</view>
</view>
<view class="no-search" wx:if="{{ !searchStatus}}">
<view class="search-keywords search-history" wx:if="{{!keyword && historyKeyword.length}}">
<view class="h">
<text class="title">历史记录</text>
<image class="icon" bindtap="clearHistory" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/del1-93f0a4add4.png"></image>
</view>
<view class="b">
<view class="item" bindtap="onKeywordTap" data-keyword="{{item.keyword}}" wx:for="{{historyKeyword}}" wx:key="keyword" hover-class="navigator-hover">{{item.keyword}}</view>
</view>
</view>
<view class="search-keywords search-hot" wx:if="{{!keyword && hotKeyword.length}}">
<view class="h">
<text class="title">热门搜索</text>
</view>
<view class="b">
<view class="item {{item.is_hot === 1 ? 'active' : ''}}" hover-class="navigator-hover" bindtap="onKeywordTap" data-keyword="{{item.keyword}}" wx:for="{{hotKeyword}}" wx:key="id">{{item.keyword}}</view>
</view>
</view>
<view class="shelper-list" wx:if="{{keyword}}">
<view class="item" hover-class="navigator-hover" wx:for="{{helpKeyword}}" wx:key="id" bindtap="onKeywordTap" data-keyword="{{item}}">{{item}}</view>
</view>
</view>
<view class="search-result" wx:if="{{ searchStatus && goodsList.length}}">
<view class="sort">
<view class="sort-box">
<view class="item {{currentSortType == 'default' ? 'active' : ''}}" bindtap="openSortFilter" id="defaultSort">
<text class="txt">综合</text>
</view>
<view class="item by-price {{currentSortType == 'price' ? 'active' : ''}} {{currentSortOrder == 'asc' ? 'asc' : 'desc'}}" bindtap="openSortFilter" id="priceSort">
<text class="txt">价格</text>
</view>
<view class="item {{currentSortType == 'category' ? 'active' : ''}}" bindtap="openSortFilter" id="categoryFilter">
<text class="txt">分类</text>
</view>
</view>
<view class="sort-box-category" wx-if="{{categoryFilter}}">
<view class="item {{item.checked ? 'active' : ''}}" wx:for="{{filterCategory}}" wx:key="id" data-category-index="{{index}}" bindtap="selectCategory">{{item.name}}</view>
</view>
</view>
<view class="cate-item">
<view class="b">
<navigator class="item {{(iindex + 1) % 2 == 0 ? 'item-b' : ''}}" url="/pages/goods/goods?id={{iitem.id}}" wx:for="{{goodsList}}" wx:key="id" wx:for-item="iitem" wx:for-index="iindex">
<image class="img" src="{{iitem.picUrl}}" background-size="cover"></image>
<text class="name">{{iitem.name}}</text>
<text class="price">¥{{iitem.retailPrice}}</text>
</navigator>
</view>
</view>
</view>
<view class="search-result-empty" wx:if="{{!goodsList.length && searchStatus}}">
<image class="icon" src="http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/noSearchResult-7572a94f32.png"></image>
<text class="text">您寻找的商品还未上架</text>
</view>
</scroll-view>
\ No newline at end of file
page {
min-height: 100%;
background-color: #f4f4f4;
}
.container {
min-height: 100%;
background-color: #f4f4f4;
}
.search-header {
position: fixed;
top: 0;
width: 750rpx;
height: 91rpx;
display: flex;
background: #fff;
border-bottom: 1px solid rgba(0, 0, 0, 0.15);
padding: 0 31.25rpx;
font-size: 29rpx;
color: #333;
}
.search-header .input-box {
position: relative;
margin-top: 16rpx;
float: left;
width: 0;
flex: 1;
height: 59rpx;
line-height: 59rpx;
padding: 0 20rpx;
background: #fff;
border: 2rpx solid #FF1B40;
border-radius: 40rpx;
}
.search-header .icon {
position: absolute;
top: 14rpx;
left: 20rpx;
width: 28rpx;
height: 28rpx;
}
.search-header .del {
position: absolute;
top: 3rpx;
right: 10rpx;
width: 53rpx;
height: 53rpx;
z-index: 10;
}
.search-header .keywrod {
position: absolute;
top: 0;
left: 40rpx;
width: 506rpx;
height: 59rpx;
padding-left: 30rpx;
font-size:24rpx;
}
.search-header .right {
margin-top: 24rpx;
margin-left: 31rpx;
margin-right: 6rpx;
width: 58rpx;
height: 43rpx;
line-height: 43rpx;
float: right;
}
.no-search {
height: auto;
overflow: hidden;
margin-top: 91rpx;
}
.search-keywords {
background: #fff;
width: 750rpx;
height: auto;
overflow: hidden;
margin-bottom: 20rpx;
}
.search-keywords .h {
padding: 0 31.25rpx;
height: 93rpx;
line-height: 93rpx;
width: 100%;
color: #999;
font-size: 29rpx;
}
.search-keywords .title {
display: block;
width: 120rpx;
float: left;
}
.search-keywords .icon {
margin-top: 19rpx;
float: right;
display: block;
margin-left: 511rpx;
height: 55rpx;
width: 55rpx;
}
.search-keywords .b {
width: 750rpx;
height: auto;
overflow: hidden;
padding-left: 31.25rpx;
}
.search-keywords .item {
display: inline-block;
width: auto;
line-height: 40rpx;
padding: 0 15rpx;
border: 1px solid #999;
margin: 0 31.25rpx 31.25rpx 0;
font-size: 24rpx;
color: #333;
border-radius: 30rpx;
}
.search-keywords .item.active {
color: #FF1B40;
border: 2rpx solid #FF1B40;
}
.shelper-list {
width: 750rpx;
height: auto;
overflow: hidden;
background: #fff;
padding: 0 31.25rpx;
}
.shelper-list .item {
height: 93rpx;
width: 687.5rpx;
line-height: 93rpx;
font-size: 24rpx;
color: #333;
border-bottom: 1px solid #f4f4f4;
}
.sort {
position: fixed;
top: 91rpx;
background: #fff;
width: 100%;
height: 78rpx;
}
.sort-box {
background: #fff;
width: 100%;
height: 78rpx;
overflow: hidden;
padding: 0 30rpx;
display: flex;
border-bottom: 1px solid #d9d9d9;
}
.sort-box .item {
height: 78rpx;
line-height: 78rpx;
text-align: center;
flex: 1;
color: #333;
font-size: 30rpx;
}
.sort-box .item .txt {
display: block;
width: 100%;
height: 100%;
color: #333;
}
.sort-box .item.active .txt {
color: #b4282d;
}
.sort-box .item.by-price {
background: url(//yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/no-3127092a69.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.asc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/up-636b92c0a5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box .item.by-price.active.desc {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/down-95e035f3e5.png) 155rpx center no-repeat;
background-size: 15rpx 21rpx;
}
.sort-box-category {
padding: 0 20rpx 20rpx 5rpx;
background: #fff;
width: 100%;
height: auto;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
display: flex;
justify-content: flex-start;
flex-direction: row;
flex-wrap: wrap;
}
.sort-box-category .item {
text-align: center;
padding: 0 16rpx;
border:1px solid #6E6E6E;
border-radius:4px;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#6E6E6E;
line-height:50rpx;
margin-left: 16rpx;
margin-top: 20rpx;
}
.sort-box-category .item.active {
border:1px solid rgba(255,34,70,1);
color:rgba(255,34,70,1);
}
.cate-item {
margin-top: 175rpx;
height: auto;
overflow: hidden;
}
.cate-item .h {
height: 145rpx;
width: 750rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cate-item .h .name {
display: block;
height: 35rpx;
margin-bottom: 18rpx;
font-size: 30rpx;
color: #333;
}
.cate-item .h .desc {
display: block;
height: 24rpx;
font-size: 24rpx;
color: #999;
}
.cate-item .b {
width: 750rpx;
padding: 0 6.25rpx;
height: auto;
overflow: hidden;
}
.cate-item .list-filter {
height: 80rpx;
width: 100%;
background: #fff;
margin-bottom: 6.25rpx;
}
.cate-item .b .item {
float: left;
background: #fff;
width: 365rpx;
margin-bottom: 6.25rpx;
padding-bottom: 33.333rpx;
height: auto;
overflow: hidden;
text-align: center;
}
.cate-item .b .item-b {
margin-left: 6.25rpx;
}
.cate-item .item .img {
width: 302rpx;
height: 302rpx;
}
.cate-item .item .name {
display: block;
width: 365.625rpx;
height: 35rpx;
margin: 10rpx 0 ;
text-align: center;
overflow: hidden;
padding: 0 20rpx;
color: #333;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
}
.cate-item .item .price {
display: block;
width: 365.625rpx;
height: 30rpx;
text-align: center;
font-size: 30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
.search-result-empty {
width: 100%;
height: 100%;
padding-top: 300rpx;
}
.search-result-empty .icon {
margin: 0 auto;
display: block;
width: 240rpx;
height: 240rpx;
}
.search-result-empty .text {
display: block;
width: 100%;
height: 40rpx;
font-size: 28rpx;
text-align: center;
color: #999;
}
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
var app = getApp()
Page({
data: {
topicList: [],
page: 1,
size: 10,
count: 0,
scrollTop: 0,
showPage: false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.getTopic();
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
this.getTopic();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
nextPage: function(event) {
var that = this;
if (this.data.page > that.data.count / that.data.size) {
wx.showToast({
title: '-_-没有下一页了-_-',
icon: 'none'
})
return true;
}
that.setData({
page: that.data.page + 1
});
this.getTopic();
},
getTopic: function() {
let that = this;
that.setData({
scrollTop: 0,
showPage: false,
topicList: []
});
// 页面渲染完成
wx.showToast({
title: '加载中...',
icon: 'loading',
duration: 2000
});
util.request(api.TopicList, {
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
that.setData({
scrollTop: 0,
topicList: res.data.data,
showPage: true,
count: res.data.count
});
}
wx.hideToast();
});
},
prevPage: function(event) {
if (this.data.page <= 1) {
wx.showToast({
title: '-_-没有上一页了-_-',
icon: 'none'
})
return false;
}
var that = this;
that.setData({
page: that.data.page - 1
});
this.getTopic();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "专题精选"
}
\ No newline at end of file
<view class="container">
<scroll-view class="topic-list" scroll-y="true" scroll-top="{{scrollTop}}">
<navigator class="item" wx:for="{{topicList}}" wx:key="id" url="../topicDetail/topicDetail?id={{item.id}}">
<image class="img" src="{{item.picUrl}}"></image>
<view class="info">
<text class="title">{{item.title}}</text>
<text class="desc">{{item.subtitle}}</text>
<text class="price" wx:if="{{item.price}}">{{item.price}}元起</text>
</view>
</navigator>
<view class="page" wx:if="{{showPage}}">
<view class="prev {{ page <= 1 ? 'disabled' : ''}}" bindtap="prevPage">上一页</view>
<view class="next {{ (count / size) < page ? 'disabled' : ''}}" bindtap="nextPage">下一页</view>
</view>
</scroll-view>
</view>
\ No newline at end of file
page ,.container{
width: 750rpx;
height: 100%;
overflow: hidden;
background: #fff;
}
.topic-list{
width: 750rpx;
height: 100%;
overflow: hidden;
background: #fff;
}
.topic-list .item{
width: 100%;
height: 625rpx;
overflow: hidden;
background: #fff;
margin-bottom: 20rpx;
}
.topic-list .img{
width: 100%;
height: 415rpx;
}
.topic-list .info{
width: 100%;
height: 210rpx;
overflow: hidden;
}
.topic-list .title{
display: block;
text-align: center;
width: 100%;
height: 33rpx;
line-height: 35rpx;
color: #333;
overflow: hidden;
font-size: 35rpx;
margin-top: 30rpx;
}
.topic-list .desc{
display: block;
text-align: center;
position: relative;
width: auto;
height: 24rpx;
line-height: 24rpx;
overflow: hidden;
color: #999;
font-size: 24rpx;
margin-top: 16rpx;
margin-bottom: 30rpx;
}
.topic-list .price{
display: block;
text-align: center;
width: 100%;
height: 27rpx;
line-height: 27rpx;
overflow: hidden;
color: #FF1B40;
font-size: 27rpx;
}
.page {
width: 750rpx;
background: #fff;
margin-bottom: 80rpx;
display: flex;
justify-content: center;
}
.prev, .next {
width: 200rpx;
line-height: 60rpx;
font-size: 24rpx;
font-weight: 400;
color: #FF1B40;
border-radius: 50rpx;
border: 1rpx solid #FF1B40;
text-align: center;
}
.prev {
margin-right: 20rpx;
}
.page .disabled {
border:1rpx solid rgba(110,110,110,1);
color: rgba(110,110,110,1);
}
\ No newline at end of file
var app = getApp();
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
comments: [],
allCommentList: [],
picCommentList: [],
type: 0,
valueId: 0,
showType: 0,
allCount: 0,
hasPicCount: 0,
allPage: 1,
picPage: 1,
size: 20
},
getCommentCount: function() {
let that = this;
util.request(api.CommentCount, {
valueId: that.data.valueId,
type: that.data.type
}).then(function(res) {
if (res.errno === 0) {
that.setData({
allCount: res.data.allCount,
hasPicCount: res.data.hasPicCount
});
}
});
},
getCommentList: function() {
let that = this;
util.request(api.CommentList, {
valueId: that.data.valueId,
type: that.data.type,
size: that.data.size,
page: (that.data.showType == 0 ? that.data.allPage : that.data.picPage),
showType: that.data.showType
}).then(function(res) {
if (res.errno === 0) {
if (that.data.showType == 0) {
that.setData({
allCommentList: that.data.allCommentList.concat(res.data.data),
allPage: res.data.currentPage,
comments: that.data.allCommentList.concat(res.data.data)
});
} else {
that.setData({
picCommentList: that.data.picCommentList.concat(res.data.data),
picPage: res.data.currentPage,
comments: that.data.picCommentList.concat(res.data.data)
});
}
}
});
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.setData({
type: options.type,
valueId: options.valueId
});
this.getCommentCount();
this.getCommentList();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
switchTab: function() {
this.setData({
showType: this.data.showType == 1 ? 0 : 1
});
this.getCommentList();
},
onReachBottom: function() {
console.log('onPullDownRefresh');
if (this.data.showType == 0) {
if (this.data.allCount / this.data.size < this.data.allPage) {
return false;
}
this.setData({
'allPage': this.data.allPage + 1
});
} else {
if (this.data.hasPicCount / this.data.size < this.data.picPage) {
return false;
}
this.setData({
'picPage': this.data.picPage + 1
});
}
this.getCommentList();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "评论"
}
\ No newline at end of file
<view class="comments">
<view class="b">
<view class="item" wx:for="{{comments}}" wx:key="id">
<view class="info">
<view class="user">
<image src="{{item.userInfo.avatarUrl}}"></image>
<text>{{item.userInfo.nickName}}</text>
</view>
<view class="time">{{item.addTime}}</view>
</view>
<view class="comment">{{item.content}}</view>
<view class="imgs" wx:if="{{item.picList.length > 0}}">
<image class="img" wx:for="{{item.picList}}" wx:key="id" wx:for-item="pitem" src="{{pitem.picUrl}}"></image>
</view>
</view>
</view>
</view>
\ No newline at end of file
.comments {
width: 100%;
height: auto;
padding-left: 30rpx;
background: #fff;
margin: 20rpx 0;
}
.comments .b {
height: auto;
width: 720rpx;
}
.comments .b.no-h {
margin-top: 0;
}
.comments .item {
height: auto;
width: 720rpx;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
padding-bottom: 25rpx;
}
.comments .info {
height: 127rpx;
width: 100%;
padding: 33rpx 0 27rpx 0;
}
.comments .user {
float: left;
width: auto;
height: 67rpx;
line-height: 67rpx;
font-size: 0;
}
.comments .user image {
float: left;
width: 67rpx;
height: 67rpx;
margin-right: 17rpx;
border-radius: 50%;
}
.comments .user text {
display: inline-block;
width: auto;
height: 66rpx;
overflow: hidden;
font-size: 29rpx;
line-height: 66rpx;
}
.comments .time {
display: block;
float: right;
width: auto;
height: 67rpx;
line-height: 67rpx;
color: #7f7f7f;
font-size: 25rpx;
margin-right: 30rpx;
}
.comments .comment {
width: 720rpx;
padding-right: 30rpx;
line-height: 45.8rpx;
font-size: 29rpx;
margin-bottom: 16rpx;
}
.comments .imgs {
width: 720rpx;
height: 150rpx;
margin-bottom: 25rpx;
}
.comments .imgs .img {
height: 150rpx;
width: 150rpx;
margin-right: 28rpx;
}
.comments .customer-service {
width: 690rpx;
height: auto;
overflow: hidden;
margin-top: 23rpx;
background: rgba(0, 0, 0, 0.03);
padding: 21rpx;
}
.comments .customer-service .u {
font-size: 24rpx;
color: #333;
line-height: 37.5rpx;
}
.comments .customer-service .c {
font-size: 24rpx;
color: #999;
line-height: 37.5rpx;
}
// 上传组件 基于https://github.com/Tencent/weui-wxss/tree/master/src/example/uploader
var app = getApp();
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
valueId: 0,
topic: {},
content: '',
stars: [0, 1, 2, 3, 4],
star: 5,
starText: '十分满意',
hasPicture: false,
picUrls: [],
files: []
},
chooseImage: function(e) {
if (this.data.files.length >= 5) {
util.showErrorToast('只能上传五张图片')
return false;
}
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.setData({
files: that.data.files.concat(res.tempFilePaths)
});
that.upload(res);
}
})
},
upload: function(res) {
var that = this;
const uploadTask = wx.uploadFile({
url: api.StorageUpload,
filePath: res.tempFilePaths[0],
name: 'file',
success: function(res) {
var _res = JSON.parse(res.data);
if (_res.errno === 0) {
var url = _res.data.url
that.data.picUrls.push(url)
that.setData({
hasPicture: true,
picUrls: that.data.picUrls
})
}
},
fail: function(e) {
wx.showModal({
title: '错误',
content: '上传失败',
showCancel: false
})
},
})
uploadTask.onProgressUpdate((res) => {
console.log('上传进度', res.progress)
console.log('已经上传的数据长度', res.totalBytesSent)
console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
})
},
previewImage: function(e) {
wx.previewImage({
current: e.currentTarget.id, // 当前显示图片的http链接
urls: this.data.files // 需要预览的图片http链接列表
})
},
selectRater: function(e) {
var star = e.currentTarget.dataset.star + 1;
var starText;
if (star == 1) {
starText = '很差';
} else if (star == 2) {
starText = '不太满意';
} else if (star == 3) {
starText = '满意';
} else if (star == 4) {
starText = '比较满意';
} else {
starText = '十分满意'
}
this.setData({
star: star,
starText: starText
})
},
onLoad: function(options) {
if (parseInt(options.type) !== 1) {
return;
}
var that = this;
that.setData({
valueId: options.valueId
});
this.getTopic();
},
getTopic: function() {
let that = this;
util.request(api.TopicDetail, {
id: that.data.valueId
}).then(function(res) {
if (res.errno === 0) {
that.setData({
topic: res.data.topic
});
}
});
},
onClose: function() {
wx.navigateBack();
},
onPost: function() {
let that = this;
if (!this.data.content) {
util.showErrorToast('请填写评论')
return false;
}
util.request(api.CommentPost, {
type: 1,
valueId: that.data.valueId,
content: that.data.content,
star: that.data.star,
hasPicture: that.data.hasPicture,
picUrls: that.data.picUrls
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '评论成功',
complete: function() {
wx.navigateBack();
}
})
}
});
},
bindInputValue(event) {
let value = event.detail.value;
//判断是否超过140个字符
if (value && value.length > 140) {
return false;
}
this.setData({
content: event.detail.value,
})
},
onReady: function() {
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "评论"
}
\ No newline at end of file
<view class="container">
<view class="post-comment">
<view class="goods">
<view class="img">
<image src="{{topic.picUrl}}"></image>
</view>
<view class="info">
<view class="t">
<text class="name">{{topic.title}}</text>
</view>
<view class="attr">{{topic.subtitle}}</view>
</view>
</view>
<view class="rater">
<text class="rater-title">评分</text>
<block wx:for="{{stars}}" wx:key="*this" wx:for-item="item">
<image src="/static/images/icon_collect_checked.png" bindtap="selectRater" data-star="{{item}}" wx:if="{{item < star}}"></image>
<image src="/static/images/icon_collect.png" bindtap="selectRater" data-star="{{item}}" wx:else></image>
</block>
<text class="rater-desc">{{starText}}</text>
</view>
<view class="input-box">
<textarea class="content" focus="true" bindinput="bindInputValue" maxlength="140" placeholder="留言经过筛选后,对所有人可见" />
<text class="count">{{140 - content.length}}</text>
</view>
<view class="weui-uploader">
<view class="weui-uploader__hd">
<view class="weui-uploader__title">图片上传</view>
<view class="weui-uploader__info">{{picUrls.length}}/{{files.length}}</view>
</view>
<view class="weui-uploader__bd">
<view class="weui-uploader__files" id="uploaderFiles">
<block wx:for="{{files}}" wx:key="*this">
<view class="weui-uploader__file" bindtap="previewImage" id="{{item}}">
<image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
</view>
</block>
<view class="weui-uploader__input-box">
<view class="weui-uploader__input" bindtap="chooseImage"></view>
</view>
</view>
</view>
</view>
<view class="btns">
<view class="close" bindtap="onClose">取消</view>
<view class="post" bindtap="onPost">发表</view>
</view>
</view>
</view>
\ No newline at end of file
page, .container {
height: 100%;
background: #f4f4f4;
}
.post-comment {
width: 750rpx;
height: auto;
overflow: hidden;
padding: 30rpx;
background: #fff;
}
.post-comment .goods {
display: flex;
align-items: center;
height: 199rpx;
margin-left: 31.25rpx;
}
.post-comment .goods .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.post-comment .goods .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.post-comment .goods .info {
height: 145.83rpx;
flex: 1;
padding-left: 20rpx;
}
.post-comment .goods .name {
margin-top: 30rpx;
display: block;
height: 44rpx;
line-height: 44rpx;
color: #333;
font-size: 30rpx;
}
.post-comment .goods .number {
display: block;
height: 37rpx;
line-height: 37rpx;
color: #666;
font-size: 25rpx;
}
.post-comment .goods .status {
width: 105rpx;
color: #b4282d;
font-size: 25rpx;
}
.post-comment .rater {
display: flex;
flex-direction: row;
height: 55rpx;
}
.post-comment .rater .rater-title {
font-size: 29rpx;
padding-right: 10rpx;
}
.post-comment .rater image {
padding-left: 5rpx;
height: 50rpx;
width: 50rpx;
}
.post-comment .rater .rater-desc {
font-size: 29rpx;
padding-left: 10rpx;
}
.post-comment .input-box {
height: 337.5rpx;
width: 690rpx;
position: relative;
background: #fff;
}
.post-comment .input-box .content {
position: absolute;
top: 0;
left: 0;
display: block;
background: #fff;
font-size: 29rpx;
border: 5px solid #f4f4f4;
height: 300rpx;
width: 650rpx;
padding: 20rpx;
}
.post-comment .input-box .count {
position: absolute;
bottom: 20rpx;
right: 20rpx;
display: block;
height: 30rpx;
width: 50rpx;
font-size: 29rpx;
color: #999;
}
.post-comment .btns {
height: 108rpx;
}
.post-comment .close {
float: left;
height: 108rpx;
line-height: 108rpx;
text-align: left;
color: #666;
padding: 0 30rpx;
}
.post-comment .post {
float: right;
height: 108rpx;
line-height: 108rpx;
text-align: right;
padding: 0 30rpx;
}
.weui-uploader {
margin-top: 50rpx;
}
.weui-uploader__hd {
display: -webkit-box;
display: -webkit-flex;
display: flex;
padding-bottom: 10px;
-webkit-box-align: center;
-webkit-align-items: center;
align-items: center;
}
.weui-uploader__title {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
.weui-uploader__info {
color: #b2b2b2;
}
.weui-uploader__bd {
margin-bottom: -4px;
margin-right: -9px;
overflow: hidden;
}
.weui-uploader__file {
float: left;
margin-right: 9px;
margin-bottom: 9px;
}
.weui-uploader__img {
display: block;
width: 79px;
height: 79px;
}
.weui-uploader__file_status {
position: relative;
}
.weui-uploader__file_status:before {
content: " ";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.weui-uploader__file-content {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
color: #fff;
}
.weui-uploader__input-box {
float: left;
position: relative;
margin-right: 9px;
margin-bottom: 9px;
width: 77px;
height: 77px;
border: 1px solid #d9d9d9;
}
.weui-uploader__input-box:after, .weui-uploader__input-box:before {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #d9d9d9;
}
.weui-uploader__input-box:before {
width: 2px;
height: 39.5px;
}
.weui-uploader__input-box:after {
width: 39.5px;
height: 2px;
}
.weui-uploader__input-box:active {
border-color: #999;
}
.weui-uploader__input-box:active:after, .weui-uploader__input-box:active:before {
background-color: #999;
}
.weui-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
var app = getApp();
var WxParse = require('../../lib/wxParse/wxParse.js');
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
id: 0,
topic: {},
topicList: [],
commentCount: 0,
commentList: [],
topicGoods: []
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
var that = this;
that.setData({
id: options.id
});
util.request(api.TopicDetail, {
id: that.data.id
}).then(function(res) {
if (res.errno === 0) {
that.setData({
topic: res.data.topic,
topicGoods: res.data.goods
});
WxParse.wxParse('topicDetail', 'html', res.data.topic.content, that);
}
});
util.request(api.TopicRelated, {
id: that.data.id
}).then(function(res) {
if (res.errno === 0) {
that.setData({
topicList: res.data
});
}
});
},
getCommentList() {
let that = this;
util.request(api.CommentList, {
valueId: that.data.id,
type: 1,
showType: 0,
page: 1,
size: 5
}).then(function(res) {
if (res.errno === 0) {
that.setData({
commentList: res.data.data,
commentCount: res.data.count
});
}
});
},
postComment() {
if (!app.globalData.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
} else {
wx.navigateTo({
url: '/pages/topicCommentPost/topicCommentPost?valueId=' + this.data.id + '&type=1',
})
}
},
onReady: function() {
},
onShow: function() {
// 页面显示
this.getCommentList();
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "专题详情"
}
\ No newline at end of file
<scroll-view class="container">
<scroll-view class="content">
<import src="../../lib/wxParse/wxParse.wxml" />
<template is="wxParse" data="{{wxParseData:topicDetail.nodes}}" />
</scroll-view>
<scroll-view class="sv-goods" wx:if="{{topicGoods.length > 0 }}">
<view class="topic-goods">
<view class="h">
<text class="t">专题商品</text>
<image bindtap="postComment" class="i" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/comment-add-2aca147c3f.png"></image>
</view>
<view class="b">
<view class="item" wx:for="{{topicGoods}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<navigator url="/pages/goods/goods?id={{item.id}}">
<image class="img" src="{{item.picUrl}}" background-size="cover"></image>
<view class="right">
<view class="text">
<text class="name">{{item.name}}</text>
<text class="desc">{{item.brief}}</text>
<text class="price">¥{{item.retailPrice}}</text>
</view>
</view>
</navigator>
</view>
</view>
</view>
</scroll-view>
<scroll-view class="comments">
<view class="h">
<text class="t">精选留言</text>
<image bindtap="postComment" class="i" src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/comment-add-2aca147c3f.png"></image>
</view>
<view class="has-comments" wx:if="{{commentList.length > 0 }}">
<view class="b">
<view class="item" wx:for="{{commentList}}" wx:key="id">
<view class="info">
<view class="user">
<image class="avatar" src="{{item.userInfo.avatarUrl}}"></image>
<text class="nickname">{{item.userInfo.nickName}}</text>
</view>
<view class="time">{{item.addTime}}</view>
</view>
<view class="comment">
{{item.content}}
</view>
</view>
</view>
<view class="load" wx:if="{{commentCount > 5}}">
<navigator url="/pages/topicComment/topicComment?valueId={{topic.id}}&type=1">查看更多</navigator>
</view>
</view>
<view class="no-comments" wx:if="{{commentList.length <= 0}}">
<view class="b">
<image class="icon" src="http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/no-comment-560f87660a.png"></image>
<text class="txt">等你来留言</text>
</view>
</view>
</scroll-view>
<scroll-view class="rec-box">
<view class="h">
<text class="txt">专题推荐</text>
</view>
<view class="b">
<navigator class="item" wx:for="{{topicList}}" wx:key="id" url="../topicDetail/topicDetail?id={{item.id}}">
<image class="img" src="{{item.picUrl}}"></image>
<text class="title">{{item.title}}</text>
</navigator>
</view>
</scroll-view>
</scroll-view>
\ No newline at end of file
.content {
width: 100%;
height: auto;
font-size: 0;
}
.content image {
display: inline-block;
width: 100%;
}
.comments {
width: 100%;
height: auto;
padding-left: 30rpx;
background: #fff;
margin-top: 20rpx;
}
.comments .h {
height: 93rpx;
line-height: 93rpx;
width: 720rpx;
padding-right: 30rpx;
border-bottom: 1px solid #d9d9d9;
}
.comments .h .t {
display: block;
float: left;
width: 50%;
font-size: 29rpx;
color: #333;
}
.comments .h .i {
display: block;
float: right;
margin-top: 30rpx;
width: 33rpx;
height: 33rpx;
}
.comments .b {
height: auto;
width: 720rpx;
}
.comments .item {
height: auto;
width: 720rpx;
overflow: hidden;
border-bottom: 1px solid #d9d9d9;
}
.comments .info {
height: 127rpx;
width: 100%;
padding: 33rpx 0 27rpx 0;
}
.comments .user {
float: left;
width: auto;
height: 67rpx;
line-height: 67rpx;
font-size: 0;
}
.comments .user .avatar {
display: block;
float: left;
width: 67rpx;
height: 67rpx;
margin-right: 17rpx;
border-radius: 50%;
}
.comments .user .nickname {
display: block;
width: auto;
float: left;
height: 66rpx;
overflow: hidden;
font-size: 29rpx;
line-height: 66rpx;
}
.comments .time {
display: block;
float: right;
width: auto;
height: 67rpx;
line-height: 67rpx;
color: #7f7f7f;
font-size: 25rpx;
margin-right: 30rpx;
}
.comments .comment {
width: 720rpx;
padding-right: 30rpx;
line-height: 45.8rpx;
margin-bottom: 30rpx;
font-size: 29rpx;
color: #333;
}
.comments .load {
width: 720rpx;
height: 108rpx;
line-height: 108rpx;
text-align: center;
font-size: 38.5rpx;
}
.no-comments {
height: 297rpx;
}
.no-comments .txt {
height: 43rpx;
line-height: 43rpx;
display: block;
width: 100%;
text-align: center;
font-size: 29rpx;
color: #7f7f7f;
}
.no-comments .icon {
margin: 48rpx auto 18rpx auto;
height: 130rpx;
display: block;
width: 115rpx;
}
.sv-goods {
width: 100%;
height: auto;
padding-left: 30rpx;
background: #fff;
margin-top: 20rpx;
}
.topic-goods .b .item {
border-top: 1px solid #d9d9d9;
margin: 0 20rpx;
height: 244rpx;
width: 710rpx;
}
.topic-goods .b .img {
margin-top: 12rpx;
margin-right: 12rpx;
float: left;
width: 220rpx;
height: 220rpx;
}
.topic-goods .b .right {
float: left;
height: 244rpx;
width: 476rpx;
display: flex;
flex-flow: row nowrap;
}
.topic-goods .b .text {
display: flex;
flex-wrap: nowrap;
flex-direction: column;
justify-content: center;
overflow: hidden;
height: 244rpx;
width: 476rpx;
}
.topic-goods .b .name {
float: left;
width: 330rpx;
display: block;
color: #333;
line-height: 50rpx;
font-size: 30rpx;
}
.topic-goods .b .desc {
width: 476rpx;
display: block;
color: #999;
line-height: 50rpx;
font-size: 25rpx;
}
.topic-goods .b .price {
width: 476rpx;
display: flex;
color: #b4282d;
line-height: 50rpx;
font-size: 33rpx;
}
.rec-box {
width: 690rpx;
height: auto;
margin: 0 30rpx;
}
.rec-box .h {
position: relative;
width: 690rpx;
height: 96rpx;
/*border-bottom: 1px solid #d0d0d0;*/
margin-bottom: 32rpx;
}
.rec-box .h .txt {
display: inline-block;
position: absolute;
background: #f4f4f4;
top: 59rpx;
left: 200rpx;
width: 290rpx;
height: 45rpx;
line-height: 45rpx;
font-size: 30rpx;
color: #999;
text-align: center;
}
.rec-box .b .item {
width: 690rpx;
height: 397rpx;
padding: 24rpx 24rpx 30rpx 24rpx;
background: #fff;
margin-bottom: 30rpx;
}
.rec-box .b .item .img {
height: 278rpx;
width: 642rpx;
}
.rec-box .b .item .title {
display: block;
margin-top: 30rpx;
height: 30rpx;
width: 642rpx;
font-size: 28rpx;
}
@import "../../lib/wxParse/wxParse.wxss";
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
addressList: [],
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
this.getAddressList();
},
getAddressList() {
let that = this;
util.request(api.AddressList).then(function(res) {
if (res.errno === 0) {
that.setData({
addressList: res.data
});
}
});
},
addressAddOrUpdate(event) {
console.log(event)
//返回之前,先取出上一页对象,并设置addressId
var pages = getCurrentPages();
var prevPage = pages[pages.length - 2];
if (prevPage.route == "pages/checkout/checkout") {
try {
wx.setStorageSync('addressId', event.currentTarget.dataset.addressId);
} catch (e) {
}
let addressId = event.currentTarget.dataset.addressId;
if (addressId && addressId != 0) {
wx.navigateBack();
} else {
wx.navigateTo({
url: '/pages/ucenter/addressAdd/addressAdd?id=' + addressId
})
}
} else {
wx.navigateTo({
url: '/pages/ucenter/addressAdd/addressAdd?id=' + event.currentTarget.dataset.addressId
})
}
},
deleteAddress(event) {
console.log(event.target)
let that = this;
wx.showModal({
title: '',
content: '确定要删除地址?',
success: function(res) {
if (res.confirm) {
let addressId = event.target.dataset.addressId;
util.request(api.AddressDelete, {
id: addressId
}, 'POST').then(function(res) {
if (res.errno === 0) {
that.getAddressList();
wx.removeStorage({
key: 'addressId',
success: function(res) {},
})
}
});
console.log('用户点击确定')
}
}
})
return false;
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "我的收货地址"
}
\ No newline at end of file
<view class="container">
<view class="address-list" wx:if="{{ addressList.length > 0 }}">
<view class="item" wx:for="{{addressList}}" wx:key="id" bindtap="addressAddOrUpdate" data-address-id="{{item.id}}">
<view class="address">{{item.detailedAddress}}</view>
<view class="name-box">
<view class="name">{{item.name}}</view>
<view class="mobile">{{item.mobile}}</view>
</view>
<view class="default" wx:if="{{item.isDefault}}">默认</view>
<image class='editor' src="/static/images/my-enditor.png"></image>
</view>
</view>
<view class="empty-view" wx:if="{{ addressList.length <= 0 }}">
<image class="icon" src="http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/noAddress-26d570cefa.png"></image>
<text class="text">收货地址在哪里</text>
</view>
<view class="add-address" bindtap="addressAddOrUpdate" data-address-id="0">
<image class='add-address-icon' src="/static/images/add-address.png"></image>
<text class='add-address-text'>新增收货地址</text>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #fff;
}
.container {
height: 100%;
width: 100%;
background: #fff;
}
.address-list {
/* background: #fff url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/address-bg-bd30f2bfeb.png) 0 0 repeat-x; */
border-top: 3rpx solid rgba(239,239,239,1);
overflow: hidden;
}
.address-list .item {
height: 128rpx;
display: flex;
flex-direction: column;
justify-content: center;
border-bottom:3rpx solid rgba(239,239,239,1);
position: relative;
}
.address {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
width: 80%;
margin-left: 31rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.name-box {
display: flex;
margin-left: 31rpx;
margin-top: 5rpx;
}
.name {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(125,125,125,1);
}
.mobile {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(125,125,125,1);
margin-left: 55rpx;
}
.editor {
width: 28rpx;
height: 29rpx;
position: absolute;
top: 50%;
right: 29rpx;
z-index: 100;
transform: translateY(-50%);
}
.default {
position: absolute;
top: 50%;
right: 79rpx;
font-size: 16rpx;
border-radius: 25rpx;
padding: 5rpx 10rpx;
border: 1rpx solid #E31436;
color: #E31436;
transform: translateY(-50%);
}
.add-address {
position: absolute;
bottom: 0;
height: 90rpx;
width: 100%;
border-top: 3rpx solid rgba(239,239,239,1);
display: flex;
justify-content: center;
align-items: center;
}
.add-address-icon {
width: 34rpx;
height: 34rpx;
}
.add-address-text {
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 23rpx;
}
.empty-view {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.empty-view .icon {
height: 248rpx;
width: 258rpx;
margin-bottom: 10rpx;
}
.empty-view .text {
width: auto;
font-size: 28rpx;
line-height: 35rpx;
color: #999;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var check = require('../../../utils/check.js');
var app = getApp();
Page({
data: {
address: {
id: 0,
provinceId: 0,
cityId: 0,
areaId: 0,
address: '',
name: '',
mobile: '',
isDefault: 0,
provinceName: '',
cityName: '',
areaName: ''
},
addressId: 0,
openSelectRegion: false,
selectRegionList: [{
id: 0,
name: '省份',
pid: 1,
type: 1
},
{
id: 0,
name: '城市',
pid: 1,
type: 2
},
{
id: 0,
name: '区县',
pid: 1,
type: 3
}
],
regionType: 1,
regionList: [],
selectRegionDone: false
},
bindinputMobile(event) {
let address = this.data.address;
address.mobile = event.detail.value;
this.setData({
address: address
});
},
bindinputName(event) {
let address = this.data.address;
address.name = event.detail.value;
this.setData({
address: address
});
},
bindinputAddress(event) {
let address = this.data.address;
address.address = event.detail.value;
this.setData({
address: address
});
},
bindIsDefault() {
let address = this.data.address;
address.isDefault = !address.isDefault;
this.setData({
address: address
});
},
getAddressDetail() {
let that = this;
util.request(api.AddressDetail, {
id: that.data.addressId
}).then(function(res) {
if (res.errno === 0) {
if (res.data) {
that.setData({
address: res.data
});
}
}
});
},
setRegionDoneStatus() {
let that = this;
let doneStatus = that.data.selectRegionList.every(item => {
return item.id != 0;
});
that.setData({
selectRegionDone: doneStatus
})
},
chooseRegion() {
let that = this;
this.setData({
openSelectRegion: !this.data.openSelectRegion
});
//设置区域选择数据
let address = this.data.address;
if (address.provinceId > 0 && address.cityId > 0 && address.areaId > 0) {
let selectRegionList = this.data.selectRegionList;
selectRegionList[0].id = address.provinceId;
selectRegionList[0].name = address.provinceName;
selectRegionList[0].pid = 0;
selectRegionList[1].id = address.cityId;
selectRegionList[1].name = address.cityName;
selectRegionList[1].pid = address.provinceId;
selectRegionList[2].id = address.areaId;
selectRegionList[2].name = address.areaName;
selectRegionList[2].pid = address.cityId;
this.setData({
selectRegionList: selectRegionList,
regionType: 3
});
this.getRegionList(address.cityId);
} else {
this.setData({
selectRegionList: [{
id: 0,
name: '省份',
pid: 0,
type: 1
},
{
id: 0,
name: '城市',
pid: 0,
type: 2
},
{
id: 0,
name: '区县',
pid: 0,
type: 3
}
],
regionType: 1
})
this.getRegionList(0);
}
this.setRegionDoneStatus();
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
console.log(options)
if (options.id && options.id != 0) {
this.setData({
addressId: options.id
});
this.getAddressDetail();
}
},
onReady: function() {
},
selectRegionType(event) {
let that = this;
let regionTypeIndex = event.target.dataset.regionTypeIndex;
let selectRegionList = that.data.selectRegionList;
//判断是否可点击
if (regionTypeIndex + 1 == this.data.regionType || (regionTypeIndex - 1 >= 0 && selectRegionList[regionTypeIndex - 1].id <= 0)) {
return false;
}
this.setData({
regionType: regionTypeIndex + 1
})
let selectRegionItem = selectRegionList[regionTypeIndex];
this.getRegionList(selectRegionItem.pid);
this.setRegionDoneStatus();
},
selectRegion(event) {
let that = this;
let regionIndex = event.target.dataset.regionIndex;
let regionItem = this.data.regionList[regionIndex];
let regionType = regionItem.type;
let selectRegionList = this.data.selectRegionList;
selectRegionList[regionType - 1] = regionItem;
if (regionType != 3) {
this.setData({
selectRegionList: selectRegionList,
regionType: regionType + 1
})
this.getRegionList(regionItem.id);
} else {
this.setData({
selectRegionList: selectRegionList
})
}
//重置下级区域为空
selectRegionList.map((item, index) => {
if (index > regionType - 1) {
item.id = 0;
item.name = index == 1 ? '城市' : '区县';
item.pid = 0;
}
return item;
});
this.setData({
selectRegionList: selectRegionList
})
that.setData({
regionList: that.data.regionList.map(item => {
//标记已选择的
if (that.data.regionType == item.type && that.data.selectRegionList[that.data.regionType - 1].id == item.id) {
item.selected = true;
} else {
item.selected = false;
}
return item;
})
});
this.setRegionDoneStatus();
},
doneSelectRegion() {
if (this.data.selectRegionDone === false) {
return false;
}
let address = this.data.address;
let selectRegionList = this.data.selectRegionList;
address.provinceId = selectRegionList[0].id;
address.cityId = selectRegionList[1].id;
address.areaId = selectRegionList[2].id;
address.provinceName = selectRegionList[0].name;
address.cityName = selectRegionList[1].name;
address.areaName = selectRegionList[2].name;
this.setData({
address: address,
openSelectRegion: false
});
},
cancelSelectRegion() {
this.setData({
openSelectRegion: false,
regionType: this.data.regionDoneStatus ? 3 : 1
});
},
getRegionList(regionId) {
let that = this;
let regionType = that.data.regionType;
util.request(api.RegionList, {
pid: regionId
}).then(function(res) {
if (res.errno === 0) {
that.setData({
regionList: res.data.map(item => {
//标记已选择的
if (regionType == item.type && that.data.selectRegionList[regionType - 1].id == item.id) {
item.selected = true;
} else {
item.selected = false;
}
return item;
})
});
}
});
},
cancelAddress() {
let that = this;
wx.showModal({
title: '',
content: '确定要删除地址?',
success: function (res) {
if (res.confirm) {
let addressId = that.data.address.id;
util.request(api.AddressDelete, {
id: addressId
}, 'POST').then(function (res) {
if (res.errno === 0) {
wx.removeStorage({
key: 'addressId',
success: function (res) { },
})
wx.navigateBack();
}
});
console.log('用户点击确定')
}
}
})
},
saveAddress() {
console.log(this.data.address)
let address = this.data.address;
if (address.name == '') {
util.showErrorToast('请输入姓名');
return false;
}
if (address.mobile == '') {
util.showErrorToast('请输入手机号码');
return false;
}
if (address.areaId == 0) {
util.showErrorToast('请输入省市区');
return false;
}
if (address.address == '') {
util.showErrorToast('请输入详细地址');
return false;
}
if (!check.isValidPhone(address.mobile)) {
util.showErrorToast('手机号不正确');
return false;
}
let that = this;
util.request(api.AddressSave, {
id: address.id,
name: address.name,
mobile: address.mobile,
provinceId: address.provinceId,
cityId: address.cityId,
areaId: address.areaId,
address: address.address,
isDefault: address.isDefault
}, 'POST').then(function(res) {
if (res.errno === 0) {
//返回之前,先取出上一页对象,并设置addressId
var pages = getCurrentPages();
var prevPage = pages[pages.length - 2];
console.log(prevPage);
if (prevPage.route == "pages/checkout/checkout") {
prevPage.setData({
addressId: res.data
})
try {
wx.setStorageSync('addressId', res.data);
} catch (e) {
}
console.log("set address");
}
wx.navigateBack();
}
});
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "编辑收货地址"
}
\ No newline at end of file
<view class="add-address">
<view class="add-form">
<view class="form-item">
<text class="form-text">联系人:</text>
<input class="input" bindinput="bindinputName" placeholder="请输入姓名" value="{{address.name}}" auto-focus/>
</view>
<view class="form-item">
<text class="form-text">手机号:</text>
<input class="input" bindinput="bindinputMobile" value="{{address.mobile}}" maxlength='{{11}}' placeholder="手机号码" />
</view>
<view class="form-item">
<text class="form-text">地址:</text>
<input class="input" value="{{address.provinceName + address.cityName + address.areaName}}" disabled="true" bindtap="chooseRegion" placeholder="省份、城市、区县" />
</view>
<view class="form-item">
<text class="form-text">详细地址:</text>
<input class="input" bindinput="bindinputAddress" value="{{address.address}}" placeholder="详细地址, 如街道、楼盘号等" />
</view>
<view class="form-default">
<text bindtap="bindIsDefault" class="default-input {{address.isDefault == 1 ? 'selected' : ''}}">设为默认地址</text>
</view>
</view>
<view class="btns">
<button class="save btn" bindtap="saveAddress">保存</button>
<button class="cannel btn" bindtap="cancelAddress">删除地址</button>
</view>
<view class="region-select" wx:if="{{openSelectRegion}}">
<view class="hd">
<view class="region-selected">
<view class="item {{item.id == 0 ? 'disabled' : ''}} {{(regionType -1) === index ? 'selected' : ''}}" bindtap="selectRegionType" data-region-type-index="{{index}}" wx:for="{{selectRegionList}}" wx:key="id">{{item.name}}</view>
</view>
<view class="done {{selectRegionDone ? '' : 'disabled'}}" bindtap="doneSelectRegion">确定</view>
</view>
<view class="bd">
<scroll-view scroll-y class="region-list">
<view class="item {{item.selected ? 'selected' : ''}}" bindtap="selectRegion" data-region-index="{{index}}" wx:for="{{regionList}}" wx:key="id">{{item.name}}</view>
</scroll-view>
</view>
</view>
</view>
<view class="bg-mask" bindtap="cancelSelectRegion" wx:if="{{openSelectRegion}}"></view>
\ No newline at end of file
page {
height: 100%;
background: #fff;
}
.add-address .add-form {
background: #fff;
width: 100%;
height: auto;
overflow: hidden;
}
.add-address .form-item {
height: 116rpx;
padding-left: 31.25rpx;
border-bottom: 1px solid #d9d9d9;
display: flex;
align-items: center;
padding-right: 31.25rpx;
}
.form-text {
width: 160rpx;
line-height: 116rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.add-address .input {
flex: 1;
height: 44rpx;
line-height: 44rpx;
overflow: hidden;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-top: 5rpx;
}
.add-address .form-default {
height: 96rpx;
background: #fff;
padding-top: 28rpx;
font-size: 28rpx;
}
.default-input {
margin: 0 auto;
display: block;
width: 240rpx;
height: 40rpx;
padding-left: 50rpx;
line-height: 40rpx;
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/sprites/checkbox-sed825af9d3-a6b8540d42.png) 1rpx -448rpx no-repeat;
background-size: 38rpx 486rpx;
font-size: 28rpx;
}
.default-input.selected {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NzEzQ0RFRUY0QzlBMTFFOTgzQzZGMzdBNUYyOUVBOUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NzEzQ0RFRjA0QzlBMTFFOTgzQzZGMzdBNUYyOUVBOUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3MTNDREVFRDRDOUExMUU5ODNDNkYzN0E1RjI5RUE5RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3MTNDREVFRTRDOUExMUU5ODNDNkYzN0E1RjI5RUE5RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PnnPqFsAAAJOSURBVHjaxJjNSsNAEMen6ycKgq0f+AEV9KIPoFDRkyAeChVvPkB71Afw6APUo30Ab2LAQxE9WQz4AoLSQ4uCqFjFkx8YnSkTaWNNNsmu+cPQpJ3u/pid7Mwmdj0wCz7VgTaFtoC2gpZx/G6gFdFKaGW0D7fBxh/Om+7bfYAk0fItAJzKOHwIcBOtKjOJkPCJo52hVSRg/gKs8BjxsEBZtEe0FIRXisfKBgGi7w/QdkG9dnlsIQskOCEzoE8ZnkPIAO0rWiKZJdz3AspqjsyvSN0MzjXlVKxhH4pz0kWhBO5HNWeEDiE6HTqXLPlPefNnPuHSJRuB8hC98nYOUW161z3b8Ole/fNucd3NrVNwodSq0csj6JielHGdaueqrU2N1dwjOqQFwS2ENlm15/onJq2M+wrl0JcOkJGLIrQNxv3AyLUf3UspGL06hrGbEvSup+v3sjCfDzVfMLL9EIj+Poh1dUL/zha0DSVcoRphbmf8Z4MU0NPG9s+1G1RYGBvIcHN4PTHh8/7RE0oFDLEIbsghKFTP2rIqGFKRnrJpvLiQ8aaIEATB2Pp6e6/nlwIY0ozgo4qUWkWKYAhKAQypLPjcZASBIhDr6aUJMIQM3NU/7AYtyUeVKDWBQFX7sadDnBkhjEkwzn0oHSFQutXGSD1tLgKYnN1Pt9qpC34SXFEiF7xKx9o/5ZPJc3nWMoubNp2RMngOS7a4kuOqppzK8dhWkGpP65tQtIQmj1UI237QEzBPG1fAZTT4v/M8lqv8vEGrcqiVvtJz6luAAQCWxM77mAW5gAAAAABJRU5ErkJggg==) no-repeat;
background-size: 38rpx 38rpx;
}
.add-address .btns {
overflow: hidden;
width: 400rpx;
margin: 0 auto;
}
.add-address .cannel, .add-address .save {
height: 70rpx;
text-align: center;
line-height: 70rpx;
font-size: 28rpx;
color: #fff;
border: none;
border-radius:35px;
font-family:PingFangSC-Regular;
font-weight:400;
}
.add-address .cannel {
background: #fff;
color: #FF1B40;
border: 1rpx solid #FF1B40;
box-sizing:border-box;
margin-top: 28rpx;
}
.add-address .save {
background:#FF1B40;
}
.btn::after {
border: none;
border-radius: 0%;
}
.region-select {
width: 100%;
height: 600rpx;
background: #fff;
position: fixed;
z-index: 10;
left: 0;
bottom: 0;
}
.region-select .hd {
height: 108rpx;
width: 100%;
border-bottom: 1px solid #f4f4f4;
padding: 46rpx 30rpx 0 30rpx;
}
.region-select .region-selected {
float: left;
height: 60rpx;
display: flex;
}
.region-select .region-selected .item {
max-width: 140rpx;
margin-right: 30rpx;
text-align: left;
line-height: 60rpx;
height: 100%;
color: #333;
font-size: 28rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.region-select .region-selected .item.disabled {
color: #999;
}
.region-select .region-selected .item.selected {
color: #b4282d;
}
.region-select .done {
float: right;
height: 60rpx;
width: 60rpx;
border: none;
background: #fff;
line-height: 60rpx;
text-align: center;
color: #333;
font-size: 28rpx;
}
.region-select .done.disabled {
color: #999;
}
.region-select .bd {
height: 492rpx;
width: 100%;
padding: 0 30rpx;
}
.region-select .region-list {
height: 492rpx;
}
.region-select .region-list .item {
width: 100%;
height: 104rpx;
line-height: 104rpx;
text-align: left;
color: #333;
font-size: 28rpx;
}
.region-select .region-list .item.selected {
color: #b4282d;
}
.bg-mask {
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.4);
position: fixed;
top: 0;
left: 0;
z-index: 8;
}
var api = require('../../../config/api.js');
import WeCropper from '../../../components/xz-cropper/xz-cropper.js'
const device = wx.getSystemInfoSync() // 获取设备信息
const width = device.windowWidth // 示例为一个与屏幕等宽的正方形裁剪框
const height = width
Page({
data: {
cropperOpt: {
id: 'cropper', // 用于手势操作的canvas组件标识符
targetId: 'targetCropper', // 用于用于生成截图的canvas组件标识符
pixelRatio: device.pixelRatio, // 传入设备像素比
width, // 画布宽度
height, // 画布高度
scale: 2.5, // 最大缩放倍数
zoom: 8, // 缩放系数
cut: {
x: (width - 200) / 2, // 裁剪框x轴起点
y: (width - 200) / 2, // 裁剪框y轴期起点
width: 200, // 裁剪框宽度
height: 200 // 裁剪框高度
},
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
let that = this;
const {
cropperOpt
} = this.data;
let _src = JSON.parse(options.data).path;
if (_src) {
cropperOpt.src = _src;
console.log(cropperOpt.src)
this.cropper = new WeCropper(cropperOpt)
.on('ready', (rtx) => {
console.log(`wecropper is ready for work!`)
}).on('beforeImageLoad', (ctx) => {
console.log(`before picture loaded, i can do something`)
console.log(`current canvas context:`, ctx)
wx.showToast({
title: '上传中',
icon: 'loading',
duration: 20000
})
})
.on('imageLoad', (ctx) => {
console.log(`picture loaded`)
console.log(`current canvas context:`, ctx)
wx.hideToast()
})
.on('beforeDraw', (ctx, instance) => {
console.log(`before canvas draw,i can do something`)
console.log(`current canvas context:`, ctx)
});
}
console.log(_src)
},
/**
* 点击完成的回调
* 完成截图,回传图片到上一页
*/
complete() {
let that = this;
this.cropper.getCropperImage((avatar) => {
let _tempData = {
// ?id=${wx.getStorageSync("userId")}&openid=${wx.getStorageSync("openid")}&operFlag=上传头像
url: api.UploadPortrait,
filePath: avatar,
name: 'file',
header: {
'Content-Type': 'multipart/form-data',
'X-Litemall-Token': wx.getStorageSync('token')
}
}
that.uploadImg(_tempData);
})
},
touchStart(e) {
this.cropper.touchStart(e)
},
touchMove(e) {
this.cropper.touchMove(e)
},
touchEnd(e) {
this.cropper.touchEnd(e)
},
/**
* 取消截图
*/
cancel(event) {
wx.navigateBack()
},
reset(event) {
},
/**
* 上传头像
*/
uploadImg(data) {
let _this = this;
wx.showLoading({
title: '头像上传中!', //提示的内容,
mask: true, //显示透明蒙层,防止触摸穿透,
success: res => {}
});
console.log(data.filePath)
wx.uploadFile({
url: data.url,
filePath: data.filePath,
name: data.name,
header: data.header,
formData: {
openid: wx.getStorageSync("openid"),
operFlag: '上传头像'
},
success(res) {
let _data = JSON.parse(res.data).data;
console.log(_data)
wx.setStorage({
key: 'userData',
data: JSON.stringify(_data)
})
// 将图片回传到上一页
var pages = getCurrentPages();
if (pages.length > 1) {
wx.hideLoading();
var prePage = pages[pages.length - 2];
console.log(_data.avatar);
prePage.setData({
'messages.avatar': _data.avatar
})
}
wx.navigateBack()
},
file(err) {
wx.showToast({
title: err.message,
icon: 'none'
})
}
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
// app.globalData.editorMessageStorage = true;
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
// app.globalData.editorMessageStorage = false;
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
}
})
\ No newline at end of file
{
"navigationBarTitleText": "个人头像"
}
\ No newline at end of file
<import src="/components/xz-cropper/xz-cropper.wxml" />
<view class="cropper-wrapper">
<template is="xz-cropper" data="{{...cropperOpt}}" />
</view>
<view class='bottom'>
<view class='button' bindtap='cancel'>取消</view>
<!-- <view class='button' bindtap='reset'>撤销</view> -->
<view class='button' bindtap='complete'>完成</view>
</view>
\ No newline at end of file
.cropper-wrapper{
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 100vh;
background-color: black;
}
.bottom{
width: 100%;
box-sizing: border-box;
background: black;
opacity: 0.5;
height: 120rpx;
position:fixed;
bottom: 0;
left: 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.button::after{
border: 0
}
.button{
height: 100rpx;
width: 25%;
line-height: 100rpx;
font-size: 32rpx;
color: white;
text-align: center;
opacity: 1;
}
.button:first-child{
text-align: left;
margin-left: 5%;
}
.button:last-child{
text-align: right;
margin-right: 5%;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
type: 0,
collectList: [],
page: 1,
size: 10,
totalPages: 1
},
getCollectList() {
wx.showLoading({
title: '加载中...',
});
let that = this;
util.request(api.CollectList, {
type: that.data.type,
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
that.setData({
collectList: that.data.collectList.concat(res.data.collectList),
totalPages: res.data.totalPages
});
}
wx.hideLoading();
});
},
onLoad: function(options) {
this.getCollectList();
},
onReachBottom() {
if (this.data.totalPages > this.data.page) {
this.setData({
page: this.data.page + 1
});
this.getCollectList();
} else {
wx.showToast({
title: '没有更多用户收藏了',
icon: 'none',
duration: 2000
});
return false;
}
},
onReady: function() {
},
onShow: function() {
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
openGoods(event) {
let that = this;
let index = event.currentTarget.dataset.index;
let goodsId = this.data.collectList[index].valueId;
//触摸时间距离页面打开的毫秒数
var touchTime = that.data.touchEnd - that.data.touchStart;
console.log(touchTime);
//如果按下时间大于350为长按
if (touchTime > 350) {
wx.showModal({
title: '',
content: '确定删除吗?',
success: function(res) {
if (res.confirm) {
util.request(api.CollectAddOrDelete, {
type: that.data.type,
valueId: goodsId
}, 'POST').then(function(res) {
if (res.errno === 0) {
console.log(res.data);
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 2000
});
that.data.collectList.splice(index, 1)
that.setData({
collectList: that.data.collectList
});
}
});
}
}
})
} else {
wx.navigateTo({
url: '/pages/goods/goods?id=' + goodsId,
});
}
},
//按下事件开始
touchStart: function(e) {
let that = this;
that.setData({
touchStart: e.timeStamp
})
},
//按下事件结束
touchEnd: function(e) {
let that = this;
that.setData({
touchEnd: e.timeStamp
})
},
})
\ No newline at end of file
{
"navigationBarTitleText": "我的收藏"
}
\ No newline at end of file
<view class="container">
<view class="no-collect" wx:if="{{collectList.length <= 0}}">
<view class="c">
<image src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>还没有收藏</text>
</view>
</view>
<view class="collect-list" wx:else>
<view class="item" bindtap="openGoods" bindtouchstart="touchStart" bindtouchend="touchEnd" wx:for="{{collectList}}" wx:key="id" data-index="{{index}}">
<image class="img" src="{{item.picUrl}}"></image>
<view class="info">
<view class="name">{{item.name}}</view>
<view class="subtitle">{{item.brief}}</view>
<view class="price">¥{{item.retailPrice}}</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
page {
background: #f4f4f4;
min-height: 100%;
}
.container {
background: #f4f4f4;
min-height: 100%;
width: 100%;
height: auto;
overflow: hidden;
}
.no-collect {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-collect .c {
width: 100%;
height: auto;
margin-top: 200rpx;
}
.no-collect .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
}
.no-collect .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 29rpx;
line-height: 29rpx;
text-align: center;
font-size: 29rpx;
color: #999;
}
.collect-list {
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
padding-left: 30rpx;
border-top: 1px solid #e1e1e1;
}
.item {
height: 212rpx;
width: 720rpx;
background: #fff;
padding: 30rpx 30rpx 30rpx 0;
border-bottom: 1px solid #e1e1e1;
}
.item:last-child {
border-bottom: 1px solid #fff;
}
.item .img {
float: left;
width: 150rpx;
height: 150rpx;
}
.item .info {
float: right;
width: 540rpx;
height: 150rpx;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 20rpx;
}
.item .info .name {
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.item .info .subtitle {
margin-top: 8rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.item .info .price {
margin-top: 8rpx;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
couponList: [],
code: '',
status: 0,
page: 1,
size: 10,
count: 0,
scrollTop: 0,
showPage: false
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getCouponList();
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
},
getCouponList: function() {
let that = this;
that.setData({
scrollTop: 0,
showPage: false,
couponList: []
});
util.request(api.CouponMyList, {
status: that.data.status,
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
that.setData({
scrollTop: 0,
couponList: res.data.data,
showPage: true,
count: res.data.count
});
}
});
},
bindExchange: function (e) {
this.setData({
code: e.detail.value
});
},
clearExchange: function () {
this.setData({
code: ''
});
},
goExchange: function() {
if (this.data.code.length === 0) {
util.showErrorToast("请输入兑换码");
return;
}
let that = this;
util.request(api.CouponExchange, {
code: that.data.code
}, 'POST').then(function (res) {
if (res.errno === 0) {
that.getCouponList();
that.clearExchange();
wx.showToast({
title: "领取成功",
duration: 2000
})
}
else{
util.showErrorToast(res.errmsg);
}
});
},
nextPage: function(event) {
var that = this;
if (this.data.page > that.data.count / that.data.size) {
return true;
}
that.setData({
page: that.data.page + 1
});
this.getCouponList();
},
prevPage: function(event) {
if (this.data.page <= 1) {
return false;
}
var that = this;
that.setData({
page: that.data.page - 1
});
this.getCouponList();
},
switchTab: function(e) {
this.setData({
couponList: [],
status: e.currentTarget.dataset.index,
page: 1,
size: 10,
count: 0,
scrollTop: 0,
showPage: false
});
this.getCouponList();
},
gotoHome: function() {
wx.reLaunch({
url: '/pages/index2/index2',
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "我的优惠券"
}
\ No newline at end of file
<view class="container">
<view class="h">
<view class="item {{ status == 0 ? 'active' : ''}}" bindtap="switchTab" data-index="0">
<view class="txt">未使用</view>
</view>
<view class="item {{ status == 1 ? 'active' : ''}}" bindtap="switchTab" data-index="1">
<view class="txt">已使用</view>
</view>
<view class="item {{ status == 2 ? 'active' : ''}}" bindtap="switchTab" data-index="2">
<view class="txt">已过期</view>
</view>
</view>
<view class="b">
<view class="coupon-form" wx:if="{{status == 0}}">
<view class="input-box">
<input class="coupon-sn" placeholder="请输入优惠码" value="{{code}}" bindinput="bindExchange"/>
<image class="clear-icon" wx:if="{{ code.length > 0 }}" src="/static/images/clear_input.png" catchtap="clearExchange"></image>
</view>
<view class="add-btn" bindtap='goExchange'>兑换</view>
</view>
<!-- <view class="help" wx:if="{{status == 0}}">使用说明</view> -->
<scroll-view class="coupon-list" scroll-y="true" scroll-top="{{scrollTop}}">
<view class="item {{ status == 0 ? 'active' : ''}}" wx:for="{{couponList}}" wx:for-index="index" wx:for-item="item" wx:key="id">
<image class='coupon-bg' src="{{status == 0?'/static/images/coupon-bg.png':'/static/images/coupon-bg-gray.png'}}"></image>
<view class='coupon-main'>
<view class='coupon-main-left'>
<view class="discount">
<text class="discount-text {{status!=0?'discount-text-gray':''}}">¥</text>
<text class="discount-num {{status!=0?'discount-text-gray':''}}">{{item.discount}}</text>
</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class='coupon-main-right'>
<view class="name">{{item.name}}</view>
<view class="time">{{item.startTime}} - </view>
<view class="time">{{item.endTime}}<text wx:if="{{status == 1}}" class="use-out">(已使用)</text><text wx:if="{{status == 2}}" class="use-out">(已过期)</text></view>
<view class='use' wx:if="{{status == 0}}" bindtap='gotoHome'>
去使用
</view>
</view>
</view>
<!-- <view class="tag">{{item.tag}}</view>
<view class="content">
<view class="left">
<view class="discount">{{item.discount}}元</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class="right">
<view class="name">{{item.name}}</view>
<view class="time"> 有效期:{{item.startTime}} - {{item.endTime}}</view>
</view>
</view>
<view class="condition">
<text class="txt">{{item.desc}}</text>
<image src="{{item.pic}}" class="icon"></image>
</view> -->
</view>
<view class="page" wx:if="{{showPage && page>1}}">
<view class="prev {{ page <= 1 ? 'disabled' : ''}}" bindtap="prevPage">上一页</view>
<view class="next {{ (count / size) < page ? 'disabled' : ''}}" bindtap="nextPage">下一页</view>
</view>
</scroll-view>
</view>
</view>
\ No newline at end of file
page {
background: #fff;
min-height: 100%;
}
.container {
background: #fff;
min-height: 100%;
padding-top: 30rpx;
}
.container .h {
position: fixed;
left: 0;
top: 0;
z-index: 2000;
width: 100%;
display: flex;
background: #fff;
height: 84rpx;
border-top: 1px solid rgba(0, 0, 0, 0.15);
}
.container .h .item {
display: inline-block;
height: 82rpx;
width: 50%;
padding: 0 15rpx;
text-align: center;
}
.container .h .item .txt {
display: inline-block;
height: 82rpx;
padding: 0 20rpx;
line-height: 82rpx;
color: #333;
font-size: 30rpx;
width: 170rpx;
}
.container .h .item.active .txt {
color: #E31436;
}
.container .b {
margin-top: 85rpx;
height: auto;
}
.container .b .coupon-form {
height: 110rpx;
width: 100%;
background: #fff;
padding-left: 30rpx;
padding-right: 30rpx;
padding-top: 20rpx;
display: flex;
}
.container .b .input-box {
flex: 1;
height: 70rpx;
color: #333;
font-size: 24rpx;
background: #fff;
position: relative;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4rpx;
margin-right: 30rpx;
}
.container .b .input-box .coupon-sn {
position: absolute;
top: 10rpx;
left: 30rpx;
height: 50rpx;
width: 100%;
color: #000;
line-height: 50rpx;
font-size: 24rpx;
}
.container .b .clear-icon {
position: absolute;
top: 10rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.container .b .add-btn {
height: 70rpx;
border: none;
width: 168rpx;
background: #E31436;
border-radius: 0;
line-height: 70rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
}
.container .b .add-btn.disabled {
background: #ccc;
}
.container .b .help {
height: 72rpx;
line-height: 72rpx;
text-align: right;
padding-right: 30rpx;
background: url(https://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/couponHelp-4768607555.png) 590rpx center no-repeat;
background-size: 28rpx;
color: #999;
font-size: 24rpx;
}
.container .b .coupon-list {
width: 750rpx;
height: 100%;
overflow: hidden;
}
.container .b .item {
position: relative;
height: 200rpx;
margin-left: 30rpx;
margin-right: 30rpx;
}
.coupon-bg {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 0;
z-index: 100;
}
.coupon-main {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
overflow: hidden;
}
.coupon-main-left {
float: left;
}
.discount {
width: 204rpx;
display: flex;
align-items:flex-end;
justify-content: center;
margin-top: 30rpx;
}
.discount-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
color:rgba(255,34,70,1);
display: block;
margin-bottom: 15rpx;
margin-right: 5rpx;
}
.discount-num {
font-size:60rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(255,34,70,1);
}
.discount-text-gray {
color: #333333;
}
.min {
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
text-align: center;
}
.coupon-main-right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.name {
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 37rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.time {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
margin-left: 37rpx;
color:rgba(110,110,110,1);
}
.use-out {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.use {
width: 126rpx;
border-radius:50rpx;
border:1rpx solid #FF1B40;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color:#FF1B40;
text-align: center;
line-height: 50rpx;
position: absolute;
right: 40rpx;
top: 70rpx;
}
.container .b .page {
width: 750rpx;
height: 108rpx;
background: #fff;
margin-bottom: 20rpx;
}
.container .b .page view {
height: 108rpx;
width: 50%;
float: left;
font-size: 29rpx;
color: #333;
text-align: center;
line-height: 108rpx;
}
.container .b .page .prev {
border-right: 1px solid #d9d9d9;
}
.container .b .page .disabled {
color: #ccc;
}
\ No newline at end of file
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
couponList: [],
cartId: 0,
couponId: 0,
grouponLinkId: 0,
scrollTop: 0
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
// 页面显示
wx.showLoading({
title: '加载中...',
});
try {
var cartId = wx.getStorageSync('cartId');
if (!cartId) {
cartId = 0;
}
var couponId = wx.getStorageSync('couponId');
if (!couponId) {
couponId = 0;
}
var grouponRulesId = wx.getStorageSync('grouponRulesId');
if (!grouponRulesId) {
grouponRulesId = 0;
}
this.setData({
cartId: cartId,
couponId: couponId,
grouponRulesId: grouponRulesId
});
} catch (e) {
// Do something when catch error
console.log(e);
}
this.getCouponList();
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
getCouponList: function () {
let that = this;
that.setData({
couponList: []
});
// 页面渲染完成
wx.showToast({
title: '加载中...',
icon: 'loading',
duration: 2000
});
util.request(api.CouponSelectList, {
cartId: that.data.cartId,
grouponRulesId: that.data.grouponRulesId,
}).then(function (res) {
if (res.errno === 0) {
that.setData({
couponList: res.data
});
}
wx.hideToast();
});
},
selectCoupon: function (e) {
try {
wx.setStorageSync('couponId', e.currentTarget.dataset.id);
} catch (error) {
}
wx.navigateBack();
},
unselectCoupon: function() {
// 如果优惠券ID设置-1,则表示订单不使用优惠券
try {
wx.setStorageSync('couponId', -1);
} catch (error) {
}
wx.navigateBack();
}
})
\ No newline at end of file
{
"navigationBarTitleText": "选择优惠券"
}
\ No newline at end of file
<view class="container">
<scroll-view class="coupon-list" scroll-y="true" scroll-top="{{scrollTop}}">
<view class="unselect" bindtap='unselectCoupon'>不选择优惠券</view>
<view class="item" wx:for="{{couponList}}" wx:for-index="index" wx:for-item="item" wx:key="id" bindtap="selectCoupon" data-id="{{item.id}}">
<!-- <view class="tag">{{item.tag}}</view>
<view class="content">
<view class="left">
<view class="discount">{{item.discount}}元</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class="right">
<view class="name">{{item.name}}</view>
<view class="time"> 有效期:{{item.startTime}} - {{item.endTime}}</view>
</view>
</view>
<view class="condition">
<text class="txt">{{item.desc}}</text>
<image src="{{item.pic}}" class="icon"></image>
</view> -->
<image class='coupon-bg' src="/static/images/coupon-bg.png"></image>
<view class="content">
<view class="left">
<view class="discount">
<text class="discount-text">¥</text>
<text class="discount-num">{{item.discount}}</text>
</view>
<view class="min"> 满{{item.min}}元使用</view>
</view>
<view class='coupon-main-right'>
<view class="name">{{item.name}}</view>
<view class="time" wx:if="{{item.startTime}}">{{item.startTime}} - {{item.endTime}}</view>
<view class="time" wx:if="{{item.days}}">有效期:{{item.days}}天</view>
<view class="time" wx:if="{{item.desc}}">{{item.desc}}</view>
</view>
</view>
</view>
</scroll-view>
</view>
\ No newline at end of file
page {
background: #f4f4f4;
min-height: 100%;
}
.container {
background: #f4f4f4;
min-height: 100%;
padding-top: 30rpx;
}
.coupon-list {
width: 750rpx;
height: 100%;
overflow: hidden;
}
.unselect {
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:35rpx;
border: none;
text-align: center;
margin: 30rpx auto;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(255,255,255,1);
}
.item {
position: relative;
height: 200rpx;
width: 698rpx;
margin-bottom: 10rpx;
margin-left: 30rpx;
margin-right: 30rpx;
padding-top: 30rpx;
}
.coupon-bg {
width: 689rpx;
height: 193rpx;
position: absolute;
top: 0;
left: 4.5rpx;
z-index: 200;
}
.content {
width: 689rpx;
height: 193rpx;
display: flex;
flex-direction: row;
position: absolute;
top: 0;
left: 0;
z-index: 1000;
}
.content .left {
width: 204rpx;
float: left;
}
.discount {
width: 204rpx;
display: flex;
align-items:flex-end;
justify-content: center;
margin-top: 30rpx;
}
.discount-text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:bold;
color:rgba(255,34,70,1);
display: block;
margin-bottom: 15rpx;
margin-right: 5rpx;
}
.discount-num {
font-size:60rpx;
font-family:PingFangSC-Semibold;
font-weight:600;
color:rgba(255,34,70,1);
}
.min {
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
text-align: center;
}
.content .right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.coupon-main-right {
width: 484rpx;
height: 193rpx;
float: right;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
}
.name {
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
margin-left: 37rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
}
.time {
font-size:20rpx;
font-family:PingFangSC-Regular;
font-weight:400;
margin-left: 37rpx;
color:rgba(110,110,110,1);
}
.use {
width: 126rpx;
border-radius:50rpx;
background: #FF1B40;
font-size:24rpx;
font-family:PingFangSC-Light;
font-weight:300;
color: #fff;
text-align: center;
line-height: 50rpx;
position: absolute;
right: 40rpx;
top: 70rpx;
}
.condition {
position: absolute;
width: 100%;
bottom: 0;
left: 0;
height: 78rpx;
background: rgba(0, 0, 0, 0.08);
padding: 24rpx 40rpx;
display: flex;
flex-direction: row;
}
.condition .txt {
display: block;
height: 30rpx;
flex: 1;
overflow: hidden;
font-size: 24rpx;
line-height: 30rpx;
color: #fff;
}
.condition .icon {
margin-left: 30rpx;
width: 24rpx;
height: 24rpx;
}
\ No newline at end of file
var util = require('../../../utils/util.js');
var check = require('../../../utils/check.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
array: ['请选择反馈类型', '商品相关', '功能异常', '优化建议', '其他'],
index: 0,
content: '',
contentLength: 0,
mobile: '',
hasPicture: false,
picUrls: [],
files: []
},
chooseImage: function(e) {
if (this.data.files.length >= 5) {
util.showErrorToast('只能上传五张图片')
return false;
}
var that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function(res) {
that.setData({
files: that.data.files.concat(res.tempFilePaths)
});
that.upload(res);
}
})
},
upload: function(res) {
var that = this;
const uploadTask = wx.uploadFile({
url: api.StorageUpload,
filePath: res.tempFilePaths[0],
name: 'file',
success: function(res) {
var _res = JSON.parse(res.data);
if (_res.errno === 0) {
var url = _res.data.url
that.data.picUrls.push(url)
that.setData({
hasPicture: true,
picUrls: that.data.picUrls
})
}
},
fail: function(e) {
wx.showModal({
title: '错误',
content: '上传失败',
showCancel: false
})
},
})
uploadTask.onProgressUpdate((res) => {
console.log('上传进度', res.progress)
console.log('已经上传的数据长度', res.totalBytesSent)
console.log('预期需要上传的数据总长度', res.totalBytesExpectedToSend)
})
},
previewImage: function(e) {
wx.previewImage({
current: e.currentTarget.id, // 当前显示图片的http链接
urls: this.data.files // 需要预览的图片http链接列表
})
},
bindPickerChange: function(e) {
this.setData({
index: e.detail.value
});
},
mobileInput: function(e) {
this.setData({
mobile: e.detail.value
});
},
contentInput: function(e) {
this.setData({
contentLength: e.detail.cursor,
content: e.detail.value,
});
},
clearMobile: function(e) {
this.setData({
mobile: ''
});
},
submitFeedback: function(e) {
if (!app.globalData.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
let that = this;
if (that.data.index == 0) {
util.showErrorToast('请选择反馈类型');
return false;
}
if (that.data.content == '') {
util.showErrorToast('请输入反馈内容');
return false;
}
if (that.data.mobile == '') {
util.showErrorToast('请输入手机号码');
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
this.setData({
mobile: ''
});
util.showErrorToast('请输入手机号码');
return false;
}
wx.showLoading({
title: '提交中...',
mask: true,
success: function() {
}
});
util.request(api.FeedbackAdd, {
mobile: that.data.mobile,
feedType: that.data.array[that.data.index],
content: that.data.content,
hasPicture: that.data.hasPicture,
picUrls: that.data.picUrls
}, 'POST').then(function(res) {
wx.hideLoading();
if (res.errno === 0) {
wx.showToast({
title: '感谢您的反馈!',
icon: 'success',
duration: 2000,
complete: function() {
that.setData({
index: 0,
content: '',
contentLength: 0,
mobile: '',
hasPicture: false,
picUrls: [],
files: []
});
}
});
} else {
util.showErrorToast(res.errmsg);
}
});
},
onLoad: function(options) {
},
onReady: function() {
},
onShow: function() {
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "意见反馈"
}
\ No newline at end of file
<view class="container">
<picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">
<view class="picker">
<view class="fb-type">
<view class="type-label">{{array[index]}}</view>
<image class="type-icon" src="http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/pickerArrow-a8b918f05f.png"></image>
</view>
</view>
</picker>
<view class="fb-body">
<textarea class="content" placeholder="对我们网站、商品、服务,你还有什么建议吗?你还希望在商城上买到什么?请告诉我们..." bindinput="contentInput" maxlength="500" auto-focus="true" value="{{content}}" />
<view class="weui-uploader__files" id="uploaderFiles">
<block wx:for="{{files}}" wx:key="*this">
<view class="weui-uploader__file" bindtap="previewImage" id="{{item}}">
<image class="weui-uploader__img" src="{{item}}" mode="aspectFill" />
</view>
</block>
<view class="weui-uploader__input-box" wx:if="{{ files.length < 5 }}">
<view class="weui-uploader__input" bindtap="chooseImage"></view>
</view>
</view>
<view class="text-count">{{contentLength}}/500</view>
</view>
<view class="fb-mobile">
<view class="label">手机号码</view>
<view class="mobile-box">
<input class="mobile" maxlength="11" type="number" placeholder="方便我们与你联系" bindinput="mobileInput" value="{{mobile}}" />
<image class="clear-icon" src="/static/images/clear_input.png" wx:if="{{ mobile.length > 0 }}" catchtap="clearMobile"></image>
</view>
</view>
<view class="fb-btn" bindtap="submitFeedback">提交</view>
</view>
\ No newline at end of file
page {
background: #f4f4f4;
min-height: 100%;
}
.container {
background: #f4f4f4;
min-height: 100%;
padding-top: 30rpx;
}
.fb-type {
height: 104rpx;
width: 100%;
background: #fff;
margin-bottom: 20rpx;
display: flex;
flex-direction: row;
align-items: center;
padding-left: 30rpx;
padding-right: 30rpx;
}
.fb-type .type-label {
height: 36rpx;
flex: 1;
color: #333;
font-size: 28rpx;
}
.fb-type .type-icon {
height: 36rpx;
width: 36rpx;
}
.fb-body {
width: 100%;
background: #fff;
height: 600rpx;
padding: 18rpx 30rpx 64rpx 30rpx;
}
.fb-body .content {
width: 100%;
height: 400rpx;
color: #333;
line-height: 40rpx;
font-size: 28rpx;
}
.weui-uploader__files {
width: 100%;
}
.weui-uploader__file {
float: left;
margin-right: 9px;
margin-bottom: 9px;
}
.weui-uploader__img {
display: block;
width: 50px;
height: 50px;
}
.weui-uploader__input-box {
float: left;
position: relative;
margin-right: 9px;
margin-bottom: 9px;
width: 50px;
height: 50px;
border: 1px solid #d9d9d9;
}
.weui-uploader__input-box:after, .weui-uploader__input-box:before {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #d9d9d9;
}
.weui-uploader__input-box:before {
width: 2px;
height: 39.5px;
}
.weui-uploader__input-box:after {
width: 39.5px;
height: 2px;
}
.weui-uploader__input-box:active {
border-color: #999;
}
.weui-uploader__input-box:active:after, .weui-uploader__input-box:active:before {
background-color: #999;
}
.weui-uploader__input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.fb-body .text-count {
line-height: 30rpx;
float: right;
color: #666;
font-size: 24rpx;
}
.fb-mobile {
height: 162rpx;
width: 100%;
}
.fb-mobile .label {
height: 58rpx;
width: 100%;
padding-top: 14rpx;
padding-bottom: 11rpx;
color: #7f7f7f;
font-size: 24rpx;
padding-left: 30rpx;
padding-right: 30rpx;
line-height: 33rpx;
}
.fb-mobile .mobile-box {
height: 104rpx;
width: 100%;
color: #333;
padding-left: 30rpx;
padding-right: 30rpx;
font-size: 24rpx;
background: #fff;
position: relative;
}
.fb-mobile .mobile {
position: absolute;
top: 27rpx;
left: 30rpx;
height: 50rpx;
width: 100%;
color: #333;
line-height: 50rpx;
font-size: 24rpx;
}
.fb-mobile .clear-icon {
position: absolute;
top: 27rpx;
right: 30rpx;
width: 48rpx;
height: 48rpx;
z-index: 2;
}
.fb-btn {
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:40rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(255,255,255,1);
text-align: center;
position: fixed;
bottom: 60rpx;
left: 50%;
z-index: 1000;
transform: translateX(-50%);
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
footprintList: [],
page: 1,
size: 10,
totalPages: 1
},
getFootprintList() {
wx.showLoading({
title: '加载中...',
});
let that = this;
util.request(api.FootprintList, {
page: that.data.page,
size: that.data.size
}).then(function(res) {
if (res.errno === 0) {
let f1 = that.data.footprintList;
let f2 = res.data.footprintList;
for (let i = 0; i < f2.length; i++) {
let last = f1.length - 1;
if (last >= 0 && f1[last][0].addTime === f2[i].addTime) {
f1[last].push(f2[i]);
} else {
let tmp = [];
tmp.push(f2[i])
f1.push(tmp);
}
}
that.setData({
footprintList: f1,
totalPages: res.data.totalPages
});
}
wx.hideLoading();
});
},
deleteItem(event) {
let that = this;
let index = event.currentTarget.dataset.index;
let iindex = event.currentTarget.dataset.iindex;
let footprintId = this.data.footprintList[index][iindex].id;
let goodsId = this.data.footprintList[index][iindex].goodsId;
var touchTime = that.data.touchEnd - that.data.touchStart;
console.log(touchTime);
//如果按下时间大于350为长按
if (touchTime > 350) {
wx.showModal({
title: '',
content: '要删除所选足迹?',
success: function(res) {
if (res.confirm) {
util.request(api.FootprintDelete, {
id: footprintId
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '删除成功',
icon: 'success',
duration: 2000
});
that.data.footprintList[index].splice(iindex, 1)
if (that.data.footprintList[index].length == 0) {
that.data.footprintList.splice(index, 1)
}
that.setData({
footprintList: that.data.footprintList
});
}
});
}
}
});
} else {
wx.navigateTo({
url: '/pages/goods/goods?id=' + goodsId,
});
}
},
onLoad: function(options) {
this.getFootprintList();
},
onPullDownRefresh() {
this.getFootprintList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
onReachBottom() {
if (this.data.totalPages > this.data.page) {
this.setData({
page: this.data.page + 1
});
this.getFootprintList();
} else {
wx.showToast({
title: '没有更多用户足迹了',
icon: 'none',
duration: 2000
});
return false;
}
},
onReady: function() {
},
onShow: function() {
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
//按下事件开始
touchStart: function(e) {
let that = this;
that.setData({
touchStart: e.timeStamp
})
console.log(e.timeStamp + '- touchStart')
},
//按下事件结束
touchEnd: function(e) {
let that = this;
that.setData({
touchEnd: e.timeStamp
})
console.log(e.timeStamp + '- touchEnd')
},
})
\ No newline at end of file
{
"navigationBarTitleText": "我的足迹"
}
\ No newline at end of file
<view class="container">
<view class="no-footprint" wx:if="{{footprintList.length <= 0}}">
<view class="c">
<image src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>没有浏览足迹</text>
</view>
</view>
<view class="footprint" wx:if="{{footprintList.length > 0}}">
<view class="day-item" wx:for="{{footprintList}}" wx:key="*this" wx:for-index="index">
<view class="day-hd" wx:if="{{item.length > 0}}">{{item[0].addTime}}</view>
<view class="day-list" wx:if="{{item.length > 0}}">
<view class="item" data-index="{{index}}" data-iindex="{{iindex}}" bindtouchstart="touchStart" bindtouchend="touchEnd" bindtap="deleteItem" wx:for="{{item}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="id">
<image class="img" src="{{iitem.picUrl}}"></image>
<view class="info">
<view class="name">{{iitem.name}}</view>
<view class="subtitle">{{iitem.brief}}</view>
<view class="price">¥{{iitem.retailPrice}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
page {
background: #f4f4f4;
min-height: 100%;
}
.container {
background: #f4f4f4;
min-height: 100%;
width: 100%;
height: auto;
overflow: hidden;
}
.no-footprint {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-footprint .c {
width: 100%;
height: auto;
margin-top: 200rpx;
}
.no-footprint .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
}
.no-footprint .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 29rpx;
line-height: 29rpx;
text-align: center;
font-size: 29rpx;
color: #999;
}
.footprint {
height: auto;
overflow: hidden;
width: 100%;
border-top: 1px solid #e1e1e1;
}
.day-item {
height: auto;
overflow: hidden;
width: 100%;
margin-bottom: 20rpx;
}
.day-hd {
height: 94rpx;
width: 100%;
line-height: 94rpx;
background: #fff;
padding-left: 30rpx;
color: #333;
font-size: 28rpx;
}
.day-list {
width: 100%;
height: auto;
overflow: hidden;
background: #fff;
padding-left: 30rpx;
border-top: 1px solid #e1e1e1;
}
.item {
height: 212rpx;
width: 720rpx;
background: #fff;
padding: 30rpx 30rpx 30rpx 0;
border-bottom: 1px solid #e1e1e1;
}
.item:last-child {
border-bottom: 1px solid #fff;
}
.item .img {
float: left;
width: 150rpx;
height: 150rpx;
}
.item .info {
float: right;
width: 540rpx;
height: 150rpx;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 20rpx;
}
.item .info .name {
font-size:30rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.item .info .subtitle {
margin-top: 8rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.item .info .price {
margin-top: 8rpx;
line-height: 40rpx;
font-size:36rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:#FF1B40;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var user = require('../../../utils/user.js');
var app = getApp();
Page({
data: {
userInfo: {
nickName: '点击登录',
avatarUrl: 'http://yanxuan.nosdn.127.net/8945ae63d940cc42406c3f67019c5cb6.png'
},
order: {
unpaid: 0,
unship: 0,
unrecv: 0,
uncomment: 0
},
owner: {
avatar: '',
collection: 0,
coupon: 0,
integral: 0,
name: '',
gyId: ''
},
hasLogin: false,
loginPhoneShow: false
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
//获取用户的登录信息
if (app.globalData.hasLogin) {
let userInfo = wx.getStorageSync('userInfo');
this.setData({
userInfo: userInfo,
hasLogin: true
});
this.getUserMsg();
}
this.getSetUp();
},
onReady: function() {
},
onShow: function() {
console.log(5)
},
getUserMsg() {
let that = this;
util.request(api.UserIndex).then(function (res) {
if (res.errno === 0) {
that.setData({
order: res.data.order,
owner: res.data.owner
});
}
});
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
goSet() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/setUp/setUp"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
},
goLogin() {
if (!this.data.hasLogin) {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
},
goOrder() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/order/order"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
}
},
goOrderIndex(e) {
if (this.data.hasLogin) {
let tab = e.currentTarget.dataset.index
let route = e.currentTarget.dataset.route
try {
wx.setStorageSync('tab', tab);
} catch (e) {
}
wx.navigateTo({
url: route,
success: function(res) {},
fail: function(res) {},
complete: function(res) {},
})
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goCoupon() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/couponList/couponList"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goGroupon() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/groupon/myGroupon/myGroupon"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goCollect() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/collect/collect"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goFeedback(e) {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/feedback/feedback"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goFootprint() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/footprint/footprint"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
goAddress() {
if (this.data.hasLogin) {
wx.navigateTo({
url: "/pages/ucenter/address/address"
});
} else {
wx.navigateTo({
url: "/pages/auth/login/login"
});
};
},
bindPhoneNumber: function(e) {
let that = this;
if (e.detail.errMsg !== "getPhoneNumber:ok") {
// 拒绝授权
return;
}
if (!this.data.hasLogin) {
wx.showToast({
title: '绑定失败:请先登录',
icon: 'none',
duration: 2000
});
return;
}
util.request(api.AuthBindPhone, {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
}, 'POST').then(function(res) {
if (res.errno === 0) {
that.setData({
loginPhoneShow: false
})
that.getUserMsg();
wx.showToast({
title: '绑定手机号成功',
icon: 'success',
duration: 2000
});
}
});
},
getSetUp() {
let that = this;
util.request(api.UserGetSetUp, {}, "POST").then(function (res) {
console.log(">>>>,",res)
if (res.errno === 0) {
if (!res.data || !res.data.tel){
that.setData({
loginPhoneShow: true
})
}
} else if (res.errno === 502) {
that.setData({
loginPhoneShow: false
})
} else {
that.setData({
loginPhoneShow: true
})
}
});
},
goAfterSale: function() {
wx.showToast({
title: '目前不支持',
icon: 'none',
duration: 2000
});
},
aboutUs: function() {
wx.navigateTo({
url: '/pages/about/about'
});
},
exitLogin: function() {
wx.showModal({
title: '',
confirmColor: '#b4282d',
content: '退出登录?',
success: function(res) {
if (!res.confirm) {
return;
}
util.request(api.AuthLogout, {}, 'POST');
app.globalData.hasLogin = false;
wx.removeStorageSync('token');
wx.removeStorageSync('userInfo');
wx.reLaunch({
url: '/pages/index2/index2'
});
}
})
}
})
\ No newline at end of file
{
"backgroundColor": "#f4f4f4",
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": false
}
\ No newline at end of file
<view class="container">
<view class="profile-info" bindtap="goLogin">
<image class="profile-background" src='/static/images/ucenter-top-bg.png'></image>
<view class="info-count">
<view class='info-set' bindtap="goSet">
<image class='info-set-icon' src="/static/images/ucenter-top-set.png"></image>
</view>
<view class="info-avatar">
<image class="avatar" src="{{owner.avatar||userInfo.avatarUrl}}"></image>
<view class="info">
<text class="name">{{owner.name||userInfo.nickName}}</text>
<view class='ge-friend'>
<image class='ge-friend-icon' src="{{owner.isGy!=1?'/static/images/ge-friends-out.png':'/static/images/ge-friends.png'}}"></image>
<text class='ge-friend-text'>{{owner.gyId?('戈友ID:'+owner.gyId):''}}</text>
</view>
</view>
</view>
<view class="count-message">
<view class='collection' bindtap='goCollect'>
<text class='collection-count'>{{owner.collection}}</text>
<text class='collection-name'>收藏</text>
</view>
<view class='line'></view>
<view class='integral'>
<text class='integral-count'>{{owner.integral}}</text>
<text class='integral-name'>戈币</text>
</view>
<view class='line'></view>
<view class='coupon' bindtap='goCoupon'>
<text class='coupon-count'>{{owner.coupon}}</text>
<text class='coupon-name'>优惠券</text>
</view>
</view>
</view>
</view>
<view class='user_area'>
<view class='user_row' bindtap='goOrder'>
<view class='user_row_left'>我的订单</view>
<view class='user_more'>
<text class='user_more_text'>查看全部</text>
<image class='user_row_right' src='/static/images/ucenter-more.png'></image>
</view>
</view>
<view class='user_column'>
<view class='user_column_item' bindtap='goOrderIndex' data-index='1' data-route='/pages/ucenter/order/order'>
<view class='user_column_item-icon'>
<text class="user_column_item_badge" wx:if="{{order.unpaid != 0}}">{{order.unpaid}}</text>
<image class='user_column_item_image pendpay' src='/static/images/pendpay.png'></image>
</view>
<view class='user_column_item_text'>待付款</view>
</view>
<view class='user_column_item' bindtap='goOrderIndex' data-index='2' data-route='/pages/ucenter/order/order'>
<view class='user_column_item-icon'>
<text class="user_column_item_badge" wx:if="{{order.unship != 0}}">{{order.unship}}</text>
<image class='user_column_item_image send' src='/static/images/send.png'></image>
</view>
<view class='user_column_item_text'>待发货</view>
</view>
<view class='user_column_item' bindtap='goOrderIndex' data-index='3' data-route='/pages/ucenter/order/order'>
<view class='user_column_item-icon'>
<text class="user_column_item_badge" wx:if="{{order.unrecv != 0}}">{{order.unrecv}}</text>
<image class='user_column_item_image receive' src='/static/images/receive.png'></image>
</view>
<view class='user_column_item_text'>已发货</view>
</view>
<view class='user_column_item' bindtap='goOrderIndex' data-index='4' data-route='/pages/ucenter/order/order'>
<view class='user_column_item-icon'>
<text class="user_column_item_badge" wx:if="{{order.uncomment != 0}}">{{order.uncomment}}</text>
<image class='user_column_item_image comment' src='/static/images/comment.png'></image>
</view>
<view class='user_column_item_text'>待评价</view>
</view>
<view class='user_column_item' bindtap='goOrderIndex' data-index='5' data-route='/pages/ucenter/order/order'>
<view class='user_column_item-icon'>
<text class="user_column_item_badge" wx:if="{{order.uncomment != 0}}">{{order.uncomment}}</text>
<image class='user_column_item_image return' src='/static/images/return.png'></image>
</view>
<view class='user_column_item_text'>退款退货</view>
</view>
</view>
</view>
<view class='my-menu my-collection' bindtap='goCollect'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:34rpx; height: 34rpx;" src="/static/images/my-collection.png"></image>
</view>
<text class='my-menu-name'>我的收藏</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<view class='my-menu my-address' bindtap='goAddress'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:44rpx; height: 34rpx;" src="/static/images/my-address.png"></image>
</view>
<text class='my-menu-name'>我的收货地址</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<view class='my-menu my-coupon' bindtap='goCoupon'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:36rpx; height: 30rpx;" src="/static/images/my-coupon.png"></image>
</view>
<text class='my-menu-name'>领券中心</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<view class='my-menu my-integral'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:34rpx; height: 34rpx;" src="/static/images/my-integral.png"></image>
</view>
<text class='my-menu-name'>我的戈币</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<view class='my-menu my-integral' bindtap='goFootprint'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:38rpx; height: 38rpx;" src="/static/images/footprint.png"></image>
</view>
<text class='my-menu-name'>浏览足迹</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<view class='my-menu my-integral' bindtap='goGroupon'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:38rpx; height: 38rpx;" src="/static/images/group.png"></image>
</view>
<text class='my-menu-name'>我的拼团</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view>
<button class="my-menu bind-phone" open-type="getPhoneNumber" bindgetphonenumber="bindPhoneNumber">
<view class='menu-icon'>
<image class='my-menu-icon' style="width:38rpx; height: 38rpx;" src="/static/images/mobile.png"></image>
</view>
<text class='my-menu-name'>绑定手机</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</button>
<view class='my-menu customer'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:38rpx; height: 38rpx;" src="/static/images/customer.png"></image>
</view>
<text class='my-menu-name'>联系客服</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
<view style='position: absolute;width:100%; height:100%;display:flex;align-items:center;'>
<view wx:for="{{20}}" wx:key="{{index}}">
<contact-button style="opacity:0;" type="default-dark" session-from="weapp" size="27">
</contact-button>
</view>
</view>
</view>
<!-- <view class='my-menu my-integral' bindtap='goFeedback'>
<view class='menu-icon'>
<image class='my-menu-icon' style="width:38rpx; height: 38rpx;" src="/static/images/feedback.png"></image>
</view>
<text class='my-menu-name'>意见反馈</text>
<image class='my-menu-arrow' src='/static/images/ucenter-more.png'></image>
</view> -->
<!-- wx:if="{{loginPhoneShow}}" -->
<view class='login-get-phone' catchtouchmove='true' wx:if="{{loginPhoneShow}}">
<view class='login-get-phone-box'>
<image class='login-get-phone-icon' style="width:76rpx; height: 86rpx;" src="/static/images/mobile.png"></image>
<text class='login-get-phone-text'>绑定手机号,获取戈币,购买更省钱哦!</text>
<button class="account-phone-btn" open-type="getPhoneNumber" bindgetphonenumber="bindPhoneNumber">绑定手机号</button>
</view>
</view>
<!--
<view class='separate'></view>
<view class='user_row'>
<view class='user_row_left'>核心服务</view>
</view>
<view class='user_column'>
<view class='user_column_item' bindtap='goCoupon'>
<image class='user_column_item_image' src='/static/images/coupon.png'></image>
<view class='user_column_item_text'>优惠卷</view>
</view>
<view class='user_column_item' bindtap='goCollect'>
<image class='user_column_item_image' src='/static/images/icon_collect.png'></image>
<view class='user_column_item_text'>商品收藏</view>
</view>
<view class='user_column_item' bindtap='goFootprint'>
<image class='user_column_item_image' src='/static/images/footprint.png'></image>
<view class='user_column_item_text'>浏览足迹</view>
</view>
<view class='user_column_item' bindtap='goGroupon'>
<image class='user_column_item_image' src='/static/images/group.png'></image>
<view class='user_column_item_text'>我的拼团</view>
</view>
<view class='user_column_item' bindtap='goAfterSale'>
<image class='user_column_item_image' src='/static/images/aftersale.png'></image>
<view class='user_column_item_text'>售后</view>
</view>
</view>
<view class='separate'></view>
<view class='user_row'>
<view class='user_row_left'>必备工具</view>
</view>
<view class='user_column'>
<view class='user_column_item' bindtap='goAddress'>
<image class='user_column_item_image' src='/static/images/address.png'></image>
<view class='user_column_item_text'>地址管理</view>
</view>
<button class="user_column_item_phone" open-type="getPhoneNumber" bindgetphonenumber="bindPhoneNumber">
<image class='user_column_item_image' src='/static/images/mobile.png'></image>
<view class='user_column_item_text'>绑定手机</view>
</button>
<view class='user_column_item' bindtap='goFeedback'>
<image class='user_column_item_image' src='/static/images/feedback.png'></image>
<view class='user_column_item_text'>意见反馈</view>
</view>
<view class='user_column_item'>
<contact-button style="opacity:0;position:absolute;" type="default-dark" session-from="weapp" size="27">
</contact-button>
<image class='user_column_item_image' src='/static/images/customer.png'></image>
<view class='user_column_item_text'>联系客服</view>
</view>
<view class='user_column_item' bindtap='aboutUs'>
<image class='user_column_item_image' src='/static/images/about_us.png'></image>
<view class='user_column_item_text'>关于我们</view>
</view>
</view> -->
<!-- <view class="logout" wx:if="{{hasLogin}}" bindtap="exitLogin">退出登录</view> -->
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #fff;
}
.container {
background: #fff;
height: auto;
overflow: hidden;
width: 100%;
}
.profile-info {
width: 100%;
height: 316rpx;
color: #f4f4f4;
display: flex;
align-items: center;
font-size: 28rpx;
position: relative;
background: #fff;
}
.profile-background {
position: absolute;
top: 0;
left: 0;
z-index: 100;
width: 100%;
height: 316rpx;
}
.profile-info .info-count {
width: 100%;
height: 316rpx;
position: absolute;
left: 0;
top: 0;
z-index: 200;
}
.info-set {
padding: 40rpx 50rpx;
position: absolute;
right: 0rpx;
top: 0rpx;
z-index: 300;
}
.info-set-icon {
width: 36rpx;
height: 38rpx;
}
.profile-info .info-avatar {
display: flex;
margin-top: 55rpx;
margin-left: 37rpx;
}
.info-count .avatar {
height: 134rpx;
width: 134rpx;
border-radius: 50%;
}
.info-count .info {
flex: 1;
height: 85rpx;
padding-left: 31.25rpx;
}
.info-count .name {
display: block;
height: 45rpx;
line-height: 45rpx;
color: #fff;
font-size: 30rpx;
font-weight: 400;
margin-top: 26rpx;
font-family:PingFangSC-Regular;
}
.ge-friend {
display: flex;
align-items: center;
}
.ge-friend-icon {
width: 44rpx;
height: 44rpx;
}
.ge-friend-text {
color: #fff;
font-size:24rpx;
font-weight:600;
margin-left: 10rpx;
}
.info-count .level {
display: block;
height: 30rpx;
line-height: 30rpx;
margin-bottom: 10rpx;
color: #7f7f7f;
font-size: 30rpx;
}
.count-message {
width: 580rpx;
height: 100rpx;
margin-left: 140rpx;
color:#FFFFFF;
display: flex;
align-items: center;
}
.count-message .line {
width: 1rpx;
height: 40rpx;
background: #fff;
}
.collection, .integral, .coupon {
width: 177rpx;
display: flex;
align-items: center;
flex-direction: column;
}
.collection-count, .integral-count, .coupon-count {
color: #fff;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
display: block;
}
.collection-name, .integral-name, .coupon-name {
color: #fff;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
display: block;
}
.user_area {
width: 100%;
height: 246rpx;
background: #fff;
overflow: hidden;
border-bottom:2rpx solid rgba(239,239,239,1);
}
.user_row {
/* border: 1px solid black; */
height: 96rpx;
line-height: 96rpx;
border-bottom:2rpx solid rgba(239,239,239,1);
}
.user_row_left {
/* border: 1px solid #757575; */
float: left;
height: 96rpx;
line-height: 96rpx;
margin-left: 35rpx;
letter-spacing: 1rpx;
font-size:28rpx;
font-family:PingFangSC-Medium;
font-weight:500;
color:rgba(51,51,51,1);
}
.user_more {
float: right;
display: flex;
align-items: center;
}
.user_more_text {
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(110,110,110,1);
}
.user_row_right {
height: 22rpx;
width: 12rpx;
font-weight: 550;
margin-right: 30rpx;
margin-left: 20rpx;
}
.user_column {
height: 140rpx;
display: flex;
justify-content: center;
align-items: center;
}
.user_column_item {
width: 30%;
height: 140rpx;
background: #fff;
text-align: center;
position: relative;
}
.user_column_item_badge {
height: 32rpx;
width: 32rpx;
line-height: 32rpx;
position: absolute;
background: #E31436;
color: #fff;
border-radius: 50%;
text-align: center;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
right: 34rpx;
}
.user_column_item-icon {
height: 90rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.user_column_item_image {
width: 50rpx;
height: 50rpx;
margin-top: 30rpx;
}
.user_column_item .pendpay {
width: 40rpx;
height: 44rpx;
}
.user_column_item .send {
width: 42rpx;
height: 36rpx;
}
.user_column_item .receive {
width: 48rpx;
height: 34rpx;
}
.user_column_item .comment {
width: 42rpx;
height: 44rpx;
}
.user_column_item .return {
width: 48rpx;
height: 46rpx;
}
.user_column_item_text {
/* border: 1px solid black; */
margin-top: 5rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.separate {
background: #e0e3da;
width: 100%;
height: 6rpx;
}
.user_column_item_phone {
width: 30%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap;
float: left;
background: #fff;
border-bottom: 1px solid #fafafa;
}
.user_column_item_phone::after {
border: none;
}
.my-menu {
width: 100%;
height: 100rpx;
overflow: hidden;
display: flex;
align-items: center;
border-bottom: 2rpx solid #fafafa;
}
.my-collection{
margin-top: 10rpx;
}
.menu-icon {
width: 50rpx;
height: 34rpx;
margin-left: 46rpx;
display: flex;
align-items: center;
justify-content: center;
}
.my-menu-icon {
width: 34rpx;
height: 34rpx;
}
.my-menu-name {
flex: 1;
margin-left: 22rpx;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
}
.my-menu-arrow {
width: 12rpx;
height: 22rpx;
margin-right: 41rpx;
}
.bind-phone {
background: #fff;
border: none;
text-align: left;
padding: 0;
}
.bind-phone::after {
border: none;
border-radius: 0;
}
.customer {
position: relative;
overflow: hidden;
}
.logout {
height: 80rpx;
line-height: 80rpx;
width: 300rpx;
text-align: center;
border-radius: 50rpx;
color: #fff;
font-size: 30rpx;
font-weight: 600;
background: #E31436;
margin: 30rpx auto;
}
.login-get-phone {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 5000;
}
.login-get-phone-box {
width: 600rpx;
height: 300rpx;
background: #fff;
border-radius: 5px;
position: absolute;
top: 50%;
left: 50%;
z-index: 5050;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
}
.login-get-phone-icon {
display: block;
margin: 20px auto 10px;
}
.login-get-phone-text {
margin: 0 auto;
color: #000;
font-size: 30rpx;
font-weight: 600;
text-align: center;
}
.account-phone-btn {
width:400rpx;
line-height:70rpx;
background:#FF1B40;
border-radius:35px;
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(255,255,255,1);
text-align: center;
margin: 20rpx auto;
border: none;
}
\ No newline at end of file
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
name: ''
},
onLoad: function(options) {
this.setData({
name: options.nickName
})
// 页面初始化 options为页面跳转所带来的参数
},
clearName: function() {
this.setData({
name: ""
})
},
onReady: function() {
},
onShow: function() {
if (app.globalData.hasLogin) {
let userInfo = wx.getStorageSync('userInfo');
this.setData({
userInfo: userInfo
})
}
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
this.makeName(this.data.name);
},
/**
* @param {String} 昵称
*/
makeName(nickName) {
util.request(api.UserNickName, {nickName},"POST").then(function (res) {
if (res.errno === 0) {
console.log(res)
}
});
},
/**
* @param {Object} 事件对象
* @param {String} 提交的类别名称
*/
confirm(e) {
let inputValue = e.detail.value;
this.setData({
name: inputValue
})
},
})
\ No newline at end of file
{
"backgroundColor": "#f4f4f4",
"navigationBarTitleText": "昵称",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#f4f4f4"
}
\ No newline at end of file
<view class='container'>
<view class='name'>
<input class="name-text" confirm-type="search" value="{{name}}" bindinput="confirm" placeholder="输入昵称" bindconfirm="confirm" bindinput="confirm" />
<image class='close' src="/static/images/nick-name-close.png" bindtap='clearName'></image>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #F4F4F4;
}
.container {
background:#F4F4F4;
height: auto;
overflow: hidden;
width: 100%;
}
.name {
width: 100%;
height: 99rpx;
display: flex;
align-items: center;
padding-left: 30rpx;
background: #ffffff;
}
.name-text {
font-size:30rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(17, 17, 17, 1);
flex: 1;
}
.close {
width: 34rpx;
height: 34rpx;
margin-right: 26rpx;
}
\ No newline at end of file
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
Page({
data: {
orderList: [],
showType: 0
},
onLoad: function(options) {
if (options.tab) {
this.setData({
showType: options.tab
});
} else {
// 页面初始化 options为页面跳转所带来的参数
let that = this
try {
var tab = wx.getStorageSync('tab');
this.setData({
showType: tab
});
} catch (e) {}
}
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getOrderList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
getOrderList() {
let that = this;
util.request(api.OrderList, {
showType: that.data.showType
}).then(function(res) {
if (res.errno === 0) {
console.log(JSON.stringify(res.data));
that.setData({
orderList: res.data.data
});
}
});
},
switchTab: function(event) {
let showType = event.currentTarget.dataset.index;
this.setData({
showType: showType
});
this.getOrderList();
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
this.getOrderList();
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "我的订单"
}
\ No newline at end of file
<view class="container">
<view class="orders-switch">
<view class="item {{ showType == 0 ? 'active' : ''}}" bindtap="switchTab" data-index='0'>
<view class="txt">全部</view>
</view>
<view class="item {{ showType == 1 ? 'active' : ''}}" bindtap="switchTab" data-index='1'>
<view class="txt">待付款</view>
</view>
<view class="item {{ showType == 2 ? 'active' : ''}}" bindtap="switchTab" data-index='2'>
<view class="txt">待发货</view>
</view>
<view class="item {{ showType == 3 ? 'active' : ''}}" bindtap="switchTab" data-index='3'>
<view class="txt">待收货</view>
</view>
<view class="item {{ showType == 4 ? 'active' : ''}}" bindtap="switchTab" data-index='4'>
<view class="txt">待评价</view>
</view>
</view>
<view class="no-order" wx:if="{{orderList.length <= 0}}">
<view class="c">
<image src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>还没有任何订单呢</text>
</view>
</view>
<view class="orders">
<navigator url="../orderDetail/orderDetail?id={{item.id}}" class="order" wx:for="{{orderList}}" wx:key="id">
<view class="h">
<view class="l">订单编号:{{item.orderSn}}</view>
<view class="r">{{item.orderStatusText}}</view>
</view>
<view class="goods" wx:for="{{item.goodsList}}" wx:key="id" wx:for-item="gitem">
<view class="img">
<image src="{{gitem.picUrl}}"></image>
</view>
<view class="info">
<text class="name">{{gitem.goodsName}}</text>
<text class="number">共{{gitem.number}}件商品</text>
</view>
<view class="status"></view>
</view>
<view class="b">
<view class="l">实付:¥{{item.actualPrice}}</view>
</view>
</navigator>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #f4f4f4;
}
.orders-switch {
width: 100%;
background: #fff;
height: 84rpx;
/* border-bottom: 1px solid rgba(0,0,0,.15); */
display: flex;
}
.orders-switch .item {
height: 82rpx;
flex: 1;
margin-top:3rpx
}
.orders-switch .item .txt {
display: inline-block;
height: 82rpx;
margin: 0 20rpx;
padding: 0 12rpx;
line-height: 82rpx;
color: #111111;
font-size: 28rpx;
/* width: 170rpx; */
font-family:PingFangSC-Regular;
font-weight:400;
}
.orders-switch .item.active .txt {
color: #111111;
border-bottom: 5rpx solid #FF2246;
}
.no-order {
width: 100%;
height: auto;
margin: 0 auto;
}
.no-order .c {
width: 100%;
height: auto;
margin-top: 200rpx;
}
.no-order .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
}
.no-order .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 29rpx;
line-height: 29rpx;
text-align: center;
font-size: 29rpx;
color: #999;
}
.orders {
height: auto;
width: 100%;
overflow: hidden;
}
.order {
margin-top: 20rpx;
background: #fff;
}
.order .h {
height: 83.3rpx;
line-height: 83.3rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
font-size: 30rpx;
color: #333;
}
.order .h .l {
float: left;
}
.order .h .r {
float: right;
color: #FF2246;
font-size: 24rpx;
}
.order .goods {
display: flex;
align-items: center;
height: 199rpx;
margin-left: 31.25rpx;
}
.order .goods .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.order .goods .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.order .goods .info {
height: 145.83rpx;
flex: 1;
padding-left: 20rpx;
}
.order .goods .name {
width: 500rpx;
margin-top: 30rpx;
display: block;
height: 44rpx;
line-height: 44rpx;
color: #333;
font-size: 30rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.order .goods .number {
display: block;
height: 37rpx;
line-height: 37rpx;
color: #666;
font-size: 25rpx;
}
.order .goods .status {
width: 105rpx;
color: #b4282d;
font-size: 25rpx;
}
.order .b {
height: 103rpx;
line-height: 103rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-top: 1px solid #f4f4f4;
font-size: 30rpx;
color: #333;
}
.order .b .l {
float: left;
}
.order .b .r {
float: right;
}
.order .b .btn {
margin-top: 19rpx;
height: 64.5rpx;
line-height: 64.5rpx;
text-align: center;
padding: 0 20rpx;
border-radius: 5rpx;
font-size: 28rpx;
color: #fff;
background: #b4282d;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
Page({
data: {
orderId: 0,
orderInfo: {},
orderGoods: [],
expressInfo: {},
flag: false,
handleOption: {}
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
this.setData({
orderId: options.id
});
this.getOrderDetail();
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getOrderDetail();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
expandDetail: function() {
let that = this;
this.setData({
flag: !that.data.flag
})
},
getOrderDetail: function() {
wx.showLoading({
title: '加载中',
});
setTimeout(function() {
wx.hideLoading()
}, 2000);
let that = this;
util.request(api.OrderDetail, {
orderId: that.data.orderId
}).then(function(res) {
if (res.errno === 0) {
console.log(res.data);
that.setData({
orderInfo: res.data.orderInfo,
orderGoods: res.data.orderGoods,
handleOption: res.data.orderInfo.handleOption,
expressInfo: res.data.expressInfo
});
}
wx.hideLoading();
});
},
// “去付款”按钮点击效果
payOrder: function() {
let that = this;
util.request(api.OrderPrepay, {
orderId: that.data.orderId
}, 'POST').then(function(res) {
if (res.errno === 0) {
const payParam = res.data;
console.log("支付过程开始");
if (that.data.orderInfo.actualPrice>0) {
wx.requestPayment({
'timeStamp': payParam.timeStamp,
'nonceStr': payParam.nonceStr,
'package': payParam.wxPackage,
'signType': payParam.signType,
'paySign': payParam.paySign,
'success': function(res) {
console.log("支付过程成功");
util.redirect('/pages/ucenter/order/order');
},
'fail': function(res) {
console.log(res);
console.log("支付过程失败");
util.showErrorToast('支付失败');
},
'complete': function(res) {
console.log(res);
console.log("支付过程结束")
}
});
} else {
wx.redirectTo({
url: '/pages/payResult/payResult?status=1&orderId=' + that.data.orderId
});
}
} else if (res.errno == 710) {
wx.redirectTo({
url: '/pages/payResult/payResult?success=0'
});
return;
}
});
},
// “取消订单”点击效果
cancelOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要取消此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderCancel, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '取消订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “取消订单并退款”点击效果
refundOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要取消此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderRefund, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '取消订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “删除”点击效果
deleteOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确定要删除此订单?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderDelete, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '删除订单成功'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
// “确认收货”点击效果
confirmOrder: function() {
let that = this;
let orderInfo = that.data.orderInfo;
wx.showModal({
title: '',
content: '确认收货?',
success: function(res) {
if (res.confirm) {
util.request(api.OrderConfirm, {
orderId: orderInfo.id
}, 'POST').then(function(res) {
if (res.errno === 0) {
wx.showToast({
title: '确认收货成功!'
});
util.redirect('/pages/ucenter/order/order');
} else {
util.showErrorToast(res.errmsg);
}
});
}
}
});
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
}
})
\ No newline at end of file
{
"navigationBarTitleText": "订单详情"
}
\ No newline at end of file
<view class="container">
<view class="order-info">
<view class="item-a">下单时间:{{orderInfo.addTime}}</view>
<view class="item-b">订单编号:{{orderInfo.orderSn}}</view>
<view class="item-c">
<view class="l">实付:
<text class="cost">¥{{orderInfo.actualPrice}}</text><text wx:if="{{orderInfo.totalUseScores}}" style='margin-left: 20rpx;' class="cost">+{{orderInfo.totalUseScores}}戈币</text>
</view>
<view class="r">
<view class="btn esc-btn" bindtap="cancelOrder" wx:if="{{handleOption.cancel}}">取消订单</view>
<view class="btn active" bindtap="payOrder" wx:if="{{handleOption.pay}}">去付款</view>
<view class="btn active" bindtap="confirmOrder" wx:if="{{handleOption.confirm}}">确认收货</view>
<view class="btn esc-btn" bindtap="deleteOrder" wx:if="{{handleOption.delete}}">删除订单</view>
<view class="btn esc-btn" bindtap="refundOrder" wx:if="{{handleOption.refund}}">申请退款</view>
</view>
</view>
</view>
<view class="order-goods">
<view class="h">
<view class="label">商品信息</view>
<view class="status">{{orderInfo.orderStatusText}}</view>
</view>
<view class="goods">
<view class="item" wx:for="{{orderGoods}}" wx:key="id">
<view class="img">
<image src="{{item.picUrl}}"></image>
</view>
<view class="info">
<view class="t">
<text class="name">{{item.goodsName}}</text>
<text class="number">x{{item.number}}</text>
</view>
<view class="attr">{{item.specifications}}</view>
<view class="price">¥{{item.price}} <text wx:if="{{item.useScores}}" style='margin-left: 20rpx;' class="cost">+{{item.useScores}}戈币</text></view>
<view class="btn active" wx:if="{{handleOption.comment && (item.comment == 0)}}">
<navigator url="../../commentPost/commentPost?orderId={{item.orderId}}&&valueId={{item.goodsId}}&type=0">去评价</navigator>
</view>
<view class="btn active" wx:if="{{handleOption.rebuy}}">
<navigator url="../../goods/goods?id={{item.goodsId}}">再次购买</navigator>
</view>
</view>
</view>
</view>
<view class="order-bottom">
<view class="address">
<view class="t">
<text class="name">{{orderInfo.consignee}}</text>
<text class="mobile">{{orderInfo.mobile}}</text>
</view>
<view class="b">{{orderInfo.address}}</view>
</view>
<view class="total">
<view class="t">
<text class="label">商品合计:</text>
<text class="txt">¥{{orderInfo.goodsPrice}}<text wx:if="{{item.useScores}}" style='margin-left: 20rpx;' class="cost">+{{item.useScores}}戈币</text></text>
</view>
<view class="t">
<text class="label">运费:</text>
<text class="txt">¥{{orderInfo.freightPrice}}</text>
</view>
</view>
<view class="pay-fee">
<text class="label">实付:</text>
<text class="txt">¥{{orderInfo.actualPrice}} <text wx:if="{{orderInfo.totalUseScores}}" style='margin-left: 20rpx;' class="cost">+{{orderInfo.totalUseScores}}戈币</text></text>
</view>
</view>
</view>
<!-- 物流信息,仅收货状态下可见 -->
<view class="order-express" bindtap="expandDetail" wx:if="{{ handleOption.confirm }}">
<view class="order-express">
<view class="title">
<view class="t">快递公司:{{expressInfo.shipperName}}</view>
<view class="b">物流单号:{{expressInfo.logisticCode}}</view>
</view>
<image class="ti" src="/static/images/address_right.png" background-size="cover"></image>
</view>
<view class="traces" wx:for="{{expressInfo.Traces}}" wx:key="item" wx:for-item="iitem" wx:if="{{ flag }}">
<view class="trace">
<view class="acceptStation">{{iitem.AcceptStation}}</view>
<view class="acceptTime">{{iitem.AcceptTime}}</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #f4f4f4;
}
.order-info {
padding-top: 25rpx;
background: #fff;
height: auto;
overflow: hidden;
}
.item-a {
padding-left: 31.25rpx;
height: 42.5rpx;
padding-bottom: 12.5rpx;
line-height: 30rpx;
font-size: 30rpx;
color: #666;
}
.item-b {
padding-left: 31.25rpx;
height: 29rpx;
line-height: 29rpx;
margin-top: 12.5rpx;
margin-bottom: 41.5rpx;
font-size: 30rpx;
color: #666;
}
.item-c {
margin-left: 31.25rpx;
border-top: 1px solid #f4f4f4;
height: 103rpx;
line-height: 103rpx;
}
.item-c .l {
float: left;
}
.item-c .r {
height: 103rpx;
float: right;
display: flex;
align-items: center;
padding-right: 16rpx;
}
.item-c .r .btn {
float: right;
}
.item-c .cost {
color: #FF2246;
}
.item-c .btn {
line-height: 48rpx;
border-radius: 40rpx;
text-align: center;
margin: 0 15rpx;
padding: 0 20rpx;
font-size:24rpx;
font-family:PingFangSC-Regular;
font-weight:400;
}
.item-c .btn.active {
border: 1rpx solid#FF2246;
color: #FF2246;
}
.item-c .btn.esc-btn {
border: 1rpx solid#6E6E6E;
color: #6E6E6E;
}
.order-goods {
margin-top: 20rpx;
background: #fff;
}
.order-goods .h {
height: 93.75rpx;
line-height: 93.75rpx;
margin-left: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
padding-right: 31.25rpx;
}
.order-goods .h .label {
float: left;
font-size: 30rpx;
color: #333;
}
.order-goods .h .status {
float: right;
font-size: 30rpx;
color: #FF2246;
}
.order-goods .item {
display: flex;
align-items: center;
height: 192rpx;
margin-left: 31.25rpx;
padding-right: 31.25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-goods .item:last-child {
border-bottom: none;
}
.order-goods .item .img {
height: 145.83rpx;
width: 145.83rpx;
background: #f4f4f4;
}
.order-goods .item .img image {
height: 145.83rpx;
width: 145.83rpx;
}
.order-goods .item .info {
flex: 1;
height: 145.83rpx;
margin-left: 20rpx;
}
.order-goods .item .t {
margin-top: 8rpx;
height: 33rpx;
line-height: 33rpx;
margin-bottom: 10.5rpx;
}
.order-goods .item .t .name {
display: block;
float: left;
height: 33rpx;
line-height: 33rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .t .number {
display: block;
float: right;
height: 33rpx;
text-align: right;
line-height: 33rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .attr {
height: 29rpx;
line-height: 29rpx;
color: #666;
margin-bottom: 25rpx;
font-size: 25rpx;
}
.order-goods .item .price {
display: block;
float: left;
height: 30rpx;
line-height: 30rpx;
color: #333;
font-size: 30rpx;
}
.order-goods .item .btn {
height: 50rpx;
line-height: 50rpx;
border-radius: 5rpx;
text-align: center;
display: block;
float: right;
margin: 0 15rpx;
padding: 0 20rpx;
}
.order-goods .item .btn.active {
border: 1px solid #FF2246;
color: #FF2246;
}
.order-bottom {
margin-top: 20rpx;
padding-left: 31.25rpx;
height: auto;
overflow: hidden;
background: #fff;
}
.order-bottom .address {
height: 128rpx;
padding-top: 25rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-bottom .address .t {
height: 35rpx;
line-height: 35rpx;
margin-bottom: 7.5rpx;
}
.order-bottom .address .name {
display: inline-block;
height: 35rpx;
width: 140rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .address .mobile {
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .address .b {
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .total {
height: 106rpx;
padding-top: 20rpx;
border-bottom: 1px solid #f4f4f4;
}
.order-bottom .total .t {
height: 30rpx;
line-height: 30rpx;
margin-bottom: 7.5rpx;
display: flex;
}
.order-bottom .total .label {
width: 150rpx;
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .total .txt {
flex: 1;
display: inline-block;
height: 35rpx;
line-height: 35rpx;
font-size: 30rpx;
}
.order-bottom .pay-fee {
height: 81rpx;
line-height: 81rpx;
}
.order-bottom .pay-fee .label {
display: inline-block;
width: 140rpx;
color: #FF2246;
}
.order-bottom .pay-fee .txt {
display: inline-block;
width: 140rpx;
color: #FF2246;
}
.order-express {
margin-top: 20rpx;
width: 100%;
height: 100rpx;
background: #fff;
}
.order-express .title {
float: left;
margin-bottom: 20rpx;
padding: 10rpx;
}
.order-express .ti {
float: right;
width: 52rpx;
height: 52rpx;
margin-right: 16rpx;
margin-top: 28rpx;
}
.order-express .t {
font-size: 29rpx;
margin-left: 10.25rpx;
color: #a78845;
}
.order-express .b {
font-size: 29rpx;
margin-left: 10.25rpx;
color: #a78845;
}
.order-express .traces {
padding: 17.5rpx;
background: #fff;
border-bottom: 1rpx solid #f1e6cdcc;
}
.order-express .trace {
padding-bottom: 17.5rpx;
padding-top: 17.5rpx;
background: #fff;
}
.order-express .acceptTime {
margin-top: 20rpx;
margin-right: 40rpx;
text-align: right;
font-size: 26rpx;
}
.order-express .acceptStation {
font-size: 26rpx;
}
var util = require('../../../utils/util.js');
var api = require('../../../config/api.js');
var app = getApp();
Page({
data: {
hasLogin: true,
userInfo: {
nickName: '',
avatarUrl: 'http://yanxuan.nosdn.127.net/8945ae63d940cc42406c3f67019c5cb6.png'
},
setUserInfo: {
name: '',
tel: '',
avatar: ''
},
shadeMessage: ['拍照', '从手机相册选择', '取消'],
shadeShow: false, // 遮罩显示隐藏
},
onLoad: function(options) {
// 页面初始化 options为页面跳转所带来的参数
},
onReady: function() {
},
onShow: function() {
if (app.globalData.hasLogin) {
let userInfo = wx.getStorageSync('userInfo');
this.setData({
userInfo: userInfo
})
}
this.getSetUp();
},
getSetUp() {
let that = this;
util.request(api.UserGetSetUp, {}, "POST").then(function (res) {
if (res.errno === 0) {
that.setData({
setUserInfo: res.data
})
}
});
},
bindPhoneNumber: function (e) {
let that = this;
if (e.detail.errMsg !== "getPhoneNumber:ok") {
// 拒绝授权
return;
}
if (!this.data.hasLogin) {
wx.showToast({
title: '绑定失败:请先登录',
icon: 'none',
duration: 2000
});
return;
}
util.request(api.AuthBindPhone, {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData
}, 'POST').then(function (res) {
if (res.errno === 0) {
wx.showToast({
title: '绑定手机号码成功',
icon: 'success',
duration: 2000
});
that.getSetUp();
}
});
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
exitLogin: function () {
wx.showModal({
title: '',
confirmColor: '#ED0E1B',
content: '退出登录?',
success: function (res) {
if (!res.confirm) {
return;
}
util.request(api.AuthLogout, {}, 'POST');
app.globalData.hasLogin = false;
wx.removeStorageSync('token');
wx.removeStorageSync('userInfo');
wx.reLaunch({
url: '/pages/index2/index2'
});
}
})
},
stopPageScroll() {
return
},
/**
* 选择图片方式 0拍照 1选文件 2取消
*/
chooseType(e) {
let index = e.currentTarget.dataset.index;
if (index === 0) {
this.cropImage('camera');
} else if (index === 1) {
this.cropImage('album');
} else {
this.setData({
shadeShow: false
})
}
},
/**
* 裁切图片
* @param {Object} 事件
*/
cropImage(type) {
let that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: [type], // album 从相册选图,camera 使用相机,默认二者都有
success: function (res) {
console.log("从相册选图", res)
wx.getImageInfo({
src: res.tempFilePaths[0],
success(res) {
that.setData({
shadeShow: false
})
wx.navigateTo({
url: '../avatarCropper/avatarCropper?data=' + JSON.stringify(res)
})
}
})
}
});
},
/**
* 遮罩显示与隐藏
*/
shadeFun() {
this.setData({
shadeShow: !this.data.shadeShow
})
},
/**
* 设置名字
*/
setName() {
let _nickName = this.data.setUserInfo.name || this.data.userInfo.nickName;
wx.navigateTo({
url: "/pages/ucenter/nickName/nickName?nickName=" + _nickName
});
}
})
\ No newline at end of file
{
"backgroundColor": "#f4f4f4",
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#f4f4f4"
}
\ No newline at end of file
<view class='container'>
<view class='avatar-row' bindtap="shadeFun">
<text class="title">头像</text>
<image class='avatar' src='{{setUserInfo.avatar || userInfo.avatarUrl}}'></image>
<image class='user_row_right' src='/static/images/ucenter-more.png'></image>
</view>
<view class='avatar-row' bindtap="setName">
<text class="title">昵称</text>
<text class="name">{{setUserInfo.name || userInfo.nickName}}</text>
<image class='user_row_right' src='/static/images/ucenter-more.png'></image>
</view>
<view class='avatar-row'>
<text class="title">登录手机号</text>
<text class="phone">{{setUserInfo.tel}}</text>
<button class="bind-phone" wx:if="{{!setUserInfo.tel}}" open-type="getPhoneNumber" bindgetphonenumber="bindPhoneNumber"></button>
</view>
<view class="logout" wx:if="{{hasLogin}}" bindtap="exitLogin">退出当前账户</view>
<view class="shade" hidden="{{!(shadeShow)}}" catchtap="stopPageScroll">
<view class="shade-main {{[shadeShow ? 'shade-show' : '']}}">
<view class="msg" wx:key="index" key="{{index}}" catchtap="chooseType" data-index="{{index}}" wx:for="{{shadeMessage}}" wx:for-index="index" wx:for-item="item">
{{item}}
</view>
</view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
width: 100%;
background: #F4F4F4;
}
.container {
background:#F4F4F4;
height: auto;
overflow: hidden;
width: 100%;
}
.avatar-row{
height: 140rpx;
width: 100%;
background: #fff;
display: flex;
align-items: center;
position: relative;
}
.avatar-row:first-child {
padding-top: 30rpx;
}
.title {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(51,51,51,1);
flex: 1;
margin-left: 42rpx;
}
.name {
font-size:28rpx;
font-family:PingFangSC-Regular;
font-weight:400;
color:rgba(125,125,125,1);
margin-right: 28rpx;
}
.avatar {
width: 98rpx;
height: 98rpx;
border-radius: 50%;
margin-right: 28rpx;
}
.user_row_right {
width: 12rpx;
height: 22rpx;
margin-right: 32rpx;
}
.phone {
margin-right: 73rpx;
}
.bind-phone {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 2000;
background: none;
border: none;
}
.bind-phone::after {
border:none;
border-radius: 0;
}
.logout {
width: 100%;
height: 99rpx;
line-height: 99rpx;
background: #fff;
margin-top: 20rpx;
color: #E31436;
font-size:30rpx;
font-family: MicrosoftYaHei;
font-weight:400;
text-align: center;
}
.shade {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 5000;
background: rgba(0, 0, 0, 0.5);
}
.shade-main {
position: absolute;
bottom: -400rpx;
left: 0;
width: 100%;
transition: all 0.5s;
}
.shade-show {
bottom: 0;
transition: all 0.5s;
}
.msg {
width: 100%;
line-height: 106rpx;
text-align: center;
background: #ffffff;
font-size: 36rpx;
font-family: PingFangSC-Regular;
font-weight: 400;
color: rgba(51, 51, 51, 1);
border-bottom: 1rpx solid rgba(220, 218, 218, 1);
}
.msg:last-child {
margin-top: 17rpx;
border: none;
}
\ No newline at end of file
{
"description": "项目配置文件。",
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true,
"autoAudits": false,
"uglifyFileName": true,
"checkInvalidKey": true
},
"compileType": "miniprogram",
"libVersion": "2.6.4",
"appid": "wx4359791c2e1f0be0",
"projectname": "%E6%88%88%E5%8F%8B%E5%95%86%E5%9F%8E",
"simulatorType": "wechat",
"simulatorPluginLibVersion": {},
"condition": {
"search": {
"current": -1,
"list": []
},
"conversation": {
"current": -1,
"list": []
},
"plugin": {
"current": -1,
"list": []
},
"game": {
"list": []
},
"miniprogram": {
"current": 22,
"list": [
{
"id": -1,
"name": "首页",
"pathName": "pages/index2/index2",
"query": ""
},
{
"id": -1,
"name": "专题",
"pathName": "pages/topic/topic",
"query": ""
},
{
"id": -1,
"name": "专题详情",
"pathName": "pages/topicDetail/topicDetail",
"query": "id=314"
},
{
"id": -1,
"name": "专题评论列表",
"pathName": "pages/topicComment/topicComment",
"query": "valueId=314&type=1"
},
{
"id": -1,
"name": "专题评论添加",
"pathName": "pages/topicCommentPost/topicCommentPost",
"query": "valueId=314&type=1"
},
{
"id": -1,
"name": "品牌",
"pathName": "pages/brand/brand",
"query": ""
},
{
"id": -1,
"name": "品牌详情",
"pathName": "pages/brandDetail/brandDetail",
"query": "id=1001000"
},
{
"id": -1,
"name": "人气推荐",
"pathName": "pages/hotGoods/hotGoods",
"query": ""
},
{
"id": -1,
"name": "新品首发",
"pathName": "pages/newGoods/newGoods",
"query": ""
},
{
"id": -1,
"name": "分类",
"pathName": "pages/catalog/catalog",
"query": ""
},
{
"id": -1,
"name": "分类详情",
"pathName": "pages/category/category",
"query": "id=1008002"
},
{
"id": -1,
"name": "查找",
"pathName": "pages/search/search",
"query": ""
},
{
"id": 12,
"name": "商品",
"pathName": "pages/goods/goods",
"query": "id=1181003"
},
{
"id": -1,
"name": "商品评论列表",
"pathName": "pages/comment/comment",
"query": "valueId=1181000&type=0"
},
{
"id": -1,
"name": "购物车",
"pathName": "pages/cart/cart",
"query": ""
},
{
"id": -1,
"name": "下单",
"pathName": "pages/checkout/checkout",
"query": ""
},
{
"id": -1,
"name": "支付结果",
"pathName": "pages/payResult/payResult",
"query": ""
},
{
"id": -1,
"name": "我的",
"pathName": "pages/ucenter/index/index",
"query": ""
},
{
"id": -1,
"name": "我的订单列表",
"pathName": "pages/ucenter/order/order",
"query": ""
},
{
"id": -1,
"name": "我的订单详情",
"pathName": "pages/ucenter/orderDetail/orderDetail",
"query": "id=1"
},
{
"id": 22,
"name": "待评价的订单详情",
"pathName": "pages/ucenter/orderDetail/orderDetail",
"query": "id=1"
},
{
"id": -1,
"name": "购买商品评价",
"pathName": "pages/commentPost/commentPost",
"query": "orderId=2&type=0&valueId=1116011"
},
{
"id": 22,
"name": "我的优惠券",
"pathName": "pages/ucenter/couponList/couponList",
"query": ""
},
{
"id": -1,
"name": "我的收藏",
"pathName": "pages/ucenter/collect/collect",
"query": ""
},
{
"id": -1,
"name": "我的足迹",
"pathName": "pages/ucenter/footprint/footprint",
"query": ""
},
{
"id": -1,
"name": "我的地址",
"pathName": "pages/ucenter/address/address",
"query": ""
},
{
"id": -1,
"name": "我的地址添加",
"pathName": "pages/ucenter/addressAdd/addressAdd",
"query": ""
},
{
"id": -1,
"name": "登录",
"pathName": "pages/auth/login/login",
"query": ""
},
{
"id": -1,
"name": "账号登录",
"pathName": "pages/auth/accountLogin/accountLogin",
"query": ""
},
{
"id": -1,
"name": "注册",
"pathName": "pages/auth/register/register",
"query": ""
},
{
"id": -1,
"name": "找回密码",
"pathName": "pages/auth/reset/reset",
"query": ""
},
{
"id": -1,
"name": "关于",
"pathName": "pages/about/about",
"query": ""
},
{
"id": -1,
"name": "测试更新",
"pathName": "pages/index2/index2",
"query": ""
},
{
"id": -1,
"name": "意见反馈",
"pathName": "pages/ucenter/feedback/feedback",
"query": ""
},
{
"id": -1,
"name": "团购专区",
"pathName": "pages/groupon/grouponList/grouponList",
"query": ""
},
{
"id": -1,
"name": "选择优惠券",
"pathName": "pages/ucenter/couponSelect/couponSelect",
"query": ""
},
{
"id": -1,
"name": "我的优惠券列表",
"pathName": "pages/ucenter/couponList/couponList",
"query": ""
},
{
"id": -1,
"name": "优惠券列表",
"pathName": "pages/coupon/coupon",
"query": ""
}
]
}
}
}
\ No newline at end of file
{
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
"rules": [{
"action": "allow",
"page": "*"
}]
}
\ No newline at end of file
function isValidPhone(str) {
var myreg = /^[1][3,4,5,7,8][0-9]{9}$/;
if (!myreg.test(str)) {
return false;
} else {
return true;
}
}
module.exports = {
isValidPhone
}
\ No newline at end of file
var startX
var startY
class touch {
constructor() {
}
_touchstart(e, items) {
//开始触摸时 重置所有删除
items.forEach(function (v, i) {
if (v.isTouchMove) //只操作为true的
v.isTouchMove = false;
})
startX = e.changedTouches[0].clientX
startY = e.changedTouches[0].clientY
return items
}
_touchmove(e, items) {
var index = e.currentTarget.dataset.index, //当前索引
touchMoveX = e.changedTouches[0].clientX, //滑动变化坐标
touchMoveY = e.changedTouches[0].clientY, //滑动变化坐标
//获取滑动角度
angle = this._angle({
X: startX,
Y: startY
}, {
X: touchMoveX,
Y: touchMoveY
});
items.forEach(function (v, i) {
v.isTouchMove = false
//滑动超过30度角 return
if (Math.abs(angle) > 30) return;
if (i == index) {
if (touchMoveX > startX) //右滑
v.isTouchMove = false
else //左滑
v.isTouchMove = true
}
})
return items
}
_angle(start, end) {
var _X = end.X - start.X,
_Y = end.Y - start.Y
//返回角度 /Math.atan()返回数字的反正切值
return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
}
}
export default touch
\ No newline at end of file
/**
* 用户相关服务
*/
const util = require('../utils/util.js');
const api = require('../config/api.js');
/**
* Promise封装wx.checkSession
*/
function checkSession() {
return new Promise(function(resolve, reject) {
wx.checkSession({
success: function() {
resolve(true);
},
fail: function() {
reject(false);
}
})
});
}
/**
* Promise封装wx.login
*/
function login() {
return new Promise(function(resolve, reject) {
wx.login({
success: function(res) {
if (res.code) {
console.log(res.code)
resolve(res);
} else {
reject(res);
}
},
fail: function(err) {
reject(err);
}
});
});
}
/**
* 调用微信登录
*/
function loginByWeixin(userInfo) {
return new Promise(function(resolve, reject) {
return login().then((res) => {
//登录远程服务器
util.request(api.AuthLoginByWeixin, {
code: res.code,
userInfo: userInfo
}, 'POST').then(res => {
if (res.errno === 0) {
//存储用户信息
wx.setStorageSync('userInfo', res.data.userInfo);
wx.setStorageSync('token', res.data.token);
resolve(res);
} else {
reject(res);
}
}).catch((err) => {
reject(err);
});
}).catch((err) => {
reject(err);
})
});
}
/**
* 判断用户是否登录
*/
function checkLogin() {
return new Promise(function(resolve, reject) {
if (wx.getStorageSync('userInfo') && wx.getStorageSync('token')) {
checkSession().then(() => {
resolve(true);
}).catch(() => {
reject(false);
});
} else {
reject(false);
}
});
}
module.exports = {
loginByWeixin,
checkLogin,
};
\ No newline at end of file
var api = require('../config/api.js');
var app = getApp();
function formatTime(date) {
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('-') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
/**
* 封封微信的的request
*/
function request(url, data = {}, method = "GET") {
return new Promise(function(resolve, reject) {
wx.request({
url: url,
data: data,
method: method,
header: {
'Content-Type': 'application/json',
'X-Litemall-Token': wx.getStorageSync('token')
},
success: function(res) {
if (res.statusCode == 200) {
if (res.data.errno == 501) {
// 清除登录相关内容
try {
wx.removeStorageSync('userInfo');
wx.removeStorageSync('token');
} catch (e) {
// Do something when catch error
}
// 切换到登录页面
wx.navigateTo({
url: '/pages/auth/login/login'
});
} else {
resolve(res.data);
}
} else {
reject(res.errMsg);
}
},
fail: function(err) {
reject(err)
}
})
});
}
function redirect(url) {
//判断页面是否需要登录
if (false) {
wx.redirectTo({
url: '/pages/auth/login/login'
});
return false;
} else {
wx.redirectTo({
url: url
});
}
}
function showErrorToast(msg) {
wx.showToast({
title: msg,
image: '/static/images/icon_error.png'
})
}
module.exports = {
formatTime,
request,
redirect,
showErrorToast
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment