├── .gitignore ├── LICENSE ├── README.md └── resources ├── cloudfunctions ├── get_posts_qrcode │ ├── index.js │ ├── package-lock.json │ └── package.json ├── get_posts_statistics │ ├── index.js │ ├── package-lock.json │ └── package.json ├── login │ ├── index.js │ ├── package-lock.json │ └── package.json ├── openapi │ ├── config.json │ ├── index.js │ ├── package-lock.json │ └── package.json ├── push_child_comments │ ├── index.js │ ├── package-lock.json │ └── package.json └── upsert_posts_statistics │ ├── index.js │ ├── package-lock.json │ └── package.json ├── miniprogram ├── app.js ├── app.json ├── app.wxss ├── dist │ ├── actionsheet │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── badge │ │ └── index.wxss │ ├── btn │ │ └── index.wxss │ ├── capsule │ │ ├── index.wxml │ │ └── index.wxss │ ├── card │ │ └── index.wxss │ ├── cell │ │ └── index.wxss │ ├── col │ │ └── index.wxss │ ├── color │ │ └── index.wxss │ ├── common │ │ └── helper.js │ ├── dialog │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── field │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── helper │ │ └── index.wxss │ ├── icon │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── index.js │ ├── index.wxss │ ├── loadmore │ │ ├── index.wxml │ │ └── index.wxss │ ├── noticebar │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── panel │ │ └── index.wxss │ ├── popup │ │ └── index.wxss │ ├── row │ │ └── index.wxss │ ├── select │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── stepper │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── steps │ │ ├── index.wxml │ │ ├── index.wxss │ │ └── wxss │ │ │ ├── step.wxss │ │ │ └── vstep.wxss │ ├── switch │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── tab │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ ├── tag │ │ └── index.wxss │ ├── toast │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss │ └── toptips │ │ ├── index.js │ │ ├── index.wxml │ │ └── index.wxss ├── images │ ├── icon │ │ ├── collect.png │ │ ├── collected.png │ │ ├── gravatar.png │ │ ├── like.png │ │ ├── liked.png │ │ ├── poster.png │ │ ├── reward.png │ │ └── share.png │ └── tabbar │ │ ├── about.png │ │ ├── about_click.png │ │ ├── home.png │ │ ├── home_click.png │ │ ├── like.png │ │ └── like_click.png ├── pages │ ├── about │ │ ├── about_me.js │ │ ├── about_me.json │ │ ├── about_me.wxml │ │ ├── about_me.wxss │ │ ├── about_wechat.js │ │ ├── about_wechat.json │ │ ├── about_wechat.wxml │ │ └── about_wechat.wxss │ ├── collected │ │ ├── collected.js │ │ ├── collected.json │ │ ├── collected.wxml │ │ └── collected.wxss │ ├── detail │ │ ├── detail.js │ │ ├── detail.json │ │ ├── detail.wxml │ │ └── detail.wxss │ ├── index │ │ ├── index.js │ │ ├── index.json │ │ ├── index.wxml │ │ └── index.wxss │ ├── logs │ │ ├── logs.js │ │ ├── logs.json │ │ ├── logs.wxml │ │ └── logs.wxss │ ├── mine │ │ ├── mine.js │ │ ├── mine.json │ │ ├── mine.wxml │ │ └── mine.wxss │ ├── setting │ │ ├── setting.js │ │ ├── setting.json │ │ ├── setting.wxml │ │ └── setting.wxss │ └── topic │ │ ├── topic.js │ │ ├── topic.json │ │ ├── topic.wxml │ │ └── topic.wxss ├── sitemap.json ├── templates │ ├── login.wxml │ ├── poster.wxml │ └── poster.wxss ├── utils │ ├── api.js │ ├── runtime.js │ ├── util.js │ ├── wxApi.js │ └── wxRequest.js └── wxParse │ ├── html2json.js │ ├── htmlparser.js │ ├── showdown.js │ ├── wxDiscode.js │ ├── wxParse.js │ ├── wxParse.wxml │ └── wxParse.wxss ├── project.config.json └── sitemap.json /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | */*/*/node_modules/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Cavin.Cao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 友情提醒 2 | 本小程序后端依赖`ghost`开源博客框架,若没有ghost博客的,可以参考基于云开发的博客小程序「无需后端」,开源地址:[https://github.com/CavinCao/mini-blog](https://github.com/CavinCao/mini-blog) 3 | 4 | ## 更新记录 5 | #### 2019-04-13更新 6 | 1. 评论通知功能实现 7 | 2. 已知问题修复 8 | 9 | 相关文章参考: 10 | - [[博客小程序]评论通知功能实现(一)——小程序发送模板消息的几种实现](https://www.bug2048.com/wechat20190411/) 11 | - [[博客小程序]评论通知功能实现(二)——实战过程中的坑](https://www.bug2048.com/wechat20190413/) 12 | 13 | #### 2018-10-15更新 14 | 15 | 1. 生成海报功能 16 | 2. 已知问题修复 17 | 18 | 相关文章参考: 19 | - [利用云开发优化博客小程序(三)——生成海报功能](https://www.bug2048.com/wechat20181015/) 20 | 21 | #### 2018-09-30更新 22 | 23 | 1. 新增公众号关注组件 24 | 2. 评论、点赞功能实现,浏览量统计 25 | 3. 已知问题修复 26 | 27 | 相关文章参考: 28 | - [利用云开发优化博客小程序(一)——浏览量统计](https://www.bug2048.com/wechat20190917/) 29 | - [利用云开发优化博客小程序(二)——评论功能](https://www.bug2048.com/wechat20180930/) 30 | 31 | #### 2018-07-05更新 32 | 33 | wx.getUserInfo官方文档中做了一些调整,授权方式做了下调整,相关文章参考: 34 | - [微信小程序版博客——授权登录的修改(wx.getUserInfo)](https://www.bug2048.com/wechat20180705/) 35 | 36 | -------------------------------------------------------------------------------- 37 | > 花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结。 38 | 39 | ## 一些体会 40 | 41 | 四月份的空余时间都在折腾自己的微信小程序版博客,作为后端开发的我鼓捣起前端的技术还是稍微有点吃力的,有些语法确实不太熟悉。 42 | 43 | 但总的来说还好,静下心来看看文档,熟悉下语法,实现一些功能的时候还是挺有成就感的。 44 | 45 | 对于小程序,基础的语法和API调用,我觉得腾讯的官方文档已经写了非常详细了,完全可以通过阅读文档来熟悉小程序。 46 | 47 | 对于基础还是要花点时间静下心来去学学,毕竟有时候无脑百度也挺花时间的。一些容易遗忘的点还是要做好笔记,相信如果一个月没碰前端的代码,估计也忘的7788了。 48 | 49 | 前阵子`mpvue`很火,有时间的话也希望自己能体验一把。 50 | 51 | ## 相关文章 52 | 53 | 在开发的同时也积累了一些文章,用于记录和分享本次开发小程序的过程: 54 | 55 | 1. [微信小程序版博客——前期准备](https://www.bug2048.com/wechat20180419/) 56 | 2. [微信小程序版博客——整体框架搭建](https://www.bug2048.com/wechat20180421/) 57 | 3. [微信小程序版博客——图片相关处理](https://www.bug2048.com/wechat20180424/) 58 | 4. [微信小程序版博客——列表页相关问题汇总](https://www.bug2048.com/wechat20180425/) 59 | 5. [微信小程序版博客——文章详情页设计及问题汇总](https://www.bug2048.com/wechat20180428/) 60 | 6. [微信小程序版博客——小程序授权登陆的一点优化](https://www.bug2048.com/wechat20180429/) 61 | 7. [微信小程序版博客——用户中心页面设计问题汇总](https://www.bug2048.com/wechat20180501/) 62 | 8. [微信小程序版博客——小优化](https://www.bug2048.com/wechat20180502/) 63 | 64 | ## 关于审核 65 | 66 | 小程序审核不是一帆风顺,我审核了三次才通过,主要还是服务类目选择的问题,像博客这种应该选择`教育` > `教育信息服务`这类,这个需要注意下,在5月1日劳动节的时候,终于发布了我的1.0版本: 67 | 68 | ![image](http://image.bug2048.com/1525220924740.jpg) 69 | 70 | ## 总结 71 | 72 | 作为程序员,还是需要有一个地方去记录你的知识积累,毕竟大脑的记忆还是有限的,你需要去不断总结,不断积累,为了更好的沉淀。 73 | 74 | 相信总有一天,量变总会达到质变。 75 | 76 | ## 其他 77 | 78 | 补充下利用小程序云开发的数据库的结构: 79 | 80 | - posts_statistics(记录文章的点评,喜欢数量) 81 | 82 | ``` 83 | 84 | "_id": W5y6i7orBK9ufeyD 85 | //点评数量 86 | "comment_count": 8 87 | //喜欢数量 88 | "like_count": 14 89 | //文章id 90 | "post_id": 5b3de6b464546644ae0b7eb4 91 | //访问数量 92 | "view_count": 231 93 | 94 | ``` 95 | 96 | - posts_comments (文章点评记录表) 97 | 98 | ``` 99 | "_id": W69AgvD0YIt7pc32 100 | "_openid": '' 101 | "cAvatarUrl": ''//头像 102 | "cNickName": ''//昵称 103 | "childComment"://子评论 104 | [ 105 | {"cAvatarUrl":"","cNickName":"","cOpenId":"","comment":"","createDate":"2018-10-17","flag":0,"tNickName":"","tOpenId":"","timestamp":1539706875589} 106 | ] 107 | "comment": '' 108 | "createDate": 2018-09-29 109 | "flag": 0 110 | "postId": 5ba057e864546644ae0b7ee5 111 | "timestamp": 1538211970612 112 | ``` 113 | 114 | 最后贴下自己的小程序二维码: 115 | 116 | ![image](http://image.bug2048.com/gh_e63f2dcd02ee_258.jpg) 117 | 118 | 119 | > 博客地址:[http//:www.bug2048.com](https://www.bug2048.com/) 120 | > 微信公众号与微信:Bug生活2048 121 | 122 | ![image](https://www.bug2048.com//content/images/2018/02/qrcode_for_gh_cac1ef8c9733_258.jpg) 123 | 124 | ![image](http://image.bug2048.com/WechatIMG2.jpeg?imageView2/1/w/200/h/200/q/100) 125 | 126 | -------------------------------------------------------------------------------- /resources/cloudfunctions/get_posts_qrcode/index.js: -------------------------------------------------------------------------------- 1 | // 云函数入口文件 2 | const cloud = require('wx-server-sdk') 3 | 4 | cloud.init() 5 | 6 | const db = cloud.database() 7 | 8 | const fs = require('fs') 9 | 10 | const request = require('request'); 11 | 12 | const rp = require('request-promise') 13 | 14 | const tokenUrl ='https://api.weixin.qq.com/cgi-bin/token' 15 | 16 | const wxcodeUrl ='https://api.weixin.qq.com/wxa/getwxacode' 17 | 18 | // 云函数入口函数 19 | exports.main = async (event, context) => { 20 | 21 | var res = await getToken() 22 | 23 | console.info(res) 24 | res = JSON.parse(res) 25 | console.info(res.access_token) 26 | 27 | var url = `${wxcodeUrl}?access_token=${res.access_token}` 28 | console.info(url) 29 | request({ 30 | method: "POST", 31 | url: url, 32 | headers: { 33 | "content-type": "application/json" 34 | }, 35 | body: { 36 | path: 'pages/index/index', 37 | width: 300 38 | }, 39 | json: true 40 | }, function (error, response, body) { 41 | console.log('1------:' + body); 42 | console.log('2------:' + response); 43 | console.log(error) 44 | /*cloud.uploadFile({ 45 | cloudPath: 'demo111.png', 46 | fileContent: body 47 | })*/ 48 | }) 49 | 50 | // return "" 51 | 52 | //const fileStream = wxacode.pipe("demo.jpg") 53 | /*return await cloud.uploadFile({ 54 | cloudPath: 'demo.png', 55 | fileContent: wxacode, 56 | })*/ 57 | 58 | 59 | //return res 60 | /*return new Promise((resolve, reject) => { 61 | request.get(url, (error, response, body) => { 62 | if (error || response.statusCode !== 200) { 63 | reject(error) 64 | } else { 65 | try { 66 | console.info(body) 67 | resolve(body) 68 | } catch (e) { 69 | reject(e) 70 | } 71 | } 72 | }) 73 | })*/ 74 | } 75 | 76 | /** 77 | * 获取token 78 | */ 79 | async function getToken() { 80 | 81 | var config = await db.collection('posts_config').doc('W7ye4QIrVDZJFskA').get(); 82 | appId = config.data['appId'] 83 | appSecret = config.data['appSecret'] 84 | 85 | var url = `${tokenUrl}?grant_type=client_credential&appid=${appId}&secret=${appSecret}` 86 | 87 | return rp(url) 88 | } 89 | 90 | /** 91 | * 获取二维码 92 | */ 93 | async function getWxacode(access_token){ 94 | var url = `${wxcodeUrl}?access_token=${access_token}` 95 | console.info(url) 96 | var options = { 97 | method: 'POST', 98 | json: true, 99 | uri: url, 100 | body: { 101 | path: 'pages/index/index', 102 | width: 300 103 | } 104 | } 105 | 106 | return rp(options).then(res=>{ 107 | console.info("1------:"+res) 108 | console.info("2------:" +res.statusCode) 109 | console.info("3------:" +res.body) 110 | }) 111 | } 112 | 113 | /** 114 | * 获取二维码 115 | */ 116 | function getWxacode1(access_token) { 117 | var url = `${wxcodeUrl}?access_token=${access_token}` 118 | console.info(url) 119 | request({ 120 | method: "POST", 121 | url: url, 122 | headers: { 123 | "content-type": "application/json" 124 | }, 125 | body: { 126 | path: 'pages/index/index', 127 | width: 300 128 | }, 129 | json: true 130 | }, (error, response, body) => { 131 | console.log('1------:'+body); 132 | console.log('2------:'+response); 133 | cloud.uploadFile({ 134 | cloudPath: 'demo111.png', 135 | fileContent: body 136 | }) 137 | }) 138 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/get_posts_qrcode/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get_posts_qrcode", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "request-promise": "^4.2.2", 13 | "wx-server-sdk": "latest" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /resources/cloudfunctions/get_posts_statistics/index.js: -------------------------------------------------------------------------------- 1 | // 云函数入口文件 2 | const cloud = require('wx-server-sdk') 3 | 4 | cloud.init() 5 | 6 | const db = cloud.database() 7 | const _ = db.command 8 | 9 | // 根据文章Id集合批量查询统计数据 10 | exports.main = async (event, context) => { 11 | try { 12 | var result= await db.collection('posts_statistics').where({ 13 | post_id: _.in(event.post_ids) 14 | }).get(); 15 | return result.data 16 | } 17 | catch(e) 18 | { 19 | console.error(e) 20 | return [] 21 | } 22 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/get_posts_statistics/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get_posts_statistics", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ajv": { 8 | "version": "5.5.2", 9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 10 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 11 | "requires": { 12 | "co": "^4.6.0", 13 | "fast-deep-equal": "^1.0.0", 14 | "fast-json-stable-stringify": "^2.0.0", 15 | "json-schema-traverse": "^0.3.0" 16 | } 17 | }, 18 | "asn1": { 19 | "version": "0.2.4", 20 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 21 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 22 | "requires": { 23 | "safer-buffer": "~2.1.0" 24 | } 25 | }, 26 | "assert-plus": { 27 | "version": "1.0.0", 28 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 29 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 30 | }, 31 | "asynckit": { 32 | "version": "0.4.0", 33 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 34 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 35 | }, 36 | "aws-sign2": { 37 | "version": "0.7.0", 38 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 39 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 40 | }, 41 | "aws4": { 42 | "version": "1.8.0", 43 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 44 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 45 | }, 46 | "bcrypt-pbkdf": { 47 | "version": "1.0.2", 48 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 49 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 50 | "optional": true, 51 | "requires": { 52 | "tweetnacl": "^0.14.3" 53 | } 54 | }, 55 | "caseless": { 56 | "version": "0.12.0", 57 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 58 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 59 | }, 60 | "co": { 61 | "version": "4.6.0", 62 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 63 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 64 | }, 65 | "combined-stream": { 66 | "version": "1.0.6", 67 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 68 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 69 | "requires": { 70 | "delayed-stream": "~1.0.0" 71 | } 72 | }, 73 | "core-util-is": { 74 | "version": "1.0.2", 75 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 76 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 77 | }, 78 | "dashdash": { 79 | "version": "1.14.1", 80 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 81 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 82 | "requires": { 83 | "assert-plus": "^1.0.0" 84 | } 85 | }, 86 | "deep-assign": { 87 | "version": "2.0.0", 88 | "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-2.0.0.tgz", 89 | "integrity": "sha1-6+BrHwfwja5ZdiDj3RYi83GhxXI=", 90 | "requires": { 91 | "is-obj": "^1.0.0" 92 | } 93 | }, 94 | "delayed-stream": { 95 | "version": "1.0.0", 96 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 97 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 98 | }, 99 | "ecc-jsbn": { 100 | "version": "0.1.2", 101 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 102 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 103 | "optional": true, 104 | "requires": { 105 | "jsbn": "~0.1.0", 106 | "safer-buffer": "^2.1.0" 107 | } 108 | }, 109 | "extend": { 110 | "version": "3.0.2", 111 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 112 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 113 | }, 114 | "extsprintf": { 115 | "version": "1.3.0", 116 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 117 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 118 | }, 119 | "fast-deep-equal": { 120 | "version": "1.1.0", 121 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 122 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 123 | }, 124 | "fast-json-stable-stringify": { 125 | "version": "2.0.0", 126 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 127 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 128 | }, 129 | "forever-agent": { 130 | "version": "0.6.1", 131 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 132 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 133 | }, 134 | "form-data": { 135 | "version": "2.3.2", 136 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 137 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 138 | "requires": { 139 | "asynckit": "^0.4.0", 140 | "combined-stream": "1.0.6", 141 | "mime-types": "^2.1.12" 142 | } 143 | }, 144 | "getpass": { 145 | "version": "0.1.7", 146 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 147 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 148 | "requires": { 149 | "assert-plus": "^1.0.0" 150 | } 151 | }, 152 | "har-schema": { 153 | "version": "2.0.0", 154 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 155 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 156 | }, 157 | "har-validator": { 158 | "version": "5.1.0", 159 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", 160 | "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", 161 | "requires": { 162 | "ajv": "^5.3.0", 163 | "har-schema": "^2.0.0" 164 | } 165 | }, 166 | "http-signature": { 167 | "version": "1.2.0", 168 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 169 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 170 | "requires": { 171 | "assert-plus": "^1.0.0", 172 | "jsprim": "^1.2.2", 173 | "sshpk": "^1.7.0" 174 | } 175 | }, 176 | "is-obj": { 177 | "version": "1.0.1", 178 | "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", 179 | "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" 180 | }, 181 | "is-typedarray": { 182 | "version": "1.0.0", 183 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 184 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 185 | }, 186 | "isstream": { 187 | "version": "0.1.2", 188 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 189 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 190 | }, 191 | "jsbn": { 192 | "version": "0.1.1", 193 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 194 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 195 | "optional": true 196 | }, 197 | "json-schema": { 198 | "version": "0.2.3", 199 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 200 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 201 | }, 202 | "json-schema-traverse": { 203 | "version": "0.3.1", 204 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 205 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 206 | }, 207 | "json-stringify-safe": { 208 | "version": "5.0.1", 209 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 210 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 211 | }, 212 | "jsprim": { 213 | "version": "1.4.1", 214 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 215 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 216 | "requires": { 217 | "assert-plus": "1.0.0", 218 | "extsprintf": "1.3.0", 219 | "json-schema": "0.2.3", 220 | "verror": "1.10.0" 221 | } 222 | }, 223 | "mime-db": { 224 | "version": "1.36.0", 225 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", 226 | "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==" 227 | }, 228 | "mime-types": { 229 | "version": "2.1.20", 230 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", 231 | "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", 232 | "requires": { 233 | "mime-db": "~1.36.0" 234 | } 235 | }, 236 | "oauth-sign": { 237 | "version": "0.9.0", 238 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 239 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 240 | }, 241 | "performance-now": { 242 | "version": "2.1.0", 243 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 244 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 245 | }, 246 | "psl": { 247 | "version": "1.1.29", 248 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 249 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" 250 | }, 251 | "punycode": { 252 | "version": "1.4.1", 253 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 254 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 255 | }, 256 | "qs": { 257 | "version": "6.5.2", 258 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 259 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 260 | }, 261 | "request": { 262 | "version": "2.88.0", 263 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 264 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 265 | "requires": { 266 | "aws-sign2": "~0.7.0", 267 | "aws4": "^1.8.0", 268 | "caseless": "~0.12.0", 269 | "combined-stream": "~1.0.6", 270 | "extend": "~3.0.2", 271 | "forever-agent": "~0.6.1", 272 | "form-data": "~2.3.2", 273 | "har-validator": "~5.1.0", 274 | "http-signature": "~1.2.0", 275 | "is-typedarray": "~1.0.0", 276 | "isstream": "~0.1.2", 277 | "json-stringify-safe": "~5.0.1", 278 | "mime-types": "~2.1.19", 279 | "oauth-sign": "~0.9.0", 280 | "performance-now": "^2.1.0", 281 | "qs": "~6.5.2", 282 | "safe-buffer": "^5.1.2", 283 | "tough-cookie": "~2.4.3", 284 | "tunnel-agent": "^0.6.0", 285 | "uuid": "^3.3.2" 286 | } 287 | }, 288 | "safe-buffer": { 289 | "version": "5.1.2", 290 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 291 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 292 | }, 293 | "safer-buffer": { 294 | "version": "2.1.2", 295 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 296 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 297 | }, 298 | "sshpk": { 299 | "version": "1.14.2", 300 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", 301 | "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", 302 | "requires": { 303 | "asn1": "~0.2.3", 304 | "assert-plus": "^1.0.0", 305 | "bcrypt-pbkdf": "^1.0.0", 306 | "dashdash": "^1.12.0", 307 | "ecc-jsbn": "~0.1.1", 308 | "getpass": "^0.1.1", 309 | "jsbn": "~0.1.0", 310 | "safer-buffer": "^2.0.2", 311 | "tweetnacl": "~0.14.0" 312 | } 313 | }, 314 | "tcb-admin-node": { 315 | "version": "1.1.0", 316 | "resolved": "https://registry.npmjs.org/tcb-admin-node/-/tcb-admin-node-1.1.0.tgz", 317 | "integrity": "sha512-MkLssLxEQhthyKFi+9cp5qfyFlJap5otN+EaOxeqZ9+3X2USURCdo+j+g+OC4MsiRk12aJb292ftPi6OhC5tPg==", 318 | "requires": { 319 | "deep-assign": "^2.0.0", 320 | "request": "^2.87.0" 321 | } 322 | }, 323 | "tough-cookie": { 324 | "version": "2.4.3", 325 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 326 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 327 | "requires": { 328 | "psl": "^1.1.24", 329 | "punycode": "^1.4.1" 330 | } 331 | }, 332 | "tslib": { 333 | "version": "1.9.3", 334 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 335 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" 336 | }, 337 | "tunnel-agent": { 338 | "version": "0.6.0", 339 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 340 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 341 | "requires": { 342 | "safe-buffer": "^5.0.1" 343 | } 344 | }, 345 | "tweetnacl": { 346 | "version": "0.14.5", 347 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 348 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 349 | "optional": true 350 | }, 351 | "uuid": { 352 | "version": "3.3.2", 353 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 354 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 355 | }, 356 | "verror": { 357 | "version": "1.10.0", 358 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 359 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 360 | "requires": { 361 | "assert-plus": "^1.0.0", 362 | "core-util-is": "1.0.2", 363 | "extsprintf": "^1.2.0" 364 | } 365 | }, 366 | "wx-server-sdk": { 367 | "version": "0.0.17", 368 | "resolved": "https://registry.npmjs.org/wx-server-sdk/-/wx-server-sdk-0.0.17.tgz", 369 | "integrity": "sha512-VZ78RoQlm6c4xv7CNE7wHw0BEa8sOqoCyWIxF4vaQNLhROkMTrCM47MHa0Q6/AOtNj2cm90FuJ4zkVZMlOi88w==", 370 | "requires": { 371 | "tcb-admin-node": "^1.1.0", 372 | "tslib": "^1.9.3" 373 | } 374 | } 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /resources/cloudfunctions/get_posts_statistics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get_posts_statistics", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "wx-server-sdk": "latest" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/cloudfunctions/login/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 这个示例将经自动鉴权过的小程序用户 openid 返回给小程序端 3 | * 4 | * event 参数包含 5 | * - 小程序端调用传入的 data 6 | * - 经过微信鉴权直接可信的用户唯一标识 openid 7 | * 8 | */ 9 | exports.main = (event, context) => { 10 | 11 | // 可执行其他自定义逻辑 12 | // console.log 的内容可以在云开发云函数调用日志查看 13 | 14 | return { 15 | openid: event.userInfo.openId, 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /resources/cloudfunctions/login/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "login", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "wx-server-sdk": "latest" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/cloudfunctions/openapi/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "permissions": { 3 | "openapi": [ 4 | "wxacode.getUnlimited", 5 | "templateMessage.send", 6 | "templateMessage.addTemplate", 7 | "templateMessage.deleteTemplate", 8 | "templateMessage.getTemplateList", 9 | "templateMessage.getTemplateLibraryById", 10 | "templateMessage.getTemplateLibraryList" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/openapi/index.js: -------------------------------------------------------------------------------- 1 | // 云函数入口文件 2 | const cloud = require('wx-server-sdk') 3 | 4 | cloud.init() 5 | 6 | const db = cloud.database() 7 | const _ = db.command 8 | 9 | //收到评论通知 10 | const template = 'HcZHCKUF-nG4gEvnj5f_dLefO1z0bzSgc6XTAj8wrFs' 11 | 12 | // 云函数入口函数 13 | exports.main = async (event) => { 14 | switch (event.action) { 15 | case 'sendTemplateMessage': { 16 | return sendTemplateMessage(event) 17 | } 18 | case 'checkAuthor': { 19 | return checkAuthor(event) 20 | } 21 | case 'removeExpireFormId': { 22 | return removeExpireFormId(event) 23 | } 24 | case 'queryFormIds': { 25 | return queryFormIds(event) 26 | } 27 | default: break 28 | } 29 | } 30 | 31 | /** 32 | * 获取总的formIds和过期的formIds 33 | * @param {} event 34 | */ 35 | async function queryFormIds(event) { 36 | var data = {} 37 | var formIdsResult = await db.collection('openid_formids').where({ 38 | _openid: process.env.author // 填入当前用户 openid 39 | }).count() 40 | 41 | console.info(formIdsResult) 42 | 43 | console.info(new Date().removeDays(7).getTime()) 44 | var formIdsExpireResult = await db.collection('openid_formids').where({ 45 | _openid: process.env.author, // 填入当前用户 openid 46 | timestamp: _.lt(new Date().removeDays(7).getTime()) 47 | }).count() 48 | 49 | console.info(formIdsExpireResult) 50 | 51 | data.formIds = formIdsResult.total 52 | data.expireFromIds = formIdsExpireResult.total 53 | return data; 54 | } 55 | 56 | /** 57 | * 删除过期的formID 58 | * @param {} event 59 | */ 60 | async function removeExpireFormId(event) { 61 | try { 62 | return await db.collection('openid_formids').where({ 63 | timestamp: _.lt(new Date().removeDays(7).getTime()) 64 | }).remove() 65 | } catch (e) { 66 | console.error(e) 67 | } 68 | } 69 | 70 | /** 71 | * 验证 72 | * @param {} event 73 | */ 74 | async function checkAuthor(event) { 75 | if (event.userInfo.openId == process.env.author) { 76 | return true; 77 | } 78 | return false; 79 | } 80 | /** 81 | * 发送通知消息 82 | * @param event 83 | */ 84 | async function sendTemplateMessage(event) { 85 | 86 | var touser = ""; 87 | var form_id = ""; 88 | var openId = event.tOpenId == "" ? process.env.author : event.tOpenId 89 | 90 | var openIdformIds = await db.collection('openid_formids').where({ 91 | _openid: openId 92 | }).limit(1).get() 93 | if (openIdformIds.code) { 94 | return; 95 | } 96 | if (!openIdformIds.data.length) { 97 | return; 98 | } 99 | touser = openIdformIds.data[0]['_openid'] 100 | form_id = openIdformIds.data[0]['formId'] 101 | console.info("openId:"+touser+";formId:"+form_id) 102 | 103 | const removeResult = await db.collection('openid_formids').doc(openIdformIds.data[0]['_id']).remove() 104 | console.info(event.nickName + ":" + event.message) 105 | 106 | const sendResult = await cloud.openapi.templateMessage.send({ 107 | touser: touser, 108 | templateId: template, 109 | formId: form_id, 110 | page: 'pages/detail/detail?blogId=' + event.blogId, 111 | data: { 112 | keyword1: { 113 | value: event.nickName // keyword1 的值 114 | }, 115 | keyword2: { 116 | value: event.message // keyword2 的值 117 | } 118 | }, 119 | }) 120 | return sendResult 121 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/openapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openapi", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "date-utils": "^1.2.21", 13 | "wx-server-sdk": "^0.4.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /resources/cloudfunctions/push_child_comments/index.js: -------------------------------------------------------------------------------- 1 | // 云函数入口文件 2 | const cloud = require('wx-server-sdk') 3 | 4 | cloud.init() 5 | const db = cloud.database() 6 | const _ = db.command 7 | 8 | // 云函数入口函数 9 | exports.main = async (event, context) => { 10 | return await db.collection('posts_comments').doc(event.id).update({ 11 | data: { 12 | childComment: _.push(event.comments) 13 | } 14 | }) 15 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/push_child_comments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "push_child_comments", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "wx-server-sdk": "latest" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/cloudfunctions/upsert_posts_statistics/index.js: -------------------------------------------------------------------------------- 1 | // 云函数入口文件 2 | const cloud = require('wx-server-sdk') 3 | 4 | cloud.init() 5 | 6 | const db = cloud.database() 7 | 8 | // 更新文章统计数据,没有则默认初始化一笔 9 | exports.main = async (event, context) => { 10 | try { 11 | var posts = await db.collection('posts_statistics').where({ 12 | post_id:event.post_id 13 | }).get() 14 | 15 | if (posts.data.length>0) { 16 | await db.collection('posts_statistics').doc(posts.data[0]['_id']).update({ 17 | data: { 18 | view_count: posts.data[0]['view_count'] + event.view_count ,//浏览量 19 | comment_count: posts.data[0]['comment_count']+event.comment_count,//评论数 20 | like_count: posts.data[0]['like_count'] + event.like_count//点赞数 21 | } 22 | }) 23 | } 24 | else { 25 | //默认初始化一笔数据 26 | await db.collection('posts_statistics').add({ 27 | data: { 28 | post_id: event.post_id,//文章id 29 | view_count: 100 + Math.floor(Math.random() * 40),//浏览量 30 | comment_count: 0,//评论数 31 | like_count: 10 + Math.floor(Math.random() * 40)//点赞数 32 | } 33 | }) 34 | } 35 | return true 36 | } catch (e) { 37 | console.error(e) 38 | return false 39 | } 40 | } -------------------------------------------------------------------------------- /resources/cloudfunctions/upsert_posts_statistics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upsert_posts_statistics", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "wx-server-sdk": "latest" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /resources/miniprogram/app.js: -------------------------------------------------------------------------------- 1 | App({ 2 | onLaunch: function() { 3 | 4 | if (!wx.cloud) { 5 | console.error('请使用 2.2.3 或以上的基础库以使用云能力') 6 | } else { 7 | wx.cloud.init({ 8 | traceUser: true, 9 | }) 10 | 11 | wx.cloud.callFunction({ 12 | name: 'login', 13 | data: {}, 14 | success: res => { 15 | console.log(res) 16 | console.log('[云函数] [login] user openid: ', res.result.openid) 17 | this.globalData.openid = res.result.openid 18 | }, 19 | fail: err => { 20 | console.error('[云函数] [login] 调用失败', err) 21 | } 22 | }) 23 | } 24 | //调用API从本地缓存中获取数据 25 | var logs = wx.getStorageSync('logs') || [] 26 | logs.unshift(Date.now()) 27 | wx.setStorageSync('logs', logs) 28 | }, 29 | checkUserInfo: function(cb) { 30 | let that = this 31 | if (that.globalData.userInfo) { 32 | typeof cb == "function" && cb(that.globalData.userInfo, true); 33 | } else { 34 | wx.getSetting({ 35 | success: function(res) { 36 | if (res.authSetting['scope.userInfo']) { 37 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称 38 | wx.getUserInfo({ 39 | success: function(res) { 40 | that.globalData.userInfo = JSON.parse(res.rawData); 41 | typeof cb == "function" && cb(that.globalData.userInfo, true); 42 | } 43 | }) 44 | } else { 45 | typeof cb == "function" && cb(that.globalData.userInfo, false); 46 | } 47 | } 48 | }) 49 | } 50 | }, 51 | globalData: { 52 | openid: "", 53 | userInfo: null, 54 | //默认图片 55 | defaultImageUrl: 'http://image.bug2048.com/blogdefault.jpeg?', 56 | imageUrl: 'http://image.bug2048.com/', 57 | imageStyle200To200: 'imageView2/1/w/200/h/200/q/100', 58 | imageStyle600To300: 'imageView2/1/w/600/h/300/q/75|watermark/2/text/QnVn55Sf5rS7MjA0OA==/font/5a6L5L2T/fontsize/280/fill/IzAwMDAwMA==/dissolve/100/gravity/SouthEast/dx/10/dy/10' 59 | } 60 | }) -------------------------------------------------------------------------------- /resources/miniprogram/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/logs/logs", 5 | "pages/mine/mine", 6 | "pages/topic/topic", 7 | "pages/detail/detail", 8 | "pages/collected/collected", 9 | "pages/about/about_wechat", 10 | "pages/about/about_me", 11 | "pages/setting/setting" 12 | ], 13 | "window": { 14 | "backgroundTextStyle": "light", 15 | "navigationBarBackgroundColor": "#fff", 16 | "navigationBarTitleText": "Bug生活2048", 17 | "navigationBarTextStyle": "black" 18 | }, 19 | "navigateToMiniProgramAppIdList": [ 20 | "wx5642e868dfc28bb0" 21 | ], 22 | "tabBar": { 23 | "color": "#959394", 24 | "selectedColor": "#959394", 25 | "backgroundColor": "#f0f0f0", 26 | "borderStyle": "white", 27 | "list": [ 28 | { 29 | "pagePath": "pages/index/index", 30 | "iconPath": "images/tabbar/home.png", 31 | "selectedIconPath": "images/tabbar/home_click.png", 32 | "text": "首页" 33 | }, 34 | { 35 | "pagePath": "pages/topic/topic", 36 | "iconPath": "images/tabbar/like.png", 37 | "selectedIconPath": "images/tabbar/like_click.png", 38 | "text": "专题" 39 | }, 40 | { 41 | "pagePath": "pages/mine/mine", 42 | "iconPath": "images/tabbar/about.png", 43 | "selectedIconPath": "images/tabbar/about_click.png", 44 | "text": "我的" 45 | } 46 | ] 47 | }, 48 | "sitemapLocation": "sitemap.json" 49 | } -------------------------------------------------------------------------------- /resources/miniprogram/app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | @import "dist/index.wxss"; 3 | .wxParse-p { 4 | margin-top: 20rpx; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/actionsheet/index.js: -------------------------------------------------------------------------------- 1 | const { extractComponentId } = require('../common/helper'); 2 | 3 | module.exports = { 4 | _handleZanActionsheetMaskClick({ currentTarget = {} }) { 5 | const dataset = currentTarget.dataset || {}; 6 | const { componentId, closeOnClickOverlay } = dataset; 7 | 8 | // 判断是否在点击背景时需要关闭弹层 9 | if (!closeOnClickOverlay) { 10 | return; 11 | } 12 | 13 | resolveCancelClick.call(this, { componentId }); 14 | }, 15 | 16 | _handleZanActionsheetCancelBtnClick(e) { 17 | const componentId = extractComponentId(e); 18 | 19 | resolveCancelClick.call(this, { componentId }); 20 | }, 21 | 22 | _handleZanActionsheetBtnClick({ currentTarget = {} }) { 23 | const dataset = currentTarget.dataset || {}; 24 | const { componentId, index } = dataset; 25 | 26 | if (this.handleZanActionsheetClick) { 27 | this.handleZanActionsheetClick({ componentId, index }); 28 | } else { 29 | console.warn('页面缺少 handleZanActionsheetClick 回调函数'); 30 | } 31 | } 32 | }; 33 | 34 | function resolveCancelClick({ componentId }) { 35 | 36 | if (this.handleZanActionsheetCancel) { 37 | this.handleZanActionsheetCancel({ componentId }); 38 | } else { 39 | console.warn('页面缺少 handleZanActionsheetCancel 回调函数'); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/actionsheet/index.wxml: -------------------------------------------------------------------------------- 1 | 41 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/actionsheet/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-actionsheet{background-color:#f8f8f8}.zan-actionsheet__mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:10;background:rgba(0,0,0,.7);display:none}.zan-actionsheet__container{position:fixed;left:0;right:0;bottom:0;background:#f8f8f8;transform:translate3d(0,50%,0);transform-origin:center;transition:all .2s ease;z-index:11;opacity:0;visibility:hidden}.zan-actionsheet__btn.zan-btn{height:50px;line-height:50px;margin-bottom:0}.zan-actionsheet__btn.zan-btn::after{border-width:0;border-bottom-width:1px}.zan-actionsheet__btn.zan-btn:last-child::after{border-bottom-width:0}.zan-actionsheet__subname{margin-left:2px;font-size:12px;color:#666}.zan-actionsheet__footer{margin-top:10px}.zan-actionsheet__btn.zan-btn--loading .zan-actionsheet__subname{color:transparent}.zan-actionsheet--show .zan-actionsheet__container{opacity:1;transform:translate3d(0,0,0);visibility:visible}.zan-actionsheet--show .zan-actionsheet__mask{display:block} -------------------------------------------------------------------------------- /resources/miniprogram/dist/badge/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-badge{position:relative}.zan-badge__count{position:absolute;top:-16px;right:0;height:1.6em;min-width:1.6em;line-height:1.6;padding:0 .4em;font-size:20px;border-radius:.8em;background:#f44;color:#fff;text-align:center;white-space:nowrap;transform:translateX(50%) scale(.5);transform-origin:center;z-index:10;box-shadow:0 0 0 2px #fff;box-sizing:border-box} -------------------------------------------------------------------------------- /resources/miniprogram/dist/btn/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-btn{position:relative;color:#333;background-color:#fff;margin-bottom:10px;padding-left:15px;padding-right:15px;border-radius:2px;font-size:16px;line-height:45px;height:45px;box-sizing:border-box;text-decoration:none;text-align:center;vertical-align:middle}.zan-btn::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-width:1px;border-radius:4px}.zan-btns{margin:15px}.zan-btn--primary{color:#fff;background-color:#4b0}.zan-btn--primary::after{border-color:#0a0}.zan-btn--warn{color:#fff;background-color:#f85}.zan-btn--warn::after{border-color:#f85}.zan-btn--danger{color:#fff;background-color:#f44}.zan-btn--danger::after{border-color:#e33}.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}.zan-btn--plain.zan-btn{background-color:transparent}.zan-btn--plain.zan-btn--primary{color:#06bf04}.zan-btn--plain.zan-btn--warn{color:#f60}.zan-btn--plain.zan-btn--danger{color:#f44}.button-hover{opacity:.9}.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 .6s linear;animation-iteration-count:infinite}.zan-btn--danger.zan-btn--loading::before,.zan-btn--primary.zan-btn--loading::before,.zan-btn--warn.zan-btn--loading::before{border-color:#fff rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.1)}@keyframes btn-spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}.zan-btn.zan-btn--disabled{color:#999!important;background:#f8f8f8!important;border-color:#e5e5e5!important;cursor:not-allowed!important;opacity:1!important}.zan-btn.zan-btn--disabled::after{border-color:#e5e5e5!important}.zan-btn--last-child,.zan-btn:last-child{margin-bottom:0;margin-right:0} -------------------------------------------------------------------------------- /resources/miniprogram/dist/capsule/index.wxml: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/capsule/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-capsule{display:inline-block;font-size:12px;vertical-align:middle;line-height:19px;transform:scale(.83)}.zan-capsule__left,.zan-capsule__right{display:inline-block;line-height:17px;height:19px;vertical-align:middle;box-sizing:border-box}.zan-capsule__left{padding:0 2px;color:#fff;background:#999;border-radius:2px 0 0 2px;border:1rpx solid #999}.zan-capsule__right{padding:0 5px;color:#999;border-radius:0 2px 2px 0;border:1rpx solid #999}.zan-capsule--danger .zan-capsule__left{color:#fff;background:#f24544;border-color:#f24544}.zan-capsule--danger .zan-capsule__right{color:#f24544;border-color:#f24544} -------------------------------------------------------------------------------- /resources/miniprogram/dist/card/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-card { 2 | margin-left: 0; 3 | width: auto; 4 | padding: 5px 15px; 5 | overflow: hidden; 6 | position: relative; 7 | font-size: 14px; 8 | } 9 | 10 | .zan-card__thumb { 11 | width: 90px; 12 | height: 90px; 13 | float: left; 14 | position: relative; 15 | margin-left: auto; 16 | margin-right: auto; 17 | overflow: hidden; 18 | background-size: cover; 19 | } 20 | 21 | .zan-card__img { 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | right: 0; 26 | bottom: 0; 27 | width: auto; 28 | height: auto; 29 | max-width: 100%; 30 | max-height: 100%; 31 | } 32 | 33 | .zan-card__detail { 34 | margin-left: 100px; 35 | width: auto; 36 | position: relative; 37 | } 38 | 39 | .zan-card__detail-row { 40 | overflow: hidden; 41 | line-height: 20px; 42 | min-height: 20px; 43 | margin-bottom: 3px; 44 | } 45 | 46 | .zan-card__right-col { 47 | float: right; 48 | } 49 | 50 | .zan-card__left-col { 51 | margin-right: 80px; 52 | } 53 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/cell/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-cell{position:relative;padding:12px 15px;display:flex;align-items:center;line-height:1.4;font-size:14px}.zan-cell::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-bottom-width:1px;left:15px;right:0}.zan-cell__icon{margin-right:5px}.zan-cell__bd{flex:1}.zan-cell__text{line-height:24px;font-size:14px}.zan-cell__desc{line-height:1.2;font-size:12px;color:#666}.zan-cell__ft{position:relative;text-align:right;color:#666}.zan-cell__no-pading{padding:0}.zan-cell__no-pading .zan-cell__bd_padding{padding:12px 0 12px 15px}.zan-cell__no-pading .zan-cell__bd_padding .zan-form__input{height:26px}.zan-cell__no-pading .zan-cell__ft_padding{padding:12px 15px 12px 0}.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(.71,.71,-.71,.71,0,0)}.zan-cell--switch{padding-top:6px;padding-bottom:6px} -------------------------------------------------------------------------------- /resources/miniprogram/dist/col/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-col{float:left;box-sizing:border-box;width:0}.zan-col-1{width:4.16667%}.zan-col-offset-1{margin-left:4.16667%}.zan-col-2{width:8.33333%}.zan-col-offset-2{margin-left:8.33333%}.zan-col-3{width:12.5%}.zan-col-offset-3{margin-left:12.5%}.zan-col-4{width:16.66667%}.zan-col-offset-4{margin-left:16.66667%}.zan-col-5{width:20.83333%}.zan-col-offset-5{margin-left:20.83333%}.zan-col-6{width:25%}.zan-col-offset-6{margin-left:25%}.zan-col-7{width:29.16667%}.zan-col-offset-7{margin-left:29.16667%}.zan-col-8{width:33.33333%}.zan-col-offset-8{margin-left:33.33333%}.zan-col-9{width:37.5%}.zan-col-offset-9{margin-left:37.5%}.zan-col-10{width:41.66667%}.zan-col-offset-10{margin-left:41.66667%}.zan-col-11{width:45.83333%}.zan-col-offset-11{margin-left:45.83333%}.zan-col-12{width:50%}.zan-col-offset-12{margin-left:50%}.zan-col-13{width:54.16667%}.zan-col-offset-13{margin-left:54.16667%}.zan-col-14{width:58.33333%}.zan-col-offset-14{margin-left:58.33333%}.zan-col-15{width:62.5%}.zan-col-offset-15{margin-left:62.5%}.zan-col-16{width:66.66667%}.zan-col-offset-16{margin-left:66.66667%}.zan-col-17{width:70.83333%}.zan-col-offset-17{margin-left:70.83333%}.zan-col-18{width:75%}.zan-col-offset-18{margin-left:75%}.zan-col-19{width:79.16667%}.zan-col-offset-19{margin-left:79.16667%}.zan-col-20{width:83.33333%}.zan-col-offset-20{margin-left:83.33333%}.zan-col-21{width:87.5%}.zan-col-offset-21{margin-left:87.5%}.zan-col-22{width:91.66667%}.zan-col-offset-22{margin-left:91.66667%}.zan-col-23{width:95.83333%}.zan-col-offset-23{margin-left:95.83333%}.zan-col-24{width:100%}.zan-col-offset-24{margin-left:100%} -------------------------------------------------------------------------------- /resources/miniprogram/dist/color/index.wxss: -------------------------------------------------------------------------------- 1 | .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:#38f!important}.zan-c-green{color:#06bf04!important} -------------------------------------------------------------------------------- /resources/miniprogram/dist/common/helper.js: -------------------------------------------------------------------------------- 1 | // 从事件对象中解析得到 componentId 2 | // 需要在元素上声明 data-component-id 3 | function extractComponentId(event = {}) { 4 | const { dataset: { componentId } } = event.currentTarget || {}; 5 | return componentId; 6 | } 7 | 8 | /* 9 | 注:默认合并所有生命周期函数 10 | 配置合并指定的生命周期 or 忽略指定字段 11 | const extend = extendCreator({ 12 | life: ['onLoad', 'onPullDownRefresh'], 13 | exclude: ['binder'] 14 | }); 15 | 16 | Page(extend({}, { 17 | onLoad() {}, 18 | ... 19 | })); 20 | */ 21 | 22 | const LIFE_CYCLE = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll']; 23 | 24 | const extendCreator = (config = {}) => { 25 | const { 26 | life = LIFE_CYCLE, 27 | exclude = [] 28 | } = config; 29 | 30 | const excludeList = exclude.concat(LIFE_CYCLE.map(getFuncArrayName)); 31 | 32 | if (!Array.isArray(life) || !Array.isArray(exclude)) throw new Error('Invalid Extend Config'); 33 | let lifeCycleList = life.filter(item => LIFE_CYCLE.indexOf(item) >= 0); 34 | return function extend(target, ...objList) { 35 | objList.forEach((source) => { 36 | if (source) { 37 | let keys = Object.keys(source); 38 | keys.forEach((key) => { 39 | let value = source[key]; 40 | if (excludeList.indexOf(key) >= 0) return; 41 | if (lifeCycleList.indexOf(key) >= 0 && typeof value === 'function') { 42 | let funcArrayName = getFuncArrayName(key); 43 | if (!target[funcArrayName]) { 44 | target[funcArrayName] = []; 45 | if (target[key]) { 46 | target[funcArrayName].push(target[key]); 47 | } 48 | target[key] = function (...rest) { 49 | target[funcArrayName].forEach(func => func.apply(this, rest)); 50 | }; 51 | } 52 | 53 | if (source[funcArrayName]) { 54 | // 经过生命周期合并的组件直接整合函数列表 55 | target[funcArrayName].push(...source[funcArrayName]); 56 | } else { 57 | // 添加生命周期函数进入函数列表 58 | target[funcArrayName].push(value); 59 | } 60 | } else { 61 | target[key] = value; 62 | } 63 | }); 64 | } 65 | }); 66 | return target; 67 | }; 68 | }; 69 | 70 | const getFuncArrayName = name => `__$${name}`; 71 | 72 | module.exports = { 73 | extractComponentId, 74 | extend: Object.assign, 75 | extendCreator 76 | }; 77 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/dialog/index.js: -------------------------------------------------------------------------------- 1 | const _f = function () {}; 2 | 3 | module.exports = { 4 | showZanDialog(options = {}) { 5 | const { 6 | // 自定义 btn 列表 7 | // { type: 按钮类型,回调时以此作为区分依据,text: 按钮文案, color: 按钮文字颜色 } 8 | buttons = [], 9 | // 标题 10 | title = '', 11 | // 内容 12 | content = ' ', 13 | // 按钮是否展示为纵向 14 | buttonsShowVertical = false, 15 | // 是否展示确定 16 | showConfirm = true, 17 | // 确认按钮文案 18 | confirmText = '确定', 19 | // 确认按钮颜色 20 | confirmColor = '#3CC51F', 21 | // 是否展示取消 22 | showCancel = false, 23 | // 取消按钮文案 24 | cancelText = '取消', 25 | // 取消按钮颜色 26 | cancelColor = '#333' 27 | } = options; 28 | 29 | // 处理默认按钮的展示 30 | // 纵向排布确认按钮在上方 31 | let showCustomBtns = false; 32 | if (buttons.length === 0) { 33 | if (showConfirm) { 34 | buttons.push({ 35 | type: 'confirm', 36 | text: confirmText, 37 | color: confirmColor 38 | }); 39 | } 40 | 41 | if (showCancel) { 42 | const cancelButton = { 43 | type: 'cancel', 44 | text: cancelText, 45 | color: cancelColor 46 | }; 47 | if (buttonsShowVertical) { 48 | buttons.push(cancelButton); 49 | } else { 50 | buttons.unshift(cancelButton); 51 | } 52 | } 53 | } else { 54 | showCustomBtns = true; 55 | } 56 | 57 | return new Promise((resolve, reject) => { 58 | this.setData({ 59 | zanDialog: { 60 | show: true, 61 | showCustomBtns, 62 | buttons, 63 | title, 64 | content, 65 | buttonsShowVertical, 66 | showConfirm, 67 | confirmText, 68 | confirmColor, 69 | showCancel, 70 | cancelText, 71 | cancelColor, 72 | // 回调钩子 73 | resolve, 74 | reject 75 | } 76 | }); 77 | }); 78 | }, 79 | 80 | _handleZanDialogButtonClick(e) { 81 | const { currentTarget = {} } = e; 82 | const { dataset = {} } = currentTarget; 83 | 84 | // 获取当次弹出框的信息 85 | const zanDialogData = this.data.zanDialog || {}; 86 | const { resolve = _f, reject = _f } = zanDialogData; 87 | 88 | // 重置 zanDialog 里的内容 89 | this.setData({ 90 | zanDialog: { show: false } 91 | }); 92 | 93 | // 自定义按钮,全部 resolve 形式返回,根据 type 区分点击按钮 94 | if (zanDialogData.showCustomBtns) { 95 | resolve({ 96 | type: dataset.type 97 | }); 98 | return; 99 | } 100 | 101 | // 默认按钮,确认为 resolve,取消为 reject 102 | if (dataset.type === 'confirm') { 103 | resolve({ 104 | type: 'confirm' 105 | }); 106 | } else { 107 | reject({ 108 | type: 'cancel' 109 | }); 110 | } 111 | } 112 | }; 113 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/dialog/index.wxml: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/dialog/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-dialog--container { 2 | position: fixed; 3 | top: 45%; 4 | left: 50%; 5 | width: 80%; 6 | height: 0; 7 | font-size: 16px; 8 | overflow: hidden; 9 | transition: all 0.2s linear; 10 | border-radius: 4px; 11 | background-color: #fff; 12 | transform: translate3d(-50%, -50%, 0); 13 | color: #333; 14 | opacity: 0; 15 | z-index: 1; 16 | } 17 | 18 | .zan-dialog--mask { 19 | position: fixed; 20 | width: 100%; 21 | height: 100%; 22 | top: 0; 23 | left: 0; 24 | background-color: rgba(0, 0, 0, 0.6); 25 | transition: 0.3s; 26 | display: none; 27 | z-index: 1; 28 | } 29 | 30 | .zan-dialog__header { 31 | padding: 15px 0 0; 32 | text-align: center; 33 | } 34 | 35 | .zan-dialog__content { 36 | position: relative; 37 | padding: 15px 20px; 38 | line-height: 1.5; 39 | min-height: 40px; 40 | } 41 | 42 | .zan-dialog__content::after { 43 | content: ''; 44 | position: absolute; 45 | top: 0; 46 | left: 0; 47 | width: 200%; 48 | height: 200%; 49 | transform: scale(0.5); 50 | transform-origin: 0 0; 51 | pointer-events: none; 52 | box-sizing: border-box; 53 | border: 0 solid #e5e5e5; 54 | border-bottom-width: 1px; 55 | } 56 | 57 | .zan-dialog__content--title { 58 | color: #999; 59 | font-size: 14px; 60 | } 61 | 62 | .zan-dialog__footer { 63 | overflow: hidden; 64 | } 65 | 66 | .zan-dialog__button { 67 | line-height: 50px; 68 | height: 50px; 69 | padding: 0 5px; 70 | border-radius: 0; 71 | margin-bottom: 0; 72 | } 73 | 74 | .zan-dialog__button::after { 75 | border-width: 0; 76 | border-radius: 0; 77 | } 78 | 79 | .zan-dialog--show .zan-dialog--container { 80 | opacity: 1; 81 | height: auto; 82 | } 83 | 84 | .zan-dialog--show .zan-dialog--mask { 85 | display: block; 86 | } 87 | 88 | .zan-dialog__footer--horizon { 89 | display: flex; 90 | } 91 | 92 | .zan-dialog__footer--horizon .zan-dialog__button { 93 | flex: 1; 94 | } 95 | 96 | .zan-dialog__footer--horizon .zan-dialog__button::after { 97 | border-right-width: 1px; 98 | } 99 | 100 | .zan-dialog__footer--horizon .zan-dialog__button:last-child::after { 101 | border-right-width: 0; 102 | } 103 | 104 | .zan-dialog__footer--vertical .zan-dialog__button { 105 | flex: 1; 106 | } 107 | 108 | .zan-dialog__footer--vertical .zan-dialog__button::after { 109 | border-bottom-width: 1px; 110 | } 111 | 112 | .zan-dialog__footer--vertical .zan-dialog__button:last-child::after { 113 | border-bottom-width: 0; 114 | } 115 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/field/index.js: -------------------------------------------------------------------------------- 1 | const { extractComponentId } = require('../common/helper'); 2 | 3 | module.exports = { 4 | _handleZanFieldChange(event) { 5 | const componentId = extractComponentId(event); 6 | event.componentId = componentId; 7 | 8 | 9 | 10 | if (this.handleZanFieldChange) { 11 | return this.handleZanFieldChange(event); 12 | } 13 | 14 | console.warn('页面缺少 handleZanFieldChange 回调函数'); 15 | }, 16 | 17 | _handleZanFieldFocus(event) { 18 | const componentId = extractComponentId(event); 19 | event.componentId = componentId; 20 | 21 | 22 | 23 | if (this.handleZanFieldFocus) { 24 | return this.handleZanFieldFocus(event); 25 | } 26 | }, 27 | 28 | _handleZanFieldBlur(event) { 29 | const componentId = extractComponentId(event); 30 | event.componentId = componentId; 31 | 32 | 33 | 34 | if (this.handleZanFieldBlur) { 35 | return this.handleZanFieldBlur(event); 36 | } 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/field/index.wxml: -------------------------------------------------------------------------------- 1 | 36 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/field/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-cell{position:relative;padding:12px 15px;display:flex;align-items:center;line-height:1.4;font-size:14px}.zan-cell::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-bottom-width:1px;left:15px;right:0}.zan-cell__icon{margin-right:5px}.zan-cell__bd{flex:1}.zan-cell__text{line-height:24px;font-size:14px}.zan-cell__desc{line-height:1.2;font-size:12px;color:#666}.zan-cell__ft{position:relative;text-align:right;color:#666}.zan-cell__no-pading{padding:0}.zan-cell__no-pading .zan-cell__bd_padding{padding:12px 0 12px 15px}.zan-cell__no-pading .zan-cell__bd_padding .zan-form__input{height:26px}.zan-cell__no-pading .zan-cell__ft_padding{padding:12px 15px 12px 0}.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(.71,.71,-.71,.71,0,0)}.zan-cell--switch{padding-top:6px;padding-bottom:6px}.zan-field{padding:7px 15px;color:#333}.zan-field--wrapped{margin:0 15px;background-color:#fff}.zan-field--wrapped::after{left:0;border-width:1px;border-radius:4px}.zan-field.zan-field--wrapped::after{display:block}.zan-field--wrapped+.zan-field--wrapped{margin-top:10px}.zan-field--error{color:#f40}.zan-field--wrapped.zan-field--error::after{border-color:#f40}.zan-field__title{color:#333;min-width:65px;padding-right:10px}.zan-field__input{flex:1;line-height:1.6;padding:4px 0;min-height:22px;height:auto;font-size:14px}.zan-field__placeholder{font-size:14px}.zan-field__input--right{text-align:right} -------------------------------------------------------------------------------- /resources/miniprogram/dist/helper/index.wxss: -------------------------------------------------------------------------------- 1 | .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:700}.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(.71,.71,-.71,.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}.zan-hairline,.zan-hairline--bottom,.zan-hairline--left,.zan-hairline--right,.zan-hairline--surround,.zan-hairline--top,.zan-hairline--top-bottom{position:relative}.zan-hairline--bottom::after,.zan-hairline--left::after,.zan-hairline--right::after,.zan-hairline--surround::after,.zan-hairline--top-bottom::after,.zan-hairline--top::after,.zan-hairline::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5}.zan-hairline--top::after{border-top-width:1px}.zan-hairline--left::after{border-left-width:1px}.zan-hairline--right::after{border-right-width:1px}.zan-hairline--bottom::after{border-bottom-width:1px}.zan-hairline--top-bottom::after{border-width:1px 0}.zan-hairline--surround::after{border-width:1px} -------------------------------------------------------------------------------- /resources/miniprogram/dist/icon/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Component({ 4 | properties: { 5 | type: { 6 | type: String, 7 | value: '' 8 | } 9 | } 10 | }); -------------------------------------------------------------------------------- /resources/miniprogram/dist/icon/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true 3 | } 4 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/icon/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/icon/index.wxss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-style: normal; 3 | font-weight: 400; 4 | font-family: vant-icon; 5 | src: url(https://img.yzcdn.cn/vant/vant-icon-76f274.ttf) format('truetype'); 6 | } 7 | 8 | .van-icon { 9 | position: relative; 10 | display: inline-block; 11 | font: normal normal normal 14px/1 vant-icon; 12 | font-size: inherit; 13 | text-rendering: auto; 14 | } 15 | 16 | .van-icon__info { 17 | color: #fff; 18 | left: 100%; 19 | top: -.5em; 20 | font-size: 0.5em; 21 | padding: 0 0.3em; 22 | text-align: center; 23 | min-width: 1.2em; 24 | line-height: 1.2; 25 | position: absolute; 26 | border-radius: 0.6em; 27 | box-sizing: border-box; 28 | background-color: #f44; 29 | -webkit-transform: translateX(-50%); 30 | transform: translateX(-50%); 31 | font-family: PingFang SC, Helvetica Neue, Arial, sans-serif; 32 | } 33 | 34 | .van-icon::before { 35 | display: inline-block; 36 | } 37 | 38 | .van-icon-add-o::before { 39 | content: "\F000"; 40 | } 41 | 42 | .van-icon-add::before { 43 | content: "\F001"; 44 | } 45 | 46 | .van-icon-add2::before { 47 | content: "\F002"; 48 | } 49 | 50 | .van-icon-after-sale::before { 51 | content: "\F003"; 52 | } 53 | 54 | .van-icon-aim::before { 55 | content: "\F004"; 56 | } 57 | 58 | .van-icon-alipay::before { 59 | content: "\F005"; 60 | } 61 | 62 | .van-icon-arrow-left::before { 63 | content: "\F006"; 64 | } 65 | 66 | .van-icon-arrow::before { 67 | content: "\F007"; 68 | } 69 | 70 | .van-icon-balance-pay::before { 71 | content: "\F008"; 72 | } 73 | 74 | .van-icon-browsing-history::before { 75 | content: "\F009"; 76 | } 77 | 78 | .van-icon-card::before { 79 | content: "\F00A"; 80 | } 81 | 82 | .van-icon-cart::before { 83 | content: "\F00B"; 84 | } 85 | 86 | .van-icon-cash-back-record::before { 87 | content: "\F00C"; 88 | } 89 | 90 | .van-icon-cash-on-deliver::before { 91 | content: "\F00D"; 92 | } 93 | 94 | .van-icon-certificate::before { 95 | content: "\F00E"; 96 | } 97 | 98 | .van-icon-chat::before { 99 | content: "\F00F"; 100 | } 101 | 102 | .van-icon-check::before { 103 | content: "\F010"; 104 | } 105 | 106 | .van-icon-checked::before { 107 | content: "\F011"; 108 | } 109 | 110 | .van-icon-clear::before { 111 | content: "\F012"; 112 | } 113 | 114 | .van-icon-clock::before { 115 | content: "\F013"; 116 | } 117 | 118 | .van-icon-close::before { 119 | content: "\F014"; 120 | } 121 | 122 | .van-icon-completed::before { 123 | content: "\F015"; 124 | } 125 | 126 | .van-icon-contact::before { 127 | content: "\F016"; 128 | } 129 | 130 | .van-icon-coupon::before { 131 | content: "\F017"; 132 | } 133 | 134 | .van-icon-credit-pay::before { 135 | content: "\F018"; 136 | } 137 | 138 | .van-icon-debit-pay::before { 139 | content: "\F019"; 140 | } 141 | 142 | .van-icon-delete::before { 143 | content: "\F01A"; 144 | } 145 | 146 | .van-icon-description::before { 147 | content: "\F01B"; 148 | } 149 | 150 | .van-icon-discount::before { 151 | content: "\F01C"; 152 | } 153 | 154 | .van-icon-ecard-pay::before { 155 | content: "\F01D"; 156 | } 157 | 158 | .van-icon-edit-data::before { 159 | content: "\F01E"; 160 | } 161 | 162 | .van-icon-edit::before { 163 | content: "\F01F"; 164 | } 165 | 166 | .van-icon-exchange-record::before { 167 | content: "\F020"; 168 | } 169 | 170 | .van-icon-exchange::before { 171 | content: "\F021"; 172 | } 173 | 174 | .van-icon-fail::before { 175 | content: "\F022"; 176 | } 177 | 178 | .van-icon-free-postage::before { 179 | content: "\F023"; 180 | } 181 | 182 | .van-icon-gift-card-pay::before { 183 | content: "\F024"; 184 | } 185 | 186 | .van-icon-gift-card::before { 187 | content: "\F025"; 188 | } 189 | 190 | .van-icon-gift::before { 191 | content: "\F026"; 192 | } 193 | 194 | .van-icon-gold-coin::before { 195 | content: "\F027"; 196 | } 197 | 198 | .van-icon-goods-collect::before { 199 | content: "\F028"; 200 | } 201 | 202 | .van-icon-home::before { 203 | content: "\F029"; 204 | } 205 | 206 | .van-icon-hot-sale::before { 207 | content: "\F02A"; 208 | } 209 | 210 | .van-icon-hot::before { 211 | content: "\F02B"; 212 | } 213 | 214 | .van-icon-idcard::before { 215 | content: "\F02C"; 216 | } 217 | 218 | .van-icon-info-o::before { 219 | content: "\F02D"; 220 | } 221 | 222 | .van-icon-like-o::before { 223 | content: "\F02E"; 224 | } 225 | 226 | .van-icon-like::before { 227 | content: "\F02F"; 228 | } 229 | 230 | .van-icon-location::before { 231 | content: "\F030"; 232 | } 233 | 234 | .van-icon-logistics::before { 235 | content: "\F031"; 236 | } 237 | 238 | .van-icon-more-o::before { 239 | content: "\F032"; 240 | } 241 | 242 | .van-icon-more::before { 243 | content: "\F033"; 244 | } 245 | 246 | .van-icon-new-arrival::before { 247 | content: "\F034"; 248 | } 249 | 250 | .van-icon-new::before { 251 | content: "\F035"; 252 | } 253 | 254 | .van-icon-other-pay::before { 255 | content: "\F036"; 256 | } 257 | 258 | .van-icon-passed::before { 259 | content: "\F037"; 260 | } 261 | 262 | .van-icon-password-not-view::before { 263 | content: "\F038"; 264 | } 265 | 266 | .van-icon-password-view::before { 267 | content: "\F039"; 268 | } 269 | 270 | .van-icon-pause::before { 271 | content: "\F03A"; 272 | } 273 | 274 | .van-icon-peer-pay::before { 275 | content: "\F03B"; 276 | } 277 | 278 | .van-icon-pending-deliver::before { 279 | content: "\F03C"; 280 | } 281 | 282 | .van-icon-pending-evaluate::before { 283 | content: "\F03D"; 284 | } 285 | 286 | .van-icon-pending-orders::before { 287 | content: "\F03E"; 288 | } 289 | 290 | .van-icon-pending-payment::before { 291 | content: "\F03F"; 292 | } 293 | 294 | .van-icon-phone::before { 295 | content: "\F040"; 296 | } 297 | 298 | .van-icon-photo::before { 299 | content: "\F041"; 300 | } 301 | 302 | .van-icon-photograph::before { 303 | content: "\F042"; 304 | } 305 | 306 | .van-icon-play::before { 307 | content: "\F043"; 308 | } 309 | 310 | .van-icon-point-gift::before { 311 | content: "\F044"; 312 | } 313 | 314 | .van-icon-points-mall::before { 315 | content: "\F045"; 316 | } 317 | 318 | .van-icon-points::before { 319 | content: "\F046"; 320 | } 321 | 322 | .van-icon-qr-invalid::before { 323 | content: "\F047"; 324 | } 325 | 326 | .van-icon-qr::before { 327 | content: "\F048"; 328 | } 329 | 330 | .van-icon-question::before { 331 | content: "\F049"; 332 | } 333 | 334 | .van-icon-receive-gift::before { 335 | content: "\F04A"; 336 | } 337 | 338 | .van-icon-records::before { 339 | content: "\F04B"; 340 | } 341 | 342 | .van-icon-search::before { 343 | content: "\F04C"; 344 | } 345 | 346 | .van-icon-send-gift::before { 347 | content: "\F04D"; 348 | } 349 | 350 | .van-icon-setting::before { 351 | content: "\F04E"; 352 | } 353 | 354 | .van-icon-share::before { 355 | content: "\F04F"; 356 | } 357 | 358 | .van-icon-shop-collect::before { 359 | content: "\F050"; 360 | } 361 | 362 | .van-icon-shop::before { 363 | content: "\F051"; 364 | } 365 | 366 | .van-icon-shopping-cart::before { 367 | content: "\F052"; 368 | } 369 | 370 | .van-icon-sign::before { 371 | content: "\F053"; 372 | } 373 | 374 | .van-icon-stop::before { 375 | content: "\F054"; 376 | } 377 | 378 | .van-icon-success::before { 379 | content: "\F055"; 380 | } 381 | 382 | .van-icon-tosend::before { 383 | content: "\F056"; 384 | } 385 | 386 | .van-icon-underway::before { 387 | content: "\F057"; 388 | } 389 | 390 | .van-icon-upgrade::before { 391 | content: "\F058"; 392 | } 393 | 394 | .van-icon-value-card::before { 395 | content: "\F059"; 396 | } 397 | 398 | .van-icon-wap-home::before { 399 | content: "\F05A"; 400 | } 401 | 402 | .van-icon-wap-nav::before { 403 | content: "\F05B"; 404 | } 405 | 406 | .van-icon-warn::before { 407 | content: "\F05C"; 408 | } 409 | 410 | .van-icon-wechat::before { 411 | content: "\F05D"; 412 | } 413 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/index.js: -------------------------------------------------------------------------------- 1 | exports.Actionsheet = require('./actionsheet/index'); 2 | exports.Dialog = require('./dialog/index'); 3 | exports.Field = require('./field/index'); 4 | exports.NoticeBar = require('./noticebar/index'); 5 | exports.Select = require('./select/index'); 6 | exports.Stepper = require('./stepper/index'); 7 | exports.Switch = require('./switch/index'); 8 | exports.Tab = require('./tab/index'); 9 | exports.Toast = require('./toast/index'); 10 | exports.TopTips = require('./toptips/index'); 11 | 12 | // 兼容老版本,在下次大版本发布时会被移除 13 | exports.CheckLabel = require('./select/index'); 14 | 15 | const { extend } = require('./common/helper'); 16 | exports.extend = extend; 17 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/loadmore/index.wxml: -------------------------------------------------------------------------------- 1 | 25 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/loadmore/index.wxss: -------------------------------------------------------------------------------- 1 | .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{color:#999}.zan-loadmore--nodata::after,.zan-loadmore--nomore::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-top-width:1px}.zan-loadmore--nodata{margin-top:120px}.zan-loadmore--nodata .zan-loadmore__tips{position:relative;top:-11px;background:#f9f9f9;padding:0 6px;z-index:1}.zan-loadmore--nomore .zan-loadmore__tips{position:relative;top:-11px;background:#f9f9f9;padding:0 6px;z-index:1}.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} -------------------------------------------------------------------------------- /resources/miniprogram/dist/noticebar/index.js: -------------------------------------------------------------------------------- 1 | const ZanNoticeBar = { 2 | initZanNoticeBarScroll(componentId) { 3 | this.zanNoticeBarNode = this.zanNoticeBarNode || {}; 4 | this.zanNoticeBarNode[`${componentId}`] = { 5 | width: undefined, 6 | wrapWidth: undefined, 7 | animation: null, 8 | resetAnimation: null 9 | }; 10 | 11 | const currentComponent = this.zanNoticeBarNode[`${componentId}`]; 12 | wx.createSelectorQuery() 13 | .in(this) 14 | .select(`#${componentId}__content`) 15 | .boundingClientRect((rect) => { 16 | if (!rect || !rect.width) { 17 | console.warn('页面缺少 noticebar 元素'); 18 | return; 19 | } 20 | 21 | currentComponent.width = rect.width; 22 | wx 23 | .createSelectorQuery() 24 | .in(this) 25 | .select(`#${componentId}__content-wrap`) 26 | .boundingClientRect((rect) => { 27 | if (!rect || !rect.width) { 28 | return; 29 | } 30 | 31 | clearTimeout(this.data[componentId].setTimeoutId) 32 | 33 | currentComponent.wrapWidth = rect.width; 34 | if (currentComponent.wrapWidth < currentComponent.width) { 35 | var mstime = currentComponent.width / 40 * 1000; 36 | currentComponent.animation = wx.createAnimation({ 37 | duration: mstime, 38 | timingFunction: 'linear' 39 | }); 40 | currentComponent.resetAnimation = wx.createAnimation({ 41 | duration: 0, 42 | timingFunction: 'linear' 43 | }); 44 | this.scrollZanNoticeBar(componentId, mstime); 45 | } 46 | }) 47 | .exec(); 48 | }) 49 | .exec(); 50 | }, 51 | 52 | scrollZanNoticeBar(componentId, mstime) { 53 | const currentComponent = this.zanNoticeBarNode[`${componentId}`]; 54 | const resetAnimationData = currentComponent.resetAnimation.translateX(currentComponent.wrapWidth).step(); 55 | this.setData({ 56 | [`${componentId}.animationData`]: resetAnimationData.export() 57 | }); 58 | const aninationData = currentComponent.animation.translateX(-mstime * 40 / 1000).step(); 59 | setTimeout(() => { 60 | this.setData({ 61 | [`${componentId}.animationData`]: aninationData.export() 62 | }); 63 | }, 100); 64 | 65 | const setTimeoutId = setTimeout(() => { 66 | this.scrollZanNoticeBar(componentId, mstime); 67 | }, mstime); 68 | this.setData({ 69 | [`${componentId}.setTimeoutId`]: setTimeoutId 70 | }) 71 | } 72 | }; 73 | 74 | module.exports = ZanNoticeBar; 75 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/noticebar/index.wxml: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/noticebar/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-noticebar{color:#f60;padding:9px 10px;font-size:12px;line-height:1.5;background-color:#fff7cc} -------------------------------------------------------------------------------- /resources/miniprogram/dist/panel/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-panel{position:relative;background:#fff;margin-top:10px;overflow:hidden}.zan-panel::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-top-width:1px;border-bottom-width:1px}.zan-panel-title{font-size:14px;line-height:1;color:#999;padding:20px 15px 0 15px}.zan-panel--without-margin-top{margin-top:0}.zan-panel--without-border::after{border:0 none} -------------------------------------------------------------------------------- /resources/miniprogram/dist/popup/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-popup{visibility:hidden}.zan-popup--show{visibility:visible}.zan-popup__mask{position:fixed;top:0;left:0;right:0;bottom:0;z-index:10;background:rgba(0,0,0,.7);display:none}.zan-popup__container{position:fixed;left:50%;top:50%;background:#fff;transform:translate3d(-50%,-50%,0);transform-origin:center;transition:all .4s ease;z-index:11;opacity:0}.zan-popup--show .zan-popup__container{opacity:1}.zan-popup--show .zan-popup__mask{display:block}.zan-popup--left .zan-popup__container{left:0;top:auto;transform:translate3d(-100%,0,0)}.zan-popup--show.zan-popup--left .zan-popup__container{transform:translate3d(0,0,0)}.zan-popup--right .zan-popup__container{right:0;top:auto;left:auto;transform:translate3d(100%,0,0)}.zan-popup--show.zan-popup--right .zan-popup__container{transform:translate3d(0,0,0)}.zan-popup--bottom .zan-popup__container{top:auto;left:auto;bottom:0;transform:translate3d(0,100%,0)}.zan-popup--show.zan-popup--bottom .zan-popup__container{transform:translate3d(0,0,0)}.zan-popup--top .zan-popup__container{top:0;left:auto;transform:translate3d(0,-100%,0)}.zan-popup--show.zan-popup--top .zan-popup__container{transform:translate3d(0,0,0)} -------------------------------------------------------------------------------- /resources/miniprogram/dist/row/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-row:after{content:"";display:table;clear:both} -------------------------------------------------------------------------------- /resources/miniprogram/dist/select/index.js: -------------------------------------------------------------------------------- 1 | const { extractComponentId } = require('../common/helper'); 2 | 3 | function handle(e) { 4 | const componentId = extractComponentId(e); 5 | const value = e.detail.value; 6 | 7 | callback.call(this, componentId, value); 8 | } 9 | 10 | function callback(componentId, value) { 11 | const e = { componentId, value }; 12 | 13 | 14 | if (this.handleZanSelectChange) { 15 | this.handleZanSelectChange(e); 16 | } else { 17 | console.warn('页面缺少 handleZanSelectChange 回调函数'); 18 | } 19 | } 20 | 21 | module.exports = { 22 | _handleZanSelectChange(e) { 23 | handle.call(this, e); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/select/index.wxml: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | function getColor(color) { 25 | color = color || '#ff4444' 26 | return color; 27 | } 28 | 29 | module.exports = { 30 | getColor: getColor, 31 | getItemStyle: function(item, checkedValue, activeColor) { 32 | var padding = item.padding * 10; 33 | var style = 'padding-left: ' + padding + 'px;'; 34 | 35 | // 如果为选中状态,则高亮 36 | if (item.value === checkedValue) { 37 | style += 'color: ' + getColor(activeColor); 38 | } 39 | 40 | return style; 41 | } 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/select/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-select__list .zan-select__radio{display:none} -------------------------------------------------------------------------------- /resources/miniprogram/dist/stepper/index.js: -------------------------------------------------------------------------------- 1 | function handle(e, num) { 2 | var dataset = e.currentTarget.dataset; 3 | var componentId = dataset.componentId; 4 | var disabled = dataset.disabled; 5 | var stepper = +dataset.stepper; 6 | 7 | if (disabled) return null; 8 | 9 | callback.call(this, componentId, stepper + num); 10 | } 11 | 12 | function callback(componentId, stepper) { 13 | stepper = +stepper; 14 | var e = { componentId, stepper }; 15 | 16 | 17 | if (this.handleZanStepperChange) { 18 | this.handleZanStepperChange(e); 19 | } else { 20 | console.warn('页面缺少 handleZanStepperChange 回调函数'); 21 | } 22 | } 23 | 24 | var Stepper = { 25 | _handleZanStepperMinus(e) { 26 | handle.call(this, e, -1); 27 | }, 28 | 29 | _handleZanStepperPlus(e) { 30 | handle.call(this, e, +1); 31 | }, 32 | 33 | _handleZanStepperBlur(e) { 34 | var dataset = e.currentTarget.dataset; 35 | var componentId = dataset.componentId; 36 | var max = +dataset.max; 37 | var min = +dataset.min; 38 | var value = e.detail.value; 39 | 40 | if (!value) { 41 | setTimeout(() => { 42 | callback.call(this, componentId, min); 43 | }, 16); 44 | callback.call(this, componentId, value); 45 | return '' + value; 46 | } 47 | 48 | value = +value; 49 | if (value > max) { 50 | value = max; 51 | } else if (value < min) { 52 | value = min; 53 | } 54 | 55 | callback.call(this, componentId, value); 56 | 57 | return '' + value; 58 | } 59 | }; 60 | 61 | module.exports = Stepper; 62 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/stepper/index.wxml: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/stepper/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-stepper{color:#666}.zan-stepper 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-stepper .zan-stepper__minus{border-right:none;border-radius:2px 0 0 2px}.zan-stepper .zan-stepper__text{border:1rpx solid #999;display:inline-block;text-align:center;vertical-align:middle;height:30px;width:40px;min-height:auto;font-size:12px;line-height:30px}.zan-stepper .zan-stepper__plus{border-left:none;border-radius:0 2px 2px 0}.zan-stepper .zan-stepper--disabled{background:#f8f8f8;color:#bbb;border-color:#e8e8e8}.zan-stepper--small view{min-width:36px;line-height:18px}.zan-stepper--small .zan-stepper__text{width:36px;line-height:28px;height:28px} -------------------------------------------------------------------------------- /resources/miniprogram/dist/steps/index.wxml: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/steps/index.wxss: -------------------------------------------------------------------------------- 1 | .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:0;top:32px;width:100%;height:1px;background-color:#e5e5e5}.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}.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}.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:#4b0}.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} -------------------------------------------------------------------------------- /resources/miniprogram/dist/steps/wxss/step.wxss: -------------------------------------------------------------------------------- 1 | .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:0;top:32px;width:100%;height:1px;background-color:#e5e5e5}.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}.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}.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} -------------------------------------------------------------------------------- /resources/miniprogram/dist/steps/wxss/vstep.wxss: -------------------------------------------------------------------------------- 1 | .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:#4b0}.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} -------------------------------------------------------------------------------- /resources/miniprogram/dist/switch/index.js: -------------------------------------------------------------------------------- 1 | var Switch = { 2 | _handleZanSwitchChange(e) { 3 | var dataset = e.currentTarget.dataset; 4 | 5 | var checked = !dataset.checked; 6 | var loading = dataset.loading; 7 | var disabled = dataset.disabled; 8 | var componentId = dataset.componentId; 9 | 10 | if (loading || disabled) return; 11 | 12 | 13 | 14 | if (this.handleZanSwitchChange) { 15 | this.handleZanSwitchChange({ 16 | checked, 17 | componentId 18 | }); 19 | } else { 20 | console.warn('页面缺少 handleZanSwitchChange 回调函数'); 21 | } 22 | } 23 | }; 24 | 25 | module.exports = Switch; 26 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/switch/index.wxml: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/switch/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-switch { 2 | position: relative; 3 | display: inline-block; 4 | width: 52px; 5 | height: 32px; 6 | vertical-align: middle; 7 | box-sizing: border-box; 8 | border-radius: 16px; 9 | background: #44db5e; 10 | border: 1px solid #44db5e; 11 | } 12 | 13 | .zan-switch__circle { 14 | position: absolute; 15 | top: 0; 16 | left: 0; 17 | width: 30px; 18 | height: 30px; 19 | display: inline-block; 20 | background: #fff; 21 | border-radius: 15px; 22 | box-sizing: border-box; 23 | box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1), 24 | 0 3px 1px 0 rgba(0, 0, 0, 0.05), 25 | 0 2px 2px 0 rgba(0, 0, 0, 0.1), 26 | 0 3px 3px 0 rgba(0, 0, 0, 0.05); 27 | transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1); 28 | z-index: 2; 29 | } 30 | 31 | .zan-switch__bg { 32 | position: absolute; 33 | top: -1px; 34 | left: -1px; 35 | width: 52px; 36 | height: 32px; 37 | background: #fff; 38 | border-radius: 26px; 39 | display: inline-block; 40 | border: 1px solid #e5e5e5; 41 | box-sizing: border-box; 42 | transition: transform 0.35s cubic-bezier(0.45, 1, 0.4, 1); 43 | transform: scale(0); 44 | transform-origin: 36px 16px; 45 | } 46 | 47 | .zan-switch--on .zan-switch__circle { 48 | transform: translateX(20px); 49 | } 50 | 51 | .zan-switch--off .zan-switch__bg { 52 | transform: scale(1); 53 | } 54 | 55 | .zan-swtich--disabled { 56 | opacity: 0.4; 57 | } 58 | 59 | .zan-switch__loading { 60 | position: absolute; 61 | left: 7px; 62 | top: 7px; 63 | width: 16px; 64 | height: 16px; 65 | background: url(https://img.yzcdn.cn/public_files/2017/02/24/9acec77d91106cd15b8107c4633d9155.png) no-repeat; 66 | background-size: 16px 16px; 67 | animation: zan-switch-loading 0.8s infinite linear; 68 | } 69 | 70 | @keyframes zan-switch-loading { 71 | from { 72 | transform: rotate(0); 73 | } 74 | 75 | to { 76 | transform: rotate(360deg); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/tab/index.js: -------------------------------------------------------------------------------- 1 | const { extractComponentId } = require('../common/helper'); 2 | 3 | var Tab = { 4 | _handleZanTabChange(e) { 5 | const componentId = extractComponentId(e); 6 | const dataset = e.currentTarget.dataset; 7 | const selectedId = dataset.itemId; 8 | const data = { componentId, selectedId }; 9 | 10 | 11 | if (this.handleZanTabChange) { 12 | this.handleZanTabChange(data); 13 | } else { 14 | console.warn('页面缺少 handleZanTabChange 回调函数'); 15 | } 16 | } 17 | }; 18 | 19 | module.exports = Tab; 20 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/tab/index.wxml: -------------------------------------------------------------------------------- 1 | 25 | 26 | 38 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/tab/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-tab { 2 | height: 45px; 3 | } 4 | 5 | .zan-tab__bd { 6 | width: 750rpx; 7 | display: flex; 8 | flex-direction: row; 9 | border-bottom: 1rpx solid #e5e5e5; 10 | background: #fff; 11 | } 12 | 13 | .zan-tab__bd--fixed { 14 | position: fixed; 15 | top: 0; 16 | z-index: 2; 17 | } 18 | 19 | .zan-tab__item { 20 | flex: 1; 21 | display: inline-block; 22 | padding: 0 10px; 23 | line-height: 0; 24 | box-sizing: border-box; 25 | overflow: hidden; 26 | text-align: center; 27 | } 28 | 29 | .zan-tab__title { 30 | display: inline-block; 31 | max-width: 100%; 32 | height: 44px; 33 | line-height: 44px; 34 | overflow: hidden; 35 | text-overflow: ellipsis; 36 | box-sizing: border-box; 37 | word-break: keep-all; 38 | font-size: 14px; 39 | color: #666; 40 | } 41 | 42 | .zan-tab__item--selected .zan-tab__title { 43 | color: #f44; 44 | border-bottom: 2px solid #f44; 45 | } 46 | 47 | .zan-tab__bd--scroll { 48 | display: block; 49 | white-space: nowrap; 50 | } 51 | 52 | .zan-tab__bd--scroll .zan-tab__item { 53 | min-width: 70px; 54 | } 55 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/tag/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-tag{display:inline-block;position:relative;box-sizing:border-box;line-height:16px;padding:0 5px;border-radius:2px;font-size:11px;background:#c9c9c9;text-align:center;color:#fff}.zan-tag::after{content:'';position:absolute;top:0;left:0;width:200%;height:200%;transform:scale(.5);transform-origin:0 0;pointer-events:none;box-sizing:border-box;border:0 solid #e5e5e5;border-width:1px;border-radius:4px}.zan-tag--plain{color:#c9c9c9;background:#fff}.zan-tag--primary{color:#fff;background-color:#4b0}.zan-tag--primary::after{border-color:#4b0}.zan-tag--primary.zan-tag--plain{color:#4b0;background:#fff}.zan-tag--danger{color:#fff;background:#f44}.zan-tag--danger::after{border-color:#f44}.zan-tag--danger.zan-tag--plain{color:#f44;background:#fff}.zan-tag--warn{color:#fff;background:#f85}.zan-tag--warn::after{border-color:#f85}.zan-tag--warn.zan-tag--plain{color:#f85;background:#fff}.zan-tag--disabled{color:#999!important;background:#e5e5e5}.zan-tag--disabled::after{border-color:#ccc} -------------------------------------------------------------------------------- /resources/miniprogram/dist/toast/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | showZanToast(title, timeout) { 3 | const options = formatParameter(title, timeout); 4 | 5 | // 清除上一轮的计时器 6 | const { timer = 0 } = this.data.zanToast || {}; 7 | clearTimeout(timer); 8 | 9 | // 弹层设置~ 10 | const zanToast = { 11 | show: true, 12 | icon: options.icon, 13 | image: options.image, 14 | title: options.title 15 | }; 16 | this.setData({ 17 | zanToast 18 | }); 19 | 20 | // 传入的显示时长小于0,就认为需要一直显示 21 | if (timeout < 0) { 22 | return; 23 | } 24 | 25 | // 下一轮计时器 26 | const nextTimer = setTimeout(() => { 27 | this.clearZanToast(); 28 | }, timeout || 3000); 29 | 30 | this.setData({ 31 | 'zanToast.timer': nextTimer 32 | }); 33 | }, 34 | 35 | // 清除所有 toast 36 | clearZanToast() { 37 | const { timer = 0 } = this.data.zanToast || {}; 38 | clearTimeout(timer); 39 | 40 | this.setData({ 41 | 'zanToast.show': false 42 | }); 43 | }, 44 | 45 | // 快捷方法,显示 loading 46 | showZanLoading(title) { 47 | const options = formatParameter(title); 48 | 49 | this.showZanToast({ 50 | ...options, 51 | icon: 'loading' 52 | }); 53 | } 54 | }; 55 | 56 | function formatParameter(title, timeout = 0) { 57 | // 如果传入的 title 是对象,那么认为所有的配置属性都在这个对象中了 58 | if (typeof title === 'object') { 59 | return title; 60 | } 61 | 62 | return { 63 | title, 64 | timeout 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/toast/index.wxml: -------------------------------------------------------------------------------- 1 | 32 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/toast/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-toast{position:fixed;top:35%;left:50%;transform:translate3d(-50%,-50%,0);background:rgba(0,0,0,.7);color:#fff;font-size:14px;line-height:1.5em;margin:0 auto;box-sizing:border-box;padding:10px 18px;text-align:center;border-radius:4px;z-index:100}.zan-toast--notitle{padding:18px}.zan-toast__icon{width:40px;height:40px;line-height:40px;margin:0 auto;padding:12px 15px;font-size:38px;text-align:center}.zan-toast__icon-loading{line-height:0}.zan-toast__icon-loading .zan-loading{width:40px;height:40px}.zan-toast__icon-image{background-size:40px;background-position:center;background-repeat:no-repeat} -------------------------------------------------------------------------------- /resources/miniprogram/dist/toptips/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | showZanTopTips(content = '', options = {}) { 3 | let zanTopTips = this.data.zanTopTips || {}; 4 | // 如果已经有一个计时器在了,就清理掉先 5 | if (zanTopTips.timer) { 6 | clearTimeout(zanTopTips.timer); 7 | zanTopTips.timer = 0; 8 | } 9 | 10 | if (typeof options === 'number') { 11 | options = { 12 | duration: options 13 | }; 14 | } 15 | 16 | // options参数默认参数扩展 17 | options = Object.assign({ 18 | duration: 3000 19 | }, options); 20 | 21 | // 设置定时器,定时关闭topTips 22 | let timer = setTimeout(() => { 23 | this.setData({ 24 | 'zanTopTips.show': false, 25 | 'zanTopTips.timer': 0 26 | }); 27 | }, options.duration); 28 | 29 | // 展示出topTips 30 | this.setData({ 31 | zanTopTips: { 32 | show: true, 33 | content, 34 | options, 35 | timer 36 | } 37 | }); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/toptips/index.wxml: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /resources/miniprogram/dist/toptips/index.wxss: -------------------------------------------------------------------------------- 1 | .zan-toptips{display:block;position:fixed;-webkit-transform:translateZ(0) 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;opacity:0;transition:all .4s ease}.zan-toptips--show{-webkit-transform:translateZ(0) translateY(0);opacity:1} -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/collect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/collect.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/collected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/collected.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/gravatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/gravatar.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/like.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/liked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/liked.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/poster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/poster.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/reward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/reward.png -------------------------------------------------------------------------------- /resources/miniprogram/images/icon/share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/icon/share.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/about.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/about_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/about_click.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/home.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/home_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/home_click.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/like.png -------------------------------------------------------------------------------- /resources/miniprogram/images/tabbar/like_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CavinCao/ghost-wechat-blog/5c4f8793f12a2420bdf4c26aedff05df7e87c0a2/resources/miniprogram/images/tabbar/like_click.png -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_me.js: -------------------------------------------------------------------------------- 1 | 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | email:'cavincao2005@163.com', 9 | wechat:'bug生活2048', 10 | selfwechat:'wuxinxiake123', 11 | github:'https://github.com/CavinCao', 12 | weibo:'https://www.weibo.com/bug2048' 13 | }, 14 | 15 | /** 16 | * 生命周期函数--监听页面加载 17 | */ 18 | onLoad: function (options) { 19 | 20 | }, 21 | formSubmit: function (e) { 22 | let that = this; 23 | if (e.detail != undefined && e.detail.formId != undefined) { 24 | console.log(e.detail.formId) 25 | } 26 | }, 27 | copyDataTap:function(e){ 28 | var data = e.target.dataset.index 29 | wx.setClipboardData({ 30 | data: data, 31 | success: function (res) { 32 | wx.getClipboardData({ 33 | success: function (res) { 34 | console.log(res.data) 35 | } 36 | }) 37 | } 38 | }) 39 | } 40 | }) -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_me.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_me.wxml: -------------------------------------------------------------------------------- 1 | 2 | 关于我 3 | 4 | 5 | 普通程序员一枚,没有高深的技术,有一颗学习的心。 6 | 喜欢周杰伦,喜欢火影,喜欢Dota,喜欢盗墓笔记。 7 | 很想脱离世俗,也想财务自由,无奈现实残酷,生活所迫,注定做个平凡人。\n 8 | 很想分享些什么,无奈知识有限。 9 | 很想记录些什么,无奈文笔有限。 10 | 但终究还是想写点什么,毕竟记忆力有限。 11 | 12 | 13 | 14 | 15 | 联系我 16 | 17 | 18 | 邮箱: 19 | {{email}} 20 | 21 | 22 | 微信公众号: 23 | {{wechat}} 24 | 25 | 26 | 个人微信号: 27 | {{selfwechat}} 28 | 29 | 30 | github: 31 | {{github}} 32 | 33 | 34 | 新浪微博: 35 | {{weibo}} 36 | 37 | 38 | -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_me.wxss: -------------------------------------------------------------------------------- 1 | /* pages/about/about_me.wxss */ 2 | 3 | .zan-text-underline { 4 | text-decoration: underline; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_wechat.js: -------------------------------------------------------------------------------- 1 | // pages/about/about_wechat.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | 9 | }, 10 | 11 | /** 12 | * 生命周期函数--监听页面加载 13 | */ 14 | onLoad: function (options) { 15 | 16 | }, 17 | 18 | /** 19 | * 生命周期函数--监听页面初次渲染完成 20 | */ 21 | onReady: function () { 22 | 23 | }, 24 | 25 | /** 26 | * 生命周期函数--监听页面显示 27 | */ 28 | onShow: function () { 29 | 30 | }, 31 | 32 | /** 33 | * 生命周期函数--监听页面隐藏 34 | */ 35 | onHide: function () { 36 | 37 | }, 38 | 39 | /** 40 | * 生命周期函数--监听页面卸载 41 | */ 42 | onUnload: function () { 43 | 44 | }, 45 | 46 | /** 47 | * 页面相关事件处理函数--监听用户下拉动作 48 | */ 49 | onPullDownRefresh: function () { 50 | 51 | }, 52 | 53 | /** 54 | * 页面上拉触底事件的处理函数 55 | */ 56 | onReachBottom: function () { 57 | 58 | }, 59 | 60 | /** 61 | * 用户点击右上角分享 62 | */ 63 | onShareAppMessage: function () { 64 | 65 | } 66 | }) -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_wechat.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_wechat.wxml: -------------------------------------------------------------------------------- 1 | 2 | 关于这里 3 | 4 | 5 | 只是学习过程中的一个寄托,一个港湾,一个承载学习过程的地方。 6 | 与需要的人分享,与一起奋斗的人共勉。 7 | 8 | 9 | 10 | 11 | Bug生活2048由来 12 | 13 | 14 | 其实没有啥由来,作为程序猿,第一个想到的就是bug,后来用bug开头找域名,发现bug1024被人注册了,然后就找到bug2048了,后来就有了bug生活2048这个名字。 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /resources/miniprogram/pages/about/about_wechat.wxss: -------------------------------------------------------------------------------- 1 | /* pages/about/about_wechat.wxss */ -------------------------------------------------------------------------------- /resources/miniprogram/pages/collected/collected.js: -------------------------------------------------------------------------------- 1 | const util = require('../../utils/util.js'); 2 | var Zan = require('../../dist/index'); 3 | 4 | Page(Object.assign({}, Zan.Dialog, { 5 | data: { 6 | posts: [], 7 | loading: false, 8 | nodata: false, 9 | nomore: false, 10 | showName: '浏览日期:', 11 | defaultImageUrl: getApp().globalData.defaultImageUrl + getApp().globalData.imageStyle200To200 12 | }, 13 | onLoad: function (options) { 14 | var gotoType = options.gotoType; 15 | var content = ''; 16 | var isShowContent = wx.getStorageSync('isShowContent_' + gotoType); 17 | if (gotoType == 'recent') { 18 | wx.setNavigationBarTitle({ 19 | title: '最近浏览' 20 | }) 21 | this.setData({ 22 | showName: '浏览日期:' 23 | }); 24 | content = '容量有限,只能展示最近30条浏览记录哟'; 25 | this.getData(gotoType); 26 | } 27 | else { 28 | wx.setNavigationBarTitle({ 29 | title: '我的收藏' 30 | }) 31 | this.setData({ 32 | showName: '收藏日期:' 33 | }); 34 | content = '容量有限,只能展示最近30条收藏记录哟'; 35 | this.getData(gotoType); 36 | } 37 | if (isShowContent!=1) { 38 | this.showZanDialog({ 39 | title: '友情提示', 40 | content: content, 41 | buttons: [{ 42 | text: '确定', 43 | color: '#3CC51F', 44 | type: 'submit' 45 | }, { 46 | text: '不再提示', 47 | type: 'cancel' 48 | }] 49 | }).then(({ type }) => { 50 | if (type == 'cancel') { 51 | wx.setStorageSync('isShowContent_' + gotoType, 1); 52 | } 53 | }); 54 | } 55 | }, 56 | //事件处理函数 57 | bindItemTap: function (e) { 58 | let blogId = e.currentTarget.id; 59 | wx.navigateTo({ 60 | url: '../detail/detail?blogId=' + blogId 61 | }) 62 | }, 63 | //图片加载失败给到默认图片 64 | errorloadImage: function (e) { 65 | if (e.type == "error") { 66 | var index = e.target.dataset.index 67 | var posts = this.data.posts 68 | posts[index].imageUrl = this.data.defaultImageUrl 69 | this.setData({ 70 | posts: posts 71 | }) 72 | } 73 | }, 74 | getData: function (gotoType) { 75 | let that = this; 76 | var postsRecent = gotoType == 'recent' ? wx.getStorageSync('posts_Recent') : wx.getStorageSync('posts_CollectedDetail'); 77 | if (postsRecent) { 78 | var posts = []; 79 | if (Object.getOwnPropertyNames(postsRecent).length > 0) { 80 | for (var item in postsRecent) { 81 | var post = {}; 82 | post['id'] = item; 83 | post['title'] = postsRecent[item]['title']; 84 | post['imageUrl'] = postsRecent[item]['imageUrl']; 85 | post['created_at'] = postsRecent[item]['time']; 86 | posts.push(post); 87 | } 88 | that.setData({ 89 | posts: posts.reverse(), 90 | nodata: false, 91 | nomore: true 92 | }) 93 | } 94 | else { 95 | that.setData({ 96 | nodata: true, 97 | nomore: false 98 | }) 99 | } 100 | } 101 | else { 102 | that.setData({ 103 | nodata: true, 104 | nomore: false 105 | }) 106 | } 107 | } 108 | })); 109 | -------------------------------------------------------------------------------- /resources/miniprogram/pages/collected/collected.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /resources/miniprogram/pages/collected/collected.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {{item.title}} 18 | 19 | 20 | 21 | 22 | 23 | {{showName}} 24 | 25 | {{item.created_at}} 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |