添加Renard小程序

This commit is contained in:
Menethil
2018-08-25 10:19:24 +08:00
parent a50998e68f
commit 854bacf604
222 changed files with 17928 additions and 8 deletions

View File

@@ -9,6 +9,7 @@ import java.util.Map;
* 配置基类,该类实际持有所有的配置,子类只是提供代理访问方法
*/
abstract class BaseConfig {
//所有的配置均保存在该 HashMap 中
protected static Map<String, String> configs = new HashMap<>();

View File

@@ -1,8 +1,5 @@
package org.linlinjava.litemall.db.dao;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

View File

@@ -1,12 +1,7 @@
package org.linlinjava.litemall.db.service;
import com.github.pagehelper.PageHelper;
import org.linlinjava.litemall.db.dao.LitemallUserMapper;
import org.linlinjava.litemall.db.dao.StatMapper;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.domain.LitemallUserExample;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.List;

31
renard-wx/app.js Normal file
View File

@@ -0,0 +1,31 @@
var util = require('./utils/util.js');
var api = require('./config/api.js');
var user = require('./utils/user.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
}
})

78
renard-wx/app.json Normal file
View File

@@ -0,0 +1,78 @@
{
"pages": [
"pages/index/index",
"pages/catalog/catalog",
"pages/newGoods/newGoods",
"pages/hotGoods/hotGoods",
"pages/ucenter/index/index",
"pages/ucenter/address/address",
"pages/ucenter/addressAdd/addressAdd",
"pages/ucenter/footprint/footprint",
"pages/ucenter/order/order",
"pages/ucenter/orderDetail/orderDetail",
"pages/ucenter/coupon/coupon",
"pages/ucenter/collect/collect",
"pages/auth/login/login",
"pages/auth/register/register",
"pages/auth/reset/reset",
"pages/payResult/payResult",
"pages/comment/comment",
"pages/commentPost/commentPost",
"pages/topic/topic",
"pages/topicComment/topicComment",
"pages/topicDetail/topicDetail",
"pages/topicCommentPost/topicCommentPost",
"pages/brand/brand",
"pages/brandDetail/brandDetail",
"pages/search/search",
"pages/category/category",
"pages/cart/cart",
"pages/shopping/checkout/checkout",
"pages/goods/goods",
"pages/groupon/myGroupon/myGroupon",
"pages/groupon/grouponDetail/grouponDetail"
],
"window": {
"navigationBarTitleText": "Renard",
"enablePullDownRefresh": true,
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTextStyle": "black"
},
"tabBar": {
"color": "#6e6d6b",
"selectedColor": "#e64340",
"borderStyle": "white",
"backgroundColor": "#fff",
"box-shadow": "0 0 6px 0",
"list": [
{
"pagePath": "pages/index/index",
"iconPath": "images/tabbar/like-f.png",
"selectedIconPath": "images/tabbar/like-o.png"
},
{
"pagePath": "pages/catalog/catalog",
"iconPath": "images/tabbar/menu-f.png",
"selectedIconPath": "images/tabbar/menu-o.png"
},
{
"pagePath": "pages/cart/cart",
"iconPath": "images/tabbar/cart-f.png",
"selectedIconPath": "images/tabbar/cart-o.png"
},
{
"pagePath": "pages/ucenter/index/index",
"iconPath": "images/tabbar/user-f.png",
"selectedIconPath": "images/tabbar/user-o.png"
}
]
},
"networkTimeout": {
"request": 10000,
"connectSocket": 10000,
"uploadFile": 10000,
"downloadFile": 10000
},
"debug": true
}

24
renard-wx/app.wxss Normal file
View File

@@ -0,0 +1,24 @@
/**app.wxss**/
.container {
box-sizing: border-box;
font-family: PingFangSC-Light,helvetica,'Heiti SC';
width: 100%;
height: 100%;
}
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: #a78845;
}
.wxParse-img {
display: block !important;
}

View File

