├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── app.js
├── app.json
├── app.wxss
├── config.js
├── demo
└── diaries.js
├── files
└── preview.gif
├── images
├── icons
│ ├── add.png
│ ├── collect.png
│ ├── collectHL.png
│ ├── comment.png
│ ├── compose.png
│ ├── composeHL.png
│ ├── like.png
│ ├── likeHL.png
│ ├── mark.png
│ ├── markHL.png
│ ├── mine.png
│ ├── mineHL.png
│ ├── more.png
│ ├── moreHL.png
│ ├── poi.png
│ ├── strategy.png
│ ├── strategyHL.png
│ └── user_privatemsg.png
├── nav
│ ├── comment.png
│ ├── download.png
│ ├── fav.png
│ └── share.png
└── tabbar
│ ├── Plus Math.png
│ ├── add.png
│ ├── cancel.png
│ ├── image.png
│ ├── more.png
│ ├── ok.png
│ └── text.png
├── pages
├── entry
│ ├── entry.js
│ ├── entry.wxml
│ └── entry.wxss
├── list
│ ├── list.js
│ ├── list.wxml
│ └── list.wxss
├── mine
│ ├── mine.js
│ ├── mine.wxml
│ └── mine.wxss
└── new
│ ├── new.js
│ ├── new.wxml
│ └── new.wxss
├── services
├── geo.js
└── request.js
└── utils
├── input.js
└── util.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 2016-10-12
2 |
3 | * 更新开发者工具至`v0.10.101100`
4 | * 修改`new`页的数据绑定方式 & 修改多行文本框输入时的bug
5 |
6 | # 2016-10-13
7 |
8 | * 完善日志编辑页
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 小闹钟
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 |
3 | ## 关于 ##
4 |
5 | * 我是一名后端程序员,做这个仅仅是因为觉得微信小程序好玩;
6 | * 没有明确的产品意图,东抄抄西抄抄只是为了验证和学习微信小程序;
7 | * 大体是想做一个个人/家庭日常记录的app;
8 | * 持续开发中,有兴趣请持续关注
9 |
10 | ## 预览 ##
11 |
12 | * 概览
13 |
14 |
15 |
16 |
17 |
18 | ## 功能特点 ##
19 |
20 | * 功能完备,实用导向
21 | * Server端API支持
22 | * 涵盖众多组件、API使用,适用于学习微信小程序
23 | * 多行文本模拟实现
24 | * tab切换
25 | * 模态框
26 | * 本地数据组织及存储
27 | * 图片预览功能
28 |
29 | ## 使用步骤
30 |
31 | 1. 克隆代码:
32 |
33 | ```bash
34 | $ cd path/to/your/workspace
35 | $ git clone https://github.com/harveyqing/BearDiary.git
36 | ```
37 |
38 | 2. 打开`微信Web开放者工具`(注意:须`v0.10.101100`及以上版本)
39 |
40 | 3. 添加项目
41 |
42 | * AppID:选`无AppID`
43 | * 项目名称:任意填写
44 | * 项目目录:path/to/your/workspace
45 | * 点击 `添加项目`
46 |
47 | ## 开发计划 ##
48 |
49 | - [ ] 开发server端API接口
50 | - [ ] 完成日记撰写页
51 | - [ ] 添加评论、喜欢、收藏功能
52 | - [ ] 规范`coding style`
53 |
54 | ## 小程序开发相关资源 ##
55 |
56 | ### 开发者工具下载 ###
57 |
58 | > 最新版本 0.10.101100
59 |
60 | - [windows 64](https://servicewechat.com/wxa-dev-logic/download_redirect?type=x64&from=mpwiki&t=1476434677599)
61 | - [windows 32](https://servicewechat.com/wxa-dev-logic/download_redirect?type=ia32&from=mpwiki&t=1476434677599)
62 | - [mac](https://servicewechat.com/wxa-dev-logic/download_redirect?type=darwin&from=mpwiki&t=1476434677599)
63 |
64 | ### 开发者文档 ###
65 |
66 | - [微信官方文档](https://mp.weixin.qq.com/debug/wxadoc/dev/)
67 |
68 | ### 最好的资源集 ###
69 |
70 | - [justjavac/awesome-wechat-weapp](https://github.com/justjavac/awesome-wechat-weapp)
71 |
72 | ## Anyway, 欢迎PR ##
73 |
74 | ## LICENSE ##
75 |
76 | [MIT](./LICENSE)
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | // app.js
2 |
3 | const config = require('config');
4 | const diaries = require('demo/diaries');
5 |
6 | App({
7 |
8 | onLaunch: function () {
9 | },
10 |
11 | // 获取用户信息
12 | getUserInfo: function(cb) {
13 | var that = this;
14 |
15 | if (this.globalData.userInfo) {
16 | typeof cb == 'function' && cb(this.globalData.userInfo)
17 | } else {
18 | // 先登录
19 | wx.login({
20 | success: function() {
21 | wx.getUserInfo({
22 | success: (res) => {
23 | that.globalData.userInfo = res.userInfo;
24 | typeof cb == 'function' && cb(that.globalData.userInfo)
25 | }
26 | })
27 | }
28 | })
29 | }
30 | },
31 |
32 | // 获取本地全部日记列表
33 | getDiaryList(cb) {
34 | var that = this;
35 |
36 | if (this.globalData.diaryList) {
37 | typeof cb == 'function' && cb(this.globalData.diaryList);
38 | } else {
39 | let list = [];
40 |
41 | this.getLocalDiaries(storage => {
42 | // 本地缓存数据
43 | for (var k in storage) {
44 | list.push(storage[k]);
45 | }
46 | });
47 |
48 | // 本地假数据
49 | list.push(...diaries.diaries);
50 | that.globalData.diaryList = list;
51 | typeof cb == 'function' && cb(that.globalData.diaryList)
52 | }
53 | },
54 |
55 | // 获取本地日记缓存
56 | getLocalDiaries(cb) {
57 | var that = this;
58 |
59 | if (this.globalData.localDiaries) {
60 | typeof cb == 'function' && cb(this.globalData.localDiaries);
61 | } else {
62 | wx.getStorage({
63 | key: config.storage.diaryListKey,
64 | success: (res) => {
65 | that.globalData.localDiaries = res.data;
66 | typeof cb == 'function' && cb(that.globalData.localDiaries);
67 | },
68 | fail: (error) => {
69 | that.globalData.localDiaries = {};
70 | typeof cb == 'function' && cb(that.globalData.localDiaries);
71 | }
72 | });
73 | }
74 | },
75 |
76 | // 获取当前设备信息
77 | getDeviceInfo: function(callback) {
78 | var that = this;
79 |
80 | if (this.globalData.deviceInfo) {
81 | typeof callback == "function" && callback(this.globalData.deviceInfo)
82 | } else {
83 | wx.getSystemInfo({
84 | success: function(res) {
85 | that.globalData.deviceInfo = res;
86 | typeof callback == "function" && callback(that.globalData.deviceInfo)
87 | }
88 | })
89 | }
90 | },
91 |
92 | globalData: {
93 | // 设备信息,主要用于获取屏幕尺寸而做适配
94 | deviceInfo: null,
95 |
96 | // 本地日记缓存列表 + 假数据
97 | // TODO 真实数据同步至服务端,本地只做部分缓存
98 | diaryList: null,
99 |
100 | // 本地日记缓存
101 | localDiaries: null,
102 |
103 | // 用户信息
104 | userInfo: null,
105 | }
106 |
107 | })
108 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/list/list",
4 | "pages/mine/mine",
5 | "pages/new/new",
6 | "pages/entry/entry"
7 | ],
8 | "window":{
9 | "backgroundTextStyle": "light",
10 | "navigationBarBackgroundColor": "#39b5de",
11 | "navigationBarTitleText": "小熊の日记",
12 | "navigationBarTextStyle": "white",
13 | "backgroundColor": "#eceff4"
14 | },
15 | "tabBar": {
16 | "color": "#858585",
17 | "selectedColor": "#39b5de",
18 | "backgroundColor": "#ffffff",
19 | "borderStyle": "black",
20 | "list":[
21 | {
22 | "pagePath": "pages/list/list",
23 | "iconPath": "images/icons/mark.png",
24 | "selectedIconPath": "images/icons/markHL.png",
25 | "text": "印记"
26 | },
27 | {
28 | "pagePath": "pages/mine/mine",
29 | "iconPath": "images/icons/mine.png",
30 | "selectedIconPath": "images/icons/mineHL.png",
31 | "text": "我的"
32 | }
33 | ]
34 | },
35 | "debug": true
36 | }
37 |
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /**
2 | app.wxss
3 | 全局样式
4 | **/
5 |
6 | page {
7 | width: 100%;
8 | height: 100%;
9 | padding: 0;
10 | background-color: #eceff4;
11 | font-size: 30rpx;
12 | font-family: -apple-system-font, 'Helvetica Neue', Helvetica, 'Microsoft YaHei', sans-serif;
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | // 全局配置
2 |
3 | module.exports = {
4 | /** 腾讯地图 **/
5 | map: {
6 | baseUrl: 'https://apis.map.qq.com/ws',
7 | key: '2TCBZ-IM7K5-XHCIZ-QXLRT-CIT4J-DEFSM',
8 | },
9 |
10 | /** 输入框控件设置 **/
11 | input: {
12 | charWidth: 14, // 单个字符的宽度,in rpx
13 | },
14 |
15 | /** 本地存储 **/
16 | // TODO 数据通过API全部存储于服务端
17 | storage: {
18 | diaryListKey: 'bearDiaryList',
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/demo/diaries.js:
--------------------------------------------------------------------------------
1 | var diaries = [
2 | {
3 | meta: { // 内容元数据
4 | cover: "http://m.chanyouji.cn/index-cover/64695-2679221.jpg?imageView2/1/w/620/h/330/format/jpg",
5 | avatar: "https://pic4.zhimg.com/e515adf3b_xl.jpg",
6 | title: "此刻静好,愿幸福长存",
7 | meta: "2016.10.17",
8 | create_time: "2016.10.18 11:57:27",
9 | nickName: "肥肥的小狗熊",
10 | },
11 | list: [
12 | {
13 | type: "TEXT",
14 | content: '9月11日,15年的911事件使这天蒙上了特殊的意义。2016年的这一天,怀着激动的心情,开启了高原寻秘之旅,向着那圣洁之地出发。全程自驾近2000公里,雨崩徒步80公里,完成觐见之旅。',
15 | poi: {
16 | longitude: 117.2,
17 | latitude: 37.5,
18 | name: "北京市",
19 | },
20 | description: "",
21 | id: 1,
22 | commentNum: 0,
23 | likeNum: 0,
24 | },
25 | {
26 | type: "IMAGE",
27 | content: 'http://p.chanyouji.cn/1473699595/1740E45C-D5AF-497E-A351-06E5BA22B1A3.jpg',
28 | poi: {
29 | longitude: 117.2,
30 | latitude: 37.5,
31 | name: "深圳市",
32 | },
33 | description: "深圳宝安国际机场",
34 | id: 2,
35 | commentNum: 1,
36 | likeNum: 5,
37 | },
38 | {
39 | type: "IMAGE",
40 | content: 'http://p.chanyouji.cn/1473699603/7C3B253F-0A31-4754-B042-E04115F2C931.jpg',
41 | poi: {
42 | longitude: 117.2,
43 | latitude: 37.5,
44 | name: "丽江三义机场",
45 | },
46 | description: "丽江三义机场",
47 | id: 2,
48 | commentNum: 1,
49 | likeNum: 5,
50 | },
51 | {
52 | type: "TEXT",
53 | content: ' 玉水寨在白沙溪镇,是纳西族中部地区的东巴圣地,是丽江古城的溯源。\n\nTips:门票50元/人,游玩时间2小时。',
54 | poi: {
55 | longitude: 117.2,
56 | latitude: 37.5,
57 | name: "玉水寨",
58 | },
59 | description: "",
60 | id: 1,
61 | commentNum: 0,
62 | likeNum: 0,
63 | },
64 | {
65 | type: "IMAGE",
66 | content: 'http://p.chanyouji.cn/1473685830/2A48B40F-1F11-498D-ABD2-B0EDCD09F776.jpg',
67 | poi: {
68 | longitude: 117.2,
69 | latitude: 37.5,
70 | name: "玉水寨",
71 | },
72 | description: "阳光下的玉水寨",
73 | id: 2,
74 | commentNum: 1,
75 | likeNum: 5,
76 | },
77 | {
78 | type: "VIDEO",
79 | content: 'http://flv.bn.netease.com/videolib3/1605/22/auDfZ8781/HD/auDfZ8781-mobile.mp4',
80 | poi: {
81 | longitude: 117.2,
82 | latitude: 37.5,
83 | name: "深圳宝安国际机场",
84 | },
85 | description: "",
86 | id: 2,
87 | commentNum: 10,
88 | likeNum: 200,
89 | },
90 | ]
91 | },
92 | {
93 | meta: { // 内容元数据
94 | cover: "http://m.chanyouji.cn/articles/625/ca9e50f74e273041e3a399bf5528f7b5.jpg?imageView2/1/w/620/h/330/format/jpg",
95 | avatar: "https://pic4.zhimg.com/e515adf3b_xl.jpg",
96 | title: "梦想实现的地方-马达加斯加第二季",
97 | meta: "2013.8.10",
98 | create_time: "2016.10.18 11:57:27",
99 | nickName: "小闹钟",
100 | },
101 | list: [
102 | {
103 | type: "TEXT",
104 | content: '2012年十一,我和朋友一行五人第一次登上这个被非洲大陆抛弃的岛屿,看到了可爱的狐猴,憨态可掬的变色龙,明信片一样的猴面包树,天真的孩子淳朴的人民,结识了我们生命中一个重要的朋友导游小温(可以加地接小温QQ或微信咨询:109300820),从此,我们爱上了这片土地。马达加斯加是一个海岛,一年分成旱季和雨季,没有特别的低温或者高温季节,几乎全年都适合旅游,只是观赏的重点略有不同而已。 \n导游小温向我们介绍,在这里,每年的7月到9月,可以近距离观看座头鲸,于是,我们从那时开始期待这个夏季的到来。',
105 | poi: {
106 | longitude: 117.2,
107 | latitude: 37.5,
108 | name: "塔那那利佛",
109 | },
110 | description: "",
111 | id: 1,
112 | commentNum: 0,
113 | likeNum: 0,
114 | },
115 | {
116 | type: "TEXT",
117 | content: '第一天 8月10日 天气晴\n\n长时间的飞行,多少会有一些枯燥,然而只要你愿意,依然可以看到心中的那片风景。 \n嗨!别郁闷了,和我一起到三万英尺的高空来看云。 \n喜欢飞机起飞的刹那间,加速再加速直到脱离开地球的引力冲向自由的天空。喜欢像鸟一样俯视地面的视角,高高在上,笑看人间。 \n天,蓝,云,白。机窗外的云时而像珍珠点点,时而像棉絮团团。\n夕阳将至,云和机翼被镀上一层华丽的金。 \n金红色的阳光与蓝色的天空最终合成出一片淡淡的紫,绚丽而梦幻。',
118 | poi: {
119 | longitude: 117.2,
120 | latitude: 37.5,
121 | name: "塔那那利佛",
122 | },
123 | description: "",
124 | id: 1,
125 | commentNum: 0,
126 | likeNum: 0,
127 | },
128 | {
129 | type: "IMAGE",
130 | content: 'http://p.chanyouji.cn/64695/1377177446705p182j2oa9031j1p0b5vpuvj1voj2.jpg-o',
131 | poi: {
132 | longitude: 117.2,
133 | latitude: 37.5,
134 | name: "塔那那利佛",
135 | },
136 | description: "",
137 | id: 2,
138 | commentNum: 1,
139 | likeNum: 5,
140 | },
141 | ]
142 | }
143 | ]
144 |
145 | module.exports = {
146 | diaries: diaries,
147 | }
148 |
--------------------------------------------------------------------------------
/files/preview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/files/preview.gif
--------------------------------------------------------------------------------
/images/icons/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/add.png
--------------------------------------------------------------------------------
/images/icons/collect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/collect.png
--------------------------------------------------------------------------------
/images/icons/collectHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/collectHL.png
--------------------------------------------------------------------------------
/images/icons/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/comment.png
--------------------------------------------------------------------------------
/images/icons/compose.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/compose.png
--------------------------------------------------------------------------------
/images/icons/composeHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/composeHL.png
--------------------------------------------------------------------------------
/images/icons/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/like.png
--------------------------------------------------------------------------------
/images/icons/likeHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/likeHL.png
--------------------------------------------------------------------------------
/images/icons/mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/mark.png
--------------------------------------------------------------------------------
/images/icons/markHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/markHL.png
--------------------------------------------------------------------------------
/images/icons/mine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/mine.png
--------------------------------------------------------------------------------
/images/icons/mineHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/mineHL.png
--------------------------------------------------------------------------------
/images/icons/more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/more.png
--------------------------------------------------------------------------------
/images/icons/moreHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/moreHL.png
--------------------------------------------------------------------------------
/images/icons/poi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/poi.png
--------------------------------------------------------------------------------
/images/icons/strategy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/strategy.png
--------------------------------------------------------------------------------
/images/icons/strategyHL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/strategyHL.png
--------------------------------------------------------------------------------
/images/icons/user_privatemsg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/icons/user_privatemsg.png
--------------------------------------------------------------------------------
/images/nav/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/nav/comment.png
--------------------------------------------------------------------------------
/images/nav/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/nav/download.png
--------------------------------------------------------------------------------
/images/nav/fav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/nav/fav.png
--------------------------------------------------------------------------------
/images/nav/share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/nav/share.png
--------------------------------------------------------------------------------
/images/tabbar/Plus Math.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/Plus Math.png
--------------------------------------------------------------------------------
/images/tabbar/add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/add.png
--------------------------------------------------------------------------------
/images/tabbar/cancel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/cancel.png
--------------------------------------------------------------------------------
/images/tabbar/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/image.png
--------------------------------------------------------------------------------
/images/tabbar/more.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/more.png
--------------------------------------------------------------------------------
/images/tabbar/ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/ok.png
--------------------------------------------------------------------------------
/images/tabbar/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harveyqing/BearDiary/aee2bfa9f758268699591d319baadae5b4dd5626/images/tabbar/text.png
--------------------------------------------------------------------------------
/pages/entry/entry.js:
--------------------------------------------------------------------------------
1 | // entry.js
2 |
3 | const toolbar = [
4 | '../../images/nav/download.png', '../../images/nav/fav.png',
5 | '../../images/nav/share.png', '../../images/nav/comment.png',
6 | ];
7 | const app = getApp();
8 |
9 | Page({
10 | data: {
11 | // 当前日志详情
12 | diary: undefined,
13 |
14 | // 右上角工具栏
15 | toolbar: toolbar,
16 |
17 | // 图片预览模式
18 | previewMode: false,
19 |
20 | // 当前预览索引
21 | previewIndex: 0,
22 |
23 | // 多媒体内容列表
24 | mediaList: [],
25 | },
26 |
27 | // 加载日记
28 | getDiary(params) {
29 | console.log("Loading diary data...", params);
30 |
31 | var id = params["id"], diary;
32 | app.getDiaryList(list => {
33 | if (typeof id === 'undefined') {
34 | diary = list[0];
35 | } else {
36 | diary = list[id];
37 | }
38 | });
39 |
40 | this.setData({
41 | diary: diary,
42 | });
43 | },
44 |
45 | // 过滤出预览图片列表
46 | getMediaList() {
47 | if (typeof this.data.diary !== 'undefined' &&
48 | this.data.diary.list.length) {
49 | this.setData({
50 | mediaList: this.data.diary.list.filter(
51 | content => content.type === 'IMAGE'),
52 | })
53 | }
54 | },
55 |
56 | // 进入预览模式
57 | enterPreviewMode(event) {
58 | let url = event.target.dataset.src;
59 | let urls = this.data.mediaList.map(media => media.content);
60 | let previewIndex = urls.indexOf(url);
61 |
62 | this.setData({previewMode: true, previewIndex});
63 | },
64 |
65 | // 退出预览模式
66 | leavePreviewMode() {
67 | this.setData({previewMode: false, previewIndex: 0});
68 | },
69 |
70 | onLoad: function(params) {
71 | this.getDiary(params);
72 | this.getMediaList();
73 | },
74 |
75 | onHide: function() {
76 | },
77 | })
78 |
--------------------------------------------------------------------------------
/pages/entry/entry.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{content.content}}
8 |
9 |
10 |
11 |
12 | {{content.description}}
13 |
14 |
15 |
16 | {{content.description}}
17 |
18 |
19 |
20 |
21 |
22 |
23 |
37 |
38 |
39 |
40 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/pages/entry/entry.wxss:
--------------------------------------------------------------------------------
1 | /** item.wxss **/
2 |
3 | .container {
4 | font-size: 26rpx;
5 | }
6 |
7 | .header {
8 | height: 400rpx;
9 | }
10 |
11 | .toolbar {
12 | height: 60rpx;
13 | position: fixed;
14 | top: 0;
15 | right: 0;
16 | display: flex;
17 | flex-direction: row;
18 | justify-content: space-between;
19 | align-items: center;
20 | }
21 |
22 | .toolbar .item {
23 | width: 40rpx;
24 | height: 40rpx;
25 | margin: 10rpx 20rpx;
26 | }
27 |
28 | .title {
29 | height: 120rpx;
30 | position: absolute;
31 | top: 280rpx;
32 | }
33 |
34 | .title .avatar {
35 | margin: 20rpx;
36 | width: 80rpx;
37 | height: 80rpx;
38 | border-radius: 40rpx;
39 | float: left;
40 | }
41 |
42 | .title .desc {
43 | height: 100rpx;
44 | width: 630rpx;
45 | margin: 10rpx 0;
46 | float: right;
47 | color: white;
48 | display: flex;
49 | flex-direction: column;
50 | }
51 |
52 | .desc .item {
53 | height: 50%;
54 | padding: 12rpx 0;
55 | }
56 |
57 | .content {
58 | padding: 10rpx;
59 | border-bottom: 1px solid #E5E7ED;
60 | }
61 |
62 | .content .text {
63 | line-height: 42rpx;
64 | }
65 |
66 | .content .media {
67 | width: 730rpx;
68 | }
69 |
70 | .content .footer {
71 | height: 60rpx;
72 | margin-top: 10rpx;
73 | font-size:22rpx;
74 | color: #70899D;
75 | }
76 |
77 | .content .footer image {
78 | width: 20rpx;
79 | height: 20rpx;
80 | }
81 |
82 | .content .footer .left {
83 | display: inline-block;
84 | height: 40rpx;
85 | margin: 10rpx 0;
86 | }
87 |
88 | .content .footer .right {
89 | display: flex;
90 | justify-content: space-between;
91 | align-items: center;
92 | float: right;
93 | height: 40rpx;
94 | margin-left: 20rpx;
95 | background-color: #E5E7ED;
96 | font-size: 20rpx;
97 | }
98 |
99 | .content .footer .right image {
100 | margin: 10rpx;
101 | }
102 |
103 | .content .footer .right text {
104 | font-size: 20rpx;
105 | padding:10rpx 10rpx 10rpx 0;
106 | }
107 |
108 | #footer {
109 | width: 100%;
110 | height: 300rpx;
111 | display: flex;
112 | justify-content: center;
113 | align-items: center;
114 | }
115 |
116 | #footer .container {
117 | height: 100rpx;
118 | display: flex;
119 | flex-direction: column;
120 | justify-content: space-between;
121 | align-items: center;
122 | }
123 |
124 | #footer .container .item {
125 | height: 50%;
126 | display: flex;
127 | justify-content: center;
128 | align-items: center;
129 | }
130 |
131 | .swiper-container {
132 | position: fixed;
133 | left: 0;
134 | top: 0;
135 | width: 100%;
136 | height: 100%;
137 | background-color: #000;
138 | }
139 |
140 | .swiper-container image {
141 | width: 100%;
142 | height: 100%;
143 | }
144 |
--------------------------------------------------------------------------------
/pages/list/list.js:
--------------------------------------------------------------------------------
1 | // index.js
2 | // 日记聚合页
3 |
4 | const config = require("../../config");
5 |
6 | var app = getApp();
7 |
8 | Page({
9 |
10 | data: {
11 | // 日记列表
12 | // TODO 从server端拉取
13 | diaries: null,
14 |
15 | // 是否显示loading
16 | showLoading: false,
17 |
18 | // loading提示语
19 | loadingMessage: '',
20 | },
21 |
22 | /**
23 | * 生命周期函数--监听页面加载
24 | */
25 | onLoad() {
26 | this.getDiaries();
27 | },
28 |
29 | /**
30 | * 获取日记列表
31 | * 目前为本地缓存数据 + 本地假数据
32 | * TODO 从服务端拉取
33 | */
34 | getDiaries() {
35 | var that = this;
36 | app.getDiaryList(list => {
37 | that.setData({diaries: list});
38 | })
39 | },
40 |
41 | // 查看详情
42 | showDetail(event) {
43 | wx.navigateTo({
44 | url: '../entry/entry?id=' + event.currentTarget.id,
45 | });
46 | }
47 | })
48 |
--------------------------------------------------------------------------------
/pages/list/list.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | {{item.meta.title}}
9 | {{item.meta.meta}}
10 |
11 |
12 |
13 | {{item.meta.nickName}}
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/pages/list/list.wxss:
--------------------------------------------------------------------------------
1 | /** list.wxss **/
2 |
3 | .item-container {
4 | margin: 10rpx 20rpx;
5 | position: relative;
6 | }
7 |
8 | .cover {
9 | width: 100%;
10 | height: 400rpx;
11 | display: block;
12 | }
13 |
14 | .desc {
15 | margin: 10rpx 0;
16 | display: flex;
17 | justify-content: space-between;
18 | align-items: center;
19 | padding-bottom: 20rpx;
20 | border-bottom: 1px solid #E5E7ED;
21 | }
22 |
23 | .desc .left {
24 | }
25 |
26 | .desc .right {
27 | display: flex;
28 | flex-direction: column;
29 | align-items: center;
30 | }
31 |
32 | .right image{
33 | display: block;
34 | width: 60rpx;
35 | height: 60rpx;
36 | border-radius: 30rpx;
37 | }
38 |
--------------------------------------------------------------------------------
/pages/mine/mine.js:
--------------------------------------------------------------------------------
1 | // mine.js
2 |
3 | // 自定义标签
4 | var iconPath = "../../images/icons/"
5 | var tabs = [
6 | {
7 | "icon": iconPath + "mark.png",
8 | "iconActive": iconPath + "markHL.png",
9 | "title": "日记",
10 | "extraStyle": "",
11 | },
12 | {
13 | "icon": iconPath + "collect.png",
14 | "iconActive": iconPath + "collectHL.png",
15 | "title": "收藏",
16 | "extraStyle": "",
17 | },
18 | {
19 | "icon": iconPath + "like.png",
20 | "iconActive": iconPath + "likeHL.png",
21 | "title": "喜欢",
22 | "extraStyle": "",
23 | },
24 | {
25 | "icon": iconPath + "more.png",
26 | "iconActive": iconPath + "moreHL.png",
27 | "title": "更多",
28 | "extraStyle": "border:none;",
29 | },
30 | ]
31 | var userInfo = {
32 | avatar: "https://pic4.zhimg.com/e515adf3b_xl.jpg",
33 | nickname: "小闹钟",
34 | sex: "♂", // 0, male; 1, female
35 | meta: '1篇日记',
36 | }
37 |
38 |
39 | Page({
40 |
41 | // data
42 | data: {
43 | // 展示的tab标签
44 | tabs: tabs,
45 |
46 | // 当前选中的标签
47 | currentTab: "tab1",
48 |
49 | // 高亮的标签索引
50 | highLightIndex: "0",
51 |
52 | // 模态对话框样式
53 | modalShowStyle: "",
54 |
55 | // 待新建的日记标题
56 | diaryTitle: "",
57 |
58 | // TODO 用户信息
59 | userInfo: userInfo,
60 | },
61 |
62 | // 隐藏模态框
63 | hideModal() {
64 | this.setData({modalShowStyle: ""});
65 | },
66 |
67 | // 清除日记标题
68 | clearTitle() {
69 | this.setData({diaryTitle: ""});
70 | },
71 |
72 | onShow: function() {
73 | this.hideModal();
74 | this.clearTitle();
75 | },
76 |
77 | // 点击tab项事件
78 | touchTab: function(event){
79 | var tabIndex = parseInt(event.currentTarget.id);
80 | var template = "tab" + (tabIndex + 1).toString();
81 |
82 | this.setData({
83 | currentTab: template,
84 | highLightIndex: tabIndex.toString()
85 | }
86 | );
87 | },
88 |
89 | // 点击新建日记按钮
90 | touchAdd: function (event) {
91 | this.setData({
92 | modalShowStyle: "opacity:1;pointer-events:auto;"
93 | })
94 | },
95 |
96 | // 新建日记
97 | touchAddNew: function(event) {
98 | this.hideModal();
99 |
100 | wx.navigateTo({
101 | url: "../new/new?title=" + this.data.diaryTitle,
102 | });
103 | },
104 |
105 | // 取消标题输入
106 | touchCancel: function(event) {
107 | this.hideModal();
108 | this.clearTitle();
109 | },
110 |
111 | // 标题输入事件
112 | titleInput: function(event) {
113 | this.setData({
114 | diaryTitle: event.detail.value,
115 | })
116 | }
117 | })
118 |
--------------------------------------------------------------------------------
/pages/mine/mine.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | 请输入日记标题
29 |
30 |
31 |
32 |
33 |
34 | 确定
35 | 取消
36 |
37 |
38 |
39 |
40 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/pages/mine/mine.wxss:
--------------------------------------------------------------------------------
1 | /**mine.wxss**/
2 |
3 | .header {
4 | height: 130px;
5 | background: white;
6 | }
7 |
8 | .header .profile {
9 | height: 50%;
10 | }
11 |
12 | .profile .avatar {
13 | width: 50px;
14 | height: 50px;
15 | float: left;
16 | margin: 7.5px 10px;
17 | border-radius: 25px;
18 | }
19 |
20 | .profile .description {
21 | display: inline-block;
22 | margin: 7.5px auto;
23 | height: 50px;
24 | }
25 |
26 | .description .item {
27 | height: 50%;
28 | display: flex;
29 | align-items: center;
30 | }
31 |
32 | .profile .add {
33 | float: right;
34 | margin: 15px 10px;
35 | height: 35px;
36 | width: 35px;
37 | }
38 |
39 | .header .tablist {
40 | height: 50%;
41 | display: flex;
42 | justify-content: space-between;
43 | align-items: center;
44 | }
45 |
46 | .tablist .tab {
47 | display: flex;
48 | justify-content: center;
49 | align-items: center;
50 | height: 50px;
51 | width: 25%;
52 | margin: 7.5px 0px;
53 | border-right: 1px solid #eceff4;
54 | }
55 |
56 | .tab .content{
57 | width: 25px;
58 | height: 50px;
59 | font-size: 12px;
60 | color: #B3B3B3;
61 | }
62 |
63 | .tab .image {
64 | width: 25px;
65 | height: 25px;
66 | margin-top: 10px;
67 | }
68 |
69 | .modal {
70 | position: fixed;
71 | top: 0;
72 | left: 0;
73 | bottom: 0;
74 | right: 0;
75 | background: rgba(0, 0, 0, .5);
76 | z-index: 99999;
77 | opacity: 0;
78 | transition: opacity 400ms ease-in;
79 | pointer-events: none;
80 | display: flex;
81 | justify-content: center;
82 | align-items: center;
83 | }
84 |
85 | .modal .dialog {
86 | width: 84%;
87 | height: 28%;
88 | background-color: #eceff4;
89 | border-radius: 4px;
90 | display: flex;
91 | flex-direction: column;
92 | justify-content: space-between;
93 | }
94 |
95 | .dialog .modal-item {
96 | height: 33.3%;
97 | width: 100%;
98 | }
99 |
100 | .modal-button {
101 | height: 100rpx;
102 | margin-bottom: 0;
103 | display: flex;
104 | flex-direction: row;
105 | justify-content: space-between;
106 | }
107 |
108 | .modal-button view {
109 | width: 50%;
110 | border-top: 1px solid #E5E7ED;
111 | display: flex;
112 | justify-content: center;
113 | align-items: center;
114 | }
--------------------------------------------------------------------------------
/pages/new/new.js:
--------------------------------------------------------------------------------
1 | // new.js
2 | // TODO 并不是所有非中文字符宽度都为中文字符宽度一半,需特殊处理
3 | // TODO 由于文本框聚焦存在bug,故编辑模式待实现
4 |
5 | const input = require('../../utils/input');
6 | const config = require('../../config');
7 | const geo = require('../../services/geo');
8 | const util = require('../../utils/util');
9 |
10 | const RESOLUTION = 750; // 微信规定屏幕宽度为750rpx
11 | const MARGIN = 10; // 写字面板左右margin
12 | const ROW_CHARS = Math.floor((RESOLUTION - 2 * MARGIN) / config.input.charWidth);
13 | const MAX_CHAR = 1000; // 最多输1000字符
14 |
15 | // 内容布局
16 | const layoutColumnSize = 3;
17 |
18 | // 日记内容类型
19 | const TEXT = 'TEXT';
20 | const IMAGE = 'IMAGE';
21 | const VIDEO = 'VIDEO';
22 |
23 | const mediaActionSheetItems = ['拍照', '选择照片', '选择视频'];
24 | const mediaActionSheetBinds = ['chooseImage', 'chooseImage', 'chooseVideo'];
25 |
26 | var app = getApp();
27 |
28 | Page({
29 |
30 | data: {
31 | // 日记对象
32 | diary: {
33 | meta: {},
34 | list: [],
35 | },
36 |
37 | // 日记内容布局列表(2x2矩阵)
38 | layoutList: [],
39 |
40 | // 是否显示loading
41 | showLoading: false,
42 |
43 | // loading提示语
44 | loadingMessage: '',
45 |
46 | // 页面所处模式
47 | showMode: 'common',
48 |
49 | // 输入框状态对象
50 | inputStatus: {
51 | row: 0,
52 | column: 0,
53 | lines: [''],
54 | mode: 'INPUT',
55 | auto: false, // 是否有自动换行
56 | },
57 |
58 | // 当前位置信息
59 | poi: null,
60 |
61 | // 点击`图片`tab的action-sheet
62 | mediaActionSheetHidden: true,
63 |
64 | // 多媒体文件插入action-sheet
65 | mediaActionSheetItems: mediaActionSheetItems,
66 |
67 | // 多媒体文件插入项点击事件
68 | mediaActionSheetBinds: mediaActionSheetBinds,
69 |
70 | // 是否显示底部tab栏
71 | showTab: true,
72 | },
73 |
74 | // 显示底部tab
75 | showTab() {
76 | this.setData({showTab: true});
77 | },
78 |
79 | // 隐藏底部tab
80 | hideTab() {
81 | this.setData({showTab: false});
82 | },
83 |
84 | // 显示loading提示
85 | showLoading(loadingMessage) {
86 | this.setData({showLoading: true, loadingMessage});
87 | },
88 |
89 | // 隐藏loading提示
90 | hideLoading() {
91 | this.setData({showLoading: false, loadingMessage: ''});
92 | },
93 |
94 | // 数据初始化
95 | init() {
96 | this.getPoi();
97 | this.setMeta();
98 | },
99 |
100 | // 设置日记数据
101 | setDiary(diary) {
102 | let layout = util.listToMatrix(diary.list, layoutColumnSize);
103 | this.setData({diary: diary, layoutList: layout});
104 | this.saveDiary(diary);
105 | },
106 |
107 | // 保存日记
108 | // TODO sync to server
109 | saveDiary(diary) {
110 | const key = config.storage.diaryListKey;
111 |
112 | app.getLocalDiaries(diaries => {
113 | diaries[diary.meta.title] = diary;
114 | wx.setStorage({key: key, data: diaries});
115 | })
116 | },
117 |
118 | // 页面初始化
119 | onLoad: function(options) {
120 | if (options) {
121 | let title = options.title;
122 | if (title) {this.setData({
123 | 'diary.meta.title': title,
124 | 'diary.meta.create_time': util.formatTime(new Date()),
125 | 'diary.meta.cover': ''
126 | });}
127 | }
128 |
129 | this.init();
130 | },
131 |
132 | // 页面渲染完成
133 | onReady: function(){
134 | wx.setNavigationBarTitle({title: '编辑日记'});
135 | },
136 |
137 | onShow:function(){
138 | // 页面显示
139 | },
140 |
141 | onHide:function(){
142 | // 页面隐藏
143 | },
144 |
145 | onUnload:function(){
146 | // 页面关闭
147 | console.log('页面跳转中...');
148 | },
149 |
150 | // 清除正在输入文本
151 | clearInput() {
152 | this.setData({inputStatus: {
153 | row: 0,
154 | common: 0,
155 | lines: [''],
156 | mode: 'INPUT',
157 | auto: false,
158 | }});
159 | },
160 |
161 | // 结束文本输入
162 | inputDone() {
163 | let text = this.data.inputStatus.lines.join('\n');
164 | let diary = this.data.diary;
165 |
166 | if (text) {
167 | diary.list.push(this.makeContent(TEXT, text, ''));
168 | this.setDiary(diary);
169 | }
170 |
171 | this.inputCancel();
172 | },
173 |
174 | // 进入文本编辑模式
175 | inputTouch(event) {
176 | this.setData({showMode: 'inputText'});
177 | },
178 |
179 | // 取消文本编辑
180 | inputCancel() {
181 | this.setData({showMode: 'common'});
182 | this.clearInput();
183 | },
184 |
185 | // 文本输入
186 | textInput(event) {
187 | console.log(event);
188 | let context = event.detail;
189 |
190 | // 输入模式
191 | if (this.data.inputStatus.mode === 'INPUT') {
192 | if (context.value.length != context.cursor) {
193 | console.log('用户输入中...');
194 | } else {
195 | let text = context.value;
196 | let len = input.strlen(text);
197 | let lines = this.data.inputStatus.lines;
198 | let row = this.data.inputStatus.row;
199 | let [extra, extra_index] = [[['']], 0];
200 | let hasNewLine = false;
201 | console.log('当前文本长度: ' + len);
202 |
203 | // 当前输入长度超过规定长度
204 | if (len >= ROW_CHARS) {
205 | // TODO 此处方案不完善
206 | // 一次输入最好不超过两行
207 | hasNewLine = true;
208 | while (input.strlen(text) > ROW_CHARS) {
209 | let last = text[text.length - 1];
210 |
211 | if (input.strlen(extra[extra_index] + last) > ROW_CHARS) {
212 | extra_index += 1;
213 | extra[extra_index] = [''];
214 | }
215 |
216 | extra[extra_index].unshift(last);
217 | text = text.slice(0, -1);
218 | }
219 | }
220 |
221 | lines[lines.length - 1] = text;
222 | if (hasNewLine) {
223 | extra.reverse().forEach((element, index, array) => {
224 | lines.push(element.join(''));
225 | row += 1;
226 | });
227 | }
228 |
229 | let inputStatus = {
230 | lines: lines,
231 | row: row,
232 | mode: 'INPUT',
233 | auto: true, // // 自动换行的则处于输入模式
234 | };
235 |
236 | this.setData({inputStatus});
237 | }
238 | }
239 | },
240 |
241 | // 文本框获取到焦点
242 | focusInput(event) {
243 | let isInitialInput = this.data.inputStatus.row == 0 &&
244 | this.data.inputStatus.lines[0].length == 0;
245 | let isAutoInput = this.data.inputStatus.mode == 'INPUT' &&
246 | this.data.inputStatus.auto == true;
247 | let mode = 'EDIT';
248 |
249 | if (isInitialInput || isAutoInput) {
250 | mode = 'INPUT';
251 | }
252 |
253 | this.setData({'inputStatus.mode': mode});
254 | },
255 |
256 | // 点击多媒体插入按钮
257 | mediaTouch() {
258 | this.setData({
259 | showTab: false,
260 | mediaActionSheetHidden: false,
261 | });
262 | },
263 |
264 | mediaActionSheetChange(event) {
265 | this.setData({
266 | showTab: true,
267 | mediaActionSheetHidden: true,
268 | })
269 | },
270 |
271 | // 将内容写入至日记对象
272 | writeContent(res, type) {
273 | let diary = this.data.diary;
274 |
275 | if (type === IMAGE) {
276 | res.tempFilePaths.forEach((element, index, array) => {
277 | // TODO 内容上传至服务器
278 | diary.list.push(this.makeContent(type, element, ''))
279 | });
280 | }
281 |
282 | if (type === VIDEO) {
283 | // TODO 内容上传至服务器
284 | diary.list.push(this.makeContent(type, res.tempFilePath, ''))
285 | }
286 |
287 | // 设置日记封面
288 | if (type === IMAGE && !this.data.diary.meta.cover) {
289 | this.setData({'diary.meta.cover': res.tempFilePaths[0]});
290 | }
291 |
292 | this.setDiary(diary);
293 | this.hideLoading();
294 | this.showTab();
295 | },
296 |
297 | // 从相册选择照片或拍摄照片
298 | chooseImage() {
299 | let that = this;
300 |
301 | wx.chooseImage({
302 | count: 9, // 最多选9张
303 | sizeType: ['origin', 'compressed'],
304 | sourceType: ['album', 'camera'],
305 |
306 | success: (res) => {
307 | this.setData({mediaActionSheetHidden: true});
308 | this.showLoading('图片处理中...');
309 | that.writeContent(res, IMAGE);
310 | }
311 | })
312 | },
313 |
314 | // 从相册选择视频文件
315 | chooseVideo() {
316 | let that = this;
317 |
318 | wx.chooseVideo({
319 | sourceType: ['album'], // 仅从相册选择
320 | success: (res) => {
321 | this.setData({mediaActionSheetHidden: true});
322 | this.showLoading('视频处理中...');
323 | that.writeContent(res, VIDEO);
324 | }
325 | })
326 | },
327 |
328 | // 获得当前位置信息
329 | getPoi() {
330 | var that = this;
331 | wx.getLocation({
332 | type: 'gcj02',
333 | success: function(res) {
334 | geo.mapRequest(
335 | 'geocoder',
336 | {'location': geo.formatLocation(res)},
337 | loc => {
338 | let poi = {
339 | 'latitude': res.latitude,
340 | 'longitude': res.longitude,
341 | 'name': loc.result.address,
342 | };
343 | that.setData({poi: poi});
344 | })
345 | }
346 | })
347 | },
348 |
349 | // 构造日记内容对象
350 | makeContent(type, content, description) {
351 | return {
352 | type: type,
353 | content: content,
354 | description: description,
355 | poi: this.data.poi,
356 | };
357 | },
358 |
359 | // 构造日记meta信息
360 | setMeta() {
361 | var that = this;
362 | app.getUserInfo(info => {
363 | that.setData({
364 | 'diary.meta.avatar': info.avatarUrl,
365 | 'diary.meta.nickName': info.nickName,
366 | })
367 | })
368 | },
369 |
370 | })
371 |
--------------------------------------------------------------------------------
/pages/new/new.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | {{item.content}}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | {{item}}
40 |
41 |
42 | 取消
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | {{loadingMessage}}
71 |
72 |
73 |
--------------------------------------------------------------------------------
/pages/new/new.wxss:
--------------------------------------------------------------------------------
1 | /** new.wxss **/
2 |
3 | .container {
4 | height: 91%;
5 | }
6 |
7 | .common-container {
8 | margin: 0.1rem;
9 | }
10 |
11 | .item-group {
12 | display: flex;
13 | align-items: center;
14 | }
15 |
16 | .album-item {
17 | flex-direction: column;
18 | margin: 0.1rem;
19 | background: white;
20 | width: 6.4rem;
21 | height: 6.4rem;
22 | }
23 |
24 | .content-text{
25 | justify-content: center;
26 | align-items: center;
27 | display: flex;
28 | }
29 |
30 | .content-text view {
31 | overflow: hidden;
32 | text-overflow: ellipsis;
33 | font-size: 10px;
34 | line-height: 15px;
35 | }
36 |
37 | .tabbar {
38 | position: fixed;
39 | width: 100%;
40 | height: 8%;
41 | left: 0;
42 | right: 0;
43 | bottom: 0;
44 | background-color: white;
45 | display: flex;
46 | flex-direction: row;
47 | justify-content: space-between;
48 | }
49 |
50 | .tabbar .item {
51 | width: 33.33%;
52 | display: flex;
53 | justify-content: center;
54 | align-items: center;
55 | }
56 |
57 | .item .icon {
58 | width: 50rpx;
59 | height: 50rpx;
60 | }
61 |
62 | .input-container {
63 | height: 80%;
64 | background-color: #eceff4;
65 | background-image: linear-gradient(#E1E6EA .1em, transparent .1em);
66 | background-size: 100% 48rpx;
67 | padding: 0;
68 | box-sizing: border-box;
69 | margin: 0 10rpx;
70 | }
71 |
72 | .input-container input{
73 | height: 47rpx;
74 | max-height: 47rpx;
75 | font-size: 28rpx;
76 | margin: 0px;
77 | }
78 |
79 | .action-item, .action-cacel {
80 | font-size: 30rpx;
81 | color: #39b5de;
82 | }
83 |
--------------------------------------------------------------------------------
/services/geo.js:
--------------------------------------------------------------------------------
1 | // 基于腾讯地图API的地理位置功能封装
2 |
3 | const config = require('../config.js');
4 | const request = require('request.js');
5 |
6 | const statusCodeMap = { // 请求失败原因映射
7 | 110: '请求来源未被授权',
8 | 301: '请求参数信息有误',
9 | 311: 'key格式错误',
10 | 306: '请求有护持信息请检查字符串',
11 | }
12 |
13 | module.exports = {
14 |
15 | // 地图API请求方法
16 | mapRequest(method, params, callback) {
17 | var url = [config.map.baseUrl, method, 'v1/'].join('/');
18 | let param = Object.assign({'key': config.map.key}, params);
19 | let queryString = Object.keys(param).map(q => [q, param[q]].join('=')).join('&');
20 | url += '?' + queryString;
21 |
22 | request({'method': 'GET', 'url': url}).then(resp => {
23 | if (resp.status != 0) {
24 | console.log('请求错误:' + (statusCodeMap[resp.status] || resp.message));
25 | request
26 | }
27 |
28 | return callback(resp);
29 | }).catch(err => {console.log(err);});
30 | },
31 |
32 | // 格式化地理位置
33 | formatLocation(loc) {
34 | return [loc.latitude, loc.longitude].map(f => f.toString()).join(',');
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/services/request.js:
--------------------------------------------------------------------------------
1 | // 对微信网络请求的异步封装
2 |
3 | module.exports = (options) => {
4 | return new Promise((resolve, reject) => {
5 | options = Object.assign(options, {
6 | success(result) {
7 | if (result.statusCode === 200) {
8 | resolve(result.data);
9 | } else {
10 | reject(result);
11 | }
12 | },
13 |
14 | fail: reject,
15 | });
16 |
17 | wx.request(options);
18 | });
19 | };
20 |
--------------------------------------------------------------------------------
/utils/input.js:
--------------------------------------------------------------------------------
1 | // 输入框相关处理函数
2 |
3 | module.exports = {
4 |
5 | // 计算字符串长度(英文占一个字符,中文汉字占2个字符)
6 | strlen(str) {
7 | var len = 0;
8 | for (var i = 0; i < str.length; i++) {
9 | var c = str.charCodeAt(i);
10 | if ((c >= 0x0001 && c <= 0x007e) || (c >= 0xff60 && c <= 0xff9f)) {
11 | len++;
12 | } else {
13 | len += 2;
14 | }
15 | }
16 | return len;
17 | },
18 | }
19 |
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | // 工具函数
2 |
3 | function formatTime(date) {
4 | var year = date.getFullYear()
5 | var month = date.getMonth() + 1
6 | var day = date.getDate()
7 |
8 | var hour = date.getHours()
9 | var minute = date.getMinutes()
10 | var second = date.getSeconds();
11 |
12 |
13 | return [year, month, day].map(formatNumber).join('.') + ' ' + [hour, minute, second].map(formatNumber).join(':')
14 | }
15 |
16 | function formatNumber(n) {
17 | n = n.toString()
18 | return n[1] ? n : '0' + n
19 | }
20 |
21 | // 将一维数组转为二维数组
22 | function listToMatrix(list, elementPerSubArray) {
23 | let matrix = [], i, k;
24 |
25 | for (i = 0, k = -1; i < list.length; i += 1) {
26 | if (i % elementPerSubArray === 0) {
27 | k += 1;
28 | matrix[k] = [];
29 | }
30 |
31 | matrix[k].push(list[i]);
32 | }
33 |
34 | return matrix;
35 | }
36 |
37 | module.exports = {
38 | formatTime: formatTime,
39 | listToMatrix: listToMatrix,
40 | }
41 |
--------------------------------------------------------------------------------