杨豪
3 years ago
74 changed files with 7823 additions and 29 deletions
@ -0,0 +1,24 @@
|
||||
/** |
||||
* https://github.com/afc163/array-tree-filter
|
||||
*/ |
||||
function arrayTreeFilter(data, filterFn, options) { |
||||
options = options || {} |
||||
options.childrenKeyName = options.childrenKeyName || 'children' |
||||
let children = data || [] |
||||
const result = [] |
||||
let level = 0 |
||||
do { |
||||
const foundItem = children.filter(function(item) { |
||||
return filterFn(item, level) |
||||
})[0] |
||||
if (!foundItem) { |
||||
break |
||||
} |
||||
result.push(foundItem) |
||||
children = foundItem[options.childrenKeyName] || [] |
||||
level += 1 |
||||
} while (children.length > 0) |
||||
return result |
||||
} |
||||
|
||||
export default arrayTreeFilter |
@ -0,0 +1,77 @@
|
||||
import computedBehavior from './computedBehavior' |
||||
import relationsBehavior from './relationsBehavior' |
||||
import safeAreaBehavior from './safeAreaBehavior' |
||||
import safeSetDataBehavior from './safeSetDataBehavior' |
||||
import funcBehavior from './funcBehavior' |
||||
import compareVersion from './compareVersion' |
||||
|
||||
const { platform, SDKVersion } = wx.getSystemInfoSync() |
||||
const libVersion = '2.6.6' |
||||
|
||||
// check SDKVersion
|
||||
if (platform === 'devtools' && compareVersion(SDKVersion, libVersion) < 0) { |
||||
if (wx && wx.showModal) { |
||||
wx.showModal({ |
||||
title: '提示', |
||||
content: `当前基础库版本(${SDKVersion})过低,无法使用 Wux Weapp 组件库,请更新基础库版本 >=${libVersion} 后重试。`, |
||||
}) |
||||
} |
||||
} |
||||
|
||||
const baseComponent = (options = {}) => { |
||||
// add default externalClasses
|
||||
options.externalClasses = [ |
||||
'wux-class', |
||||
'wux-hover-class', |
||||
...(options.externalClasses = options.externalClasses || []), |
||||
] |
||||
|
||||
// add default behaviors
|
||||
options.behaviors = [ |
||||
relationsBehavior, |
||||
safeSetDataBehavior, |
||||
...(options.behaviors = options.behaviors || []), |
||||
computedBehavior, // make sure it's triggered
|
||||
] |
||||
|
||||
// use safeArea
|
||||
if (options.useSafeArea) { |
||||
options.behaviors = [...options.behaviors, safeAreaBehavior] |
||||
delete options.useSafeArea |
||||
} |
||||
|
||||
// use func
|
||||
if (options.useFunc) { |
||||
options.behaviors = [...options.behaviors, funcBehavior] |
||||
delete options.useFunc |
||||
} |
||||
|
||||
// use field
|
||||
if (options.useField) { |
||||
options.behaviors = [...options.behaviors, 'wx://form-field'] |
||||
delete options.useField |
||||
} |
||||
|
||||
// use export
|
||||
if (options.useExport) { |
||||
options.behaviors = [...options.behaviors, 'wx://component-export'] |
||||
options.methods = { |
||||
export () { |
||||
return this |
||||
}, |
||||
...options.methods, |
||||
} |
||||
delete options.useExport |
||||
} |
||||
|
||||
// add default options
|
||||
options.options = { |
||||
multipleSlots: true, |
||||
addGlobalClass: true, |
||||
...options.options, |
||||
} |
||||
|
||||
return Component(options) |
||||
} |
||||
|
||||
export default baseComponent |
@ -0,0 +1,29 @@
|
||||
/** |
||||
* 获取系统信息 |
||||
*/ |
||||
|
||||
let systemInfo = null |
||||
|
||||
export const getSystemInfo = (isForce) => { |
||||
if (!systemInfo || isForce) { |
||||
try { |
||||
systemInfo = wx.getSystemInfoSync() |
||||
} catch(e) { /* Ignore */ } |
||||
} |
||||
|
||||
return systemInfo |
||||
} |
||||
|
||||
// iPhoneX 竖屏安全区域
|
||||
export const safeAreaInset = { |
||||
top: 88, // StatusBar & NavBar
|
||||
left: 0, |
||||
right: 0, |
||||
bottom: 34, // Home Indicator
|
||||
} |
||||
|
||||
const isIPhoneX = ({ model, platform }) => { |
||||
return /iPhone X/.test(model) && platform === 'ios' |
||||
} |
||||
|
||||
export const checkIPhoneX = (isForce) => isIPhoneX(getSystemInfo(isForce)) |
@ -0,0 +1,39 @@
|
||||
/*! |
||||
Copyright (c) 2018 Jed Watson. |
||||
Licensed under the MIT License (MIT), see |
||||
http://jedwatson.github.io/classnames
|
||||
*/ |
||||
/* global define */ |
||||
'use strict'; |
||||
|
||||
var hasOwn = {}.hasOwnProperty; |
||||
|
||||
function classNames() { |
||||
var classes = []; |
||||
|
||||
for (var i = 0; i < arguments.length; i++) { |
||||
var arg = arguments[i]; |
||||
if (!arg) continue; |
||||
|
||||
var argType = typeof arg; |
||||
|
||||
if (argType === 'string' || argType === 'number') { |
||||
classes.push(arg); |
||||
} else if (Array.isArray(arg) && arg.length) { |
||||
var inner = classNames.apply(null, arg); |
||||
if (inner) { |
||||
classes.push(inner); |
||||
} |
||||
} else if (argType === 'object') { |
||||
for (var key in arg) { |
||||
if (hasOwn.call(arg, key) && arg[key]) { |
||||
classes.push(key); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return classes.join(' '); |
||||
} |
||||
|
||||
export default classNames |
@ -0,0 +1,27 @@
|
||||
/** |
||||
* Don't modify this file! |
||||
* Colors generated by themes! |
||||
*/ |
||||
|
||||
/* eslint-disable */ |
||||
|
||||
export const colors = { |
||||
'light': '#ddd', |
||||
'stable': '#b2b2b2', |
||||
'positive': '#EBB672', |
||||
'calm': '#11c1f3', |
||||
'balanced': '#33cd5f', |
||||
'energized': '#ffc900', |
||||
'assertive': '#ef473a', |
||||
'royal': '#886aea', |
||||
'dark': '#444', |
||||
} |
||||
|
||||
export const isPresetColor = (color) => { |
||||
if (!color) { |
||||
return false |
||||
} |
||||
return colors[color] ? colors[color] : color |
||||
} |
||||
|
||||
/* eslint-enable */ |
@ -0,0 +1,27 @@
|
||||
function compareVersion(v1, v2) { |
||||
const $v1 = v1.split('.') |
||||
const $v2 = v2.split('.') |
||||
const len = Math.max($v1.length, $v2.length) |
||||
|
||||
while ($v1.length < len) { |
||||
$v1.push('0') |
||||
} |
||||
while ($v2.length < len) { |
||||
$v2.push('0') |
||||
} |
||||
|
||||
for (let i = 0; i < len; i++) { |
||||
const num1 = parseInt($v1[i]) |
||||
const num2 = parseInt($v2[i]) |
||||
|
||||
if (num1 > num2) { |
||||
return 1 |
||||
} else if (num1 < num2) { |
||||
return -1 |
||||
} |
||||
} |
||||
|
||||
return 0 |
||||
} |
||||
|
||||
export default compareVersion |
@ -0,0 +1,48 @@
|
||||
import isEmpty from './isEmpty' |
||||
import shallowEqual from './shallowEqual' |
||||
|
||||
const ALL_DATA_KEY = '**' |
||||
|
||||
const trim = (str = '') => str.replace(/\s/g, '') |
||||
|
||||
export default Behavior({ |
||||
lifetimes: { |
||||
attached() { |
||||
this.initComputed() |
||||
}, |
||||
}, |
||||
definitionFilter(defFields) { |
||||
const { computed = {} } = defFields |
||||
const observers = Object.keys(computed).reduce((acc, name) => { |
||||
const [field, getter] = Array.isArray(computed[name]) ? computed[name] : [ALL_DATA_KEY, computed[name]] |
||||
return { |
||||
...acc, |
||||
[field]: function(...args) { |
||||
if (typeof getter === 'function') { |
||||
const newValue = getter.apply(this, args) |
||||
const oldValue = this.data[name] |
||||
if (!isEmpty(newValue) && !shallowEqual(newValue, oldValue)) { |
||||
this.setData({ [name]: newValue }) |
||||
} |
||||
} |
||||
}, |
||||
} |
||||
}, {}) |
||||
|
||||
Object.assign(defFields.observers = (defFields.observers || {}), observers) |
||||
Object.assign(defFields.methods = (defFields.methods || {}), { |
||||
initComputed: function(data = {}, isForce = false) { |
||||
if (!this.runInitComputed || isForce) { |
||||
this.runInitComputed = false |
||||
const context = this |
||||
const result = { ...this.data, ...data } |
||||
Object.keys(observers).forEach((key) => { |
||||
const values = trim(key).split(',').reduce((acc, name) => ([...acc, result[name]]), []) |
||||
observers[key].apply(context, values) |
||||
}) |
||||
this.runInitComputed = true |
||||
} |
||||
}, |
||||
}) |
||||
}, |
||||
}) |
@ -0,0 +1,75 @@
|
||||
class FieldsStore { |
||||
constructor(fields = {}) { |
||||
this.fields = fields |
||||
} |
||||
|
||||
setFields(fields) { |
||||
Object.assign(this.fields, fields) |
||||
} |
||||
|
||||
updateFields(fields) { |
||||
this.fields = fields |
||||
} |
||||
|
||||
clearField(name) { |
||||
delete this.fields[name] |
||||
} |
||||
|
||||
getValueFromFields(name, fields) { |
||||
const field = fields[name] |
||||
if (field && 'value' in field) { |
||||
return field.value |
||||
} |
||||
return field.initialValue |
||||
} |
||||
|
||||
getAllFieldsName() { |
||||
const { fields } = this |
||||
return fields ? Object.keys(fields) : [] |
||||
} |
||||
|
||||
getField(name) { |
||||
return { |
||||
...this.fields[name], |
||||
name, |
||||
} |
||||
} |
||||
|
||||
getFieldValuePropValue(fieldOption) { |
||||
const { name, valuePropName } = fieldOption |
||||
const field = this.getField(name) |
||||
const fieldValue = 'value' in field ? field.value : field.initialValue |
||||
|
||||
return { |
||||
[valuePropName]: fieldValue, |
||||
} |
||||
} |
||||
|
||||
getFieldValue(name) { |
||||
return this.getValueFromFields(name, this.fields) |
||||
} |
||||
|
||||
getFieldsValue(names) { |
||||
const fields = names || this.getAllFieldsName() |
||||
return fields.reduce((acc, name) => { |
||||
acc[name] = this.getFieldValue(name) |
||||
return acc |
||||
}, {}) |
||||
} |
||||
|
||||
resetFields(ns) { |
||||
const { fields } = this |
||||
const names = ns || this.getAllFieldsName() |
||||
return names.reduce((acc, name) => { |
||||
const field = fields[name] |
||||
if (field) { |
||||
acc[name] = field.initialValue |
||||
} |
||||
return acc |
||||
}, {}) |
||||
} |
||||
} |
||||
|
||||
export default function createFieldsStore(fields) { |
||||
return new FieldsStore(fields) |
||||
} |
@ -0,0 +1,56 @@
|
||||
export default function debounce(func, wait, immediate) { |
||||
let timeout, |
||||
args, |
||||
context, |
||||
timestamp, |
||||
result |
||||
|
||||
function later() { |
||||
const last = +(new Date()) - timestamp |
||||
if (last < wait && last >= 0) { |
||||
timeout = setTimeout(later, wait - last) |
||||
} else { |
||||
timeout = undefined |
||||
if (!immediate) { |
||||
result = func.apply(context, args) |
||||
if (!timeout) { |
||||
context = undefined |
||||
args = undefined |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
function debounced() { |
||||
context = this |
||||
args = arguments |
||||
timestamp = +(new Date()) |
||||
|
||||
const callNow = immediate && !timeout |
||||
if (!timeout) { |
||||
timeout = setTimeout(later, wait) |
||||
} |
||||
|
||||
if (callNow) { |
||||
result = func.apply(context, args) |
||||
context = undefined |
||||
args = undefined |
||||
} |
||||
|
||||
return result |
||||
} |
||||
|
||||
function cancel() { |
||||
if (timeout !== undefined) { |
||||
clearTimeout(timeout) |
||||
timeout = undefined |
||||
} |
||||
|
||||
context = undefined |
||||
args = undefined |
||||
} |
||||
|
||||
debounced.cancel = cancel |
||||
|
||||
return debounced |
||||
} |
@ -0,0 +1,53 @@
|
||||
const defaultEvents = { |
||||
onChange() {}, |
||||
} |
||||
|
||||
export default function eventsMixin(params = { defaultEvents }) { |
||||
return Behavior({ |
||||
lifetimes: { |
||||
created () { |
||||
this._oriTriggerEvent = this.triggerEvent |
||||
this.triggerEvent = this._triggerEvent |
||||
}, |
||||
}, |
||||
properties: { |
||||
events: { |
||||
type: Object, |
||||
value: defaultEvents, |
||||
}, |
||||
}, |
||||
data: { |
||||
inputEvents: defaultEvents, |
||||
}, |
||||
definitionFilter(defFields) { |
||||
// set default data
|
||||
Object.assign(defFields.data = (defFields.data || {}), { |
||||
inputEvents: Object.assign({}, defaultEvents, defFields.inputEvents), |
||||
}) |
||||
|
||||
// set default methods
|
||||
Object.assign(defFields.methods = (defFields.methods || {}), { |
||||
_triggerEvent(name, params, runCallbacks = true, option) { |
||||
const { inputEvents } = this.data |
||||
const method = `on${name[0].toUpperCase()}${name.slice(1)}` |
||||
const func = inputEvents[method] |
||||
|
||||
if (runCallbacks && typeof func === 'function') { |
||||
func.call(this, params) |
||||
} |
||||
|
||||
this._oriTriggerEvent(name, params, option) |
||||
}, |
||||
}) |
||||
|
||||
// set default observers
|
||||
Object.assign(defFields.observers = (defFields.observers || {}), { |
||||
events(newVal) { |
||||
this.setData({ |
||||
inputEvents: Object.assign({}, defaultEvents, this.data.inputEvents, newVal), |
||||
}) |
||||
}, |
||||
}) |
||||
}, |
||||
}) |
||||
} |
@ -0,0 +1,97 @@
|
||||
/** |
||||
* 过滤对象的函数属性 |
||||
* @param {Object} opts |
||||
*/ |
||||
const mergeOptionsToData = (opts = {}) => { |
||||
const options = Object.assign({}, opts) |
||||
|
||||
for (const key in options) { |
||||
if (options.hasOwnProperty(key) && typeof options[key] === 'function') { |
||||
delete options[key] |
||||
} |
||||
} |
||||
|
||||
return options |
||||
} |
||||
|
||||
/** |
||||
* Simple bind, faster than native |
||||
* |
||||
* @param {Function} fn |
||||
* @param {Object} ctx |
||||
* @return {Function} |
||||
*/ |
||||
const bind = (fn, ctx) => { |
||||
return (...args) => { |
||||
return args.length ? fn.apply(ctx, args) : fn.call(ctx) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Object assign |
||||
*/ |
||||
const assign = (...args) => Object.assign({}, ...args) |
||||
|
||||
export default Behavior({ |
||||
definitionFilter(defFields) { |
||||
defFields.data = mergeOptionsToData(defFields.data) |
||||
defFields.data.in = false |
||||
defFields.data.visible = false |
||||
}, |
||||
methods: { |
||||
/** |
||||
* 过滤对象的函数属性 |
||||
* @param {Object} opts |
||||
*/ |
||||
$$mergeOptionsToData: mergeOptionsToData, |
||||
/** |
||||
* 合并参数并绑定方法 |
||||
* |
||||
* @param {Object} opts 参数对象 |
||||
* @param {Object} fns 方法挂载的属性 |
||||
*/ |
||||
$$mergeOptionsAndBindMethods (opts = {}, fns = this.fns) { |
||||
const options = Object.assign({}, opts) |
||||
|
||||
for (const key in options) { |
||||
if (options.hasOwnProperty(key) && typeof options[key] === 'function') { |
||||
fns[key] = bind(options[key], this) |
||||
delete options[key] |
||||
} |
||||
} |
||||
|
||||
return options |
||||
}, |
||||
/** |
||||
* Promise setData |
||||
* @param {Array} args 参数对象 |
||||
*/ |
||||
$$setData (...args) { |
||||
const params = assign({}, ...args) |
||||
|
||||
return new Promise((resolve) => { |
||||
this.setData(params, resolve) |
||||
}) |
||||
}, |
||||
/** |
||||
* 延迟指定时间执行回调函数 |
||||
* @param {Function} callback 回调函数 |
||||
* @param {Number} timeout 延迟时间 |
||||
*/ |
||||
$$requestAnimationFrame (callback = () => {}, timeout = 1000 / 60) { |
||||
return new Promise((resolve) => setTimeout(resolve, timeout)).then(callback) |
||||
}, |
||||
}, |
||||
/** |
||||
* 组件生命周期函数,在组件实例进入页面节点树时执行 |
||||
*/ |
||||
created () { |
||||
this.fns = {} |
||||
}, |
||||
/** |
||||
* 组件生命周期函数,在组件实例被从页面节点树移除时执行 |
||||
*/ |
||||
detached () { |
||||
this.fns = {} |
||||
}, |
||||
}) |
@ -0,0 +1,50 @@
|
||||
/** |
||||
* 获取触摸点位置信息 |
||||
*/ |
||||
export const getTouchPoints = (nativeEvent, index = 0) => { |
||||
const touches = nativeEvent.touches |
||||
const changedTouches = nativeEvent.changedTouches |
||||
const hasTouches = touches && touches.length > 0 |
||||
const hasChangedTouches = changedTouches && changedTouches.length > 0 |
||||
const points = !hasTouches && hasChangedTouches ? changedTouches[index] : hasTouches ? touches[index] : nativeEvent |
||||
|
||||
return { |
||||
x: points.pageX, |
||||
y: points.pageY, |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取触摸点个数 |
||||
*/ |
||||
export const getPointsNumber = (e) => e.touches && e.touches.length || e.changedTouches && e.changedTouches.length |
||||
|
||||
/** |
||||
* 判断是否为同一点 |
||||
*/ |
||||
export const isEqualPoints = (p1, p2) => p1.x === p2.x && p1.y === p2.y |
||||
|
||||
/** |
||||
* 判断是否为相近的两点 |
||||
*/ |
||||
export const isNearbyPoints = (p1, p2, DOUBLE_TAP_RADIUS = 25) => { |
||||
const xMove = Math.abs(p1.x - p2.x) |
||||
const yMove = Math.abs(p1.y - p2.y) |
||||
return xMove < DOUBLE_TAP_RADIUS & yMove < DOUBLE_TAP_RADIUS |
||||
} |
||||
|
||||
/** |
||||
* 获取两点之间的距离 |
||||
*/ |
||||
export const getPointsDistance = (p1, p2) => { |
||||
const xMove = Math.abs(p1.x - p2.x) |
||||
const yMove = Math.abs(p1.y - p2.y) |
||||
return Math.sqrt(xMove * xMove + yMove * yMove) |
||||
} |
||||
|
||||
/** |
||||
* 获取触摸移动方向 |
||||
*/ |
||||
export const getSwipeDirection = (x1, x2, y1, y2) => { |
||||
return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down') |
||||
} |
@ -0,0 +1,19 @@
|
||||
/** |
||||
* Checks if a value is empty. |
||||
*/ |
||||
function isEmpty(value) { |
||||
if (Array.isArray(value)) { |
||||
return value.length === 0 |
||||
} else if (typeof value === 'object') { |
||||
if (value) { |
||||
for (const _ in value) { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} else { |
||||
return !value |
||||
} |
||||
} |
||||
|
||||
export default isEmpty |
@ -0,0 +1,17 @@
|
||||
/** |
||||
* 过滤对象的函数属性 |
||||
* @param {Object} opts |
||||
*/ |
||||
const mergeOptionsToData = (opts = {}) => { |
||||
const options = Object.assign({}, opts) |
||||
|
||||
for (const key in options) { |
||||
if (options.hasOwnProperty(key) && typeof options[key] === 'function') { |
||||
delete options[key] |
||||
} |
||||
} |
||||
|
||||
return options |
||||
} |
||||
|
||||
export default mergeOptionsToData |
@ -0,0 +1,314 @@
|
||||
import classNames from './classNames' |
||||
import eventsMixin from './eventsMixin' |
||||
|
||||
const DEFAULT_TRIGGER = 'onClick' |
||||
const CELL_NAME = '../cell/index' |
||||
const FIELD_NAME = '../field/index' |
||||
|
||||
const defaultToolbar = { |
||||
title: '请选择', |
||||
cancelText: '取消', |
||||
confirmText: '确定', |
||||
} |
||||
|
||||
const defaultEvents = { |
||||
onChange() {}, |
||||
onConfirm() {}, |
||||
onCancel() {}, |
||||
onVisibleChange() {}, |
||||
onValueChange() {}, |
||||
} |
||||
|
||||
const defaultPlatformProps = { |
||||
labelPropName: 'label', |
||||
format(values, props) { |
||||
return Array.isArray(values.displayValue) ? values.displayValue.join(',') : values.displayValue |
||||
}, |
||||
} |
||||
|
||||
const defaultFieldNames = { |
||||
label: 'label', |
||||
value: 'value', |
||||
children: 'children', |
||||
} |
||||
|
||||
export default function popupMixin(selector = '#wux-picker', platformProps = defaultPlatformProps) { |
||||
return Behavior({ |
||||
behaviors: [eventsMixin({ defaultEvents })], |
||||
properties: { |
||||
toolbar: { |
||||
type: Object, |
||||
value: defaultToolbar, |
||||
}, |
||||
trigger: { |
||||
type: String, |
||||
value: DEFAULT_TRIGGER, |
||||
}, |
||||
defaultVisible: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
visible: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
controlled: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
disabled: { |
||||
type: Boolean, |
||||
value: false, |
||||
}, |
||||
}, |
||||
data: { |
||||
mounted: false, |
||||
popupVisible: false, |
||||
inputValue: [], |
||||
}, |
||||
methods: { |
||||
/** |
||||
* 设置组件显示或隐藏 |
||||
*/ |
||||
setVisibleState(popupVisible, callback = () => {}) { |
||||
if (this.data.popupVisible !== popupVisible) { |
||||
const params = { |
||||
mounted: true, |
||||
inputValue: this.data.value, // forceUpdate
|
||||
popupVisible, |
||||
} |
||||
this.setData(popupVisible ? params : { popupVisible }, () => { |
||||
// collect field component & forceUpdate
|
||||
if (popupVisible && this.hasFieldDecorator) { |
||||
const field = this.getFieldElem() |
||||
if (field) { |
||||
field.changeValue(field.data.value) |
||||
} |
||||
} |
||||
callback() |
||||
}) |
||||
} |
||||
}, |
||||
/** |
||||
* 触发 visibleChange 事件 |
||||
*/ |
||||
fireVisibleChange(popupVisible) { |
||||
if (this.data.popupVisible !== popupVisible) { |
||||
if (!this.data.controlled) { |
||||
this.setVisibleState(popupVisible) |
||||
} |
||||
this.setScrollValue(undefined) |
||||
this.triggerEvent('visibleChange', { visible: popupVisible }) |
||||
} |
||||
}, |
||||
/** |
||||
* 打开 |
||||
*/ |
||||
open() { |
||||
this.fireVisibleChange(true) |
||||
}, |
||||
/** |
||||
* 关闭 |
||||
*/ |
||||
close(callback) { |
||||
if (typeof callback === 'function') { |
||||
const values = this.getPickerValue(this.scrollValue || this.data.inputValue) |
||||
callback.call(this, this.formatPickerValue(values)) |
||||
} |
||||
this.fireVisibleChange(false) |
||||
}, |
||||
/** |
||||
* 组件关闭时重置其内部数据 |
||||
*/ |
||||
onClosed() { |
||||
this.picker = null |
||||
this.setData({ mounted: false, inputValue: null }) |
||||
}, |
||||
/** |
||||
* 点击确定按钮时的回调函数 |
||||
*/ |
||||
onConfirm() { |
||||
this.close((values) => { |
||||
this.triggerEvent('change', values) // collect field component
|
||||
this.triggerEvent('confirm', values) |
||||
}) |
||||
}, |
||||
/** |
||||
* 点击取消按钮时的回调函数 |
||||
*/ |
||||
onCancel() { |
||||
this.close((values) => this.triggerEvent('cancel', values)) |
||||
}, |
||||
/** |
||||
* 每列数据选择变化后的回调函数 |
||||
*/ |
||||
onValueChange(e) { |
||||
if (!this.data.mounted) return |
||||
const { value } = e.detail |
||||
if (this.data.cascade) { |
||||
this.setCasecadeScrollValue(value) |
||||
} else { |
||||
this.setScrollValue(value) |
||||
} |
||||
|
||||
this.updated(value, true) |
||||
this.triggerEvent('valueChange', this.formatPickerValue(e.detail)) |
||||
}, |
||||
/** |
||||
* 获取当前 picker 的值 |
||||
*/ |
||||
getPickerValue(value = this.data.inputValue) { |
||||
this.picker = this.picker || this.selectComponent(selector) |
||||
return this.picker && this.picker.getValue(value) |
||||
}, |
||||
/** |
||||
* 格式化 picker 返回值 |
||||
*/ |
||||
formatPickerValue(values) { |
||||
return { |
||||
...values, |
||||
[platformProps.labelPropName]: platformProps.format(values, this.data), |
||||
} |
||||
}, |
||||
/** |
||||
* 获取 field 父元素 |
||||
*/ |
||||
getFieldElem() { |
||||
return this.field = (this.field || this.getRelationNodes(FIELD_NAME)[0]) |
||||
}, |
||||
/** |
||||
* 设置子元素 props |
||||
*/ |
||||
setChildProps() { |
||||
if (this.data.disabled) return |
||||
const elements = this.getRelationNodes(CELL_NAME) |
||||
const { trigger = DEFAULT_TRIGGER } = this.data |
||||
if (elements.length > 0) { |
||||
elements.forEach((inputElem) => { |
||||
const { inputEvents } = inputElem.data |
||||
const oriInputEvents = inputElem.data.oriInputEvents || { ...inputEvents } |
||||
inputEvents[trigger] = (...args) => { |
||||
if (oriInputEvents && oriInputEvents[trigger]) { |
||||
oriInputEvents[trigger](...args) |
||||
} |
||||
this.onTriggerClick() |
||||
} |
||||
inputElem.setData({ oriInputEvents, inputEvents }) |
||||
}) |
||||
} |
||||
}, |
||||
/** |
||||
* 触发事件 |
||||
*/ |
||||
onTriggerClick() { |
||||
this.fireVisibleChange(!this.data.popupVisible) |
||||
}, |
||||
/** |
||||
* 阻止移动触摸 |
||||
*/ |
||||
noop() {}, |
||||
/** |
||||
* 更新值 |
||||
*/ |
||||
updated(inputValue, isForce) { |
||||
if (!this.hasFieldDecorator || isForce) { |
||||
if (this.data.inputValue !== inputValue) { |
||||
this.setData({ inputValue }) |
||||
} |
||||
} |
||||
}, |
||||
/** |
||||
* 记录每列数据的变化值 |
||||
*/ |
||||
setScrollValue(value) { |
||||
this.scrollValue = value |
||||
}, |
||||
/** |
||||
* 记录每列数据的变化值 - 针对于级联 |
||||
*/ |
||||
setCasecadeScrollValue(value) { |
||||
if (value && this.scrollValue) { |
||||
const length = this.scrollValue.length |
||||
if (length === value.length && this.scrollValue[length - 1] === value[length - 1]) { |
||||
return |
||||
} |
||||
} |
||||
this.setScrollValue(value) |
||||
}, |
||||
}, |
||||
lifetimes: { |
||||
ready() { |
||||
const { defaultVisible, visible, controlled, value } = this.data |
||||
const popupVisible = controlled ? visible : defaultVisible |
||||
|
||||
// 若 defaultFieldNames 存在,则缓存之,并传递给子组件,只生效一次
|
||||
if ('defaultFieldNames' in this.data) { |
||||
this.setData({ |
||||
fieldNames: Object.assign({}, defaultFieldNames, this.data.defaultFieldNames), |
||||
}) |
||||
} |
||||
|
||||
this.mounted = true |
||||
this.scrollValue = undefined |
||||
this.setVisibleState(popupVisible) |
||||
this.setChildProps() |
||||
}, |
||||
detached() { |
||||
this.mounted = false |
||||
}, |
||||
}, |
||||
definitionFilter(defFields) { |
||||
// set default child
|
||||
Object.assign(defFields.relations = (defFields.relations || {}), { |
||||
[CELL_NAME]: { |
||||
type: 'child', |
||||
observer() { |
||||
this.setChildProps() |
||||
}, |
||||
}, |
||||
[FIELD_NAME]: { |
||||
type: 'ancestor', |
||||
}, |
||||
}) |
||||
|
||||
// set default classes
|
||||
Object.assign(defFields.computed = (defFields.computed || {}), { |
||||
classes: ['prefixCls', function(prefixCls) { |
||||
const wrap = classNames(prefixCls) |
||||
const toolbar = `${prefixCls}__toolbar` |
||||
const inner = `${prefixCls}__inner` |
||||
const cancel = classNames(`${prefixCls}__button`, { |
||||
[`${prefixCls}__button--cancel`]: true, |
||||
}) |
||||
const confirm = classNames(`${prefixCls}__button`, { |
||||
[`${prefixCls}__button--confirm`]: true, |
||||
}) |
||||
const hover = `${prefixCls}__button--hover` |
||||
const title = `${prefixCls}__title` |
||||
|
||||
return { |
||||
wrap, |
||||
toolbar, |
||||
inner, |
||||
cancel, |
||||
confirm, |
||||
hover, |
||||
title, |
||||
} |
||||
}], |
||||
}) |
||||
|
||||
// set default observers
|
||||
Object.assign(defFields.observers = (defFields.observers || {}), { |
||||
visible(popupVisible) { |
||||
if (this.data.controlled) { |
||||
this.setVisibleState(popupVisible) |
||||
} |
||||
}, |
||||
value(value) { |
||||
this.updated(value) |
||||
}, |
||||
}) |
||||
}, |
||||
}) |
||||
} |
@ -0,0 +1,67 @@
|
||||
import isEmpty from './isEmpty' |
||||
import debounce from './debounce' |
||||
|
||||
/** |
||||
* bind func to obj |
||||
*/ |
||||
function bindFunc(obj, method, observer) { |
||||
const oldFn = obj[method] |
||||
obj[method] = function(target) { |
||||
if (observer) { |
||||
observer.call(this, target, { |
||||
[method]: true, |
||||
}) |
||||
} |
||||
if (oldFn) { |
||||
oldFn.call(this, target) |
||||
} |
||||
} |
||||
} |
||||
|
||||
// default methods
|
||||
const methods = ['linked', 'linkChanged', 'unlinked'] |
||||
|
||||
// extra props
|
||||
const extProps = ['observer'] |
||||
|
||||
export default Behavior({ |
||||
lifetimes: { |
||||
created() { |
||||
this._debounce = null |
||||
}, |
||||
detached() { |
||||
if (this._debounce && this._debounce.cancel) { |
||||
this._debounce.cancel() |
||||
} |
||||
}, |
||||
}, |
||||
definitionFilter(defFields) { |
||||
const { relations } = defFields |
||||
|
||||
if (!isEmpty(relations)) { |
||||
for (const key in relations) { |
||||
const relation = relations[key] |
||||
|
||||
// bind func
|
||||
methods.forEach((method) => bindFunc(relation, method, relation.observer)) |
||||
|
||||
// delete extProps
|
||||
extProps.forEach((prop) => delete relation[prop]) |
||||
} |
||||
} |
||||
|
||||
Object.assign(defFields.methods = (defFields.methods || {}), { |
||||
getRelationsName: function(types = ['parent', 'child', 'ancestor', 'descendant']) { |
||||
return Object.keys(relations || {}).map((key) => { |
||||
if (relations[key] && types.includes(relations[key].type)) { |
||||
return key |
||||
} |
||||
return null |
||||
}).filter((v) => !!v) |
||||
}, |
||||
debounce: function(func, wait = 0, immediate = false) { |
||||
return (this._debounce = this._debounce || debounce(func.bind(this), wait, immediate)).call(this) |
||||
}, |
||||
}) |
||||
}, |
||||
}) |
@ -0,0 +1,46 @@
|
||||
import { getSystemInfo, checkIPhoneX } from './checkIPhoneX' |
||||
|
||||
const defaultSafeArea = { |
||||
top: false, |
||||
bottom: false, |
||||
} |
||||
|
||||
const setSafeArea = (params) => { |
||||
if (typeof params === 'boolean') { |
||||
return Object.assign({}, defaultSafeArea, { |
||||
top: params, |
||||
bottom: params, |
||||
}) |
||||
} else if (params !== null && typeof params === 'object') { |
||||
return Object.assign({}, defaultSafeArea) |
||||
} else if (typeof params === 'string') { |
||||
return Object.assign({}, defaultSafeArea, { |
||||
[params]: true, |
||||
}) |
||||
} |
||||
return defaultSafeArea |
||||
} |
||||
|
||||
export default Behavior({ |
||||
properties: { |
||||
safeArea: { |
||||
type: [Boolean, String, Object], |
||||
value: false, |
||||
}, |
||||
}, |
||||
observers: { |
||||
safeArea(newVal) { |
||||
this.setData({ safeAreaConfig: setSafeArea(newVal) }) |
||||
}, |
||||
}, |
||||
definitionFilter(defFields) { |
||||
const { statusBarHeight } = getSystemInfo() || {} |
||||
const isIPhoneX = checkIPhoneX() |
||||
|
||||
Object.assign(defFields.data = (defFields.data || {}), { |
||||
safeAreaConfig: defaultSafeArea, |
||||
statusBarHeight, |
||||
isIPhoneX, |
||||
}) |
||||
}, |
||||
}) |
@ -0,0 +1,57 @@
|
||||
export default Behavior({ |
||||
lifetimes: { |
||||
created() { |
||||
this.nextCallback = null |
||||
}, |
||||
detached() { |
||||
this.cancelNextCallback() |
||||
}, |
||||
}, |
||||
methods: { |
||||
/** |
||||
* safeSetData |
||||
* @param {Object} nextData 数据对象 |
||||
* @param {Function} callback 回调函数 |
||||
*/ |
||||
safeSetData(nextData, callback) { |
||||
this.pendingData = Object.assign({}, this.data, nextData) |
||||
callback = this.setNextCallback(callback) |
||||
|
||||
this.setData(nextData, () => { |
||||
this.pendingData = null |
||||
callback() |
||||
}) |
||||
}, |
||||
/** |
||||
* 设置下一回调函数 |
||||
* @param {Function} callback 回调函数 |
||||
*/ |
||||
setNextCallback(callback) { |
||||
let active = true |
||||
|
||||
this.nextCallback = (event) => { |
||||
if (active) { |
||||
active = false |
||||
this.nextCallback = null |
||||
|
||||
callback.call(this, event) |
||||
} |
||||
} |
||||
|
||||
this.nextCallback.cancel = () => { |
||||
active = false |
||||
} |
||||
|
||||
return this.nextCallback |
||||
}, |
||||
/** |
||||
* 取消下一回调函数 |
||||
*/ |
||||
cancelNextCallback() { |
||||
if (this.nextCallback !== null) { |
||||
this.nextCallback.cancel() |
||||
this.nextCallback = null |
||||
} |
||||
}, |
||||
}, |
||||
}) |
@ -0,0 +1,65 @@
|
||||
/** |
||||
* Copyright (c) 2013-present, Facebook, Inc. |
||||
* |
||||
* This source code is licensed under the MIT license found in the |
||||
* LICENSE file in the root directory of this source tree. |
||||
* |
||||
* @typechecks |
||||
*
|
||||
*/ |
||||
|
||||
/*eslint-disable no-self-compare */ |
||||
|
||||
'use strict'; |
||||
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty; |
||||
|
||||
/** |
||||
* inlined Object.is polyfill to avoid requiring consumers ship their own |
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
||||
*/ |
||||
function is(x, y) { |
||||
// SameValue algorithm
|
||||
if (x === y) { |
||||
// Steps 1-5, 7-10
|
||||
// Steps 6.b-6.e: +0 != -0
|
||||
// Added the nonzero y check to make Flow happy, but it is redundant
|
||||
return x !== 0 || y !== 0 || 1 / x === 1 / y; |
||||
} else { |
||||
// Step 6.a: NaN == NaN
|
||||
return x !== x && y !== y; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Performs equality by iterating through keys on an object and returning false |
||||
* when any key has values which are not strictly equal between the arguments. |
||||
* Returns true when the values of all keys are strictly equal. |
||||
*/ |
||||
function shallowEqual(objA, objB) { |
||||
if (is(objA, objB)) { |
||||
return true; |
||||
} |
||||
|
||||
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) { |
||||
return false; |
||||
} |
||||
|
||||
var keysA = Object.keys(objA); |
||||
var keysB = Object.keys(objB); |
||||
|
||||
if (keysA.length !== keysB.length) { |
||||
return false; |
||||
} |
||||
|
||||
// Test for A's keys different from B.
|
||||
for (var i = 0; i < keysA.length; i++) { |
||||
if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
export default shallowEqual |
@ -0,0 +1,138 @@
|
||||
'use strict'; |
||||
|
||||
/** |
||||
* CSS properties which accept numbers but are not in units of "px". |
||||
*/ |
||||
var isUnitlessNumber = { |
||||
boxFlex: true, |
||||
boxFlexGroup: true, |
||||
columnCount: true, |
||||
flex: true, |
||||
flexGrow: true, |
||||
flexPositive: true, |
||||
flexShrink: true, |
||||
flexNegative: true, |
||||
fontWeight: true, |
||||
lineClamp: true, |
||||
lineHeight: true, |
||||
opacity: true, |
||||
order: true, |
||||
orphans: true, |
||||
widows: true, |
||||
zIndex: true, |
||||
zoom: true, |
||||
|
||||
// SVG-related properties
|
||||
fillOpacity: true, |
||||
strokeDashoffset: true, |
||||
strokeOpacity: true, |
||||
strokeWidth: true |
||||
}; |
||||
|
||||
/** |
||||
* @param {string} prefix vendor-specific prefix, eg: Webkit |
||||
* @param {string} key style name, eg: transitionDuration |
||||
* @return {string} style name prefixed with `prefix`, properly camelCased, eg: |
||||
* WebkitTransitionDuration |
||||
*/ |
||||
function prefixKey(prefix, key) { |
||||
return prefix + key.charAt(0).toUpperCase() + key.substring(1); |
||||
} |
||||
|
||||
/** |
||||
* Support style names that may come passed in prefixed by adding permutations |
||||
* of vendor prefixes. |
||||
*/ |
||||
var prefixes = ['Webkit', 'ms', 'Moz', 'O']; |
||||
|
||||
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
|
||||
// infinite loop, because it iterates over the newly added props too.
|
||||
Object.keys(isUnitlessNumber).forEach(function(prop) { |
||||
prefixes.forEach(function(prefix) { |
||||
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; |
||||
}); |
||||
}); |
||||
|
||||
var msPattern = /^ms-/; |
||||
|
||||
var _uppercasePattern = /([A-Z])/g; |
||||
|
||||
/** |
||||
* Hyphenates a camelcased string, for example: |
||||
* |
||||
* > hyphenate('backgroundColor') |
||||
* < "background-color" |
||||
* |
||||
* For CSS style names, use `hyphenateStyleName` instead which works properly |
||||
* with all vendor prefixes, including `ms`. |
||||
* |
||||
* @param {string} string |
||||
* @return {string} |
||||
*/ |
||||
function hyphenate(string) { |
||||
return string.replace(_uppercasePattern, '-$1').toLowerCase(); |
||||
} |
||||
|
||||
/** |
||||
* Hyphenates a camelcased CSS property name, for example: |
||||
* |
||||
* > hyphenateStyleName('backgroundColor') |
||||
* < "background-color" |
||||
* > hyphenateStyleName('MozTransition') |
||||
* < "-moz-transition" |
||||
* > hyphenateStyleName('msTransition') |
||||
* < "-ms-transition" |
||||
* |
||||
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
|
||||
* is converted to `-ms-`. |
||||
* |
||||
* @param {string} string |
||||
* @return {string} |
||||
*/ |
||||
function hyphenateStyleName(string) { |
||||
return hyphenate(string).replace(msPattern, '-ms-'); |
||||
} |
||||
|
||||
var isArray = Array.isArray; |
||||
var keys = Object.keys; |
||||
|
||||
var counter = 1; |
||||
// Follows syntax at https://developer.mozilla.org/en-US/docs/Web/CSS/content,
|
||||
// including multiple space separated values.
|
||||
var unquotedContentValueRegex = /^(normal|none|(\b(url\([^)]*\)|chapter_counter|attr\([^)]*\)|(no-)?(open|close)-quote|inherit)((\b\s*)|$|\s+))+)$/; |
||||
|
||||
function buildRule(key, value) { |
||||
if (!isUnitlessNumber[key] && typeof value === 'number') { |
||||
value = '' + value + 'px'; |
||||
} else if (key === 'content' && !unquotedContentValueRegex.test(value)) { |
||||
value = "'" + value.replace(/'/g, "\\'") + "'"; |
||||
} |
||||
|
||||
return hyphenateStyleName(key) + ': ' + value + '; '; |
||||
} |
||||
|
||||
function styleToCssString(rules) { |
||||
var result = '' |
||||
if (typeof rules === 'string') { |
||||
return rules |
||||
} |
||||
if (!rules || keys(rules).length === 0) { |
||||
return result; |
||||
} |
||||
var styleKeys = keys(rules); |
||||
for (var j = 0, l = styleKeys.length; j < l; j++) { |
||||
var styleKey = styleKeys[j]; |
||||
var value = rules[styleKey]; |
||||
|
||||
if (isArray(value)) { |
||||
for (var i = 0, len = value.length; i < len; i++) { |
||||
result += buildRule(styleKey, value[i]); |
||||
} |
||||
} else { |
||||
result += buildRule(styleKey, value); |
||||
} |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
export default styleToCssString |
@ -0,0 +1,88 @@
|
||||
import baseComponent from '../helpers/baseComponent' |
||||
import classNames from '../helpers/classNames' |
||||
|
||||
const defaultStatus = ['wait', 'process', 'finish', 'error'] |
||||
const defaultIcon = 'ios-checkmark' |
||||
|
||||
baseComponent({ |
||||
relations: { |
||||
'../steps/index': { |
||||
type: 'parent', |
||||
}, |
||||
}, |
||||
properties: { |
||||
prefixCls: { |
||||
type: String, |
||||
value: 'wux-step', |
||||
}, |
||||
status: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
title: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
content: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
icon: { |
||||
type: String, |
||||
value: '', |
||||
}, |
||||
}, |
||||
data: { |
||||
width: '100%', |
||||
length: 1, |
||||
index: 0, |
||||
current: 0, |
||||
direction: 'horizontal', |
||||
}, |
||||
computed: { |
||||
classes: ['prefixCls, direction', function(prefixCls, direction) { |
||||
const wrap = classNames(prefixCls, { |
||||
[`${prefixCls}--${direction}`]: direction, |
||||
}) |
||||
const hd = `${prefixCls}__hd` |
||||
const icon = `${prefixCls}__icon` |
||||
const thumb = `${prefixCls}__thumb` |
||||
const bd = `${prefixCls}__bd` |
||||
const title = `${prefixCls}__title` |
||||
const content = `${prefixCls}__content` |
||||
const ft = `${prefixCls}__ft` |
||||
|
||||
return { |
||||
wrap, |
||||
hd, |
||||
icon, |
||||
thumb, |
||||
bd, |
||||
title, |
||||
content, |
||||
ft, |
||||
} |
||||
}], |
||||
}, |
||||
methods: { |
||||
updateCurrent(opts = {}) { |
||||
const width = opts.direction === 'horizontal' ? 100 / opts.length + '%' : '100%' |
||||
const index = defaultStatus.indexOf(this.data.status) |
||||
const hasIcon = opts.index < opts.current || this.data.icon |
||||
const thumb = this.data.icon || defaultIcon |
||||
const suffix = index !== -1 ? defaultStatus[index] : opts.index < opts.current ? 'finish' : opts.index === opts.current ? 'process' : '' |
||||
const className = `${this.data.prefixCls}--${suffix}` |
||||
const options = Object.assign({ |
||||
width, |
||||
className, |
||||
hasIcon, |
||||
thumb, |
||||
}, opts) |
||||
|
||||
this.setData(options) |
||||
}, |
||||
}, |
||||
attached() { |
||||
this.updateCurrent(this.data) |
||||
}, |
||||
}) |
@ -0,0 +1,6 @@
|
||||
{ |
||||
"component": true, |
||||
"usingComponents": { |
||||
"wux-icon": "../icon/index" |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
<view class="wux-class {{ classes.wrap }} {{ className }}" style="width: {{ width }}"> |
||||
<view class="{{ classes.hd }}"> |
||||
<view class="{{ classes.icon }}" wx:if="{{ !hasIcon }}">{{ index + 1 }}</view> |
||||
<view class="{{ classes.icon }}" wx:else> |
||||
<wux-icon wux-class="{{ classes.thumb }}" type="{{ thumb }}" size="24" wx:if="{{ thumb }}"></wux-icon> |
||||
</view> |
||||
</view> |
||||
<view class="{{ classes.bd }}"> |
||||
<view class="{{ classes.title }}" wx:if="{{ title }}"> |
||||
{{ title }} |
||||
</view> |
||||
<view class="{{ classes.title }}" wx:else> |
||||
<slot name="title"></slot> |
||||
</view> |
||||
<view class="{{ classes.content }}" wx:if="{{ content }}"> |
||||
<text>{{ content }}</text> |
||||
</view> |
||||
<view class="{{ classes.content }}" wx:else> |
||||
<slot name="content"></slot> |
||||
</view> |
||||
</view> |
||||
<view class="{{ classes.ft }}" wx:if="{{ index !== length - 1 }}"></view> |
||||
</view> |
@ -0,0 +1,122 @@
|
||||
.wux-step { |
||||
font-size: 0; |
||||
position: relative; |
||||
display: inline-block; |
||||
box-sizing: border-box; |
||||
padding: 0 10rpx; |
||||
vertical-align: top |
||||
} |
||||
.wux-step--vertical { |
||||
padding-bottom: 60rpx |
||||
} |
||||
.wux-step--vertical .wux-step__hd { |
||||
float: left |
||||
} |
||||
.wux-step--vertical .wux-step__bd { |
||||
overflow: hidden; |
||||
display: block; |
||||
margin-left: 80rpx; |
||||
margin-top: 0; |
||||
text-align: left; |
||||
clear: inherit |
||||
} |
||||
.wux-step--vertical .wux-step__ft { |
||||
position: absolute; |
||||
left: 38rpx; |
||||
top: 0; |
||||
height: 100%; |
||||
width: 2rpx; |
||||
padding: 60rpx 0 8rpx; |
||||
margin-left: 0 |
||||
} |
||||
.wux-step--vertical .wux-step__ft::after { |
||||
width: 2rpx; |
||||
height: 100% |
||||
} |
||||
.wux-step__ft { |
||||
position: absolute; |
||||
left: 50%; |
||||
width: 100%; |
||||
top: 24rpx; |
||||
padding: 0 48rpx; |
||||
margin-left: 6rpx; |
||||
box-sizing: border-box |
||||
} |
||||
.wux-step__ft::after { |
||||
content: ""; |
||||
display: inline-block; |
||||
background: #d9d9d9; |
||||
height: 2rpx; |
||||
border-radius: 2rpx; |
||||
width: 100%; |
||||
transition: background .3s; |
||||
position: relative; |
||||
left: -4rpx |
||||
} |
||||
.wux-step__icon { |
||||
box-sizing: border-box; |
||||
font-size: 24rpx; |
||||
width: 48rpx; |
||||
height: 100%; |
||||
border-radius: 50%; |
||||
background: #fff; |
||||
position: relative; |
||||
z-index: 2; |
||||
margin: 0 auto; |
||||
border: #e9eaec solid 2rpx |
||||
} |
||||
.wux-step__thumb { |
||||
width: 100%; |
||||
height: 100%; |
||||
display: inline-block; |
||||
overflow: hidden |
||||
} |
||||
.wux-step--process .wux-step__icon { |
||||
border: #EBB672 solid 2rpx; |
||||
color: #fff; |
||||
background: #EBB672 |
||||
} |
||||
.wux-step--wait .wux-step__icon { |
||||
border: #e9eaec solid 2rpx; |
||||
color: #e9eaec |
||||
} |
||||
.wux-step--wait .wux-step__ft::after { |
||||
background: #e9eaec |
||||
} |
||||
.wux-step--finish .wux-step__icon { |
||||
border: #EBB672 solid 2rpx; |
||||
color: #EBB672 |
||||
} |
||||
.wux-step--finish .wux-step__ft::after { |
||||
background: #EBB672 |
||||
} |
||||
.wux-step--error .wux-step__icon { |
||||
border: #ef473a solid 2rpx; |
||||
color: #ef473a |
||||
} |
||||
.wux-step--error .wux-step__ft::after { |
||||
background: #ef473a |
||||
} |
||||
.wux-step__hd { |
||||
width: auto; |
||||
height: 48rpx; |
||||
line-height: 48rpx; |
||||
text-align: center; |
||||
box-sizing: border-box |
||||
} |
||||
.wux-step__bd { |
||||
margin-top: 20rpx; |
||||
text-align: center; |
||||
clear: both |
||||
} |
||||
.wux-step__title { |
||||
font-size: 28rpx; |
||||
font-weight: 700; |
||||
color: #333; |
||||
} |
||||
.wux-step__content { |
||||
font-size: 24rpx; |
||||
margin-top: 6rpx; |
||||
color: rgba(0,0,0,.65); |
||||
line-height: 36rpx; |
||||
} |
@ -0,0 +1,49 @@
|
||||
import baseComponent from '../helpers/baseComponent' |
||||
import classNames from '../helpers/classNames' |
||||
|
||||
baseComponent({ |
||||
relations: { |
||||
'../step/index': { |
||||
type: 'child', |
||||
observer() { |
||||
this.debounce(this.updateCurrent) |
||||
}, |
||||
}, |
||||
}, |
||||
properties: { |
||||
prefixCls: { |
||||
type: String, |
||||
value: 'wux-steps', |
||||
}, |
||||
current: { |
||||
type: Number, |
||||
value: 0, |
||||
observer: 'updateCurrent', |
||||
}, |
||||
// status: {
|
||||
// type: String,
|
||||
// value: '',
|
||||
// },
|
||||
direction: { |
||||
type: String, |
||||
value: 'horizontal', |
||||
}, |
||||
}, |
||||
methods: { |
||||
updateCurrent() { |
||||
const elements = this.getRelationNodes('../step/index') |
||||
const { current, direction } = this.data |
||||
|
||||
if (elements.length > 0) { |
||||
elements.forEach((element, index) => { |
||||
element.updateCurrent({ |
||||
length: elements.length, |
||||
index, |
||||
current, |
||||
direction, |
||||
}) |
||||
}) |
||||
} |
||||
}, |
||||
}, |
||||
}) |
@ -0,0 +1,3 @@
|
||||
<view class="wux-class {{ prefixCls }}"> |
||||
<slot></slot> |
||||
</view> |
@ -0,0 +1,4 @@
|
||||
.wux-steps { |
||||
position: relative; |
||||
width: 100% |
||||
} |
After Width: | Height: | Size: 163 B |
After Width: | Height: | Size: 670 B |
After Width: | Height: | Size: 755 B |
@ -0,0 +1,183 @@
|
||||
// pages/activity/describe/index.js
|
||||
const app = getApp(); |
||||
var WxParse = require('../../../wxParse/wxParse.js'); |
||||
import util from '../../../utils/util' |
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
activityId:'' |
||||
}, |
||||
onLoad: function (options) { |
||||
console.log(options) |
||||
if(options.id){ |
||||
this.setData({activityId:options.id}); |
||||
this.getDetail() |
||||
} |
||||
}, |
||||
getDetail(){ |
||||
var that = this; |
||||
app.http('GET','activity/activityInfo/'+this.data.activityId).then((res)=>{ |
||||
console.log(res) |
||||
if(res.data.success){ |
||||
this.setData({activityDetail:res.data.data}); |
||||
let article = res.data.data.content; |
||||
WxParse.wxParse('article', 'html', article, that,5); |
||||
} else{ |
||||
wx.showToast({ |
||||
title: res.data.msg, |
||||
icon:'none' |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
call(){ |
||||
wx.makePhoneCall({ |
||||
phoneNumber: this.data.activityDetail.publisherVo.phone, |
||||
fail:function(){ |
||||
console.log('取消') |
||||
} |
||||
}) |
||||
}, |
||||
collect(){ |
||||
let data = {}; |
||||
data.id = this.data.activityDetail.id; |
||||
data.type = 'collect'; |
||||
data.status = this.data.activityDetail.collect ? false : true; |
||||
if(wx.getStorageSync('userInfo') != ''){ |
||||
this.requestCollect(data) |
||||
} else{ |
||||
wx.getUserProfile({ |
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => { |
||||
console.log(res) |
||||
var iv = res.iv; |
||||
var encryptedData = res.encryptedData; |
||||
var userInfo = res.userInfo; |
||||
wx.login({ |
||||
success: request => { |
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
app.http('POST','wxapp/auth',{code : request.code,iv:iv,encryptedData:encryptedData}).then( |
||||
response =>{ |
||||
if(response.data.success){ |
||||
wx.setStorageSync('token', 'Bearer '+ response.data.data.token); |
||||
wx.setStorageSync('userInfo', userInfo); |
||||
this.requestCollect(data) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: response.data.msg, |
||||
icon : 'none' |
||||
}) |
||||
} |
||||
}
|
||||
) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
requestCollect(data){ |
||||
app.http('POST','activity/collect',data).then((res)=>{ |
||||
if(res.data.success){ |
||||
wx.showToast({ |
||||
title: '操作成功!', |
||||
}) |
||||
this.getDetail(); |
||||
} else{ |
||||
wx.showToast({ |
||||
title: res.data.msg, |
||||
icon:'none' |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
toSignPage(){ |
||||
if(wx.getStorageSync('userInfo') != ''){ |
||||
wx.navigateTo({ |
||||
url: '../signIn/index?id='+this.data.activityId, |
||||
}) |
||||
} else{ |
||||
wx.getUserProfile({ |
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => { |
||||
console.log(res) |
||||
var iv = res.iv; |
||||
var encryptedData = res.encryptedData; |
||||
var userInfo = res.userInfo; |
||||
wx.login({ |
||||
success: request => { |
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
app.http('POST','wxapp/auth',{code : request.code,iv:iv,encryptedData:encryptedData}).then( |
||||
response =>{ |
||||
if(response.data.success){ |
||||
wx.setStorageSync('token', 'Bearer '+ response.data.data.token); |
||||
wx.setStorageSync('userInfo', userInfo); |
||||
wx.navigateTo({ |
||||
url: '../signIn/index?id='+this.data.activityId, |
||||
}) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: response.data.msg, |
||||
icon : 'none' |
||||
}) |
||||
} |
||||
}
|
||||
) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,4 @@
|
||||
{ |
||||
"usingComponents": {}, |
||||
"navigationBarTitleText": "活动详情" |
||||
} |
@ -0,0 +1,31 @@
|
||||
<!--pages/activity/describe/index.wxml--> |
||||
<import src="../../../wxParse/wxParse.wxml"/> |
||||
<view class="describe-box"> |
||||
<view class="activity-title">{{activityDetail.name}}</view> |
||||
<view class="time-box"> |
||||
<text class="name">{{activityDetail.publisherVo.name}}</text> |
||||
<text>{{activityDetail.updateTime}} 发布</text> |
||||
</view> |
||||
<view class="content"> |
||||
<!-- <rich-text nodes="{{activityDetail.content}}"></rich-text> --> |
||||
<template is="wxParse" data="{{wxParseData:article.nodes}}"/> |
||||
</view> |
||||
<view class="handle-box acea-row row-middle row-between"> |
||||
<view class="acea-row"> |
||||
<view class="call-box acea-row row-middle" bindtap="call"> |
||||
<image src="../../../images/phone.png"></image> |
||||
<text>拨号</text> |
||||
</view> |
||||
<view class="call-box acea-row row-middle" bindtap="collect"> |
||||
<image src="../../../images/collect.png"></image> |
||||
<text>{{activityDetail.collect ? '已收藏':'收藏'}}</text> |
||||
</view> |
||||
</view> |
||||
<view class="handle-btn-box"> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 2}}">报名截止</view> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 3}}">活动结束</view> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 0}}">等待报名</view> |
||||
<view class="cancel-btn signIn-btn" bindtap="toSignPage" wx:if="{{activityDetail.status == 1}}">立即报名</view> |
||||
</view> |
||||
</view> |
||||
</view> |
@ -0,0 +1,64 @@
|
||||
/* pages/activity/describe/index.wxss */ |
||||
.describe-box{ |
||||
min-height: 100%; |
||||
background: #f2f2f2; |
||||
padding: 32rpx; |
||||
box-sizing: border-box; |
||||
} |
||||
.activity-title{ |
||||
color: #000000; |
||||
font-size: 36rpx; |
||||
line-height: 50rpx; |
||||
margin-bottom: 24rpx; |
||||
} |
||||
.name{ |
||||
display: inline-block; |
||||
margin-right: 64rpx; |
||||
color: #EBB672; |
||||
} |
||||
.time-box{ |
||||
color: #7D7D7D; |
||||
font-size: 24rpx; |
||||
} |
||||
.content{ |
||||
margin-top: 38rpx; |
||||
padding-bottom: 130rpx; |
||||
} |
||||
.handle-box { |
||||
width: 100%; |
||||
position: fixed; |
||||
bottom: 0; |
||||
left: 0; |
||||
background: #fff; |
||||
padding: 42rpx 32rpx 80rpx; |
||||
box-sizing: border-box; |
||||
box-shadow: 0px -2px 8px 0px rgba(0,0,0,0.1); |
||||
} |
||||
.call-box{ |
||||
margin-right: 54rpx; |
||||
} |
||||
.call-box image{ |
||||
width: 37rpx; |
||||
height: 37rpx; |
||||
font-size: 28rpx; |
||||
color: #333333; |
||||
margin-right: 12rpx; |
||||
} |
||||
.cancel-btn{ |
||||
width: 234rpx; |
||||
height: 60rpx; |
||||
text-align: center; |
||||
line-height: 60rpx; |
||||
background: #F4F4F4; |
||||
border-radius: 30rpx; |
||||
color: #868686; |
||||
font-size: 32rpx; |
||||
} |
||||
.signIn-btn{ |
||||
background: #EBB672; |
||||
color: #fff; |
||||
} |
||||
.wxParse-p image{ |
||||
width: 100% !important; |
||||
height: auto; |
||||
} |
@ -0,0 +1,222 @@
|
||||
// pages/activity/detail/index.js
|
||||
const app = getApp(); |
||||
import util from '../../../utils/util' |
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
activityId:'', |
||||
activityDetail:{}, |
||||
current:1, |
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面加载 |
||||
*/ |
||||
onLoad: function (options) { |
||||
let erCodeId = wx.getStorageSync('activityId'); |
||||
if(options.id){ |
||||
this.setData({activityId:options.id}); |
||||
this.getDetail() |
||||
} |
||||
if(erCodeId && !options.id){ //扫码进来
|
||||
console.log('扫码进来') |
||||
this.setData({activityId:erCodeId}); |
||||
this.getDetail() |
||||
} |
||||
}, |
||||
getDetail(){ |
||||
app.http('GET','activity/activityInfo/'+this.data.activityId).then((res)=>{ |
||||
if(res.data.success){ |
||||
let detail = res.data.data; |
||||
detail.time1 = util.setTime(detail.createTime).split(' ')[0]; |
||||
detail.time2 = util.setTime(detail.applyStartTime).split(' ')[0]; |
||||
detail.time3 = util.setTime(detail.applyEndTime).split(' ')[0]; |
||||
detail.time4 = util.setTime(detail.activityEndTime).split(' ')[0]; |
||||
detail.flag = detail.flag.split(','); |
||||
detail.activityStartTime = util.setTime(detail.activityStartTime); |
||||
detail.activityEndTime = util.setTime(detail.activityEndTime); |
||||
detail.applyStartTime = util.setTime(detail.applyStartTime); |
||||
detail.applyEndTime = util.setTime(detail.applyEndTime); |
||||
this.setData({activityDetail:detail,current:detail.status}) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: res.data.msg, |
||||
icon:'none' |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
openMap(){ |
||||
const latitude = this.data.activityDetail.latitude |
||||
const longitude = this.data.activityDetail.longitude |
||||
wx.openLocation({ |
||||
latitude, |
||||
longitude, |
||||
scale: 18 |
||||
}) |
||||
}, |
||||
shareClick(){ |
||||
wx.showShareMenu({ |
||||
withShareTicket: true, |
||||
menus: ['shareAppMessage', 'shareTimeline'] |
||||
}) |
||||
}, |
||||
call(){ |
||||
wx.makePhoneCall({ |
||||
phoneNumber: this.data.activityDetail.publisherVo.phone, |
||||
fail:function(){ |
||||
console.log('取消') |
||||
} |
||||
}) |
||||
}, |
||||
collect(){ |
||||
let data = {}; |
||||
data.id = this.data.activityDetail.id; |
||||
data.type = 'collect'; |
||||
data.status = this.data.activityDetail.collect ? false : true; |
||||
if(wx.getStorageSync('userInfo') != ''){ |
||||
this.requestCollect(data) |
||||
} else{ |
||||
wx.getUserProfile({ |
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => { |
||||
console.log(res) |
||||
var iv = res.iv; |
||||
var encryptedData = res.encryptedData; |
||||
var userInfo = res.userInfo; |
||||
wx.login({ |
||||
success: request => { |
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
app.http('POST','wxapp/auth',{code : request.code,iv:iv,encryptedData:encryptedData}).then( |
||||
response =>{ |
||||
if(response.data.success){ |
||||
wx.setStorageSync('token', 'Bearer '+ response.data.data.token); |
||||
wx.setStorageSync('userInfo', userInfo); |
||||
this.requestCollect(data) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: response.data.msg, |
||||
icon : 'none' |
||||
}) |
||||
} |
||||
}
|
||||
) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
requestCollect(data){ |
||||
app.http('POST','activity/collect',data).then((res)=>{ |
||||
if(res.data.success){ |
||||
wx.showToast({ |
||||
title: '操作成功!', |
||||
}) |
||||
this.getDetail(); |
||||
} else{ |
||||
wx.showToast({ |
||||
title: res.data.msg, |
||||
icon:'none' |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
toSignPage(){ |
||||
if(wx.getStorageSync('userInfo') != ''){ |
||||
wx.navigateTo({ |
||||
url: '../signIn/index?id='+this.data.activityId, |
||||
}) |
||||
} else{ |
||||
this.getUserProfile() |
||||
} |
||||
}, |
||||
toDescribe(){ |
||||
wx.navigateTo({ |
||||
url: '../describe/index?id='+this.data.activityDetail.id, |
||||
}) |
||||
}, |
||||
getUserProfile(){ |
||||
wx.getUserProfile({ |
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => { |
||||
console.log(res) |
||||
var iv = res.iv; |
||||
var encryptedData = res.encryptedData; |
||||
var userInfo = res.userInfo; |
||||
wx.login({ |
||||
success: request => { |
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
app.http('POST','wxapp/auth',{code : request.code,iv:iv,encryptedData:encryptedData}).then( |
||||
response =>{ |
||||
if(response.data.success){ |
||||
wx.setStorageSync('token', 'Bearer '+ response.data.data.token); |
||||
wx.setStorageSync('userInfo', userInfo); |
||||
wx.navigateTo({ |
||||
url: '../signIn/index?id='+this.data.activityId, |
||||
}) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: response.data.msg, |
||||
icon : 'none' |
||||
}) |
||||
} |
||||
}
|
||||
) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,7 @@
|
||||
{ |
||||
"usingComponents": { |
||||
"wux-steps": "../../../dist/steps/index", |
||||
"wux-step": "../../../dist/step/index" |
||||
}, |
||||
"navigationBarTitleText": "活动详情" |
||||
} |
@ -0,0 +1,81 @@
|
||||
<!--pages/activity/detail/index.wxml--> |
||||
<view class="activityDetail-page"> |
||||
<view class="activity-info-box"> |
||||
<view class="activity-banner"> |
||||
<image src="{{activityDetail.images}}" mode="widthFix"></image> |
||||
</view> |
||||
<view class="activity-title line2">{{activityDetail.name}}</view> |
||||
<view class="activity-tips-box acea-row"> |
||||
<view class="price">¥{{activityDetail.price}}/人</view> |
||||
<view class="tips acea-row"> |
||||
<view class="{{activityDetail.status == 3 ? 'default-btn' : 'tip-item'}}" wx:for='{{activityDetail.flag}}' wx:key="index">{{item}}</view> |
||||
</view> |
||||
</view> |
||||
<view class="step-box"> |
||||
<wux-steps current="{{ current }}"> |
||||
<wux-step title="筹备中" content="{{activityDetail.time1}}"></wux-step> |
||||
<wux-step title="报名中" content="{{activityDetail.time2}}"></wux-step> |
||||
<wux-step title="待举办" content="{{activityDetail.time3}}"></wux-step> |
||||
<wux-step title="已结束" content="{{activityDetail.time4}}"></wux-step> |
||||
</wux-steps> |
||||
</view> |
||||
<view class="activity-info"> |
||||
<view class="info-item"> |
||||
<view class="label">活动举办时间:</view> |
||||
<view class="info">{{activityDetail.activityStartTime}} 至 {{activityDetail.activityEndTime}}</view> |
||||
</view> |
||||
<view class="info-item"> |
||||
<view class="label">报名截止时间:</view> |
||||
<view class="info">{{activityDetail.applyEndTime}}</view> |
||||
</view> |
||||
<view class="info-item" bindtap="openMap"> |
||||
<view class="label">活动举办地址:</view> |
||||
<view class="info">{{activityDetail.address}}</view> |
||||
</view> |
||||
<view class="info-item"> |
||||
<view class="label">参加人数限制:</view> |
||||
<view class="info">{{activityDetail.users.length}}/{{activityDetail.limit}}</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
<!-- <view class="company-info-box acea-row row-middle"> |
||||
<view class="company-logo"> |
||||
<image src="{{activityDetail.publisherVo.image}}"></image> |
||||
</view> |
||||
<view class="company-info"> |
||||
<view class="company-name">{{activityDetail.publisherVo.name}}</view> |
||||
<view class="company-des line2">{{activityDetail.publisherVo.desc}}</view> |
||||
</view> |
||||
</view> --> |
||||
<view class="activity-des-box"> |
||||
<view class="title2">活动简介</view> |
||||
<text class="line2">{{activityDetail.desc}}</text> |
||||
<view class="see-detail acea-row row-center-wrapper" bindtap="toDescribe">查看详情 <image src="../../../images/arror-r-s.png"></image></view> |
||||
</view> |
||||
<view class="info-item join-box"> |
||||
<view class="label" style="margin-right:0;">最近参与人:</view> |
||||
<view class="info headerImg-info" wx:if="{{activityDetail.users.length > 0}}"> |
||||
<image src="{{item.avatar}}" wx:for="{{activityDetail.users}}" wx:key="index"></image> |
||||
</view> |
||||
<view class="info headerImg-info" wx:else>快分享给好友,一起报名参与吧!</view> |
||||
</view> |
||||
<view class="handle-box acea-row row-middle row-between"> |
||||
<view class="acea-row"> |
||||
<view class="call-box acea-row row-middle" bindtap="call"> |
||||
<image src="../../../images/phone.png"></image> |
||||
<text>拨号</text> |
||||
</view> |
||||
<view class="call-box acea-row row-middle" bindtap="collect"> |
||||
<image src="../../../images/collect.png"></image> |
||||
<text>{{activityDetail.collect ? '已收藏':'收藏'}}</text> |
||||
</view> |
||||
</view> |
||||
<view class="handle-btn-box"> |
||||
<!-- <view class="cancel-btn">取消报名</view> --> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 2}}">报名截止</view> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 3}}">活动结束</view> |
||||
<view class="cancel-btn" wx:if="{{activityDetail.status == 0}}">等待报名</view> |
||||
<view class="cancel-btn signIn-btn" bindtap="toSignPage" wx:if="{{activityDetail.status == 1}}">立即报名</view> |
||||
</view> |
||||
</view> |
||||
</view> |
@ -0,0 +1,188 @@
|
||||
/* pages/activity/detail/index.wxss */ |
||||
.activityDetail-page{ |
||||
background: #f2f2f2; |
||||
min-height: 100%; |
||||
padding-bottom: 240rpx; |
||||
} |
||||
.activity-info-box,.company-info-box,.activity-des-box,.join-box{ |
||||
width: 100%; |
||||
box-sizing: border-box; |
||||
padding: 0 32rpx 40rpx; |
||||
background: #fff; |
||||
font-size: 32rpx; |
||||
} |
||||
.activity-banner{ |
||||
width: 100%; |
||||
height: 404rpx; |
||||
border-radius: 12rpx; |
||||
overflow: hidden; |
||||
} |
||||
image{ |
||||
width: 100%; |
||||
} |
||||
.activity-title{ |
||||
color: #333333; |
||||
font-weight: 600; |
||||
line-height: 44rpx; |
||||
margin: 32rpx 0; |
||||
} |
||||
.price{ |
||||
min-width: 200rpx; |
||||
color: #EBB672; |
||||
font-weight: 600; |
||||
margin-right: 28rpx; |
||||
} |
||||
.tips{ |
||||
width: 74%; |
||||
flex-wrap: wrap; |
||||
} |
||||
.tip-item{ |
||||
height: 36rpx; |
||||
margin-bottom: 6rpx; |
||||
line-height: 36rpx; |
||||
text-align: center; |
||||
padding: 0rpx 16rpx; |
||||
color: #fff; |
||||
font-size: 20rpx; |
||||
background: #C93535; |
||||
margin-right: 24rpx; |
||||
} |
||||
.default-btn{ |
||||
height: 36rpx; |
||||
margin-bottom: 6rpx; |
||||
line-height: 36rpx; |
||||
text-align: center; |
||||
padding: 0rpx 16rpx; |
||||
color: #fff; |
||||
font-size: 20rpx; |
||||
background: #A29E9E; |
||||
margin-right: 24rpx; |
||||
} |
||||
.join-box{ |
||||
height: 100rpx; |
||||
padding: 26rpx 32rpx; |
||||
box-sizing: border-box; |
||||
color: #727272; |
||||
} |
||||
|
||||
.step-box{ |
||||
margin-top: 32rpx; |
||||
} |
||||
.wux-step--process .wux-step__icon { |
||||
background: #FFC985 !important; |
||||
border-color: #FFC985 !important; |
||||
} |
||||
.wux-step__title { |
||||
color: #B5B5B5 !important; |
||||
font-size: 20rpx !important; |
||||
font-weight: 400 !important; |
||||
} |
||||
.wux-step--process .wux-step__title{ |
||||
color: #FFC985 !important; |
||||
} |
||||
.wux-step__content{ |
||||
font-size: 20rpx !important; |
||||
margin-top: 0 !important; |
||||
} |
||||
.wux-step--process .wux-step__content{ |
||||
color: #FFC985 !important; |
||||
} |
||||
.wux-step__bd { |
||||
margin-top: 10rpx !important; |
||||
} |
||||
|
||||
.info-item{ |
||||
display: flex; |
||||
justify-content: start; |
||||
align-items: center; |
||||
margin-top: 40rpx; |
||||
color: #353535; |
||||
font-size: 28rpx; |
||||
} |
||||
.label{ |
||||
width: 180rpx; |
||||
text-align: left; |
||||
margin-right: 20rpx; |
||||
color: #868686; |
||||
} |
||||
.headerImg-info{ |
||||
width: calc(100% - 180rpx); |
||||
color: #333333; |
||||
overflow-x: scroll; |
||||
white-space: nowrap; |
||||
} |
||||
.info image{ |
||||
width: 68rpx; |
||||
height: 68rpx; |
||||
margin-left: 16rpx; |
||||
display: inline-block; |
||||
border-radius: 50%; |
||||
} |
||||
|
||||
.company-info-box,.activity-des-box{ |
||||
margin-top: 32rpx; |
||||
padding-top: 32rpx; |
||||
font-size: 24rpx; |
||||
} |
||||
.company-logo image{ |
||||
width: 132rpx; |
||||
height: 132rpx; |
||||
margin-right: 24rpx; |
||||
border-radius: 50%; |
||||
} |
||||
.company-name{ |
||||
color: #333333; |
||||
font-size: 28rpx; |
||||
margin-bottom: 16rpx; |
||||
} |
||||
.activity-des-box{ |
||||
color: #727272; |
||||
} |
||||
.title2{ |
||||
color: #333; |
||||
font-size: 32rpx; |
||||
margin-bottom: 24rpx; |
||||
} |
||||
.see-detail{ |
||||
color: #333; |
||||
text-align: center; |
||||
margin-top: 12rpx; |
||||
} |
||||
.see-detail image{ |
||||
width: 24rpx; |
||||
height: 24rpx; |
||||
} |
||||
.handle-box { |
||||
width: 100%; |
||||
box-sizing: border-box; |
||||
position: fixed; |
||||
bottom: 0; |
||||
left: 0; |
||||
background: #fff; |
||||
padding: 42rpx 32rpx 80rpx; |
||||
box-shadow: 0px -2px 8px 0px rgba(0,0,0,0.1); |
||||
} |
||||
.call-box{ |
||||
margin-right: 54rpx; |
||||
} |
||||
.call-box image{ |
||||
width: 37rpx; |
||||
height: 37rpx; |
||||
font-size: 28rpx; |
||||
color: #333333; |
||||
margin-right: 12rpx; |
||||
} |
||||
.cancel-btn{ |
||||
width: 234rpx; |
||||
height: 60rpx; |
||||
text-align: center; |
||||
line-height: 60rpx; |
||||
background: #F4F4F4; |
||||
border-radius: 30rpx; |
||||
color: #868686; |
||||
font-size: 32rpx; |
||||
} |
||||
.signIn-btn{ |
||||
background: #EBB672; |
||||
color: #fff; |
||||
} |
@ -0,0 +1,97 @@
|
||||
// pages/activity/index.js
|
||||
const app = getApp(); |
||||
import util from '../../utils/util' |
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
active: 0, |
||||
activityList:[] |
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面加载 |
||||
*/ |
||||
onLoad: function (options) { |
||||
|
||||
}, |
||||
getActivityList(){ |
||||
app.http('POST','activity/activityList',{status:this.data.active}).then((res)=>{ |
||||
if(res.data.success){ |
||||
res.data.data.content.forEach((item)=>{ |
||||
item.activityStartTime = util.getWeek(item.activityStartTime) |
||||
item.activityEndTime = util.getWeek(item.activityEndTime) |
||||
}) |
||||
this.setData({activityList : res.data.data.content}) |
||||
} else{ |
||||
wx.showToast({ |
||||
title: res.data.msg, |
||||
icon:'none' |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
toDetail(e){ |
||||
let id = e.currentTarget.dataset.id; |
||||
wx.navigateTo({ |
||||
url: './detail/index?id='+id, |
||||
}) |
||||
}, |
||||
tabClick(e){ |
||||
var i = Number(e.currentTarget.dataset.i); |
||||
this.setData({ |
||||
active : i |
||||
}) |
||||
this.getActivityList(); |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
this.getActivityList(); |
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,4 @@
|
||||
{ |
||||
"usingComponents": {}, |
||||
"navigationBarTitleText": "" |
||||
} |
@ -0,0 +1,36 @@
|
||||
<!--pages/activity/index.wxml--> |
||||
<view class="activity-page"> |
||||
<view class="tab-box"> |
||||
<view class="tab-box acea-row row-around" style="position:fixed;"> |
||||
<view class="tab-item {{active == 0 ? 'tab-item-active' : ''}}" data-i="0" bindtap="tabClick">报名中</view> |
||||
<view class="tab-item {{active == 10 ? 'tab-item-active' : ''}}" data-i="10" bindtap="tabClick">已完成</view> |
||||
</view> |
||||
</view> |
||||
<view class="activity-list-box"> |
||||
<view class="activity-item acea-row row-between" wx:for="{{activityList}}" wx:key="index" bindtap="toDetail" data-id="{{item.id}}"> |
||||
<view class="activity-img"> |
||||
<view class="img-box"> |
||||
<!-- <image src="{{item.images}}" mode="widthFix"></image> --> |
||||
<image src="{{item.images}}" mode="widthFix"></image> |
||||
</view> |
||||
</view> |
||||
<view class="activity-info-box"> |
||||
<view class="activity-info-title acea-row"> |
||||
<view class="line2"><text class="sm-card">{{item.cateName}}</text>{{item.name}}</view> |
||||
</view> |
||||
<view class="activity-info-time acea-row row-middle"> |
||||
<text>{{item.activityStartTime}}</text> |
||||
<text class="address line1">{{item.address}}</text> |
||||
</view> |
||||
<view class="signUp-box acea-row row-between"> |
||||
<text>已报名人数:{{item.users.length}}</text> |
||||
<view class="status-box" wx:if="{{item.status == 0}}">筹备中</view> |
||||
<view class="status-box" wx:if="{{item.status == 1}}">报名中</view> |
||||
<view class="status-box" wx:if="{{item.status == 2}}">待举办</view> |
||||
<view class="status-box" wx:if="{{item.status == 3}}">已结束</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
<view class="under-line">—已显示全部活动—</view> |
||||
</view> |
@ -0,0 +1,56 @@
|
||||
/* pages/activity/index.wxss */ |
||||
page{ |
||||
height: 100%; |
||||
} |
||||
.activity-page{ |
||||
background: #f2f2f2; |
||||
min-height: 100%; |
||||
padding-top: 150rpx; |
||||
} |
||||
.tab-box{ |
||||
width: 100%; |
||||
height: 82rpx; |
||||
background: #fff; |
||||
margin-bottom: 50rpx; |
||||
} |
||||
.tab-item{ |
||||
height: 100%; |
||||
line-height: 82rpx; |
||||
font-size: 34rpx; |
||||
color: #A5A5A5; |
||||
padding-bottom: 12rpx; |
||||
box-sizing: border-box; |
||||
font-weight: 600; |
||||
position: relative; |
||||
} |
||||
.tab-item::after{ |
||||
display: block; |
||||
content: ''; |
||||
width: 100%; |
||||
height: 6rpx; |
||||
background: #EBB672; |
||||
position: absolute; |
||||
bottom: 0; |
||||
left: 0; |
||||
opacity: 0; |
||||
transform:scaleX(0); |
||||
transition: all .2s cubic-bezier(.18,.89,.17,.88),opacity .15s ease; |
||||
} |
||||
.tab-item-active{ |
||||
color: #333; |
||||
} |
||||
.tab-item-active::after{ |
||||
opacity: 1; |
||||
transform: scaleX(1); |
||||
} |
||||
|
||||
.activity-item{ |
||||
margin-bottom: 24rpx; |
||||
background: #fff; |
||||
padding: 16rpx 32rpx; |
||||
} |
||||
.address{ |
||||
width:70%; |
||||
display:inline-block; |
||||
margin-left:10rpx; |
||||
} |
@ -0,0 +1,113 @@
|
||||
// pages/activity/signIn/confirm/index.js
|
||||
const app = getApp(); |
||||
import util from '../../../../utils/util' |
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
payInfo : {}, |
||||
canClick:true |
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面加载 |
||||
*/ |
||||
onLoad: function (options) { |
||||
let info = JSON.parse(decodeURIComponent(options.payInfo)); |
||||
info.activity.activityStartTime = util.setTime(info.activity.activityStartTime); |
||||
info.activity.activityEndTime = util.setTime(info.activity.activityEndTime); |
||||
this.setData({ |
||||
payInfo:info |
||||
}) |
||||
console.log(this.data.payInfo) |
||||
}, |
||||
backUpPage(){ |
||||
wx.navigateBack({ |
||||
delta: 1, |
||||
}) |
||||
}, |
||||
toPay(){ |
||||
if(this.data.canClick){ |
||||
this.setData({canClick : false}); |
||||
app.http('POST','activity/orderPay',{id:this.data.payInfo.order.id}).then((res)=>{ |
||||
console.log(res) |
||||
if(res.data.success){ |
||||
//微信支付
|
||||
wx.requestPayment({ |
||||
timeStamp: res.data.data.timeStamp, |
||||
nonceStr: res.data.data.nonceStr, |
||||
package: res.data.data.packageValue, |
||||
signType: 'MD5', |
||||
paySign: res.data.data.paySign, |
||||
success: response=> { |
||||
this.setData({canClick: true}); |
||||
wx.showToast({ |
||||
title: '支付成功!', |
||||
duration: 1500 |
||||
}); |
||||
setTimeout(()=> { |
||||
wx.navigateTo({ |
||||
url: '../paymentSuccess/index', |
||||
}) |
||||
}, 1500); |
||||
}, |
||||
fail: response=> { |
||||
this.setData({canClick: true}); |
||||
console.log(response) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,6 @@
|
||||
{ |
||||
"usingComponents": {}, |
||||
"navigationBarTitleText": "信息确认", |
||||
"navigationBarBackgroundColor": "#EBB672", |
||||
"navigationBarTextStyle":"white" |
||||
} |
@ -0,0 +1,42 @@
|
||||
<!--pages/activity/signIn/confirm/index.wxml--> |
||||
<view class="confirm-page"> |
||||
<view class="userInfo-box"> |
||||
<view class="title-box acea-row row-between"> |
||||
<view>参加活动人员信息</view> |
||||
<view class="edit-box acea-row row-middle" bindtap="backUpPage"> |
||||
<image src="../../../../images/edit.png"></image> |
||||
<text>修改</text> |
||||
</view> |
||||
</view> |
||||
<view class="info-box acea-row"> |
||||
<view class="name"> |
||||
<view>昵称</view> |
||||
<view>{{payInfo.order.name}}</view> |
||||
</view> |
||||
<view class="name phone"> |
||||
<view>手机号</view> |
||||
<view>{{payInfo.order.phone}}</view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
<view class="activity-info-box"> |
||||
<view class="title">{{payInfo.activity.name}}</view> |
||||
<view class="activity-info"> |
||||
<view class="label">人数</view> |
||||
<view class="">{{payInfo.order.num}}</view> |
||||
</view> |
||||
<view class="activity-info"> |
||||
<view class="label">活动时间</view> |
||||
<view class="">{{payInfo.activity.activityStartTime}}~{{payInfo.activity.activityEndTime}}</view> |
||||
</view> |
||||
<view class="activity-info"> |
||||
<view class="label">活动地址</view> |
||||
<view class="address">{{payInfo.activity.address}}</view> |
||||
</view> |
||||
<view class="settle-box acea-row row-between"> |
||||
<view class="label">结算金额</view> |
||||
<view class="money">¥{{payInfo.activity.price}}</view> |
||||
</view> |
||||
</view> |
||||
<view class="pay-btn" bindtap="toPay">支付</view> |
||||
</view> |
@ -0,0 +1,82 @@
|
||||
/* pages/activity/signIn/confirm/index.wxss */ |
||||
.confirm-page{ |
||||
width: 100%; |
||||
min-height: 100%; |
||||
background: #f2f2f2; |
||||
} |
||||
.userInfo-box{ |
||||
box-sizing: border-box; |
||||
padding: 56rpx 32rpx; |
||||
background: #fff; |
||||
margin-bottom: 32rpx; |
||||
|
||||
} |
||||
.title-box{ |
||||
font-size: 32rpx; |
||||
color: #333; |
||||
margin-bottom: 38rpx; |
||||
} |
||||
.edit-box{ |
||||
font-size:24rpx; |
||||
} |
||||
.edit-box image{ |
||||
width: 24rpx; |
||||
height: 24rpx; |
||||
margin-right: 4rpx; |
||||
} |
||||
.info-box{ |
||||
font-size: 28rpx; |
||||
} |
||||
.phone{ |
||||
margin-left: 300rpx; |
||||
} |
||||
.name view:nth-child(1){ |
||||
color: #868686; |
||||
margin-bottom: 16rpx; |
||||
} |
||||
|
||||
.activity-info-box{ |
||||
width: 100%; |
||||
background: #fff; |
||||
padding: 32rpx; |
||||
box-sizing: border-box; |
||||
} |
||||
.title{ |
||||
font-size: 32rpx; |
||||
color: #333; |
||||
line-height: 48rpx; |
||||
font-weight: bold; |
||||
margin-bottom: 40rpx; |
||||
} |
||||
.activity-info{ |
||||
display: flex; |
||||
justify-content: space-between; |
||||
font-size: 28rpx; |
||||
margin-bottom: 24rpx; |
||||
} |
||||
.address{ |
||||
overflow:hidden; |
||||
white-space: pre-wrap; |
||||
width: 80%; |
||||
text-align: right; |
||||
} |
||||
.settle-box{ |
||||
font-size: 32rpx; |
||||
font-weight: 600; |
||||
margin-top: 60rpx; |
||||
} |
||||
.money{ |
||||
color: #EBB672; |
||||
} |
||||
.pay-btn{ |
||||
position: fixed; |
||||
bottom: 60rpx; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 76rpx; |
||||
background: #EBB672; |
||||
color: #FFF; |
||||
font-size: 32rpx; |
||||
line-height: 76rpx; |
||||
text-align: center; |
||||
} |
@ -0,0 +1,110 @@
|
||||
// pages/activity/signIn/index.js
|
||||
const app = getApp(); |
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
activityId : '', |
||||
num:'2' |
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面加载 |
||||
*/ |
||||
onLoad: function (options) { |
||||
this.setData({activityId:options.id}) |
||||
}, |
||||
toConfirm(e){ |
||||
console.log(e) |
||||
const values = e.detail.value |
||||
let name = values.name, |
||||
phone = values.phone, |
||||
code = values.code, |
||||
WeChat = values.WeChat, |
||||
num = values.num; |
||||
if(name == '' || phone == '' || code == ''){ |
||||
wx.showToast({ |
||||
title: '带*项为必填项,请检查后重新提交!', |
||||
icon:'none' |
||||
}) |
||||
return
|
||||
} else if(!/^1(3|4|5|7|8)\d{9}$/.test(phone)){ |
||||
wx.showToast({ |
||||
title: '请填写正确手机号', |
||||
icon:'none' |
||||
}) |
||||
return
|
||||
} else if(num == ''){ |
||||
num = 1 |
||||
} |
||||
app.http('post','activity/joinActivity',{activiyId:this.data.activityId,name:name,phone:phone,num:num}).then((res)=>{ |
||||
console.log(res) |
||||
if(res.data.success){ |
||||
let payInfo = encodeURIComponent(JSON.stringify(res.data.data)); |
||||
wx.navigateTo({ |
||||
url: './confirm/index?payInfo='+payInfo, |
||||
}) |
||||
} |
||||
}) |
||||
}, |
||||
inpChange(e){ |
||||
console.log(e) |
||||
let num = e.detail.value; |
||||
if(num <= 0){ |
||||
num = 1 |
||||
} else if(num > 2){ |
||||
num = 2 |
||||
} |
||||
this.setData({num}) |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,6 @@
|
||||
{ |
||||
"usingComponents": {}, |
||||
"navigationBarTitleText": "报名信息填写", |
||||
"navigationBarBackgroundColor": "#EBB672", |
||||
"navigationBarTextStyle":"white" |
||||
} |
@ -0,0 +1,39 @@
|
||||
<!--pages/activity/signIn/index.wxml--> |
||||
<view class="signIn-page"> |
||||
<view class="title-box"> |
||||
<text>参加活动人员信息填写</text> |
||||
<text>请仔细填写,方便后台快速审核通过</text> |
||||
</view> |
||||
<view class="form-box"> |
||||
<form bindsubmit="toConfirm"> |
||||
<view class="form-item"> |
||||
<view class="form-label">昵称<text style="color:#FF3B30;">*</text></view> |
||||
<input type="text" placeholder="请输入姓名" name="name" /> |
||||
</view> |
||||
<view class="form-item"> |
||||
<view class="form-label">手机号<text style="color:#FF3B30;">*</text></view> |
||||
<input type="text" placeholder="请输入手机号" name="phone" maxlength="11" /> |
||||
<!-- <view class="input-box acea-row row-middle"> |
||||
<input type="text" placeholder="请输入手机号" name="phone" /> |
||||
<input type="button" value="发送验证码" bindtap="sendCode" /> |
||||
</view> --> |
||||
</view> |
||||
<!-- <view class="form-item"> |
||||
<view class="form-label">验证码<text style="color:#FF3B30;">*</text></view> |
||||
<input type="text" placeholder="请输入验证码" name="code" /> |
||||
</view> --> |
||||
<view class="form-item"> |
||||
<view class="form-label">微信号</view> |
||||
<input type="text" placeholder="请输入微信" name="WeChat" /> |
||||
</view> |
||||
<view class="form-item"> |
||||
<view class="form-label acea-row row-between"> |
||||
<text>门票<text style="color:#FF3B30;">*</text></text> |
||||
<input type="number" bindblur="inpChange" value="{{num}}" style="width:30rpx" name="num" /> |
||||
</view> |
||||
</view> |
||||
<button class="submit-btn" form-type="submit">下一步</button> |
||||
</form> |
||||
|
||||
</view> |
||||
</view> |
@ -0,0 +1,57 @@
|
||||
/* pages/activity/signIn/index.wxss */ |
||||
.signIn-page{ |
||||
padding: 56rpx 32rpx; |
||||
} |
||||
.title-box text:nth-child(1){ |
||||
font-size: 42rpx; |
||||
font-weight: bold; |
||||
display: block; |
||||
line-height: 58rpx; |
||||
margin-bottom: 8rpx; |
||||
} |
||||
.title-box text:nth-child(2){ |
||||
font-size: 24rpx; |
||||
display: block; |
||||
color: #F96B1C; |
||||
} |
||||
.form-item{ |
||||
font-size: 32rpx; |
||||
color: #333; |
||||
margin-top: 46rpx; |
||||
} |
||||
.form-item input[type="text"]{ |
||||
padding: 26rpx 0 32rpx; |
||||
border-bottom: 2px solid #F4F4F4; |
||||
font-size: 28rpx; |
||||
} |
||||
.input-box input[type="text"]{ |
||||
width: calc(100% - 310rpx); |
||||
} |
||||
.form-item input[type="button"]{ |
||||
width: 175rpx; |
||||
height:78rpx; |
||||
line-height: 78rpx; |
||||
text-align: center; |
||||
color: #fff; |
||||
background: #EBB672; |
||||
padding: 0 10rpx; |
||||
border-radius: 8rpx; |
||||
font-size: 28rpx; |
||||
margin-left: 12rpx; |
||||
} |
||||
|
||||
.submit-btn{ |
||||
width: 100% !important; |
||||
position: fixed; |
||||
bottom: 60rpx; |
||||
left: 0; |
||||
width: 100%; |
||||
height: 76rpx !important; |
||||
background: #EBB672; |
||||
color: #FFF; |
||||
font-size: 32rpx; |
||||
line-height: 76rpx !important; |
||||
padding: 0 !important; |
||||
text-align: center; |
||||
border-radius: 0 !important; |
||||
} |
@ -0,0 +1,70 @@
|
||||
// pages/activity/signIn/paymentSuccess/index.js
|
||||
Page({ |
||||
|
||||
/** |
||||
* 页面的初始数据 |
||||
*/ |
||||
data: { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面加载 |
||||
*/ |
||||
onLoad: function (options) { |
||||
|
||||
}, |
||||
toJoin(){ |
||||
wx.switchTab({ |
||||
url: '../../../user/index', |
||||
}) |
||||
}, |
||||
/** |
||||
* 生命周期函数--监听页面初次渲染完成 |
||||
*/ |
||||
onReady: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面显示 |
||||
*/ |
||||
onShow: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面隐藏 |
||||
*/ |
||||
onHide: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 生命周期函数--监听页面卸载 |
||||
*/ |
||||
onUnload: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面相关事件处理函数--监听用户下拉动作 |
||||
*/ |
||||
onPullDownRefresh: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 页面上拉触底事件的处理函数 |
||||
*/ |
||||
onReachBottom: function () { |
||||
|
||||
}, |
||||
|
||||
/** |
||||
* 用户点击右上角分享 |
||||
*/ |
||||
onShareAppMessage: function () { |
||||
|
||||
} |
||||
}) |
@ -0,0 +1,6 @@
|
||||
{ |
||||
"usingComponents": {}, |
||||
"navigationBarTitleText": "支付", |
||||
"navigationBarBackgroundColor": "#EBB672", |
||||
"navigationBarTextStyle":"white" |
||||
} |
@ -0,0 +1,7 @@
|
||||
<!--pages/activity/signIn/paymentSuccess/index.wxml--> |
||||
<view class="page"> |
||||
<image src="../../../../images/paySuccess.png"></image> |
||||
<view class="tips">支付成功</view> |
||||
<view>支付完成,请前往我的订单中查看核销码</view> |
||||
<view class="btn" bindtap="toJoin">前往个人中心</view> |
||||
</view> |
@ -0,0 +1,30 @@
|
||||
/* pages/activity/signIn/paymentSuccess/index.wxss */ |
||||
.page{ |
||||
width: 100%; |
||||
height: 100%; |
||||
box-sizing: border-box; |
||||
background: #FAFAFA; |
||||
padding-top: 100rpx; |
||||
text-align: center; |
||||
font-size:32rpx; |
||||
} |
||||
.page image{ |
||||
width: 230rpx; |
||||
height: 212rpx; |
||||
margin:0 auto 48rpx; |
||||
display: block; |
||||
} |
||||
.tips{ |
||||
font-size: 48rpx; |
||||
color: #353535; |
||||
margin-bottom: 24rpx; |
||||
} |
||||
.btn{ |
||||
width: 380rpx; |
||||
height: 80rpx; |
||||
background: #EBB672; |
||||
border-radius: 8rpx; |
||||
color: #fff; |
||||
line-height: 80rpx; |
||||
margin: 190rpx auto; |
||||
} |
@ -0,0 +1,31 @@
|
||||
var sub = function(val) { |
||||
if (val.length == 0 || val == undefined) { |
||||
return; |
||||
} |
||||
if (val.length > 17) { |
||||
return val.substring(0, 17) + "..."; |
||||
} else { |
||||
return val.substring(0, 1); |
||||
} |
||||
} |
||||
var filters = { |
||||
toFloat: function (value) { |
||||
return parseFloat(value) |
||||
}, |
||||
toStr: function (value) { |
||||
return value.toString() |
||||
}, |
||||
toNum: function (value) { |
||||
return value.toNumber() |
||||
}, |
||||
} |
||||
var spl = function(str){ |
||||
return str.split(","); |
||||
} |
||||
module.exports = { |
||||
toFloat: filters.toFloat, |
||||
toStr: filters.toStr, |
||||
toNum: filters.toNum,//暴露接口调用 |
||||
sub: sub, |
||||
spl: spl |
||||
}; |
@ -0,0 +1,303 @@
|
||||
/** |
||||
* html2Json 改造来自: https://github.com/Jxck/html2json
|
||||
*
|
||||
*
|
||||
* 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 trimHtml(html) { |
||||
return html |
||||
.replace(/\r?\n+/g, '') |
||||
.replace(/<!--.*?-->/ig, '') |
||||
.replace(/\/\*.*?\*\//ig, '') |
||||
.replace(/[ ]+</ig, '<') |
||||
} |
||||
|
||||
|
||||
function html2json(html, bindName) { |
||||
//处理字符串
|
||||
html = removeDOCTYPE(html); |
||||
html = trimHtml(html); |
||||
html = wxDiscode.strDiscode(html); |
||||
//生成node节点
|
||||
var bufArray = []; |
||||
var results = { |
||||
node: bindName, |
||||
nodes: [], |
||||
images:[], |
||||
imageUrls:[] |
||||
}; |
||||
var index = 0; |
||||
HTMLParser(html, { |
||||
start: function (tag, attrs, unary) { |
||||
//debug(tag, attrs, unary);
|
||||
// node for this element
|
||||
var node = { |
||||
node: 'element', |
||||
tag: tag, |
||||
}; |
||||
|
||||
if (bufArray.length === 0) { |
||||
node.index = index.toString() |
||||
index += 1 |
||||
} else { |
||||
var parent = bufArray[0]; |
||||
if (parent.nodes === undefined) { |
||||
parent.nodes = []; |
||||
} |
||||
node.index = parent.index + '.' + parent.nodes.length |
||||
} |
||||
|
||||
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; |
||||
if (imgUrl[0] == '') { |
||||
imgUrl.splice(0, 1); |
||||
} |
||||
imgUrl = wxDiscode.urlToHttpUrl(imgUrl, __placeImgeUrlHttps); |
||||
node.attr.src = imgUrl; |
||||
node.from = bindName; |
||||
results.images.push(node); |
||||
results.imageUrls.push(imgUrl); |
||||
} |
||||
|
||||
// 处理font标签样式属性
|
||||
if (node.tag === 'font') { |
||||
var fontSize = ['x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '-webkit-xxx-large']; |
||||
var styleAttrs = { |
||||
'color': 'color', |
||||
'face': 'font-family', |
||||
'size': 'font-size' |
||||
}; |
||||
if (!node.attr.style) node.attr.style = []; |
||||
if (!node.styleStr) node.styleStr = ''; |
||||
for (var key in styleAttrs) { |
||||
if (node.attr[key]) { |
||||
var value = key === 'size' ? fontSize[node.attr[key]-1] : node.attr[key]; |
||||
node.attr.style.push(styleAttrs[key]); |
||||
node.attr.style.push(value); |
||||
node.styleStr += styleAttrs[key] + ': ' + value + ';'; |
||||
} |
||||
} |
||||
} |
||||
|
||||
//临时记录source资源
|
||||
if(node.tag === 'source'){ |
||||
results.source = node.attr.src; |
||||
} |
||||
|
||||
if (unary) { |
||||
// if this tag doesn'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'); |
||||
|
||||
//当有缓存source资源时于于video补上src资源
|
||||
if(node.tag === 'video' && results.source){ |
||||
node.attr.src = results.source; |
||||
delete results.source; |
||||
} |
||||
|
||||
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) { |
||||
node.index = index.toString() |
||||
index += 1 |
||||
results.nodes.push(node); |
||||
} else { |
||||
var parent = bufArray[0]; |
||||
if (parent.nodes === undefined) { |
||||
parent.nodes = []; |
||||
} |
||||
node.index = parent.index + '.' + parent.nodes.length |
||||
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 |
||||
}; |
||||
|
@ -0,0 +1,192 @@
|
||||
/** |
||||
*
|
||||
* htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
|
||||
*
|
||||
* 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 = '' |
||||
while (index === 0) { |
||||
text += "<"; |
||||
html = html.substring(1); |
||||
index = html.indexOf("<"); |
||||
} |
||||
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 { |
||||
tagName = tagName.toLowerCase(); |
||||
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; |
@ -0,0 +1,207 @@
|
||||
// HTML 支持的数学符号
|
||||
function strNumDiscode(str){ |
||||
str = str.replace(/∀/g, '∀'); |
||||
str = str.replace(/∂/g, '∂'); |
||||
str = str.replace(/&exists;/g, '∃'); |
||||
str = str.replace(/∅/g, '∅'); |
||||
str = str.replace(/∇/g, '∇'); |
||||
str = str.replace(/∈/g, '∈'); |
||||
str = str.replace(/∉/g, '∉'); |
||||
str = str.replace(/∋/g, '∋'); |
||||
str = str.replace(/∏/g, '∏'); |
||||
str = str.replace(/∑/g, '∑'); |
||||
str = str.replace(/−/g, '−'); |
||||
str = str.replace(/∗/g, '∗'); |
||||
str = str.replace(/√/g, '√'); |
||||
str = str.replace(/∝/g, '∝'); |
||||
str = str.replace(/∞/g, '∞'); |
||||
str = str.replace(/∠/g, '∠'); |
||||
str = str.replace(/∧/g, '∧'); |
||||
str = str.replace(/∨/g, '∨'); |
||||
str = str.replace(/∩/g, '∩'); |
||||
str = str.replace(/∩/g, '∪'); |
||||
str = str.replace(/∫/g, '∫'); |
||||
str = str.replace(/∴/g, '∴'); |
||||
str = str.replace(/∼/g, '∼'); |
||||
str = str.replace(/≅/g, '≅'); |
||||
str = str.replace(/≈/g, '≈'); |
||||
str = str.replace(/≠/g, '≠'); |
||||
str = str.replace(/≤/g, '≤'); |
||||
str = str.replace(/≥/g, '≥'); |
||||
str = str.replace(/⊂/g, '⊂'); |
||||
str = str.replace(/⊃/g, '⊃'); |
||||
str = str.replace(/⊄/g, '⊄'); |
||||
str = str.replace(/⊆/g, '⊆'); |
||||
str = str.replace(/⊇/g, '⊇'); |
||||
str = str.replace(/⊕/g, '⊕'); |
||||
str = str.replace(/⊗/g, '⊗'); |
||||
str = str.replace(/⊥/g, '⊥'); |
||||
str = str.replace(/⋅/g, '⋅'); |
||||
return str; |
||||
} |
||||
|
||||
//HTML 支持的希腊字母
|
||||
function strGreeceDiscode(str){ |
||||
str = str.replace(/Α/g, 'Α'); |
||||
str = str.replace(/Β/g, 'Β'); |
||||
str = str.replace(/Γ/g, 'Γ'); |
||||
str = str.replace(/Δ/g, 'Δ'); |
||||
str = str.replace(/Ε/g, 'Ε'); |
||||
str = str.replace(/Ζ/g, 'Ζ'); |
||||
str = str.replace(/Η/g, 'Η'); |
||||
str = str.replace(/Θ/g, 'Θ'); |
||||
str = str.replace(/Ι/g, 'Ι'); |
||||
str = str.replace(/Κ/g, 'Κ'); |
||||
str = str.replace(/Λ/g, 'Λ'); |
||||
str = str.replace(/Μ/g, 'Μ'); |
||||
str = str.replace(/Ν/g, 'Ν'); |
||||
str = str.replace(/Ξ/g, 'Ν'); |
||||
str = str.replace(/Ο/g, 'Ο'); |
||||
str = str.replace(/Π/g, 'Π'); |
||||
str = str.replace(/Ρ/g, 'Ρ'); |
||||
str = str.replace(/Σ/g, 'Σ'); |
||||
str = str.replace(/Τ/g, 'Τ'); |
||||
str = str.replace(/Υ/g, 'Υ'); |
||||
str = str.replace(/Φ/g, 'Φ'); |
||||
str = str.replace(/Χ/g, 'Χ'); |
||||
str = str.replace(/Ψ/g, 'Ψ'); |
||||
str = str.replace(/Ω/g, 'Ω'); |
||||
|
||||
str = str.replace(/α/g, 'α'); |
||||
str = str.replace(/β/g, 'β'); |
||||
str = str.replace(/γ/g, 'γ'); |
||||
str = str.replace(/δ/g, 'δ'); |
||||
str = str.replace(/ε/g, 'ε'); |
||||
str = str.replace(/ζ/g, 'ζ'); |
||||
str = str.replace(/η/g, 'η'); |
||||
str = str.replace(/θ/g, 'θ'); |
||||
str = str.replace(/ι/g, 'ι'); |
||||
str = str.replace(/κ/g, 'κ'); |
||||
str = str.replace(/λ/g, 'λ'); |
||||
str = str.replace(/μ/g, 'μ'); |
||||
str = str.replace(/ν/g, 'ν'); |
||||
str = str.replace(/ξ/g, 'ξ'); |
||||
str = str.replace(/ο/g, 'ο'); |
||||
str = str.replace(/π/g, 'π'); |
||||
str = str.replace(/ρ/g, 'ρ'); |
||||
str = str.replace(/ς/g, 'ς'); |
||||
str = str.replace(/σ/g, 'σ'); |
||||
str = str.replace(/τ/g, 'τ'); |
||||
str = str.replace(/υ/g, 'υ'); |
||||
str = str.replace(/φ/g, 'φ'); |
||||
str = str.replace(/χ/g, 'χ'); |
||||
str = str.replace(/ψ/g, 'ψ'); |
||||
str = str.replace(/ω/g, 'ω'); |
||||
str = str.replace(/ϑ/g, 'ϑ'); |
||||
str = str.replace(/ϒ/g, 'ϒ'); |
||||
str = str.replace(/ϖ/g, 'ϖ'); |
||||
str = str.replace(/·/g, '·'); |
||||
return str; |
||||
} |
||||
|
||||
//
|
||||
|
||||
function strcharacterDiscode(str){ |
||||
// 加入常用解析
|
||||
str = str.replace(/ /g, ' '); |
||||
str = str.replace(/"/g, "'"); |
||||
str = str.replace(/&/g, '&'); |
||||
// str = str.replace(/</g, '‹');
|
||||
// str = str.replace(/>/g, '›');
|
||||
|
||||
str = str.replace(/</g, '<'); |
||||
str = str.replace(/>/g, '>'); |
||||
str = str.replace(/•/g, '•'); |
||||
|
||||
return str; |
||||
} |
||||
|
||||
// HTML 支持的其他实体
|
||||
function strOtherDiscode(str){ |
||||
str = str.replace(/Œ/g, 'Œ'); |
||||
str = str.replace(/œ/g, 'œ'); |
||||
str = str.replace(/Š/g, 'Š'); |
||||
str = str.replace(/š/g, 'š'); |
||||
str = str.replace(/Ÿ/g, 'Ÿ'); |
||||
str = str.replace(/ƒ/g, 'ƒ'); |
||||
str = str.replace(/ˆ/g, 'ˆ'); |
||||
str = str.replace(/˜/g, '˜'); |
||||
str = str.replace(/ /g, ''); |
||||
str = str.replace(/ /g, ''); |
||||
str = str.replace(/ /g, ''); |
||||
str = str.replace(/‌/g, ''); |
||||
str = str.replace(/‍/g, ''); |
||||
str = str.replace(/‎/g, ''); |
||||
str = str.replace(/‏/g, ''); |
||||
str = str.replace(/–/g, '–'); |
||||
str = str.replace(/—/g, '—'); |
||||
str = str.replace(/‘/g, '‘'); |
||||
str = str.replace(/’/g, '’'); |
||||
str = str.replace(/‚/g, '‚'); |
||||
str = str.replace(/“/g, '“'); |
||||
str = str.replace(/”/g, '”'); |
||||
str = str.replace(/„/g, '„'); |
||||
str = str.replace(/†/g, '†'); |
||||
str = str.replace(/‡/g, '‡'); |
||||
str = str.replace(/•/g, '•'); |
||||
str = str.replace(/…/g, '…'); |
||||
str = str.replace(/‰/g, '‰'); |
||||
str = str.replace(/′/g, '′'); |
||||
str = str.replace(/″/g, '″'); |
||||
str = str.replace(/‹/g, '‹'); |
||||
str = str.replace(/›/g, '›'); |
||||
str = str.replace(/‾/g, '‾'); |
||||
str = str.replace(/€/g, '€'); |
||||
str = str.replace(/™/g, '™'); |
||||
|
||||
str = str.replace(/←/g, '←'); |
||||
str = str.replace(/↑/g, '↑'); |
||||
str = str.replace(/→/g, '→'); |
||||
str = str.replace(/↓/g, '↓'); |
||||
str = str.replace(/↔/g, '↔'); |
||||
str = str.replace(/↵/g, '↵'); |
||||
str = str.replace(/⌈/g, '⌈'); |
||||
str = str.replace(/⌉/g, '⌉'); |
||||
|
||||
str = str.replace(/⌊/g, '⌊'); |
||||
str = str.replace(/⌋/g, '⌋'); |
||||
str = str.replace(/◊/g, '◊'); |
||||
str = str.replace(/♠/g, '♠'); |
||||
str = str.replace(/♣/g, '♣'); |
||||
str = str.replace(/♥/g, '♥'); |
||||
|
||||
str = str.replace(/♦/g, '♦'); |
||||
str = str.replace(/'/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 |
||||
} |
@ -0,0 +1,159 @@
|
||||
/** |
||||
* 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'; |
||||
/** |
||||
* 配置及公有属性 |
||||
**/ |
||||
var realWindowWidth = 0; |
||||
var realWindowHeight = 0; |
||||
wx.getSystemInfo({ |
||||
success: function (res) { |
||||
realWindowWidth = res.windowWidth |
||||
realWindowHeight = res.windowHeight |
||||
} |
||||
}) |
||||
/** |
||||
* 主函数入口区 |
||||
**/ |
||||
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 || 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);
|
||||
var index = temImages[idx].index |
||||
var key = `${bindName}` |
||||
for (var i of index.split('.')) key+=`.nodes[${i}]` |
||||
var keyW = key + '.width' |
||||
var keyH = key + '.height' |
||||
that.setData({ |
||||
[keyW]: recal.imageWidth, |
||||
[keyH]: recal.imageheight, |
||||
}) |
||||
} |
||||
|
||||
// 计算视觉优先的图片宽高
|
||||
function wxAutoImageCal(originalWidth, originalHeight,that,bindName) { |
||||
//获取图片的原始长宽
|
||||
var windowWidth = 0, windowHeight = 0; |
||||
var autoWidth = 0, autoHeight = 0; |
||||
var results = {}; |
||||
var padding = that.data[bindName].view.imagePadding; |
||||
windowWidth = realWindowWidth-2*padding; |
||||
windowHeight = realWindowHeight; |
||||
//判断按照那种方式进行缩放
|
||||
// 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 |
||||
} |
||||
|
||||
|
@ -0,0 +1,967 @@
|
||||
<!--** |
||||
* 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" mode="widthFix" style="width:{{item.width}}px;" |
||||
/> |
||||
</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="WxParseBr"> |
||||
<text>\n</text> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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-src="{{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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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" style="{{item.styleStr}}"> |
||||
<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.tag == 'br'}}"> |
||||
<template is="WxParseBr"></template> |
||||
</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> |
@ -0,0 +1,207 @@
|
||||
|
||||
/** |
||||
* 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; |
||||
} |
||||
|
||||
.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; |
||||
border-top: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; |
||||
} |
||||
.wxParse-del{ |
||||
display: inline; |
||||
} |
||||
.wxParse-figure { |
||||
overflow: hidden; |
||||
} |
Loading…
Reference in new issue