@@ -0,0 +1,31 @@
'use strict';
Component({
externalClasses: ['custom-class'],
/**
* 组件的属性列表
* 用于组件自定义设置
*/
properties: {
// 颜色状态
type: {
type: String,
value: ''
},
// 自定义颜色
color: {
type: String,
value: ''
},
// 左侧内容
leftText: {
type: String,
value: ''
},
// 右侧内容
rightText: {
type: String,
value: ''
}
}
});

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,38 @@
// components/good/good.js
Component({
/**
* 组件的属性列表
*/
properties: {
title: { // 属性名
type: String, // 类型必填目前接受的类型包括String, Number, Boolean, Object, Array, null表示任意类型
value: '标题' // 属性初始值(可选),如果未指定则会根据类型选择一个
},
imageUrl: {
type: String,
value: ''
},
counterPrice: {
type: Number,
value: 0
},
retailPrice: {
type: Number,
value: 0
},
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

View File

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

View File

@@ -0,0 +1,8 @@
<view class="good">
<image class="img" src="{{imageUrl}}" background-size="cover"></image>
<view class="name">{{title}}</view>
<view class="price">
<view class="counterPrice" wx:if="{{counterPrice > retailPrice}}">原价:¥{{counterPrice}}</view>
<view class="retailPrice">现价:¥{{retailPrice}}</view>
</view>
</view>

View File

@@ -0,0 +1,41 @@
.good {
height: 480rpx;
width: 372rpx;
align-content: center;
}
.good .img {
width: 302rpx;
height: 302rpx;
z-index: 1;
}
.good .name {
text-align: center;
/* display: block; */
width: 372rpx;
height: 35rpx;
margin-bottom: 14rpx;
overflow: hidden;
font-size: 28rpx;
color: #333;
}
.good .price {
/* display: block; */
text-align: center;
line-height: 30rpx;
font-size: 28rpx;
color: #a78845;
}
.good .counterPrice {
text-decoration: line-through;
font-size: 24rpx;
color: #999;
}
.good .retailPrice {
font-size: 24rpx;
color: #a78845;
}

View File

@@ -0,0 +1,26 @@
// components/goodList/goodList.js
Component({
/**
* 组件的属性列表
*/
properties: {
goods: { // 属性名
type: Array, // 类型必填目前接受的类型包括String, Number, Boolean, Object, Array, null表示任意类型
value: [] // 属性初始值(可选),如果未指定则会根据类型选择一个
},
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"good": "../good/good"
}
}

View File

@@ -0,0 +1,9 @@
<view class="b" wx:if="{{goods.length > 0}}">
<block wx:for="{{goods}}" wx:for-index="iindex" wx:for-item="iitem" wx:key="id">
<view class="item {{iindex % 2 == 0 ? '' : 'item-b'}}">
<navigator url="../goods/goods?id={{iitem.id}}" class="a">
<good imageUrl='{{iitem.picUrl}}' title='{{iitem.name}}' retailPrice='{{iitem.retailPrice}}' counterPrice='{{iitem.counterPrice}}'></good>
</navigator>
</view>
</block>
</view>

View File

@@ -0,0 +1,33 @@
.b {
width: 750rpx;
padding: 0 6.25rpx;
height: auto;
overflow: hidden;
z-index: 1;
}
.b .good {
z-index: 1;
}
.b .item {
float: left;
background: #fff;
width: 365rpx;
margin-bottom: 6.25rpx;
height: 482rpx;
overflow: hidden;
text-align: center;
z-index: 1;
}
.b .item .a {
height: 452rpx;
width: 100%;
z-index: 1;
}
.b .item-b {
margin-left: 6.25rpx;
z-index: 1;
}

View File

@@ -0,0 +1,16 @@
Component({
externalClasses: ['custom-class'],
properties: {
info: null,
name: String,
size: String,
color: String
},
methods: {
onClick() {
this.triggerEvent('click');
}
}
});

View File

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

View File

@@ -0,0 +1,7 @@
<view
class="custom-class van-icon van-icon-{{ name }}"
style="{{ color ? 'color: ' + color : '' }}; {{ size ? 'font-size: ' + size : '' }}"
bind:tap="onClick"
>
<view wx:if="{{ info !== null }}" class="van-icon__info">{{ info }}</view>
</view>

View File

@@ -0,0 +1 @@
@font-face{font-style:normal;font-weight:400;font-family:vant-icon;src:url(https://img.yzcdn.cn/vant/vant-icon-eb8c95.ttf) format('truetype')}.van-icon{position:relative;display:inline-block;font:normal normal normal 14px/1 vant-icon;font-size:inherit;text-rendering:auto}.van-icon__info{color:#fff;left:100%;top:-.5em;font-size:.5em;padding:0 .3em;text-align:center;min-width:1.2em;line-height:1.2;position:absolute;border-radius:.6em;box-sizing:border-box;background-color:#f44;-webkit-transform:translateX(-50%);transform:translateX(-50%);font-family:PingFang SC,Helvetica Neue,Arial,sans-serif}.van-icon::before{display:inline-block}.van-icon-add-o::before{content:"\F000"}.van-icon-add::before{content:"\F001"}.van-icon-add2::before{content:"\F002"}.van-icon-after-sale::before{content:"\F003"}.van-icon-alipay::before{content:"\F004"}.van-icon-arrow-left::before{content:"\F005"}.van-icon-arrow::before{content:"\F006"}.van-icon-balance-pay::before{content:"\F007"}.van-icon-browsing-history::before{content:"\F008"}.van-icon-card::before{content:"\F009"}.van-icon-cart::before{content:"\F00A"}.van-icon-cash-back-record::before{content:"\F00B"}.van-icon-cash-on-deliver::before{content:"\F00C"}.van-icon-certificate::before{content:"\F00D"}.van-icon-chat::before{content:"\F00E"}.van-icon-check::before{content:"\F00F"}.van-icon-checked::before{content:"\F010"}.van-icon-clear::before{content:"\F011"}.van-icon-clock::before{content:"\F012"}.van-icon-close::before{content:"\F013"}.van-icon-completed::before{content:"\F014"}.van-icon-contact::before{content:"\F015"}.van-icon-coupon::before{content:"\F016"}.van-icon-credit-pay::before{content:"\F017"}.van-icon-debit-pay::before{content:"\F018"}.van-icon-delete::before{content:"\F019"}.van-icon-description::before{content:"\F01A"}.van-icon-discount::before{content:"\F01B"}.van-icon-ecard-pay::before{content:"\F01C"}.van-icon-edit-data::before{content:"\F01D"}.van-icon-edit::before{content:"\F01E"}.van-icon-exchange-record::before{content:"\F01F"}.van-icon-exchange::before{content:"\F020"}.van-icon-fail::before{content:"\F021"}.van-icon-free-postage::before{content:"\F022"}.van-icon-gift-card-pay::before{content:"\F023"}.van-icon-gift-card::before{content:"\F024"}.van-icon-gift::before{content:"\F025"}.van-icon-gold-coin::before{content:"\F026"}.van-icon-goods-collect::before{content:"\F027"}.van-icon-home::before{content:"\F028"}.van-icon-hot-sale::before{content:"\F029"}.van-icon-hot::before{content:"\F02A"}.van-icon-idcard::before{content:"\F02B"}.van-icon-info-o::before{content:"\F02C"}.van-icon-like-o::before{content:"\F02D"}.van-icon-like::before{content:"\F02E"}.van-icon-location::before{content:"\F02F"}.van-icon-logistics::before{content:"\F030"}.van-icon-more-o::before{content:"\F031"}.van-icon-more::before{content:"\F032"}.van-icon-new-arrival::before{content:"\F033"}.van-icon-new::before{content:"\F034"}.van-icon-other-pay::before{content:"\F035"}.van-icon-passed::before{content:"\F036"}.van-icon-password-not-view::before{content:"\F037"}.van-icon-password-view::before{content:"\F038"}.van-icon-pause::before{content:"\F039"}.van-icon-peer-pay::before{content:"\F03A"}.van-icon-pending-deliver::before{content:"\F03B"}.van-icon-pending-evaluate::before{content:"\F03C"}.van-icon-pending-orders::before{content:"\F03D"}.van-icon-pending-payment::before{content:"\F03E"}.van-icon-phone::before{content:"\F03F"}.van-icon-photo::before{content:"\F040"}.van-icon-photograph::before{content:"\F041"}.van-icon-play::before{content:"\F042"}.van-icon-point-gift::before{content:"\F043"}.van-icon-points-mall::before{content:"\F044"}.van-icon-points::before{content:"\F045"}.van-icon-qr-invalid::before{content:"\F046"}.van-icon-qr::before{content:"\F047"}.van-icon-question::before{content:"\F048"}.van-icon-receive-gift::before{content:"\F049"}.van-icon-records::before{content:"\F04A"}.van-icon-search::before{content:"\F04B"}.van-icon-send-gift::before{content:"\F04C"}.van-icon-setting::before{content:"\F04D"}.van-icon-share::before{content:"\F04E"}.van-icon-shop-collect::before{content:"\F04F"}.van-icon-shop::before{content:"\F050"}.van-icon-shopping-cart::before{content:"\F051"}.van-icon-sign::before{content:"\F052"}.van-icon-stop::before{content:"\F053"}.van-icon-success::before{content:"\F054"}.van-icon-tosend::before{content:"\F055"}.van-icon-underway::before{content:"\F056"}.van-icon-upgrade::before{content:"\F057"}.van-icon-value-card::before{content:"\F058"}.van-icon-wap-home::before{content:"\F059"}.van-icon-wap-nav::before{content:"\F05A"}.van-icon-warn::before{content:"\F05B"}.van-icon-wechat::before{content:"\F05C"}

View File

@@ -0,0 +1,177 @@
const VALID_MODE = ['closeable', 'link'];
const FONT_COLOR = '#f60';
const BG_COLOR = '#fff7cc';
Component({
externalClasses: ['custom-class'],
properties: {
text: {
type: String,
value: '',
observer() {
this.setData({}, this._init);
}
},
mode: {
type: String,
value: ''
},
url: {
type: String,
value: ''
},
openType: {
type: String,
value: 'navigate'
},
delay: {
type: Number,
value: 0
},
speed: {
type: Number,
value: 50
},
scrollable: {
type: Boolean,
value: true
},
leftIcon: {
type: String,
value: ''
},
color: {
type: String,
value: FONT_COLOR
},
backgroundColor: {
type: String,
value: BG_COLOR
}
},
data: {
show: true,
hasRightIcon: false,
width: undefined,
wrapWidth: undefined,
elapse: undefined,
animation: null,
resetAnimation: null,
timer: null
},
attached() {
const { mode } = this.data;
if (mode && this._checkMode(mode)) {
this.setData({
hasRightIcon: true
});
}
},
detached() {
const { timer } = this.data;
timer && clearTimeout(timer);
},
methods: {
_checkMode(val) {
const isValidMode = ~VALID_MODE.indexOf(val);
if (!isValidMode) {
console.warn(`mode only accept value of ${VALID_MODE}, now get ${val}.`);
}
return isValidMode;
},
_init() {
wx.createSelectorQuery()
.in(this)
.select('.van-notice-bar__content')
.boundingClientRect((rect) => {
if (!rect || !rect.width) {
return;
}
this.setData({
width: rect.width
});
wx.createSelectorQuery()
.in(this)
.select('.van-notice-bar__content-wrap')
.boundingClientRect((rect) => {
if (!rect || !rect.width) {
return;
}
const wrapWidth = rect.width;
const {
width, speed, scrollable, delay
} = this.data;
if (scrollable && wrapWidth < width) {
const elapse = width / speed * 1000;
const animation = wx.createAnimation({
duration: elapse,
timeingFunction: 'linear',
delay
});
const resetAnimation = wx.createAnimation({
duration: 0,
timeingFunction: 'linear'
});
this.setData({
elapse,
wrapWidth,
animation,
resetAnimation
}, () => {
this._scroll();
});
}
})
.exec();
})
.exec();
},
_scroll() {
const {
animation, resetAnimation, wrapWidth, elapse, speed
} = this.data;
resetAnimation.translateX(wrapWidth).step();
const animationData = animation.translateX(-(elapse * speed) / 1000).step();
this.setData({
animationData: resetAnimation.export()
});
setTimeout(() => {
this.setData({
animationData: animationData.export()
});
}, 100);
const timer = setTimeout(() => {
this._scroll();
}, elapse);
this.setData({
timer
});
},
_handleButtonClick() {
const { timer } = this.data;
timer && clearTimeout(timer);
this.setData({
show: false,
timer: null
});
},
onClick(event) {
this.triggerEvent('click', event);
}
}
});

View File

@@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}

View File

@@ -0,0 +1,31 @@
<view
wx:if="{{ show }}"
class="custom-class van-notice-bar {{ hasRightIcon ? 'van-notice-bar--within-icon' : '' }}"
style="color: {{ color }};background-color: {{ backgroundColor }}"
bind:tap="onClick"
>
<view wx:if="{{ leftIcon }}" class="van-notice-bar__left-icon">
<image src="{{ leftIcon }}" />
</view>
<view class="van-notice-bar__content-wrap">
<view class="van-notice-bar__content" animation="{{ animationData }}">
{{ text }}
</view>
</view>
<block wx:if="{{ mode }}">
<van-icon
wx:if="{{ mode === 'closeable' }}"
class="van-notice-bar__right-icon"
name="close"
bind:tap="_handleButtonClick"
/>
<navigator
wx:if="{{ mode === 'link' }}"
url="{{ url }}"
open-type="{{ openType }}"
>
<van-icon class="van-notice-bar__right-icon" name="arrow" />
</navigator>
</block>
</view>

View File

@@ -0,0 +1 @@
.van-notice-bar{display:-webkit-box;display:-webkit-flex;display:flex;padding:9px 10px;font-size:12px;line-height:1.5}.van-notice-bar--within-icon{position:relative;padding-right:30px}.van-notice-bar__left-icon{height:18px;min-width:20px;padding-top:1px;box-sizing:border-box}.van-notice-bar__left-icon>image{width:16px;height:16px}.van-notice-bar__right-icon{position:absolute;top:10px;right:10px;font-size:15px;line-height:1}.van-notice-bar__content-wrap{position:relative;-webkit-box-flex:1;-webkit-flex:1;flex:1;height:18px;overflow:hidden}.van-notice-bar__content{position:absolute;white-space:nowrap}

View File

@@ -0,0 +1,69 @@
Component({
properties: {
text: String,
color: {
type: String,
value: '#fff'
},
backgroundColor: {
type: String,
value: '#e64340'
},
duration: {
type: Number,
value: 3000
}
},
methods: {
show() {
const { duration } = this.data;
clearTimeout(this.timer);
this.setData({
show: true
});
if (duration > 0 && duration !== Infinity) {
this.timer = setTimeout(() => {
this.hide();
}, duration);
}
},
hide() {
clearTimeout(this.timer);
this.setData({
show: false
});
}
}
});
const defaultOptions = {
selector: '#van-notify',
duration: 3000
};
function Notify(options = {}) {
const pages = getCurrentPages();
const ctx = pages[pages.length - 1];
options = Object.assign({}, defaultOptions, parseParam(options));
const el = ctx.selectComponent(options.selector);
delete options.selector;
if (el) {
el.setData({
...options
});
el.show();
}
}
function parseParam(params = '') {
return typeof params === 'object' ? params : { text: params };
}
module.exports = Notify;

View File

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

View File

@@ -0,0 +1,6 @@
<view
class="van-notify {{ show ? 'van-notify--show' : '' }}"
style="background-color:{{ backgroundColor }}"
>
{{ text }}
</view>

View File

@@ -0,0 +1 @@
.van-notify{top:0;opacity:0;width:100%;z-index:110;color:#fff;position:fixed;min-height:32px;line-height:2.3;font-size:14px;text-align:center;background-color:#e64340;-webkit-transition:all .4s ease;transition:all .4s ease;-webkit-transform:translateZ(0) translateY(-100%);transform:translateZ(0) translateY(-100%)}.van-notify--show{opacity:1;-webkit-transform:translateZ(0) translateY(0);transform:translateZ(0) translateY(0)}

View File

@@ -0,0 +1,86 @@
// components/sharePop/sharePop.js
Component({
/**
* 组件的属性列表
*/
properties: {
url: {
type: String,
value: '', // 属性值 (可选)
},
bottom:{
type: Number,
value: 0, // 属性值 (可选)
}
},
/**
* 组件的初始数据
*/
data: {
// 弹窗显示控制
showPop: false,
},
/**
* 组件的方法列表
*/
methods: {
closeShare: function() {
this.setData({
showPop: false,
});
},
togglePopup: function() {
let that = this;
this.setData({
showPop: !this.data.showPop,
});
},
// 保存分享图
_saveShare: function() {
wx.showLoading({
title: '加载中',
});
setTimeout(function() {
wx.hideLoading()
}, 2000);
let that = this;
wx.downloadFile({
url: that.data.url,
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('用户点击确定');
}
}
});
wx.hideLoading();
},
fail: function(res) {
console.log('fail')
}
})
},
fail: function() {
console.log('fail')
}
})
},
}
})

