project init
This commit is contained in:
commit
5fe9f2bb20
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/.env
|
||||
/.idea/
|
||||
/.wepycache/
|
||||
.wepycache
|
||||
|
||||
**/node_modules
|
||||
**/.DS_Store
|
||||
|
||||
/config/config.js
|
||||
/config/group_config.js
|
||||
/config/plugin_config.js
|
||||
/config/bot_config.js
|
||||
|
||||
/public
|
||||
/logs
|
||||
/build
|
||||
/dist
|
||||
/lib
|
||||
rev-manifest.json
|
||||
/yarn.lock
|
||||
/nohup.out
|
||||
/package-lock.json
|
||||
/dist.tar.gz
|
||||
/config/apiclient_cert.p12
|
3
.prettierrc
Normal file
3
.prettierrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"singleQuote": true
|
||||
}
|
4
.wepyignore
Normal file
4
.wepyignore
Normal file
@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
.DS_Store
|
||||
*.wpy___jb_tmp___
|
39
package.json
Normal file
39
package.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "game",
|
||||
"version": "0.0.2",
|
||||
"description": "A WePY project",
|
||||
"main": "dist/app.js",
|
||||
"scripts": {
|
||||
"dev": "wepy build --watch",
|
||||
"build": "cross-env NODE_ENV=production wepy build --no-cache",
|
||||
"dev:web": "wepy build --output web",
|
||||
"clean": "find ./dist -maxdepth 1 -not -name 'project.config.json' -not -name 'dist' | xargs rm -rf",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"wepy": {
|
||||
"module-a": false,
|
||||
"./src/components/list": "./src/components/wepy-list.wpy"
|
||||
},
|
||||
"author": "zhl <zhl010101@gmail.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"redux": "^3.7.2",
|
||||
"redux-actions": "^2.2.1",
|
||||
"redux-promise": "^0.5.3",
|
||||
"wepy": "^1.7.2",
|
||||
"wepy-async-function": "^1.4.4",
|
||||
"wepy-com-toast": "^1.0.2",
|
||||
"wepy-redux": "^1.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||
"babel-plugin-transform-export-extensions": "^6.22.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"cross-env": "^5.1.3",
|
||||
"less": "^3.8.1",
|
||||
"wepy-compiler-babel": "^1.5.3",
|
||||
"wepy-compiler-less": "^1.3.14"
|
||||
}
|
||||
}
|
13
project.config.json
Normal file
13
project.config.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"description": "A WePY project",
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": false,
|
||||
"postcss": false,
|
||||
"minified": false
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"appid": "touristappid",
|
||||
"projectname": "game",
|
||||
"miniprogramRoot": "./dist"
|
||||
}
|
69
src/app.wpy
Normal file
69
src/app.wpy
Normal file
@ -0,0 +1,69 @@
|
||||
<style lang="less">
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
import 'wepy-async-function'
|
||||
|
||||
export default class extends wepy.app {
|
||||
config = {
|
||||
pages: [
|
||||
'pages/index',
|
||||
'pages/game',
|
||||
'pages/login'
|
||||
],
|
||||
window: {
|
||||
backgroundTextStyle: 'light',
|
||||
navigationBarBackgroundColor: '#fff',
|
||||
navigationBarTitleText: 'WeChat',
|
||||
navigationBarTextStyle: 'black'
|
||||
}
|
||||
}
|
||||
|
||||
globalData = {
|
||||
userInfo: null
|
||||
}
|
||||
|
||||
constructor () {
|
||||
super()
|
||||
this.use('requestfix')
|
||||
}
|
||||
|
||||
onLaunch() {
|
||||
}
|
||||
|
||||
getUserInfo() {
|
||||
return this.globalData.userInfo
|
||||
}
|
||||
checkClientLogin() {
|
||||
return !this.globalData.userInfo;
|
||||
}
|
||||
updateGlobalData(name, obj) {
|
||||
// 校验: globalData
|
||||
if (!this.globalData) return;
|
||||
// 校验: 操作字段
|
||||
if (typeof name !== 'string' || name === '') return {};
|
||||
// 取已有信息
|
||||
const info = this.globalData[name] || {};
|
||||
// 更新缓存
|
||||
if (obj) {
|
||||
// Object合并第一层
|
||||
this.globalData[name] = Object.assign({}, info, obj);
|
||||
} else if (!this.isUndefined(obj)) {
|
||||
// 其他非undefined数据直接覆盖
|
||||
this.globalData[name] = obj;
|
||||
}
|
||||
this.$apply && this.$apply();
|
||||
console.info(`[${obj ? 'UPDATE' : 'GET'} GlobalData ${name}]:`, this.globalData[name]);
|
||||
return this.globalData[name];
|
||||
}
|
||||
}
|
||||
</script>
|
5
src/common/global.js
Normal file
5
src/common/global.js
Normal file
@ -0,0 +1,5 @@
|
||||
export default {
|
||||
apiBase: 'https://pay-test.kingsome.cn',
|
||||
hostBase: 'https://pay.kingsome.cn',
|
||||
version: '1.0.1'
|
||||
}
|
4
src/common/images.js
Normal file
4
src/common/images.js
Normal file
@ -0,0 +1,4 @@
|
||||
export default {
|
||||
info_img: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABGdBTUEAALGPC/xhBQAAABh0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjMxN4N3hgAAA/BJREFUeF7tmiGPFEEUhE8gNkFwCQKCIARBFoFAkJxAIJFIJBKJRJ5DnkQikfwEJPIkEolE4nZ5ncwl5NjjZntLdE19m7xcsjfdefVVTW/3ZI6O+EAAAhCAAAQgAAEIQAACEIAABCAAgRAC2+12XfXiojabzUmI9FyZZfZx1WmZ/b3+/vOp739WndU/7uZSWqjyMvZ11a9dxl/+rq77Xd+9XyiKPFll6Ic5xu8Iwpc8WgtTXOa/7TH/YkyN/7gwJDly2m/5tJwfkoFtzfEyh9qClJZxnw5yfhpc85wvCEuGlPJuNXfTNzMk6wxyC1HZzvUzjZ17GacCp2y0Y99cZ+dc154POOmP7/XQ3f+OIyGnAadUtZ37nDt7j2tOnfTH99qOgHuYe+2lHAUNI1Wmfb3W2RkXTKeJlSGC7JbL21cz/J1zCScA1yjV3ft5jsNXXVPjv7VnCq764/ueHgid94SgzP9R4x7EQ3QHUCYe77sSTHc+7wW4m/93/21P0J7r/281mO76N0vSjZZLBCoA6zL6XXtPoJ0UpreA2ptCvBZGWiAAAQhAAAIQgAAEIAABCIxBoOdJnnLMGBSCu1Ca2TNXMPoxpPeYphwzBoXgLpRm9swVjH4M6T2mKceMQSG4C6WZPXMFox9Deo9pyjFjUAjuQmlmz1zB6MeQ3mOacswYFIK7UJrZM1cw+jGk95imHDMGheAulGb2zBWMfgzpPaYpx4xBIbgLpZk9cwWjH0N6j2nKMWNQCO5CaWbPXMHofaX3GH3VGF8KwZ0TgGDzm3QCQABkGQhH6Slf5n5N5EkgvGsCQABkGQhH6Slf5j4/AQTAk0B416wABECWgXCUnvJl7rMHIACeBMK7ZgUgALIMhKP0lC9znz0AAfAkEN41KwABkGUgHKWnfJn77AEIgCeB8K5ZAQiALAPhKD3ly9xnD0AAPAmEd80KQABkGQhH6Slf5j57AALgSSC8a1YAAiDLQDhKT/ky99kDEABPAuFdswIQAFkGwlF6ype5zx6AAHgSCO+aFYAAyDIQjtJTvsx99gAEwJNAeNesAARAloFwlJ7yZe6zByAAngTCu2YFIACyDISj9JQvc589AAHwJBDeNSsAAZBlIBylp3yZ++wBCIAngfCuWQEIgCwD4SiRDwFDAnX7P1eVoXxaLvNPVAVNQwJl/jNVGcqn5TL/qaqgaUigzH+iKkP5tFzmP1YVNA0JlPmPVGUon5bL/IeqgqYhgTL/vqoM5dNymX9PVdA0JFDm31GVoXxaLvNvqwqahgTK/FuqMpRPy2X+TVVB05BAmb9SlaF8Wi7zb6gKmhCAAAQgAAEIQAACEIAABLwJ/AEEKPggcS30pwAAAABJRU5ErkJggg==',
|
||||
accept_img: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTM4IDc5LjE1OTgyNCwgMjAxNi8wOS8xNC0wMTowOTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTcgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QjhEODI0MDNENjg0MTFFOEE1OTU4MDIxQjI4REYwRjgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QjhEODI0MDRENjg0MTFFOEE1OTU4MDIxQjI4REYwRjgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpCOEQ4MjQwMUQ2ODQxMUU4QTU5NTgwMjFCMjhERjBGOCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpCOEQ4MjQwMkQ2ODQxMUU4QTU5NTgwMjFCMjhERjBGOCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pjl/41gAAAIcSURBVHja7N1BVsMwEATRKM/3v/KwZJMFxJatUf9aQwCpetQOBo+qeiGXtyUgAAgAAoAAIAAIAAKAACAACAACgAAgAAgAAoAAIAAIgF04LMFS/PUGzWECgACh6f/vxxIABAABthn/lx4DrgL6bfynzx8mQN7mX/JaBNAB0Dz9p15TB+i/8ac6gQmwz+Z/9bUIsLdwRYC89OsANt5VgM0nAAgg/TqAjTcBbD4BQADp1wFsvAlg8wmAJ4+A2//wQfrXmQC1wQLXTpuvBO6d+rHaBMBim3+nANU8cds+VeNYfOFO3/cetPFfrdG7yeKVzfc+ACZcNr8bpaekf/0OsNx97878+yZA94RGPj9PBwg7868+Ap5MTV24ELFPzzyaL9bZTlCJqd/xCCip1wGc+eEClPQ//z7A6p2gpD7jCCip1wGc+eEClPTndQBnvgkAAjjzpwowXuvft48bOsBwmdUz9Y4ATBHAsdBwrUwAHWCa2TpBgwlpAugAWcZLvwmAiR1AJ2g2AU0AHUAikn9WE0AHeCwZJfUmAIIFGNJvAiCsA+zUCbaYYCaADiBRyf3FBNABlk1WSb0JgGABhu/FBEBYB1ipE0T89tIE0AFce6em3wRAu/8PMLMTRN7FbALoAG0Z0m8CIFyAIf0mAIKuAiTYBAABQAAQAAQAAUAAEAAEAAFAABAABAABQAAQAAQAAUAAEAAEAAFAAPzyI8AAliJQGcH8J6wAAAAASUVORK5CYII=',
|
||||
}
|
34
src/components/game-cell.wpy
Normal file
34
src/components/game-cell.wpy
Normal file
@ -0,0 +1,34 @@
|
||||
<!--游戏cell-->
|
||||
<style lang="less">
|
||||
@import "../style/game-cell.wxss";
|
||||
</style>
|
||||
<template>
|
||||
<view class="game-cell" @tap="gameTap({{item.url}})">
|
||||
<view class="game-icon">
|
||||
<image src="{{item.image}}" mode="aspectFit"></image>
|
||||
</view>
|
||||
<view class="content-view">
|
||||
<view class="title">{{item.title}}</view>
|
||||
<view class="content">{{item.content}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class gameCell extends wepy.component {
|
||||
props = {
|
||||
item: {
|
||||
type: Object,
|
||||
defalut: null
|
||||
}
|
||||
}
|
||||
data = {
|
||||
}
|
||||
methods = {
|
||||
gameTap (url, e) {
|
||||
this.$emit('gameCellTap', url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
66
src/components/zan-dialog.wpy
Normal file
66
src/components/zan-dialog.wpy
Normal file
@ -0,0 +1,66 @@
|
||||
<style lang="less">
|
||||
.zan-dialog__mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.zan-dialog__container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 750rpx;
|
||||
background: white;
|
||||
transform: translateY(100%);
|
||||
z-index: 11;
|
||||
}
|
||||
|
||||
.zan-dialog--show .zan-dialog__mask {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-dialog {{ showDialog ? 'zan-dialog--show' : '' }}">
|
||||
<view class="zan-dialog__mask" bindtap="toggleDialog" />
|
||||
<view animation="{{animationData}}" class="zan-dialog__container">
|
||||
<view style="padding: 100px 0; text-align: center;">{{content}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanDialog extends wepy.component {
|
||||
props = {}
|
||||
data = {
|
||||
showDialog: false,
|
||||
content: '',
|
||||
animationData: {}
|
||||
}
|
||||
methods = {
|
||||
toggleDialog({ content = '' }, event) {
|
||||
console.log('showZanDialogs', content)
|
||||
this.content = content
|
||||
this.showDialog = !this.showDialog
|
||||
let animation = wepy.createAnimation({
|
||||
duration: 400,
|
||||
timingFunction: 'ease'
|
||||
})
|
||||
this.animation = animation
|
||||
wx.createSelectorQuery()
|
||||
.select('.zan-dialog__container')
|
||||
.boundingClientRect((rect) => {
|
||||
this.showDialog
|
||||
? animation.translateY().step()
|
||||
: animation.translateY(rect.height).step()
|
||||
this.animationData = animation.export()
|
||||
this.$apply()
|
||||
}).exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
107
src/components/zan-loadmore.wpy
Normal file
107
src/components/zan-loadmore.wpy
Normal file
@ -0,0 +1,107 @@
|
||||
<style lang="less">
|
||||
.zan-loadmore {
|
||||
position: relative;
|
||||
width: 65%;
|
||||
margin: 21px auto;
|
||||
line-height: 20px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.zan-loading {
|
||||
width:20px;
|
||||
height:20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
animation: weuiLoading 1s steps(12, end) infinite;
|
||||
background: transparent url(data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iciIgd2lkdGg9JzEyMHB4JyBoZWlnaHQ9JzEyMHB4JyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj4KICAgIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJub25lIiBjbGFzcz0iYmsiPjwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjRTlFOUU5JwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoMCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICA8L3JlY3Q+CiAgICA8cmVjdCB4PSc0Ni41JyB5PSc0MCcgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHJ4PSc1JyByeT0nNScgZmlsbD0nIzk4OTY5NycKICAgICAgICAgIHRyYW5zZm9ybT0ncm90YXRlKDMwIDUwIDUwKSB0cmFuc2xhdGUoMCAtMzApJz4KICAgICAgICAgICAgICAgICByZXBlYXRDb3VudD0naW5kZWZpbml0ZScvPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyM5Qjk5OUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSg2MCA1MCA1MCkgdHJhbnNsYXRlKDAgLTMwKSc+CiAgICAgICAgICAgICAgICAgcmVwZWF0Q291bnQ9J2luZGVmaW5pdGUnLz4KICAgIDwvcmVjdD4KICAgIDxyZWN0IHg9JzQ2LjUnIHk9JzQwJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgcng9JzUnIHJ5PSc1JyBmaWxsPScjQTNBMUEyJwogICAgICAgICAgdHJhbnNmb3JtPSdyb3RhdGUoOTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNBQkE5QUEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCMkIyQjInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxNTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNCQUI4QjknCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgxODAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDMkMwQzEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyMTAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNDQkNCQ0InCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEMkQyRDInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgyNzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNEQURBREEnCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMDAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0PgogICAgPHJlY3QgeD0nNDYuNScgeT0nNDAnIHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyByeD0nNScgcnk9JzUnIGZpbGw9JyNFMkUyRTInCiAgICAgICAgICB0cmFuc2Zvcm09J3JvdGF0ZSgzMzAgNTAgNTApIHRyYW5zbGF0ZSgwIC0zMCknPgogICAgPC9yZWN0Pgo8L3N2Zz4=) no-repeat;
|
||||
-webkit-background-size: 100%;
|
||||
background-size: 100%;
|
||||
}
|
||||
|
||||
.zan-loadmore .zan-loading {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.zan-loadmore__tips {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.zan-loadmore--nodata,
|
||||
.zan-loadmore--nomore {
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.zan-loadmore--nodata {
|
||||
margin-top: 120px;
|
||||
}
|
||||
|
||||
.zan-loadmore--nodata .zan-loadmore__tips {
|
||||
position: relative;
|
||||
top: -11px;
|
||||
background: #f9f9f9;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.zan-loadmore--nomore .zan-loadmore__tips {
|
||||
position: relative;
|
||||
top: -11px;
|
||||
background: #f9f9f9;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.zan-loadmore__dot {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 10px;
|
||||
margin-left: -2px;
|
||||
margin-top: -2px;
|
||||
content: " ";
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: #E5E5E5;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<block wx:if="{{nomore}}">
|
||||
<view class="zan-loadmore zan-loadmore--nomore">
|
||||
<view class="zan-loadmore__tips">{{ nomore_str || '无更多数据' }}</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:elif="{{nodata}}">
|
||||
<view class="zan-loadmore zan-loadmore--nodata">
|
||||
<view class="zan-loadmore__tips">{{ nodata_str || '暂无数据' }}</view>
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<block wx:elif="{{loading}}">
|
||||
<view class="zan-loadmore">
|
||||
<view class="zan-loading"></view>
|
||||
<view class="zan-loadmore__tips">加载中...</view>
|
||||
</view>
|
||||
</block>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanLoadmore extends wepy.component {
|
||||
props = {
|
||||
loading: Boolean,
|
||||
nodata: {type: Boolean, default: false},
|
||||
nomore: {type: Boolean, default: false},
|
||||
nodata_str: String,
|
||||
nomore_str: String
|
||||
}
|
||||
methods = {
|
||||
}
|
||||
}
|
||||
</script>
|
141
src/components/zan-quantity.wpy
Normal file
141
src/components/zan-quantity.wpy
Normal file
@ -0,0 +1,141 @@
|
||||
<style lang="less">
|
||||
.zan-quantity {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.zan-quantity view {
|
||||
display: inline-block;
|
||||
line-height: 20px;
|
||||
padding: 5px 0;
|
||||
text-align: center;
|
||||
min-width: 40px;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
font-size: 12px;
|
||||
border: 1rpx solid #999;
|
||||
}
|
||||
|
||||
.zan-quantity .zan-quantity__minus {
|
||||
border-right: none;
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.zan-quantity .zan-quantity__text {
|
||||
border: 1rpx solid #999;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
height: 30px;
|
||||
width: 40px;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.zan-quantity .zan-quantity__plus {
|
||||
border-left: none;
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
.zan-quantity .zan-quantity--disabled {
|
||||
background: #f8f8f8;
|
||||
color: #bbb;
|
||||
border-color: #e8e8e8;
|
||||
}
|
||||
|
||||
.zan-quantity--small view {
|
||||
min-width: 36px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.zan-quantity--small .zan-quantity__text {
|
||||
width: 36px;
|
||||
line-height: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-quantity {{ size === 'small' ? 'zan-quantity--small' : '' }}">
|
||||
<view class="zan-quantity__minus {{ quantity <= min ? 'zan-quantity--disabled' : '' }}" data-component-id="{{ componentId }}" data-quantity="{{ quantity }}" data-disabled="{{ quantity <= min }}" bindtap="handleZanQuantityMinus">-</view>
|
||||
<input class="zan-quantity__text {{ min >= max ? 'zan-quantity--disabled' : '' }}" type="number" data-component-id="{{ componentId }}" data-min="{{ min }}" data-max="{{ max }}" value="{{ quantity }}" disabled="{{ min >= max }}" bindblur="handleZanQuantityBlur"></input>
|
||||
<view class="zan-quantity__plus {{ quantity >= max ? 'zan-quantity--disabled' : '' }}" data-component-id="{{ componentId }}" data-quantity="{{ quantity }}" data-disabled="{{ quantity >= max }}" bindtap="handleZanQuantityPlus">+</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanQuantity extends wepy.component {
|
||||
props = {
|
||||
quantity: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
min: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
max: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
size: String,
|
||||
componentId: String
|
||||
}
|
||||
data = {}
|
||||
methods = {
|
||||
handleZanQuantityMinus(e) {
|
||||
this.handle(e, -1)
|
||||
},
|
||||
|
||||
handleZanQuantityPlus(e) {
|
||||
this.handle(e, +1)
|
||||
},
|
||||
|
||||
handleZanQuantityBlur(e) {
|
||||
let dataset = e.currentTarget.dataset
|
||||
let componentId = dataset.componentId
|
||||
let max = +dataset.max
|
||||
let min = +dataset.min
|
||||
let value = e.detail.value
|
||||
|
||||
if (!value) {
|
||||
setTimeout(() => {
|
||||
this.callback(componentId, min)
|
||||
}, 16)
|
||||
this.callback(componentId, value)
|
||||
return '' + value
|
||||
}
|
||||
|
||||
value = +value
|
||||
if (value > max) {
|
||||
value = max
|
||||
} else if (value < min) {
|
||||
value = min
|
||||
}
|
||||
|
||||
this.callback(componentId, value)
|
||||
|
||||
return '' + value
|
||||
}
|
||||
}
|
||||
|
||||
handle(e, num) {
|
||||
let dataset = e.currentTarget.dataset
|
||||
let componentId = dataset.componentId
|
||||
let disabled = dataset.disabled
|
||||
let quantity = +dataset.quantity
|
||||
|
||||
if (disabled) return null
|
||||
|
||||
this.callback(componentId, quantity + num)
|
||||
}
|
||||
|
||||
callback(componentId, quantity) {
|
||||
quantity = +quantity
|
||||
let e = { componentId, quantity }
|
||||
console.info('[zan:quantity:change]', e)
|
||||
|
||||
this.$emit('zanQuantityChange', e)
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
268
src/components/zan-steps.wpy
Normal file
268
src/components/zan-steps.wpy
Normal file
@ -0,0 +1,268 @@
|
||||
<style lang="less">
|
||||
.zan-steps--steps.zan-steps--5 .zan-steps__step {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.zan-steps--steps.zan-steps--4 .zan-steps__step {
|
||||
width: 33%;
|
||||
}
|
||||
|
||||
.zan-steps--steps.zan-steps--3 .zan-steps__step {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding-bottom: 25px;
|
||||
color: #b1b1b1;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__title {
|
||||
transform: translateX(-50%);
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__icons {
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: -10px;
|
||||
padding: 0 8px;
|
||||
background-color: #fff;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__circle {
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #e5e5e5;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__line {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 32px;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* 已完成的steps */
|
||||
|
||||
.zan-steps--steps .zan-steps__step--done {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--done .zan-steps__line {
|
||||
background-color: #06bf04;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--done .zan-steps__circle {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #09bb07;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 正在进行中的steps */
|
||||
|
||||
.zan-steps--steps .zan-steps__step--cur .zan-steps__icons {
|
||||
top: 25px;
|
||||
left: -14px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--cur .zan-steps__circle {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
background-image: url("https://b.yzcdn.cn/v2/image/wap/success_small@2x.png");
|
||||
background-size: 13px 13px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--cur .zan-steps__line {
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 各种不同位置的 */
|
||||
|
||||
.zan-steps--steps .zan-steps__step--first-child .zan-steps__title {
|
||||
margin-left: 0;
|
||||
transform: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--first-child .zan-steps__icons {
|
||||
left: -7px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--last-child {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--last-child .zan-steps__title {
|
||||
transform: none;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--last-child .zan-steps__icons {
|
||||
left: auto;
|
||||
right: -6px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--last-child .zan-steps__line {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 有描述的step */
|
||||
|
||||
.zan-steps--steps .zan-steps__step--db-title {
|
||||
min-height: 29px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--db-title .zan-steps__line {
|
||||
top: 45px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--db-title .zan-steps__icons {
|
||||
top: 43px;
|
||||
}
|
||||
|
||||
.zan-steps--steps .zan-steps__step--db-title.zan-steps__step--cur .zan-steps__icons {
|
||||
top: 39px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step {
|
||||
position: relative;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step--done {
|
||||
color: #44BB00;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__line {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 7px;
|
||||
width: 1px;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__title {
|
||||
display: inline-block;
|
||||
line-height: 20px;
|
||||
padding-left: 27px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__title--desc {
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__icons {
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 2;
|
||||
padding: 3px 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__circle {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #cacaca;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step--done .zan-steps__circle {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
background-color: #09bb07;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step--cur .zan-steps__circle {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
background: transparent url("https://b.yzcdn.cn/v2/image/wap/success_small@2x.png");
|
||||
background-size: 13px 13px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__icon--active {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step--first-child .zan-steps__title::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 50%;
|
||||
left: 7px;
|
||||
width: 1px;
|
||||
background-color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.zan-steps--vsteps .zan-steps__step--last-child .zan-steps__title::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
bottom: 0%;
|
||||
left: 7px;
|
||||
width: 1px;
|
||||
background-color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.zan-steps {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-steps zan-steps--{{ type == 'vertical' ? 'vsteps' : 'steps' }} zan-steps--{{ steps.length }} {{ className }}">
|
||||
<view wx:for="{{ steps }}" wx:for-item="step" wx:key="unique" wx:for-index="index" class="zan-steps__step {{ hasDesc ? 'zan-steps__step--db-title' : '' }} {{ index == 0 ? 'zan-steps__step--first-child' : '' }} {{ index == steps.length - 1 ? 'zan-steps__step--last-child' : '' }} {{ step.done ? 'zan-steps__step--done' : '' }} {{ step.current ? 'zan-steps__step--cur' : '' }}">
|
||||
<view class="zan-steps__title">{{ step.text }}</view>
|
||||
<view wx:if="{{ hasDesc && step.desc }}" class="zan-steps__title zan-steps__title--desc">{{ step.desc }}</view>
|
||||
<view class="zan-steps__icons">
|
||||
<view class="zan-steps__circle"></view>
|
||||
</view>
|
||||
<view class="zan-steps__line"></view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanSteps extends wepy.component {
|
||||
props = {
|
||||
steps: Object,
|
||||
type: String,
|
||||
hasDesc: Boolean,
|
||||
className: String
|
||||
}
|
||||
data = {}
|
||||
methods = {}
|
||||
}
|
||||
</script>
|
122
src/components/zan-switch.wpy
Normal file
122
src/components/zan-switch.wpy
Normal file
@ -0,0 +1,122 @@
|
||||
<style lang="less">
|
||||
.zan-switch {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 52px;
|
||||
height: 32px;
|
||||
vertical-align: middle;
|
||||
box-sizing: border-box;
|
||||
border-radius: 16px;
|
||||
background: #44DB5E;
|
||||
border: 1px solid #44DB5E;
|
||||
}
|
||||
|
||||
.zan-switch__circle {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
border-radius: 15px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 0 3px 1px 0 rgba(0, 0, 0, 0.05), 0 2px 2px 0 rgba(0, 0, 0, 0.1), 0 3px 3px 0 rgba(0, 0, 0, 0.05);
|
||||
transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.zan-switch__bg {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: 52px;
|
||||
height: 32px;
|
||||
background: #fff;
|
||||
border-radius: 26px;
|
||||
display: inline-block;
|
||||
border: 1px solid #e5e5e5;
|
||||
box-sizing: border-box;
|
||||
transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1);
|
||||
transform: scale(0);
|
||||
transform-origin: 36px 16px;
|
||||
}
|
||||
|
||||
.zan-switch--on .zan-switch__circle {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
.zan-switch--off .zan-switch__bg {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.zan-swtich--disabled {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.zan-switch__loading {
|
||||
position: absolute;
|
||||
left: 7px;
|
||||
top: 7px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: url(https://img.yzcdn.cn/public_files/2017/02/24/9acec77d91106cd15b8107c4633d9155.png) no-repeat;
|
||||
background-size: 16px 16px;
|
||||
animation: zan-switch-loading 0.8s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes zan-switch-loading {
|
||||
from {
|
||||
transform: rotate(0);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-switch zan-switch--{{ checked ? 'on' : 'off' }} {{ disabled ? 'zan-swtich--disabled' : '' }}" data-checked="{{ checked }}" data-loading="{{ loading }}" data-disabled="{{ disabled }}" data-component-id="{{ componentId }}" @tap="handleZanSwitchChange">
|
||||
<view class="zan-switch__circle">
|
||||
<view hidden="{{ !loading }}" class="zan-switch__loading"></view>
|
||||
</view>
|
||||
<view class="zan-switch__bg"></view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanSwitch extends wepy.component {
|
||||
props = {
|
||||
checked: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
componentId: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
data = {}
|
||||
methods = {
|
||||
handleZanSwitchChange(e) {
|
||||
let dataset = e.currentTarget.dataset
|
||||
let { loading, disabled, componentId } = dataset
|
||||
let checked = !dataset.checked
|
||||
|
||||
if (loading || disabled) return
|
||||
|
||||
console.info('[zan:switch:change]', { checked, componentId })
|
||||
|
||||
this.$emit('zanSwitchChange', { componentId, checked })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
95
src/components/zan-tab.wpy
Normal file
95
src/components/zan-tab.wpy
Normal file
@ -0,0 +1,95 @@
|
||||
<style lang="less">
|
||||
.zan-tab {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.zan-tab__bd {
|
||||
width: 750rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.zan-tab__bd--fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.zan-tab__item {
|
||||
flex: 1;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.zan-tab__title {
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
color: #666;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
box-sizing: border-box;
|
||||
margin: 0 10px;
|
||||
word-break: keep-all;
|
||||
}
|
||||
.zan-tab__item--selected{
|
||||
pointer-events: none;
|
||||
}
|
||||
.zan-tab__item--selected .zan-tab__title {
|
||||
color: #0DAB3C;
|
||||
border-bottom: 2px solid #0DAB3C;
|
||||
}
|
||||
|
||||
.zan-tab__bd--scroll {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.zan-tab__bd--scroll .zan-tab__item {
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.zan-tab__bd--scroll .zan-tab__text {
|
||||
margin: 0 20px;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-tab">
|
||||
<block wx:if="{{tab.scroll}}">
|
||||
<scroll-view class="zan-tab__bd zan-tab__bd--scroll {{ fixed ? 'zan-tab__bd--fixed' : '' }}" scroll-x="true" style="height: {{ tab.height ? tab.height + 'px' : 'auto' }}">
|
||||
<view wx:for="{{tab.list}}" wx:key="id" class="zan-tab__item {{tab.selectedId == item.id ? 'zan-tab__item--selected' : ''}}" data-component-id="{{componentId}}" data-item-id="{{item.id}}" @tap="handleZanTabChange">
|
||||
<view class="zan-tab__title">{{item.title}}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="zan-tab__bd {{fixed ? 'zan-tab__bd--fixed' : ''}}">
|
||||
<view wx:for="{{tab.list}}" wx:key="id" class="zan-tab__item {{tab.selectedId == item.id ? 'zan-tab__item--selected' : ''}}" data-component-id="{{componentId}}" data-item-id="{{item.id}}" @tap="handleZanTabChange">
|
||||
<view class="zan-tab__title">{{item.title}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanTab extends wepy.component {
|
||||
props = {
|
||||
tab: Object,
|
||||
componentId: String
|
||||
}
|
||||
data = {
|
||||
showDialog: false
|
||||
}
|
||||
methods = {
|
||||
handleZanTabChange(e) {
|
||||
let { componentId, itemId: selectedId } = e.currentTarget.dataset
|
||||
console.info('[zan:tab:change]', { componentId, selectedId })
|
||||
this.$emit('zanTabChange', { componentId, selectedId })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
61
src/components/zan-toast.wpy
Normal file
61
src/components/zan-toast.wpy
Normal file
@ -0,0 +1,61 @@
|
||||
<style lang="less">
|
||||
.zan-toast {
|
||||
position: fixed;
|
||||
top: 35%;
|
||||
left: 20%;
|
||||
transform: translateZ(0) translateY(-100%);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
width: 60%;
|
||||
line-height: 1.5em;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="zan-toast" wx:if="{{ toast.show }}" @tap="clearZanToast">
|
||||
{{ toast.title }}</view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanToast extends wepy.component {
|
||||
props = {}
|
||||
data = {
|
||||
toast: {}
|
||||
}
|
||||
methods = {
|
||||
showZanToast({title, timeout, cb}) {
|
||||
var toast = this.toast || {}
|
||||
clearTimeout(toast.timer)
|
||||
|
||||
// 弹层设置~
|
||||
this.toast = {
|
||||
show: true,
|
||||
title
|
||||
}
|
||||
this.$apply()
|
||||
|
||||
var timer = setTimeout(() => {
|
||||
this.methods.clearZanToast.call(this)
|
||||
typeof cb === 'function' && cb()
|
||||
}, timeout || 3000)
|
||||
|
||||
this.toast.timer = timer
|
||||
this.$apply()
|
||||
},
|
||||
clearZanToast() {
|
||||
var toast = this.toast || {}
|
||||
clearTimeout(toast.timer)
|
||||
|
||||
this.toast.show = false
|
||||
this.$apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
88
src/components/zan-toptips.wpy
Normal file
88
src/components/zan-toptips.wpy
Normal file
@ -0,0 +1,88 @@
|
||||
<style lang="less">
|
||||
.zan-toptips {
|
||||
display: block;
|
||||
position: fixed;
|
||||
transform: translateY(-100%);
|
||||
width: 100%;
|
||||
/* 至少有一行的高度,保证第一次动画显示正常 */
|
||||
min-height: 32px;
|
||||
top: 0;
|
||||
line-height: 2.3;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
background-color: #E64340;
|
||||
z-index: 110;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<view animation="{{animationData}}" class="zan-toptips"> {{ topTips.content }} </view>
|
||||
</template>
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class zanToptips extends wepy.component {
|
||||
props = {}
|
||||
data = {
|
||||
topTips: {},
|
||||
animationData: {}
|
||||
}
|
||||
methods = {
|
||||
showZanTopTips({ content = '', options = {} }, event) {
|
||||
console.log('showZanTopTips', content, options)
|
||||
let topTips = this.topTips || {}
|
||||
// 如果已经有一个计时器在了,就清理掉先
|
||||
if (topTips.timer) {
|
||||
clearTimeout(topTips.timer)
|
||||
topTips.timer = undefined
|
||||
}
|
||||
|
||||
if (typeof options === 'number') {
|
||||
options = {
|
||||
duration: options
|
||||
}
|
||||
}
|
||||
|
||||
// options参数默认参数扩展
|
||||
options = Object.assign({
|
||||
duration: 3000
|
||||
}, options)
|
||||
|
||||
// 原生动画
|
||||
let animation = wepy.createAnimation({
|
||||
duration: 400,
|
||||
timingFunction: 'ease'
|
||||
})
|
||||
this.animation = animation
|
||||
|
||||
const toggle = () => {
|
||||
wx.createSelectorQuery()
|
||||
.select('.zan-toptips')
|
||||
.boundingClientRect((rect) => {
|
||||
this.topTips.show
|
||||
? animation.translateY().step()
|
||||
: animation.translateY(-rect.height).step()
|
||||
this.animationData = animation.export()
|
||||
this.$apply()
|
||||
}).exec()
|
||||
}
|
||||
|
||||
// 设置定时器,定时关闭topTips
|
||||
let timer = setTimeout(() => {
|
||||
this.topTips.show = false
|
||||
this.topTips.timer = undefined
|
||||
toggle()
|
||||
}, options.duration)
|
||||
|
||||
// 展示出topTips
|
||||
this.topTips = {
|
||||
show: true,
|
||||
content,
|
||||
timer
|
||||
}
|
||||
toggle()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
21
src/index.template.html
Normal file
21
src/index.template.html
Normal file
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<meta content="telephone=no" name="format-detection">
|
||||
|
||||
<title>转 WEB DEMO</title>
|
||||
<style>
|
||||
html, body, #app {height: 100%;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<router-view></router-view>
|
||||
<script src="./index.js"></script>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
156
src/mixins/base.js
Normal file
156
src/mixins/base.js
Normal file
@ -0,0 +1,156 @@
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class baseMixin extends wepy.mixin {
|
||||
/**
|
||||
* [公共方法]
|
||||
* @param {[type]} item [description]
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
noop() {
|
||||
return null;
|
||||
}
|
||||
hasOwn(obj, type) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* [isXXX 基础方法]
|
||||
* @param {[type]} item [description]
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
isUndefined(item) {
|
||||
return typeof item === 'undefined';
|
||||
}
|
||||
isDefined(item) {
|
||||
return !this.isUndefined(item);
|
||||
}
|
||||
isString(item) {
|
||||
return typeof item === 'string';
|
||||
}
|
||||
isNumber(item) {
|
||||
return typeof item === 'number';
|
||||
}
|
||||
isArray(item) {
|
||||
return Object.prototype.toString.apply(item) === '[object Array]';
|
||||
}
|
||||
isObject(item) {
|
||||
return typeof item === 'object' && !this.isArray(item);
|
||||
}
|
||||
isFunction(item) {
|
||||
return typeof item === 'function';
|
||||
}
|
||||
|
||||
/**
|
||||
* [getXXX 增强方法]
|
||||
* @param {[type]} item [description]
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
getString(item, defaultStr) {
|
||||
if (this.isString(item)) return item.trim();
|
||||
if (this.isNumber(item)) return `${item}`.trim();
|
||||
return defaultStr || '';
|
||||
}
|
||||
getNumber(item, defaultNum) {
|
||||
var matches = this.getString(item).match(/\d+/);
|
||||
return this.isNumber(matches && +matches[0]) ? +matches[0] : defaultNum;
|
||||
}
|
||||
getArray(item, defaultArr) {
|
||||
return this.isArray(item) ? item : (defaultArr || []);
|
||||
}
|
||||
getObject(item, defaultObj) {
|
||||
return this.isObject(item) ? item : (defaultObj || {});
|
||||
}
|
||||
getFunction(item) {
|
||||
return this.isFunction(item) ? item : noop;
|
||||
}
|
||||
|
||||
/**
|
||||
* [JSON方法]
|
||||
* @param {[type]} item [description]
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
$json(item) {
|
||||
let str = {type: Object.prototype.toString.call(item)}
|
||||
try {
|
||||
str = JSON.stringify(item)
|
||||
} catch (e) {
|
||||
str.error = e && e.stack || ''
|
||||
}
|
||||
return this.isString(str) ? str : this.$json(str)
|
||||
}
|
||||
$parse(item) {
|
||||
let obj = {type: Object.prototype.toString.call(item)}
|
||||
try {
|
||||
obj = JSON.parse(item)
|
||||
} catch (e) {
|
||||
obj.error = e && e.stack || ''
|
||||
}
|
||||
return this.isObject(obj) ? obj : this.$parse(obj)
|
||||
}
|
||||
|
||||
/**
|
||||
* [功能方法]
|
||||
* @param {[type]} item [description]
|
||||
* @return {Boolean} [description]
|
||||
*/
|
||||
isPhone(str) {
|
||||
return /^1\d{10}$/.test(str)
|
||||
}
|
||||
$alert(item = '标题', item2) {
|
||||
const param = this.isObject(item) ? Object.assign({
|
||||
// 首参数为obj
|
||||
title: 'title', content: 'content'
|
||||
}, item) : this.isString(item) ? this.isString(item2) ? {
|
||||
// 俩参数均为字符串
|
||||
title: item, content: item2
|
||||
} : {
|
||||
// 只有首参为字符串
|
||||
title: '', content: item
|
||||
} : {
|
||||
// 尝试转换字符串
|
||||
title: item.toString ? item.toString() : '参数异常'
|
||||
}
|
||||
wx.showModal(Object.assign({
|
||||
showCancel: false
|
||||
}, param))
|
||||
}
|
||||
$info(str) {
|
||||
console.log('INFO:: %s', str)
|
||||
}
|
||||
$error(str) {
|
||||
console.log('ERROR:: %s', str)
|
||||
}
|
||||
$trimStart(str, char) {
|
||||
let r2 = new RegExp('^' + char + '+')
|
||||
return str.replace(r2, '')
|
||||
}
|
||||
$remove(array, func) {
|
||||
return array.filter(func)
|
||||
}
|
||||
generateShareID () {
|
||||
let d = new Date().getTime()
|
||||
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
|
||||
d += performance.now()
|
||||
}
|
||||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
let r = (d + Math.random() * 16) % 16 | 0
|
||||
d = Math.floor(d / 16)
|
||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16)
|
||||
})
|
||||
}
|
||||
$formatMoney(money) {
|
||||
return (money/100).toFixed(2)
|
||||
}
|
||||
$randomNum(minNum,maxNum){
|
||||
return parseInt(Math.random()*(maxNum-minNum+1)+minNum,10);
|
||||
}
|
||||
$getRandomColor() {
|
||||
let rgb = []
|
||||
for (let i = 0; i < 3; ++i) {
|
||||
let color = Math.floor(Math.random() * 256).toString(16)
|
||||
color = color.length == 1 ? '0' + color : color
|
||||
rgb.push(color)
|
||||
}
|
||||
return '#' + rgb.join('')
|
||||
}
|
||||
}
|
25
src/mixins/tips.js
Normal file
25
src/mixins/tips.js
Normal file
@ -0,0 +1,25 @@
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class testMixin extends wepy.mixin {
|
||||
|
||||
showToast (title, duration) {
|
||||
if (!duration) {
|
||||
duration = 15000
|
||||
}
|
||||
wepy.showToast({
|
||||
title: title,
|
||||
icon: 'loading',
|
||||
duration: duration
|
||||
})
|
||||
}
|
||||
showLoading() {
|
||||
wepy.showToast({
|
||||
title: '加载中',
|
||||
icon: 'loading',
|
||||
duration: 3000
|
||||
})
|
||||
}
|
||||
hideToast () {
|
||||
wepy.hideToast()
|
||||
}
|
||||
}
|
26
src/pages/game.wpy
Normal file
26
src/pages/game.wpy
Normal file
@ -0,0 +1,26 @@
|
||||
<style lang="less">
|
||||
</style>
|
||||
<template>
|
||||
<view class="container">
|
||||
<web-view src="{{link}}"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import wepy from 'wepy'
|
||||
|
||||
export default class GameWebPage extends wepy.page {
|
||||
components = {};
|
||||
data = {
|
||||
link: ''
|
||||
};
|
||||
methods = {};
|
||||
|
||||
onLoad(params) {
|
||||
this.link = decodeURIComponent(params.link);
|
||||
console.log(this.link);
|
||||
this.$apply();
|
||||
}
|
||||
}
|
||||
</script>
|
109
src/pages/index.wpy
Normal file
109
src/pages/index.wpy
Normal file
@ -0,0 +1,109 @@
|
||||
<style lang="less">
|
||||
@import "../style/index.wxss";
|
||||
</style>
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class="top-view">
|
||||
<view class="userinfo">
|
||||
<image class="userinfo-avatar" src="{{avatar}}"/>
|
||||
<view class="userinfo-nickname">{{ nickname }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<repeat for="{{records}}" item="item" >
|
||||
<recordCell :item="item" @gameCellTap.user="gameTap"/>
|
||||
</repeat>
|
||||
<zanLoadmore :loading.sync="loading" :nodata.sync="noData" :nomore.sync="noMore" nodata_str="暂无数据"></zanLoadmore>
|
||||
<toast/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wepy from 'wepy';
|
||||
import Toast from 'wepy-com-toast';
|
||||
import base from '../mixins/base';
|
||||
import tips from '../mixins/tips';
|
||||
import recordCell from '../components/game-cell';
|
||||
import zanLoadmore from '../components/zan-loadmore';
|
||||
|
||||
export default class Index extends wepy.page {
|
||||
mixins = [base, tips];
|
||||
config = {
|
||||
navigationBarTitleText: '游戏大厅',
|
||||
enablePullDownRefresh: true
|
||||
};
|
||||
components = {
|
||||
toast: Toast,
|
||||
recordCell: recordCell,
|
||||
zanLoadmore: zanLoadmore
|
||||
};
|
||||
|
||||
data = {
|
||||
nickname: '加载中',
|
||||
avatar: '',
|
||||
records: [],
|
||||
all_count: 0,
|
||||
current: 0,
|
||||
loading: false,
|
||||
noData: true,
|
||||
noMore: false
|
||||
};
|
||||
|
||||
methods = {
|
||||
gameTap(url, e) {
|
||||
wepy.navigateTo({
|
||||
url: '/pages/game?link=' + url
|
||||
})
|
||||
},
|
||||
};
|
||||
|
||||
onPullDownRefresh() {
|
||||
this.initPageParam();
|
||||
this.getRecords();
|
||||
}
|
||||
|
||||
onReachBottom() {
|
||||
if (this.current < this.all_count) {
|
||||
this.loading = true;
|
||||
this.$apply();
|
||||
let self = this;
|
||||
setTimeout(() => {
|
||||
self.getRecords();
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
async onLoad(options) {
|
||||
|
||||
if (this.$parent.checkClientLogin()) {
|
||||
wepy.navigateTo({
|
||||
url: '/pages/login'
|
||||
})
|
||||
}
|
||||
this.getRecords();
|
||||
}
|
||||
onShow() {
|
||||
let userInfo = this.$parent.getUserInfo();
|
||||
console.log(userInfo);
|
||||
if (userInfo) {
|
||||
this.nickname = userInfo.nickName;
|
||||
this.avatar = userInfo.avatarUrl;
|
||||
}
|
||||
}
|
||||
initPageParam() {
|
||||
this.all_count = 999;
|
||||
this.current = 0;
|
||||
this.records = [];
|
||||
}
|
||||
|
||||
async getRecords() {
|
||||
let records = [{
|
||||
title: '超级玛丽(日版)',
|
||||
content: '《超级马里奥兄弟》又名《超级玛丽兄弟》,是任天堂于1985年出品的著名横版过关游戏,作为1983年游...',
|
||||
image: 'http://pub.hoh8.cn/files/game/fc/7002058/icon.jpg',
|
||||
url: 'http://192.168.100.84:7456/',
|
||||
id: '001'
|
||||
}];
|
||||
this.records = records;
|
||||
}
|
||||
}
|
||||
</script>
|
59
src/pages/login.wpy
Normal file
59
src/pages/login.wpy
Normal file
@ -0,0 +1,59 @@
|
||||
<style lang="less">
|
||||
.zan-btns {
|
||||
width: 95%;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="container">
|
||||
<view class='zan-font-14 zan-c-gray-dark' style='text-align:center;margin-top:50rpx;margin-bottom:50rpx;'>
|
||||
允许微信授权后,才可以使用</view>
|
||||
<view class="zan-btns">
|
||||
<button open-type='getUserInfo' bindgetuserinfo="bindGetUserInfo" class="zan-btn zan-btn--primary">授权登录</button>
|
||||
<!--<button bindtap='navigateBack' class="zan-btn">返回首页</button>-->
|
||||
</view>
|
||||
</view>
|
||||
<zanToast />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import wepy from 'wepy'
|
||||
import zanToast from '../components/zan-toast'
|
||||
|
||||
export default class Login extends wepy.page {
|
||||
config = {
|
||||
navigationBarTitleText: 'test'
|
||||
}
|
||||
components = {
|
||||
zanToast: zanToast
|
||||
}
|
||||
|
||||
data = {
|
||||
backType: 'index'
|
||||
}
|
||||
|
||||
computed = {
|
||||
now () {
|
||||
return +new Date()
|
||||
}
|
||||
}
|
||||
|
||||
methods = {
|
||||
bindGetUserInfo: function(e) {
|
||||
let self = this
|
||||
if (e.detail.userInfo) {
|
||||
console.log(e.detail.userInfo)
|
||||
self.$parent.updateGlobalData('userInfo', e.detail.userInfo);
|
||||
wepy.navigateBack({
|
||||
delta: 1
|
||||
})
|
||||
} else {
|
||||
this.$invoke('zanToast', 'showZanToast', { title: '很遗憾,您拒绝了微信授权, 无法使用该小程序', timeout: 2000 })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLoad() {
|
||||
console.log('login onLoad');
|
||||
}
|
||||
}
|
||||
</script>
|
42
src/style/game-cell.wxss
Normal file
42
src/style/game-cell.wxss
Normal file
@ -0,0 +1,42 @@
|
||||
.game-cell {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
padding: 20rpx;
|
||||
width: 660rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.game-cell .game-icon {
|
||||
width: 130px;
|
||||
float: left;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background-size: cover;
|
||||
margin-left: -15px;
|
||||
padding: 2px;
|
||||
}
|
||||
.game-cell .game-icon image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
.content-view {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
margin-left: 5px;
|
||||
}
|
||||
.content-view .title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.content-view .content {
|
||||
font-size: 14px;
|
||||
}
|
||||
.game-cell::after {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
background: #e5e5e5;
|
||||
content: ' ';
|
||||
}
|
35
src/style/index.wxss
Normal file
35
src/style/index.wxss
Normal file
@ -0,0 +1,35 @@
|
||||
.userinfo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.userinfo-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.userinfo-nickname {
|
||||
color: #aaa;
|
||||
font-size: 60 rpx;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.zan-btns {
|
||||
width: 700 rpx;
|
||||
margin-top: 60 rpx;
|
||||
|
||||
}
|
||||
|
||||
.top-view {
|
||||
border-bottom: 1 rpx solid #eee;
|
||||
box-shadow: 15 rpx 0 15px 0 rgba(0, 0, 0, 0.2);
|
||||
background-color: #fff;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.zan-loadmore--nodata {
|
||||
margin-top: 60px;
|
||||
}
|
24
src/style/zanui/badge.wxss
Normal file
24
src/style/zanui/badge.wxss
Normal file
@ -0,0 +1,24 @@
|
||||
.zan-badge {
|
||||
position: relative;
|
||||
}
|
||||
.zan-badge__count {
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: 0px;
|
||||
height: 1.6em;
|
||||
min-width: 1.6em;
|
||||
line-height: 1.6;
|
||||
padding: 0 .4em;
|
||||
font-size: 10px;
|
||||
font-family: tahoma;
|
||||
border-radius: .8em;
|
||||
background: #FF4444;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
transform: translateX(50%);
|
||||
transform-origin: -10% center;
|
||||
z-index: 10;
|
||||
box-shadow: 0 0 0 1px #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
142
src/style/zanui/btn.wxss
Normal file
142
src/style/zanui/btn.wxss
Normal file
@ -0,0 +1,142 @@
|
||||
.zan-btn {
|
||||
position: relative;
|
||||
color: #333;
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
border-radius: 2px;
|
||||
border: 1rpx solid #e5e5e5;
|
||||
font-size: 16px;
|
||||
line-height: 45px;
|
||||
height: 45px;
|
||||
box-sizing: border-box;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.zan-btn::after {
|
||||
display: none;
|
||||
}
|
||||
.zan-btns {
|
||||
margin: 15px;
|
||||
}
|
||||
|
||||
/* type */
|
||||
.zan-btn--primary {
|
||||
color: #fff;
|
||||
background-color: #4b0;
|
||||
border-color: #0a0;
|
||||
}
|
||||
|
||||
.zan-btn--warn {
|
||||
color: #fff;
|
||||
background-color: #f85;
|
||||
border-color: #f85;
|
||||
}
|
||||
|
||||
.zan-btn--danger {
|
||||
color: #fff;
|
||||
background-color: #f44;
|
||||
border-color: #e33;
|
||||
}
|
||||
|
||||
/* size */
|
||||
.zan-btn--small {
|
||||
display: inline-block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
font-size: 12px;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.zan-btn--mini {
|
||||
display: inline-block;
|
||||
line-height: 21px;
|
||||
height: 22px;
|
||||
font-size: 10px;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 0;
|
||||
padding-left: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.zan-btn--large {
|
||||
border-radius: 0;
|
||||
margin-bottom: 0;
|
||||
border: none;
|
||||
line-height: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
/* plain */
|
||||
.zan-btn--plain.zan-btn {
|
||||
background-color: transparent;
|
||||
}
|
||||
.zan-btn--plain.zan-btn--primary {
|
||||
color: #06BF04;
|
||||
}
|
||||
.zan-btn--plain.zan-btn--warn {
|
||||
color: #FF6600;
|
||||
}
|
||||
.zan-btn--plain.zan-btn--danger {
|
||||
color: #FF4444;
|
||||
}
|
||||
|
||||
/* 重写button组件的button-hover样式 */
|
||||
.button-hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* loading */
|
||||
.zan-btn--loading {
|
||||
color: transparent;
|
||||
opacity: 1;
|
||||
}
|
||||
.zan-btn--loading::before {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
content: ' ';
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-left: -8px;
|
||||
margin-top: -8px;
|
||||
border: 3px solid #e5e5e5;
|
||||
border-color: #666 #e5e5e5 #e5e5e5 #e5e5e5;
|
||||
border-radius: 8px;
|
||||
box-sizing: border-box;
|
||||
animation: btn-spin 0.6s linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
.zan-btn--primary.zan-btn--loading::before,
|
||||
.zan-btn--warn.zan-btn--loading::before,
|
||||
.zan-btn--danger.zan-btn--loading::before {
|
||||
border-color: #fff rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@keyframes btn-spin {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
/* disabled */
|
||||
.zan-btn.zan-btn--disabled {
|
||||
/* 防止样式被 button[disabled] 的规则覆盖,所以使用了important */
|
||||
color: #999 ! important;
|
||||
background: #f8f8f8 ! important;
|
||||
border-color: #e5e5e5 ! important;
|
||||
cursor: not-allowed ! important;
|
||||
opacity: 1 ! important;
|
||||
}
|
||||
|
||||
/* :last-child */
|
||||
.zan-btn--last-child,
|
||||
.zan-btn:last-child {
|
||||
margin-bottom: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
53
src/style/zanui/card.wxss
Normal file
53
src/style/zanui/card.wxss
Normal file
@ -0,0 +1,53 @@
|
||||
.zan-card {
|
||||
margin-left: 0px;
|
||||
width: auto;
|
||||
padding: 5px 15px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.zan-card__thumb {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
overflow: hidden;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.zan-card__img {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.zan-card__detail {
|
||||
margin-left: 100px;
|
||||
width: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.zan-card__detail-row {
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
min-height: 20px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.zan-card__right-col {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.zan-card__left-col {
|
||||
margin-right: 80px;
|
||||
}
|
||||
|
53
src/style/zanui/cell.wxss
Normal file
53
src/style/zanui/cell.wxss
Normal file
@ -0,0 +1,53 @@
|
||||
.zan-cell {
|
||||
position: relative;
|
||||
padding: 12px 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1.4;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.zan-cell::after {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
background: #e5e5e5;
|
||||
content: ' ';
|
||||
}
|
||||
.zan-cell__bd {
|
||||
flex: 1;
|
||||
}
|
||||
.zan-cell__ft {
|
||||
position: relative;
|
||||
text-align: right;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.zan-cell--last-child::after,
|
||||
.zan-cell:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.zan-cell--access .zan-cell__ft {
|
||||
padding-right: 13px;
|
||||
}
|
||||
|
||||
.zan-cell--access .zan-cell__ft::after {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 2px;
|
||||
content: " ";
|
||||
display: inline-block;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c8c8c8;
|
||||
border-style: solid;
|
||||
transform: translateY(-50%) matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
|
||||
}
|
||||
.zan-cell--switch {
|
||||
padding-top: 6px;
|
||||
padding-bottom: 6px;
|
||||
}
|
27
src/style/zanui/color.wxss
Normal file
27
src/style/zanui/color.wxss
Normal file
@ -0,0 +1,27 @@
|
||||
.zan-c-red {
|
||||
color: #f44 !important;
|
||||
}
|
||||
|
||||
.zan-c-gray {
|
||||
color: #c9c9c9 !important;
|
||||
}
|
||||
|
||||
.zan-c-gray-dark {
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.zan-c-gray-darker {
|
||||
color: #666 !important;
|
||||
}
|
||||
|
||||
.zan-c-black {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
.zan-c-blue {
|
||||
color: #3283fa !important;
|
||||
}
|
||||
|
||||
.zan-c-green {
|
||||
color: #44BB00 !important;
|
||||
}
|
38
src/style/zanui/form.wxss
Normal file
38
src/style/zanui/form.wxss
Normal file
@ -0,0 +1,38 @@
|
||||
.zan-form {
|
||||
background-color: #fff;
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
}
|
||||
|
||||
.zan-form__item {
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.zan-form__title {
|
||||
float: left;
|
||||
width: 80px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.zan-form__title--top {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.zan-form__input, .zan-form__textarea {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.zan-form__input input {
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.zan-form__textarea {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.zan-form__textarea textarea {
|
||||
width: auto;
|
||||
flex: 1;
|
||||
}
|
101
src/style/zanui/helper.wxss
Normal file
101
src/style/zanui/helper.wxss
Normal file
@ -0,0 +1,101 @@
|
||||
.zan-pull-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.zan-pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.zan-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.zan-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.zan-text-deleted {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.zan-font-8 {
|
||||
font-size: 8px;
|
||||
}
|
||||
.zan-font-10 {
|
||||
font-size: 10px;
|
||||
}
|
||||
.zan-font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
.zan-font-14 {
|
||||
font-size: 14px;
|
||||
}
|
||||
.zan-font-16 {
|
||||
font-size: 16px;
|
||||
}
|
||||
.zan-font-18 {
|
||||
font-size: 18px;
|
||||
}
|
||||
.zan-font-20 {
|
||||
font-size: 20px;
|
||||
}
|
||||
.zan-font-22 {
|
||||
font-size: 22px;
|
||||
}
|
||||
.zan-font-24 {
|
||||
font-size: 22px;
|
||||
}
|
||||
.zan-font-30 {
|
||||
font-size: 30px;
|
||||
}
|
||||
.zan-font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.zan-arrow {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
display: inline-block;
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
border-width: 2px 2px 0 0;
|
||||
border-color: #c8c8c8;
|
||||
border-style: solid;
|
||||
transform: translateY(-50%) matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
|
||||
}
|
||||
|
||||
.zan-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
}
|
||||
|
||||
.zan-ellipsis--l2 {
|
||||
max-height: 40px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.zan-ellipsis--l3 {
|
||||
max-height: 60px;
|
||||
line-height: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.zan-clearfix {
|
||||
zoom: 1;
|
||||
}
|
||||
.zan-clearfix::after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
66
src/style/zanui/icon.wxss
Normal file
66
src/style/zanui/icon.wxss
Normal file
@ -0,0 +1,66 @@
|
||||
/* DO NOT EDIT! Generated by fount */
|
||||
|
||||
@font-face {
|
||||
font-family: 'zuiicon';
|
||||
src: url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.eot');
|
||||
src: url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.eot?#iefix') format('embedded-opentype'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.woff2') format('woff2'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.woff') format('woff'),
|
||||
url('https://b.yzcdn.cn/zui/font/zuiicon-b37948cf5d.ttf') format('truetype')
|
||||
}
|
||||
|
||||
.zan-icon {
|
||||
display: inline-block;
|
||||
}
|
||||
.zan-icon::before {
|
||||
font-family: "zuiicon" !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
speak: none;
|
||||
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
text-align: center;
|
||||
|
||||
/* For safety - reset parent styles, that can break glyph codes*/
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
|
||||
/* fix buttons height, for twitter bootstrap */
|
||||
line-height: 1em;
|
||||
|
||||
/* Animation center compensation - margins should be symmetric */
|
||||
/* remove if not needed */
|
||||
/* margin-left: .2em; */
|
||||
|
||||
/* you can be more comfortable with increased icons size */
|
||||
/* font-size: 120%; */
|
||||
|
||||
/* Font smoothing. That was taken from TWBS */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Uncomment for 3D effect */
|
||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||
}
|
||||
/* DO NOT EDIT! Generated by fount */
|
||||
|
||||
|
||||
.zan-icon-album:before { content: '\e800'; } /* '' */
|
||||
.zan-icon-arrow:before { content: '\e801'; } /* '' */
|
||||
.zan-icon-camera:before { content: '\e802'; } /* '' */
|
||||
.zan-icon-certificate:before { content: '\e803'; } /* '' */
|
||||
.zan-icon-check:before { content: '\e804'; } /* '' */
|
||||
.zan-icon-checked:before { content: '\e805'; } /* '' */
|
||||
.zan-icon-close:before { content: '\e806'; } /* '' */
|
||||
.zan-icon-gift:before { content: '\e807'; } /* '' */
|
||||
.zan-icon-home:before { content: '\e808'; } /* '' */
|
||||
.zan-icon-location:before { content: '\e809'; } /* '' */
|
||||
.zan-icon-message:before { content: '\e80a'; } /* '' */
|
||||
.zan-icon-send:before { content: '\e80b'; } /* '' */
|
||||
.zan-icon-shopping-cart:before { content: '\e80c'; } /* '' */
|
||||
.zan-icon-sign:before { content: '\e80d'; } /* '' */
|
||||
.zan-icon-store:before { content: '\e80e'; } /* '' */
|
||||
.zan-icon-topay:before { content: '\e80f'; } /* '' */
|
||||
.zan-icon-tosend:before { content: '\e810'; } /* '' */
|
10
src/style/zanui/index.wxss
Normal file
10
src/style/zanui/index.wxss
Normal file
@ -0,0 +1,10 @@
|
||||
@import "badge.wxss";
|
||||
@import "btn.wxss";
|
||||
@import "card.wxss";
|
||||
@import "cell.wxss";
|
||||
@import "color.wxss";
|
||||
@import "form.wxss";
|
||||
@import "helper.wxss";
|
||||
@import "icon.wxss";
|
||||
@import "label.wxss";
|
||||
@import "panel.wxss";
|
34
src/style/zanui/label.wxss
Normal file
34
src/style/zanui/label.wxss
Normal file
@ -0,0 +1,34 @@
|
||||
.zan-label {
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
color: #333;
|
||||
border: 1rpx solid #999;
|
||||
padding: 0px 10px;
|
||||
border-radius: 2px;
|
||||
margin-right: 10px;
|
||||
box-sizing: border-box;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
.zan-label--primary {
|
||||
color: #fff;
|
||||
background: #f44;
|
||||
border: 1rpx solid #f44;
|
||||
}
|
||||
.zan-label--disabled {
|
||||
color: #cacaca;
|
||||
background: #eee;
|
||||
border: 1rpx solid #e5e5e5;
|
||||
}
|
||||
.zan-label--small {
|
||||
font-size: 11px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
padding: 0px 3px;
|
||||
}
|
||||
.zan-label--plain.zan-label--primary {
|
||||
color: #f44;
|
||||
background: #fff;
|
||||
}
|
19
src/style/zanui/panel.wxss
Normal file
19
src/style/zanui/panel.wxss
Normal file
@ -0,0 +1,19 @@
|
||||
.zan-panel {
|
||||
background: #fff;
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
border-bottom: 1rpx solid #e5e5e5;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.zan-panel-title {
|
||||
font-size: 24rpx;
|
||||
line-height: 1;
|
||||
color: #999;
|
||||
padding: 20px 15px 0 15px;
|
||||
}
|
||||
|
||||
|
||||
.zan-panel--without-margin-top {
|
||||
margin-top: 0;
|
||||
}
|
43
src/utils/http.js
Normal file
43
src/utils/http.js
Normal file
@ -0,0 +1,43 @@
|
||||
import wepy from 'wepy'
|
||||
import g from '../common/global'
|
||||
|
||||
const get = (url, data, header) => {
|
||||
header = header || {}
|
||||
header['accept-version'] = g.version
|
||||
return Ajax(url, 'GET', data, header)
|
||||
};
|
||||
|
||||
const post = (url, data, header) => {
|
||||
header = header || {}
|
||||
header['Content-Type'] = 'application/x-www-form-urlencoded'
|
||||
header['accept-version'] = g.version
|
||||
return Ajax(url, 'POST', data, header)
|
||||
}
|
||||
|
||||
const Ajax = (url, method, data, header) => {
|
||||
url = g.apiBase + url
|
||||
header = header || {}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wepy.request({
|
||||
url: url,
|
||||
data: data,
|
||||
method: method,
|
||||
header: header
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if (res.errcode === 0) {
|
||||
resolve(res)
|
||||
} else {
|
||||
reject(res)
|
||||
}
|
||||
}, error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default {
|
||||
get,
|
||||
post
|
||||
}
|
74
wepy.config.js
Normal file
74
wepy.config.js
Normal file
@ -0,0 +1,74 @@
|
||||
const path = require('path');
|
||||
var prod = process.env.NODE_ENV === 'production';
|
||||
|
||||
module.exports = {
|
||||
wpyExt: '.wpy',
|
||||
eslint: false,
|
||||
cliLogs: !prod,
|
||||
build: {
|
||||
web: {
|
||||
htmlTemplate: path.join('src', 'index.template.html'),
|
||||
htmlOutput: path.join('web', 'index.html'),
|
||||
jsOutput: path.join('web', 'index.js')
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
counter: path.join(__dirname, 'src/components/counter'),
|
||||
'@': path.join(__dirname, 'src')
|
||||
},
|
||||
aliasFields: ['wepy', 'weapp'],
|
||||
modules: ['node_modules']
|
||||
},
|
||||
compilers: {
|
||||
less: {
|
||||
compress: prod
|
||||
},
|
||||
/*sass: {
|
||||
outputStyle: 'compressed'
|
||||
},*/
|
||||
babel: {
|
||||
sourceMap: true,
|
||||
presets: [
|
||||
'env'
|
||||
],
|
||||
plugins: [
|
||||
'transform-class-properties',
|
||||
'transform-decorators-legacy',
|
||||
'transform-object-rest-spread',
|
||||
'transform-export-extensions',
|
||||
]
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
},
|
||||
appConfig: {
|
||||
noPromiseAPI: ['createSelectorQuery']
|
||||
}
|
||||
}
|
||||
|
||||
if (prod) {
|
||||
|
||||
// 压缩sass
|
||||
// module.exports.compilers['sass'] = {outputStyle: 'compressed'}
|
||||
|
||||
// 压缩js
|
||||
module.exports.plugins = {
|
||||
uglifyjs: {
|
||||
filter: /\.js$/,
|
||||
config: {
|
||||
}
|
||||
},
|
||||
imagemin: {
|
||||
filter: /\.(jpg|png|jpeg)$/,
|
||||
config: {
|
||||
jpg: {
|
||||
quality: 80
|
||||
},
|
||||
png: {
|
||||
quality: 80
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user