View File

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

View File

@@ -0,0 +1,17 @@
<view class="share-pop-box" hidden="{{!showPop}}">
<view class="share-pop" style='bottom:{{bottom}}rpx;'>
<view class="close" bindtap="closeShare">
<image class="icon" src="/static/images/icon_close.png"></image>
</view>
<view class="share-items">
<view class='share-touser'>
<button style="opacity:0;height: 160rpx;width: 160rpx;" open-type="share">分享给朋友
</button>
</view>
<view class='share-friend'>
<button style="opacity:0;height: 160rpx;width: 160rpx;" bindtap="_saveShare">分享朋友圈
</button>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1,62 @@
.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: 400rpx;
max-height: 780rpx;
padding: 31.25rpx;
background: #fff;
position: fixed;
z-index: 9;
bottom: 0rpx;
}
.share-pop .close {
position: absolute;
width: 48rpx;
height: 48rpx;
right: 31.25rpx;
overflow: hidden;
top: 31.25rpx;
}
.share-pop .close .icon {
width: 48rpx;
height: 48rpx;
}
.share-pop .share-items {
margin-top: 80rpx;
flex-flow: row;
display: flex;
justify-content: space-around;
}
.share-pop .share-touser {
height: 160rpx;
width: 160rpx;
background: url("https://litemall-1256968571.file.myqcloud.com/icon/%E5%88%86%E4%BA%AB_%E5%BE%AE%E4%BF%A1.png") no-repeat center 1rpx;
background-size: 160rpx auto;
border-radius: 80rpx;
}
.share-pop .share-friend {
height: 160rpx;
width: 160rpx;
background: url("https://litemall-1256968571.file.myqcloud.com/icon/%E5%88%86%E4%BA%AB_%E5%BE%AE%E4%BF%A1%E6%9C%8B%E5%8F%8B%E5%9C%88.png") no-repeat center 1rpx;
background-size: 160rpx auto;
border-radius: 10rpx;
}
.share-pop image {
height: 120rpx;
width: 120rpx;
}

85
renard-wx/config/api.js Normal file
View File

@@ -0,0 +1,85 @@
// 以下是业务服务器API地址
// 本机开发时使用
var WxApiRoot = 'http://192.168.1.105:8082/wx/';
// 云平台上线时使用
// var WxApiRoot = 'https://litemall.menethil.com.cn/wx/';
// var WxApiRoot = 'https://www.menethil.com.cn/wx/';
module.exports = {
IndexUrl: WxApiRoot + 'home/index', //首页数据接口
CatalogList: WxApiRoot + 'catalog/index', //分类目录全部分类数据接口
CatalogCurrent: WxApiRoot + 'catalog/current', //分类目录当前分类数据接口
CatalogAll: WxApiRoot + 'catalog/all', //分类目录当前分类数据接口
AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录
AuthLoginByAccount: WxApiRoot + 'auth/login', //账号登录
AuthRegister: WxApiRoot + 'auth/register', //账号注册
AuthReset: WxApiRoot + 'auth/reset', //账号密码重置
AuthRegisterCaptcha: WxApiRoot + 'auth/regCaptcha', //验证码
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', //保存收货地址
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', //确认收货
OrderComment: WxApiRoot + 'order/comment', // 代评价商品信息
FootprintList: WxApiRoot + 'footprint/list', //足迹列表
FootprintDelete: WxApiRoot + 'footprint/delete', //删除足迹
UserFormIdCreate: WxApiRoot + 'formid/create', //用户FromId用于发送模版消息
GroupOn: WxApiRoot + 'groupon/query', //团购API-查询
GroupOnMy: WxApiRoot + 'groupon/my', //团购API-我的团购
GroupOnDetail: WxApiRoot + 'groupon/detail', //团购API-详情
GroupOnJoin: WxApiRoot + 'groupon/join', //团购API-详情
StorageUpload: WxApiRoot + 'storage/upload' //图片上传
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -0,0 +1,242 @@
/**
* 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
};

View File

@@ -0,0 +1,182 @@
/**
* 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;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,206 @@
// 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
}

View File

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

View File

@@ -0,0 +1,928 @@
<!--**
* 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>

View File

@@ -0,0 +1,202 @@
/**
* 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;
}

View File

@@ -0,0 +1,140 @@
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 () {
// 页面关闭
},
wxLogin: function (e) {
if (e.detail.userInfo == undefined){
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
return;
}
user.checkLogin().catch(() => {
user.loginByWeixin(e.detail.userInfo).then(res => {
app.globalData.hasLogin = true;
wx.navigateBack({
delta: 1
})
}).catch((err) => {
app.globalData.hasLogin = false;
util.showErrorToast('微信登录失败');
});
});
},
accountLogin: function () {
var that = this;
if (this.data.password.length < 1 || this.data.username.length < 1) {
wx.showModal({
title: '错误信息',
content: '请输入用户名和密码',
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;
}
}
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "登录"
}

View File

@@ -0,0 +1,32 @@
<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 type="default" 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> -->
<button type="primary" open-type="getUserInfo" class="login-btn" bindgetuserinfo="wxLogin">微信直接登录</button>
</view>
</view>

View File

@@ -0,0 +1,90 @@
.form-box{
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 96rpx;
background: #fff;
}
.form-item{
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #a78845;
}
.form-item .username, .form-item .password, .form-item .code{
position: absolute;
top: 26rpx;
left: 0;
display: block;
width: 100%;
height: 44rpx;
background: #fff;
color: #a78845;
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{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
color: #a78845;
font-size: 30rpx;
width: 100%;
background: #b4282d;
border-radius: 6rpx;
}
.form-item-text{
height: 35rpx;
width: 100%;
color: #a78845;
}
.form-item-text .register{
display: block;
height: 34rpx;
float: left;
font-size: 28rpx;
color: #a78845;
}
.form-item-text .reset{
display: block;
height: 34rpx;
float: right;
font-size: 28rpx;
color: #a78845;
}

View File

@@ -0,0 +1,174 @@
var api = require('../../../config/api.js');
var check = require('../../../utils/check.js');
var app = getApp();
Page({
data: {
username: '',
password: '',
confirmPassword: '',
mobile: '',
code: ''
},
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function () {
},
onShow: function () {
// 页面显示
},
onHide: function () {
// 页面隐藏
},
onUnload: function () {
// 页面关闭
},
sendCode: function () {
wx.showModal({
title: '注意',
content: '由于目前不支持手机短信发送,因此验证码任意值都可以',
showCancel: false
});
},
startRegister: function () {
var that = this;
if (this.data.password.length < 3 || this.data.username.length < 3) {
wx.showModal({
title: '错误信息',
content: '用户名和密码不得少于3位',
showCancel: false
});
return false;
}
if (this.data.password != this.data.confirmPassword) {
wx.showModal({
title: '错误信息',
content: '确认密码不一致',
showCancel: false
});
return false;
}
if (this.data.mobile.length == 0 || this.data.code.length == 0) {
wx.showModal({
title: '错误信息',
content: '手机号和验证码不能为空',
showCancel: false
});
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
wx.showModal({
title: '错误信息',
content: '手机号输入不正确',
showCancel: false
});
return false;
}
wx.request({
url: api.AuthRegister,
data: {
username: that.data.username,
password: that.data.password,
mobile: that.data.mobile,
code: that.data.code
},
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({
title: '错误信息',
content: res.data.errmsg,
showCancel: false
});
}
}
});
},
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;
}
}
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "注册"
}

View File

@@ -0,0 +1,35 @@
<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" 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" bindtap="sendCode">获取验证码</view>
</view>
<button type="default" class="register-btn" bindtap="startRegister">注册</button>
</view>
</view>

View File

@@ -0,0 +1,69 @@
.form-box{
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 96rpx;
background: #fff;
}
.form-item{
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #a78845;
}
.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: #a78845;
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-btn{
float: right;
padding: 20rpx 40rpx;
border: 1px solid #d9d9d9;
color: #a78845;
border-radius: 10rpx;
}
.form-item .clear{
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.register-btn{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
color: #a78845;
font-size: 30rpx;
width: 100%;
background: #b4282d;
border-radius: 6rpx;
}

View File

@@ -0,0 +1,151 @@
var api = require('../../../config/api.js');
var check = require('../../../utils/check.js');
var app = getApp();
Page({
data: {
mobile: '',
code: '',
password: '',
confirmPassword: ''
},
onLoad: function (options) {
// 页面初始化 options为页面跳转所带来的参数
// 页面渲染完成
},
onReady: function () {
},
onShow: function () {
// 页面显示
},
onHide: function () {
// 页面隐藏
},
onUnload: function () {
// 页面关闭
},
sendCode: function () {
wx.showModal({
title: '注意',
content: '由于目前不支持手机短信发送,因此验证码任意值都可以',
showCancel: false
});
},
startReset: function(){
var that = this;
if (this.data.mobile.length == 0 || this.data.code.length == 0) {
wx.showModal({
title: '错误信息',
content: '手机号和验证码不能为空',
showCancel: false
});
return false;
}
if (!check.isValidPhone(this.data.mobile)) {
wx.showModal({
title: '错误信息',
content: '手机号输入不正确',
showCancel: false
});
return false;
}
if (this.data.password.length < 3) {
wx.showModal({
title: '错误信息',
content: '用户名和密码不得少于3位',
showCancel: false
});
return false;
}
if (this.data.password != this.data.confirmPassword) {
wx.showModal({
title: '错误信息',
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: '密码重置失败',
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;
}
}
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "密码重置"
}

View File

@@ -0,0 +1,30 @@
<view class="container">
<view class="form-box">
<view class="form-item">
<input class="mobile" value="{{mobile}}" 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" bindtap="sendCode">获取验证码</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 type="default" class="reset-btn" bindtap="startReset">密码重置</button>
</view>
</view>

View File

@@ -0,0 +1,68 @@
.form-box{
width: 100%;
height: auto;
overflow: hidden;
padding: 0 40rpx;
margin-top: 96rpx;
background: #fff;
}
.form-item{
position: relative;
background: #fff;
height: 96rpx;
border-bottom: 1px solid #d9d9d9;
}
.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{
margin-top:32rpx;
height: auto;
overflow: hidden;
width: 100%;
}
.form-item-code .form-item{
float: left;
width: 350rpx;
}
.form-item-code .code-btn{
float: right;
padding: 20rpx 40rpx;
border: 1px solid #d9d9d9;
border-radius: 10rpx;
}
.form-item .clear{
position: absolute;
top: 26rpx;
right: 18rpx;
z-index: 2;
display: block;
background: #fff;
height: 44rpx;
width: 44rpx;
}
.reset-btn{
margin: 60rpx 0 40rpx 0;
height: 96rpx;
line-height: 96rpx;
color: #fff;
font-size: 30rpx;
width: 100%;
background: #b4282d;
border-radius: 6rpx;
}

View File

@@ -0,0 +1,59 @@
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();
},
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
});
}
wx.hideLoading();
});
},
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() {
// 页面关闭
}
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "品牌商直供"
}

View File

@@ -0,0 +1,14 @@
<view class="container">
<view class="brand-list">
<navigator url="../brandDetail/brandDetail?id={{item.id}}" class="item" wx:for="{{brandList}}" wx:key="id">
<view class="img-bg">
<image src="{{item.picUrl}}" background-size="cover"></image>
</view>
<view class="txt-box">
<view class="line">
<text class="name">{{item.name}}</text>
</view>
</view>
</navigator>
</view>
</view>

View File

@@ -0,0 +1,52 @@
.brand-list .item{
display: block;
width: 750rpx;
height: 416rpx;
position: relative;
margin-bottom: 4rpx;
}
.brand-list .item .img-bg{
position: absolute;
left:0;
top:0;
z-index: 0;
width: 750rpx;
height: 417rpx;
overflow: hidden;
}
.brand-list .item .img-bg image{
width: 750rpx;
height: 416rpx;
}
.brand-list .item .txt-box{
position: absolute;
left:0;
top:0;
display: table;
z-index: 0;
width: 750rpx;
height: 417rpx;
}
.brand-list .item .line{
display: table-cell;
vertical-align: middle;
text-align: center;
height: 63rpx;
line-height: 63rpx;
}
.brand-list .item .line text{
font-size: 35rpx;
font-weight: 700;
text-shadow: 1rpx 1rpx rgba(0,0,0,.32);
color: #fff;
}
.brand-list .item .line .s{
padding: 0 10rpx;
font-size: 40rpx;
}

View File

@@ -0,0 +1,69 @@
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
},
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.getGoodsList();
}
});
},
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() {
// 页面关闭
}
})

View File

@@ -0,0 +1,6 @@
{
"navigationBarTitleText": "品牌商详情",
"usingComponents": {
"goodList": "/components/goodList/goodList"
}
}

View File

@@ -0,0 +1,20 @@
<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>
<view class="desc">
{{brand.desc}}
</view>
</view>
<view class="cate-item">
<goodList calss="goodList" goods="{{goodsList}}"></goodList>
</view>
</view>

View File

@@ -0,0 +1,61 @@
page {
background: #f4f4f4;
}
.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;
height: 37.5rpx;
font-size: 37.5rpx;
color: #fff;
}
.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;
padding: 41.5rpx 31.25rpx;
font-size: 30rpx;
color: #666;
line-height: 41.5rpx;
text-align: center;
}

View File

@@ -0,0 +1,305 @@
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() {
// 页面渲染完成
},
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"
});
},
onPullDownRefresh() {
wx.showNavigationBarLoading() //在标题栏中显示加载
this.getCartList();
wx.hideNavigationBarLoading() //完成停止加载
wx.stopPullDownRefresh() //停止下拉刷新
},
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) {
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()
});
}
},
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()
});
});
},
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: '../shopping/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;
}
});
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()
});
});
}
})

View File

@@ -0,0 +1,4 @@
{
"backgroundColor": "#f4f4f4",
"navigationBarTitleText": "购物车"
}

View File

@@ -0,0 +1,59 @@
<view class="container">
<view class="no-login" wx:if="{{!hasLogin}}">
<view class="c">
<image src="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>还没有登录</text>
<button plain="true" 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="http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/noCart-a8fe3f12e5.png" />
<text>去添加点什么吧</text>
</view>
</view>
<view class="cart-view" wx:else>
<view class="list">
<view class="group-item">
<view class="goods">
<view class="item {{isEditCart ? 'edit' : ''}}" wx:for="{{cartGoods}}" wx:key="id">
<view class="checkbox {{item.checked ? 'checked' : ''}}" bindtap="checkedItem" data-item-index="{{index}}"></view>
<view class="cart-goods">
<image class="img" src="{{item.picUrl}}"></image>
<view class="info">
<view class="t">
<text class="name">{{item.goodsName}}</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>
<view class="selnum">
<view class="cut" bindtap="cutNumber" data-item-index="{{index}}">-</view>
<input value="{{item.number}}" class="number" disabled="true" type="number" />
<view class="add" bindtap="addNumber" data-item-index="{{index}}">+</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="cart-bottom">
<view class="checkbox {{checkedAllStatus ? 'checked' : ''}}" bindtap="checkedAll">全选({{cartTotal.checkedGoodsCount}})</view>
<view class="total">{{!isEditCart ? '¥'+cartTotal.checkedGoodsAmount : ''}}</view>
<view class="delete" bindtap="editCart">{{!isEditCart ? '编辑' : '完成'}}</view>
<view class="checkout" bindtap="deleteCart" wx:if="{{isEditCart}}">删除所选</view>
<view class="checkout" bindtap="checkoutOrder" wx:if="{{!isEditCart}}">下单</view>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1,394 @@
page {
height: 100%;
min-height: 100%;
background: #f4f4f4;
}
.container {
background: #f4f4f4;
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: #a78845;
}
.no-login {
width: 100%;
height: auto;
margin: 0 auto;
color: #a78845;
}
.no-login .c {
width: 100%;
height: auto;
margin-top: 200rpx;
color: #a78845;
}
.no-login .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
color: #a78845;
}
.no-login .c text {
margin: 0 auto;
display: block;
width: 258rpx;
height: 59rpx;
line-height: 29rpx;
text-align: center;
font-size: 40rpx;
color: #a78845;
}
.no-login button {
width: 60%;
margin: 0 auto;
color: #a78845;
/* background-color: #FFF; */
border-color: #a78845;
}
.no-cart {
width: 100%;
height: auto;
margin: 0 auto;
color: #a78845;
}
.no-cart .c {
width: 100%;
height: auto;
margin-top: 200rpx;
}
.no-cart .c image {
margin: 0 auto;
display: block;
text-align: center;
width: 258rpx;
height: 258rpx;
}
.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;
}
.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;
width: 100%;
overflow: hidden;
}
.cart-view .item .checkbox {
float: left;
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;
}
.cart-view .item .checkbox.checked {
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/checkbox-checked-822e54472a.png) no-repeat;
background-size: 34rpx;
}
.cart-view .item .cart-goods {
float: left;
height: 164rpx;
width: 672rpx;
border-bottom: 1px solid #f4f4f4;
}
.cart-view .item .img {
float: left;
height: 125rpx;
width: 125rpx;
background: #f4f4f4;
margin: 19.5rpx 18rpx 19.5rpx 0;
}
.cart-view .item .info {
float: left;
height: 125rpx;
width: 503rpx;
margin: 19.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;
font-size: 25rpx;
color: #333;
overflow: hidden;
}
.cart-view .item .num {
height: 28rpx;
line-height: 28rpx;
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: 28rpx;
line-height: 28rpx;
font-size: 25rpx;
color: #333;
overflow: hidden;
}
.cart-view .item .price {
float: left;
color: #a78845;
}
.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: 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 {
width: 235rpx;
height: 52rpx;
border: 1rpx solid #ccc;
display: flex;
}
.selnum .cut {
width: 70rpx;
height: 100%;
text-align: center;
line-height: 50rpx;
}
.selnum .number {
flex: 1;
height: 100%;
text-align: center;
line-height: 68.75rpx;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
float: left;
}
.selnum .add {
width: 80rpx;
height: 100%;
text-align: center;
line-height: 50rpx;
}
.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;
}
.cart-bottom .checkbox {
height: 34rpx;
padding-left: 60rpx;
line-height: 34rpx;
margin: 33rpx 18rpx 33rpx 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;
font-size: 29rpx;
}
.cart-bottom .checkbox.checked {
background: url(http://nos.netease.com/mailpub/hxm/yanxuan-wap/p/20150730/style/img/icon-normal/checkbox-checked-822e54472a.png) no-repeat;
background-size: 34rpx;
}
.cart-bottom .total {
height: 34rpx;
flex: 1;
margin: 33rpx 10rpx;
font-size: 29rpx;
color: #a78845;
}
.cart-bottom .delete {
height: 34rpx;
width: auto;
margin: 33rpx 18rpx;
font-size: 29rpx;
}
.cart-bottom .checkout {
height: 100rpx;
width: 210rpx;
text-align: center;
line-height: 100rpx;
font-size: 29rpx;
background: #a78845;
color: #fff;
}

View File

@@ -0,0 +1,82 @@
var util = require('../../utils/util.js');
var api = require('../../config/api.js');
Page({
data: {
categoryList: [],
currentCategory: {},
currentSubCategoryList: {},
allList: {},
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.CatalogAll).then(function(res) {
that.setData({
allList: res.data.allList,
categoryList: res.data.categoryList,
currentCategory: res.data.currentCategory,
currentSubCategoryList: res.data.currentSubCategory
});
});
wx.hideLoading();
},
getCurrentCategory: function(item) {
let that = this;
for (var key in that.data.allList) {
if (key == item.id) {
that.setData({
currentCategory: item,
currentSubCategoryList: that.data.allList[key]
});
}
}
},
onReady: function() {
// 页面渲染完成
},
onShow: function() {
// 页面显示
},
onHide: function() {
// 页面隐藏
},
onUnload: function() {
// 页面关闭
},
switchCate: function(event) {
if (this.data.currentCategory.id == event.currentTarget.dataset.id) {
return false;
}
this.getCurrentCategory(event.currentTarget.dataset.id);
},
levelClick: function(e) {
console.log(e.currentTarget.dataset.id)
wx.navigateTo({
url: "/pages/category/category?id=" + e.currentTarget.dataset.id
})
}
})

View File

@@ -0,0 +1,3 @@
{
"navigationBarTitleText": "分类"
}

View File

@@ -0,0 +1,32 @@
<view class="container">
<view class="search">
<navigator url="/pages/search/search" class="input">
<image class="icon"></image>
<text class="txt">搜索</text>
</navigator>
</view>
<view class="HotName">分类
<text></text>
</view>
<view class="menu-box">
<view wx:for-items="{{categoryList}}" wx:key="id" class="menu-box-list">
<view class="menu-list-title {{currentCategory.id==item.id?'hover':''}}" bindtap="switchCate" id="{{item}}" data-id="{{item}}" data-index="{{index}}">
<text class="{{currentCategory.id==item.id ?'l':''}}"></text> {{item.name}}
<text class="{{currentCategory.id==item.id ?'r':''}}"></text>
</view>
<view class="menu-list-pro" if="{{item.level == 2}}" id="{{item.id}}">
<view class="menu-list-pro" hidden="{{currentCategory.id==item.id ? '':'true'}}">
<!--<navigator url="/pages/category/category?id={{item.id}}" wx:key="id" wx:for="{{currentSubCategoryList}}">
<image class="icon" src="{{item.wapBannerUrl}}"></image>
</navigator>-->
<view class="menu-list-item" wx:for-items="{{currentSubCategoryList}}" wx:key="id" bindtap="levelClick" data-id="{{item.id}}">
<image class="icon" src="{{item.iconUrl}}"></image>
<text class="txt">{{item.name}}</text>
</view>
</view>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1,135 @@
.HotName{
font-size:80rpx;
margin-left:40rpx;
color:#293539;
font-weight:300;
position: relative;
}
.HotName text{
width:14rpx;
height:14rpx;
position:absolute;
border:2px solid #a78845;
border-radius:50%;
}
.menu-box{
width:80%;
margin:0 auto;
margin-top:40rpx;
}
.menu-box-list{
text-align:center;
margin-bottom:30rpx;
}
.menu-box-list .menu-list-title{
color:#6a7275;
font-size:40rpx;
font-weight:300;
letter-spacing:20rpx;
position: relative;
}
.menu-box-list .hover{
color:#a78845;
}
.menu-box-list .hover .l{
width:10rpx;
height:10rpx;
position:absolute;
border:2rpx solid #a78845;
border-radius:50%;
margin-left:-38rpx;
margin-top:30rpx;
}
.menu-box-list .hover .r{
width:10rpx;
height:10rpx;
position:absolute;
border:2rpx solid #a78845;
border-radius:50%;
margin-left:6rpx;
margin-top:30rpx;
}
.menu-list-pro{
overflow-x: scroll;
margin-top: 40rpx;
white-space:nowrap;
text-overflow:ellipsis;
height: auto;
width: 100%;
overflow: hidden;
}
.menu-list-pro .menu-list-item {
display: block;
float: left;
height: 240rpx;
width: 120rpx;
margin-right: 30rpx;
}
.menu-list-pro .icon {
height: 100rpx;
width: 100rpx;
border-radius:12rpx;
box-shadow:0px 4rpx 4rpx 0px #cfc9ca;
}
.menu-list-pro .txt {
display: block;
float: left;
width: 120rpx;
color: #a78845;
}
.search {
height: 88rpx;
width: 100%;
padding: 0 30rpx;
background: #fff;
display: flex;
align-items: center;
}
.search .input {
width: 690rpx;
height: 56rpx;
background: #ededed;
border-radius: 8rpx;
display: flex;
align-items: center;
justify-content: center;
}
.search .icon {
background: url(http://yanxuan.nosdn.127.net/hxm/yanxuan-wap/p/20161201/style/img/icon-normal/search2-2fb94833aa.png) center no-repeat;
background-size: 100%;
width: 28rpx;
height: 28rpx;
}
.search .txt {
height: 42rpx;
line-height: 42rpx;
color: #666;
padding-left: 10rpx;
font-size: 30rpx;
}
/* .menu-list-pro image{
height: 80px;
width: 80px;
margin-right: 34rpx;
margin-bottom: 34px;
background-color:#f5f5f5;
margin-right:10px;
border-radius:5px;
}
.menu-list-pro text{
text-align: center;
font-size: 24rpx;
color: #333;
height: 42rpx;
width: 80px;
} */

View File

@@ -0,0 +1,140 @@
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() {
// wx.showNavigationBarLoading() //在标题栏中显示加载
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
})
//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() {
// 页面显示
console.log(1);
},
onHide: function() {
// 页面隐藏
},
getGoodsList: function() {
wx.showLoading({
title: '加载中',
});
setTimeout(function() {
wx.hideLoading()
}, 2000);
var that = this;
util.request(api.GoodsList, {
categoryId: that.data.currentCategory.id,
page: that.data.page,
size: that.data.size
})
.then(function(res) {
that.setData({
goodsList: res.data.goodsList,
});
wx.hideLoading();
});
},
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();
}
})

View File

@@ -0,0 +1,5 @@
{
"usingComponents": {
"goodList": "/components/goodList/goodList"
}
}

View File

@@ -0,0 +1,19 @@
<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>
<goodList goods="{{goodsList}}"></goodList>
</view>
</scroll-view>
</view>

View File

@@ -0,0 +1,69 @@
.container{
background: #fff;
}
.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,.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: #333;
font-size: 30rpx;
width: auto;
}
.cate-nav .item.active .name{
color: #a78845;
border-bottom: 2px solid #a78845;
}
.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;
}

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