├── 20191231204944869.jpg
├── 20191231205313718.jpg
├── 20191231205553436.jpg
├── 20191231205809984.jpg
├── LICENSE
├── README.md
├── README_imgs
├── 20191231204944869.jpg
├── 20191231205313718.jpg
├── 20191231205553436.jpg
└── 20191231205809984.jpg
├── cloudfunctions
├── login
│ ├── index.js
│ └── package.json
└── openapi
│ ├── config.json
│ ├── index.js
│ └── package.json
├── miniprogram
├── app.js
├── app.json
├── app.wxss
├── assert
│ ├── add.svg
│ ├── calendar.svg
│ ├── goback.svg
│ └── more-default.svg
├── components
│ ├── carditem
│ │ ├── carditem.js
│ │ ├── carditem.json
│ │ ├── carditem.wxml
│ │ └── carditem.wxss
│ └── navbar
│ │ ├── navbar.js
│ │ ├── navbar.json
│ │ ├── navbar.wxml
│ │ └── navbar.wxss
├── images
│ ├── button
│ │ ├── count.png
│ │ └── countback.png
│ ├── icon
│ │ ├── aboutus.png
│ │ ├── add_timecard.png
│ │ ├── arrow-right.png
│ │ ├── brand.png
│ │ ├── calendar.png
│ │ ├── cards-ed.png
│ │ ├── cards.png
│ │ ├── delete.png
│ │ ├── feedback.png
│ │ ├── model.png
│ │ ├── person.png
│ │ ├── share.png
│ │ ├── station-ed.png
│ │ └── station.png
│ └── role
│ │ ├── Ant-Man.svg
│ │ ├── Aquaman.svg
│ │ ├── Batman.svg
│ │ ├── Captain-America.svg
│ │ ├── Captain-Atom.svg
│ │ ├── Cyclops.svg
│ │ ├── Deadpool.svg
│ │ ├── Green-Lantern.svg
│ │ ├── Hulk.svg
│ │ ├── Iron-Man.svg
│ │ ├── Martian-Manhunter.svg
│ │ ├── Mister-Fantastic.svg
│ │ ├── Spider-Man.svg
│ │ ├── Superman.svg
│ │ ├── The-Flash.svg
│ │ ├── Thor.svg
│ │ └── Wolverine.svg
├── pages
│ ├── create
│ │ ├── create.js
│ │ ├── create.json
│ │ ├── create.wxml
│ │ └── create.wxss
│ ├── index
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── login
│ │ ├── login.js
│ │ ├── login.json
│ │ ├── login.wxml
│ │ └── login.wxss
├── sitemap.json
├── style
│ └── guide.wxss
└── utils
│ ├── convertDate.js
│ └── util.js
└── project.config.json
/20191231204944869.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/20191231204944869.jpg
--------------------------------------------------------------------------------
/20191231205313718.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/20191231205313718.jpg
--------------------------------------------------------------------------------
/20191231205553436.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/20191231205553436.jpg
--------------------------------------------------------------------------------
/20191231205809984.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/20191231205809984.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | @[TOC](TimeCard)
2 | `微信小程序` `倒计日` `累计日`
3 | # 项目介绍
4 | **TimeCard**——一个基于微信开发工具所编写的一款小程序,它是一个关于效率的小程序,主要提供倒计日和目标日(待完成)的功能。该项目正在持续开发中(2019年12月31日重新启动),目前版本更新为`v0.1.1`。(项目地址)
5 |
6 | ## CSDN
7 | TimeCard
8 |
9 | # 新的改变
10 |
11 | 我对**时光车站**项目进行了一些界面上的优化与数据存储结构和存储位置调整:
12 | 1. **船新的界面设计** ,增加了相应的按钮旋转动画,类型选择`ease`。这样在按下按钮时,动画不会过于生硬。同时为遮罩层添加**颜色渐变动画**,同时也为弹出的功能抽屉赋予动画。为使用者带来良好的编辑体验;
13 | 2. 为首页的卡片展示,**重新布局样式**,使用**金色**来标记起始时间与结束时间,寓意着时间的珍贵;
14 | 3. 将时间进度条拉长~~~~长,**加粗**;
15 | 4. 去掉了 ~~**已过天数 / 总天数**~~ 的显示;
16 | 5. 增加了进度条上的图表显示,如**漫威人物**等;
17 | 6. 增加了 **可旋转的** 操作按钮;
18 |
19 | # 项目功能
20 |
21 | > TimeCard
22 | >> 登录注册(使用微信自身提供的方法)
23 | >> 选择创建类型
24 | >>
25 | >>> 倒计日
26 | >>>> 创建
27 | >>>> 分享
28 | >>>> 修改
29 | >>>> 删除
30 | >>>
31 | >>> 累计日
32 | >>>> 创建
33 | >>>> 分享
34 | >>>> 修改
35 | >>>> 删除
36 |
37 | ## 已完成功能及还需完成功能
38 | - [x] 用户登录注册
39 | - [x] 新建时点击按钮的动画
40 | - [x] 倒计日创建
41 | - [ ] 倒计日模块中修改、分享及删除
42 | - [ ] 累计日模块
43 | - [ ] 名称搜索
44 | - [ ] 日期筛选
45 | - [ ] 标签模块
46 |
47 |
48 |
49 | ## 项目运行效果图
50 |
51 | 1. 登录界面
52 |
53 | 2. 程序主页
54 |
55 | 3. 选择创建类型
56 |
57 | 4. 创建倒计日
58 |
59 |
60 | ## 用户数据存储
61 | 本项目数据存储的方式由`知晓云`更改为`云开发`(微信开发工具自己开发的数据存储,为了方便前后端结合在一起开发),个人开发者小型项目免费版本基本可以满足需求。
62 |
63 | 总共设置了三个集合来存储相应的数据(以后还会增加...)
64 | 1. 用于存储用户信息的集合(`user表`)
65 | 2. 用于存储用户所填卡片信息的集合(`user-cards表`)
66 | 3. 用于存储一个用户下所有的卡片ID的集合(`user-cards-set表`)
67 |
68 | ## 云开发 quickstart
69 |
70 | 这是云开发的快速启动指引,其中演示了如何上手使用云开发的三大基础能力:
71 |
72 | - 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 文档型数据库
73 | - 文件存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
74 | - 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写业务逻辑代码
75 |
76 | ### 参考文档
77 |
78 | - [云开发文档](https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html)
79 |
80 | # 联系我
81 |
82 | 如果你喜欢这个项目,欢迎Star、Fork。也欢迎 Pull requests 一起完善这个项目。
83 | 邮箱:agonyperkey@gmail.com
84 | QQ:314068298
85 |
86 | 目前,该项目已有旧版在微信小程序上发布,但是这次所做出的修改与变化是巨大的,明年年初可以将新版本发布到微信平台,自己也在这个项目中学习到了许多关于项目开发的常识。
87 | 最后,祝大家新年快乐,不忘初心,砥砺前行!
88 | # License
89 |
90 | >Licensed under the Apache License, Version 2.0 (the “License”);
91 | you may not use this file except in compliance with the License.
92 | You may obtain a copy of the License at
93 | http://www.apache.org/licenses/LICENSE-2.0
94 | Unless required by applicable law or agreed to in writing, software
95 | distributed under the License is distributed on an “AS IS” BASIS,
96 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
97 | See the License for the specific language governing permissions and
98 | limitations under the License.
99 |
--------------------------------------------------------------------------------
/README_imgs/20191231204944869.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/README_imgs/20191231204944869.jpg
--------------------------------------------------------------------------------
/README_imgs/20191231205313718.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/README_imgs/20191231205313718.jpg
--------------------------------------------------------------------------------
/README_imgs/20191231205553436.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/README_imgs/20191231205553436.jpg
--------------------------------------------------------------------------------
/README_imgs/20191231205809984.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/README_imgs/20191231205809984.jpg
--------------------------------------------------------------------------------
/cloudfunctions/login/index.js:
--------------------------------------------------------------------------------
1 | // 云函数模板
2 | // 部署:在 cloud-functions/login 文件夹右击选择 “上传并部署”
3 |
4 | const cloud = require('wx-server-sdk')
5 |
6 | // 初始化 cloud
7 | cloud.init()
8 |
9 | /**
10 | * 这个示例将经自动鉴权过的小程序用户 openid 返回给小程序端
11 | *
12 | * event 参数包含小程序端调用传入的 data
13 | *
14 | */
15 | exports.main = (event, context) => {
16 | console.log(event)
17 | console.log(context)
18 |
19 | // 可执行其他自定义逻辑
20 | // console.log 的内容可以在云开发云函数调用日志查看
21 |
22 | // 获取 WX Context (微信调用上下文),包括 OPENID、APPID、及 UNIONID(需满足 UNIONID 获取条件)
23 | const wxContext = cloud.getWXContext()
24 |
25 | return {
26 | event,
27 | openid: wxContext.OPENID,
28 | appid: wxContext.APPID,
29 | unionid: wxContext.UNIONID,
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/cloudfunctions/openapi/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "permissions": {
3 | "openapi": [
4 | "wxacode.get",
5 | "templateMessage.send",
6 | "templateMessage.addTemplate",
7 | "templateMessage.deleteTemplate",
8 | "templateMessage.getTemplateList",
9 | "templateMessage.getTemplateLibraryById",
10 | "templateMessage.getTemplateLibraryList"
11 | ]
12 | }
13 | }
--------------------------------------------------------------------------------
/cloudfunctions/openapi/index.js:
--------------------------------------------------------------------------------
1 | // 云函数入口文件
2 | const cloud = require('wx-server-sdk')
3 |
4 | cloud.init()
5 |
6 | // 云函数入口函数
7 | exports.main = async (event, context) => {
8 | switch (event.action) {
9 | case 'sendTemplateMessage': {
10 | return sendTemplateMessage(event)
11 | }
12 | case 'getWXACode': {
13 | return getWXACode(event)
14 | }
15 | default: {
16 | return
17 | }
18 | }
19 | }
20 |
21 | async function sendTemplateMessage(event) {
22 | const { OPENID } = cloud.getWXContext()
23 |
24 | // 接下来将新增模板、发送模板消息、然后删除模板
25 | // 注意:新增模板然后再删除并不是建议的做法,此处只是为了演示,模板 ID 应在添加后保存起来后续使用
26 | const addResult = await cloud.openapi.templateMessage.addTemplate({
27 | id: 'AT0002',
28 | keywordIdList: [3, 4, 5]
29 | })
30 |
31 | const templateId = addResult.templateId
32 |
33 | const sendResult = await cloud.openapi.templateMessage.send({
34 | touser: OPENID,
35 | templateId,
36 | formId: event.formId,
37 | page: 'pages/openapi/openapi',
38 | data: {
39 | keyword1: {
40 | value: '未名咖啡屋',
41 | },
42 | keyword2: {
43 | value: '2019 年 1 月 1 日',
44 | },
45 | keyword3: {
46 | value: '拿铁',
47 | },
48 | }
49 | })
50 |
51 | await cloud.openapi.templateMessage.deleteTemplate({
52 | templateId,
53 | })
54 |
55 | return sendResult
56 | }
57 |
58 | async function getWXACode(event) {
59 |
60 | // 此处将获取永久有效的小程序码,并将其保存在云文件存储中,最后返回云文件 ID 给前端使用
61 |
62 | const wxacodeResult = await cloud.openapi.wxacode.get({
63 | path: 'pages/openapi/openapi',
64 | })
65 |
66 | const fileExtensionMatches = wxacodeResult.contentType.match(/\/([^\/]+)/)
67 | const fileExtension = (fileExtensionMatches && fileExtensionMatches[1]) || 'jpg'
68 |
69 | const uploadResult = await cloud.uploadFile({
70 | // 云文件路径,此处为演示采用一个固定名称
71 | cloudPath: `wxacode_default_openapi_page.${fileExtension}`,
72 | // 要上传的文件内容可直接传入图片 Buffer
73 | fileContent: wxacodeResult.buffer,
74 | })
75 |
76 | if (!uploadResult.fileID) {
77 | throw new Error(`upload failed with empty fileID and storage server status code ${uploadResult.statusCode}`)
78 | }
79 |
80 | return uploadResult.fileID
81 | }
82 |
--------------------------------------------------------------------------------
/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 | "wx-server-sdk": "latest"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/miniprogram/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | App({
3 | onLaunch: function () {
4 |
5 | if (!wx.cloud) {
6 | console.error('请使用 2.2.3 或以上的基础库以使用云能力')
7 | } else {
8 | wx.cloud.init({
9 | traceUser: true,
10 | })
11 | }
12 |
13 | this.globalData = {
14 |
15 | }
16 | }
17 | })
18 |
--------------------------------------------------------------------------------
/miniprogram/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/login/login",
4 | "pages/index/index",
5 | "pages/create/create"
6 | ],
7 | "window": {
8 | "backgroundColor": "#F6F6F6",
9 | "backgroundTextStyle": "light",
10 | "navigationBarBackgroundColor": "#F6F6F6",
11 | "navigationBarTitleText": "时光车站",
12 | "navigationBarTextStyle": "black",
13 | "navigationStyle": "custom"
14 | },
15 | "sitemapLocation": "sitemap.json"
16 | }
--------------------------------------------------------------------------------
/miniprogram/app.wxss:
--------------------------------------------------------------------------------
1 | /**app.wxss**/
2 | page{
3 | background-color: #FFFBF3;
4 | }
5 | .container{
6 | margin-top: 160rpx;
7 | }
8 |
--------------------------------------------------------------------------------
/miniprogram/assert/add.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/assert/calendar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/assert/goback.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/assert/more-default.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/components/carditem/carditem.js:
--------------------------------------------------------------------------------
1 | Component({
2 | properties: {
3 | /*title: { // 属性名
4 | type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
5 | value: '标题' // 属性初始值(可选),如果未指定则会根据类型选择一个
6 | },*/
7 | cardTitle: {
8 | type: String,
9 | value: '请输入标题...'
10 | },
11 | cardColor: {
12 | type: String,
13 | value: '#e63c56'
14 | },
15 | startTime: {
16 | type: String,
17 | value: '2019-05-01'
18 | },
19 | roleName: {
20 | type: String,
21 | value: 'Superman'
22 | },
23 | endTime: {
24 | type: String,
25 | value: '2019-09-01'
26 | },
27 | percent: {
28 | type: Number,
29 | value: 0
30 | },
31 | finished: {
32 | type: Boolean,
33 | value: false
34 | }
35 | },
36 | attached: function() {
37 | this.aniAct();
38 | },
39 | data: {
40 | cardHandle: true,
41 | },
42 | methods: {
43 | aniAct: function() {
44 | var that = this;
45 | // 定义旋转动画
46 | that.aniRotate = wx.createAnimation({
47 | duration: 1000,
48 | timingFunction: 'ease',
49 | });
50 | },
51 | // 点击操作,按钮旋转
52 | rotate90: function() {
53 | var that = this
54 | // 旋转角度是固定的,不是基于当前的位置
55 | if (that.data.cardHandle) {
56 | that.aniRotate.rotate(90).step()
57 | } else {
58 | that.aniRotate.rotate(0).step()
59 | }
60 | that.setData({
61 | aniRotateA: that.aniRotate.export(),
62 | cardHandle: !that.data.cardHandle
63 | })
64 | },
65 | }
66 | })
--------------------------------------------------------------------------------
/miniprogram/components/carditem/carditem.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true
3 | }
--------------------------------------------------------------------------------
/miniprogram/components/carditem/carditem.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{cardTitle}}
7 | 起始日:{{startTime}}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 已结束
30 |
31 | 截止日:{{endTime}}
32 |
33 |
34 |
36 |
37 | 倒计日
38 |
39 |
40 | 累计日
41 |
42 |
43 |
--------------------------------------------------------------------------------
/miniprogram/components/carditem/carditem.wxss:
--------------------------------------------------------------------------------
1 | .card-items {
2 | display: flex;
3 | flex-direction: column;
4 | position: relative;
5 | width: 92%;
6 | /* 加上标签 */
7 | height: 300rpx;
8 | padding: 14rpx;
9 | margin: 18rpx auto;
10 | border-radius: 20rpx;
11 | box-shadow: 2px 2px 3px #999;
12 | }
13 |
14 | /* 事件标题、时间及操作 */
15 |
16 | .card-title-createtime-handle {
17 | display: flex;
18 | flex-direction: row;
19 | justify-content: space-between;
20 | width: 100%;
21 | }
22 |
23 | .card-title-createtime {
24 | display: flex;
25 | flex-direction: column;
26 | }
27 |
28 | .card-title {
29 | color: #fff;
30 | line-height: 50rpx;
31 | font-size: 48rpx;
32 | font-weight: bolder;
33 | font-family: "heiti";
34 | }
35 |
36 | .card-createtime {
37 | font-size: 24rpx;
38 | line-height: 40rpx;
39 | color: #eee8aa;
40 | }
41 |
42 | .card-handle image {
43 | width: 80rpx;
44 | height: 80rpx;
45 | }
46 |
47 | /* 进度条 */
48 |
49 | .card-role-progress {
50 | position: relative;
51 | width: 90%;
52 | margin: 18rpx auto 0;
53 | }
54 |
55 | .card-role image {
56 | position: relative;
57 | margin-left: -42rpx;
58 | width: 90rpx;
59 | }
60 |
61 | .progress-con {
62 | position: relative;
63 | height: 18rpx;
64 | }
65 |
66 | .progress {
67 | position: absolute;
68 | top: 0;
69 | height: 18rpx;
70 | background-color: #fffbf3;
71 | border-radius: 10rpx;
72 | z-index: 4;
73 | }
74 |
75 | .progress-bott {
76 | position: absolute;
77 | top: 0;
78 | width: 100%;
79 | height: 18rpx;
80 | background-color: #505050;
81 | opacity: 0.5;
82 | border-radius: 10rpx;
83 | z-index: 3;
84 | }
85 |
86 | /* 结束时间样式与起始日相同 */
87 |
88 | .card-endtime {
89 | position: absolute;
90 | bottom: 50rpx;
91 | right: 10rpx;
92 | font-size: 24rpx;
93 | line-height: 40rpx;
94 | color: #eee8aa;
95 | text-align: right;
96 | }
97 |
98 | /* 已结束字体样式 */
99 | .finished{
100 | font-size: 80rpx;
101 | color: #ffffff;
102 | text-align: center;
103 | }
104 |
105 | /* 标签 */
106 |
107 | .card-tag {
108 | display: flex;
109 | flex-direction: row;
110 | position: absolute;
111 | bottom: 10rpx;
112 | right: 5rpx;
113 | height: 36rpx;
114 | /* background- color: red; */
115 | }
116 |
117 | .tag-item {
118 | padding: 0 4rpx;
119 | font-size: 30rpx;
120 | color: #79a2a8;
121 | font-weight: bolder;
122 | line-height: 36rpx;
123 | background-color: #fffbf3;
124 | border-radius: 6rpx;
125 | margin: 0 8rpx;
126 | right: 0;
127 | }
128 |
--------------------------------------------------------------------------------
/miniprogram/components/navbar/navbar.js:
--------------------------------------------------------------------------------
1 | Component({
2 | properties: {
3 | /*title: { // 属性名
4 | type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
5 | value: '标题' // 属性初始值(可选),如果未指定则会根据类型选择一个
6 | },*/
7 |
8 | // 背景颜色
9 | backgroundColor: {
10 | type: String,
11 | value: '#FFFBF3'
12 | },
13 | // 导航栏标题
14 | navTitleText: {
15 | type: String,
16 | value: '导航栏'
17 | },
18 | // 导航栏操作图标
19 | navHandleImg: {
20 | type: String,
21 | value: ''
22 | },
23 | method: {
24 | type: String,
25 | value: ''
26 | }
27 | },
28 | attached: function() {
29 | var that = this;
30 | that.setNavSize();
31 | that.setAnimate();
32 | },
33 | data: {
34 | statusBarHeight: 0,
35 | titleBarHeight: 0,
36 | animationB: {},
37 | addStatus: false,
38 | hideAddPopup: true
39 | },
40 | methods: {
41 | // 通过获取系统信息计算导航栏高度
42 | setNavSize: function() {
43 | var sysinfo = wx.getSystemInfoSync();
44 | var statusBarH = sysinfo.statusBarHeight;
45 | if (sysinfo.system.indexOf('iOS') > -1) {
46 | // 导航栏高度 = 胶囊按钮高度 + 状态栏到胶囊按钮间距 * 2
47 | // ios的导航栏高度
48 | var titleBarH = 32 + 6 * 2;
49 | } else {
50 | // Android的导航栏高度
51 | var titleBarH = 32 + 8 * 2;
52 | }
53 | this.setData({
54 | // 状态栏高度 + 标题栏高度
55 | statusBarHeight: sysinfo.statusBarHeight,
56 | titleBarHeight: titleBarH
57 | });
58 | },
59 | // 设置动画
60 | setAnimate: function() {
61 | var that = this;
62 | that.animation = wx.createAnimation({
63 | duration: 1000,
64 | timingFunction: 'ease',
65 | })
66 | },
67 | // 点击添加按钮,旋转图标并弹出菜单栏
68 | /*
69 | 点击出现菜单后,在点击时会出现bug
70 | 目前解决办法:使用遮罩层进行屏蔽,覆盖在按钮上面
71 | */
72 | createButtonHandle: function() {
73 | var that = this;
74 | var addStatus = that.data.addStatus;
75 | // 旋转角度是固定的,不是基于当前的位置
76 | if (!addStatus) {
77 | that.animation.rotate(45).step();
78 | // console.log("运行了1")
79 | that.setData({
80 | animationB: that.animation.export(),
81 | addStatus: !addStatus,
82 | hideAddPopup: !that.data.hideAddPopup
83 | })
84 | that.TAddPopup();
85 |
86 | } else {
87 | that.animation.rotate(0).step();
88 | that.setData({
89 | animationB: that.animation.export(),
90 | addStatus: !addStatus,
91 | hideAddPopup: !that.data.hideAddPopup
92 | })
93 | }
94 |
95 | },
96 | // 改变hideAddPopup的值实现对AddPopup的控制
97 | TAddPopup: function() {
98 | // console.log(this.data.hideAddPopup)
99 | let temp = this.data.hideAddPopup;
100 | // 点击事件带参传入父级
101 | this.triggerEvent('updataAddPopup', temp);
102 | },
103 |
104 | // 隐藏Add菜单
105 | hideAddPopup: function() {
106 | var that = this;
107 | that.setData({
108 | hideAddPopup: true
109 | })
110 | },
111 | // 显示Add菜单
112 | showAddPopup: function() {
113 | var that = this;
114 | that.setData({
115 | hideAddPopup: false
116 | })
117 | },
118 | // 返回按钮
119 | goback: function() {
120 | wx.navigateBack({
121 | delta: 1
122 | })
123 | }
124 | }
125 | })
--------------------------------------------------------------------------------
/miniprogram/components/navbar/navbar.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true
3 | }
--------------------------------------------------------------------------------
/miniprogram/components/navbar/navbar.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{navTitleText}}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/miniprogram/components/navbar/navbar.wxss:
--------------------------------------------------------------------------------
1 | .status-title-bar {
2 | width: 100%;
3 | position: fixed;
4 | top: 0;
5 | left: 0;
6 | z-index: 90;
7 | }
8 |
9 | .status-bar {
10 | width: 100%;
11 | }
12 |
13 | .title-bar {
14 | width: 100%;
15 | position: relative;
16 | }
17 | .navHandle{
18 | position: absolute;
19 | width: 32px;
20 | height: 32px;
21 | left: 24rpx;
22 | top: 50%;
23 | margin-top: -16px;
24 | }
25 | .navHandle image{
26 | width: 32px;
27 | }
28 | .navTitle {
29 | text-align: center;
30 | font-weight: bolder;
31 | color: #505050;
32 | font-size: 40rpx;
33 | letter-spacing: 0.3em;
34 | }
--------------------------------------------------------------------------------
/miniprogram/images/button/count.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/button/count.png
--------------------------------------------------------------------------------
/miniprogram/images/button/countback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/button/countback.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/aboutus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/aboutus.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/add_timecard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/add_timecard.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/arrow-right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/arrow-right.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/brand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/brand.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/calendar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/calendar.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/cards-ed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/cards-ed.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/cards.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/cards.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/delete.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/delete.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/feedback.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/feedback.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/model.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/person.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/share.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/station-ed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/station-ed.png
--------------------------------------------------------------------------------
/miniprogram/images/icon/station.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pinkpear/TimeCard/1ba936d013e266e27319c2d50f69f6b4cf7f4921/miniprogram/images/icon/station.png
--------------------------------------------------------------------------------
/miniprogram/images/role/Ant-Man.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Aquaman.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Batman.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Captain-America.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Captain-Atom.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Cyclops.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Deadpool.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Green-Lantern.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Hulk.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Iron-Man.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Martian-Manhunter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Mister-Fantastic.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Superman.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/The-Flash.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Thor.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/images/role/Wolverine.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/miniprogram/pages/create/create.js:
--------------------------------------------------------------------------------
1 | // 获得工具utils工具js里面函数,先模块化引用utils里面的js地址 reqiure('js地址')成一个面向对象
2 | var app = getApp();
3 | var convertDate = require('../../utils/convertDate.js');
4 | var util = require('../../utils/util.js');
5 | Page({
6 |
7 | /**
8 | * 页面的初始数据
9 | */
10 | data: {
11 | title: "请输入标题...",
12 | startdate: "2018-04-01",
13 | enddate: "2018-04-01",
14 | nowdate: "2018-04-01",
15 | cardstype: "",
16 | roleName: "Hulk",
17 | color: "#e63c56",
18 | roleGroups: {
19 | 'Hulk': {
20 | 'roleEname': 'Hulk',
21 | 'roleName': '浩克'
22 | },
23 | 'Superman': {
24 | 'roleEname': 'Superman',
25 | 'roleName': '超人'
26 | },
27 | 'Thor': {
28 | 'roleEname': 'Thor',
29 | 'roleName': '雷神'
30 | },
31 | 'Spider-Man': {
32 | 'roleEname': 'Spider-Man',
33 | 'roleName': '蜘蛛侠'
34 | },
35 | 'Iron-Man': {
36 | 'roleEname': 'Iron-Man',
37 | 'roleName': '钢铁侠'
38 | },
39 | 'Green-Lantern': {
40 | 'roleEname': 'Green-Lantern',
41 | 'roleName': '绿灯侠'
42 | },
43 | 'Batman': {
44 | 'roleEname': 'Batman',
45 | 'roleName': '蝙蝠侠'
46 | }
47 | }
48 | },
49 |
50 | /**
51 | * 生命周期函数--监听页面加载
52 | */
53 | onLoad: function(options) {
54 | var that = this;
55 | that.getdate();
56 | that.setData({
57 | cardstype: options.cardstype
58 | })
59 | },
60 |
61 | /**
62 | * 生命周期函数--监听页面初次渲染完成
63 | */
64 | onReady: function() {
65 |
66 | },
67 |
68 | /**
69 | * 生命周期函数--监听页面显示
70 | */
71 | onShow: function() {
72 |
73 |
74 | },
75 |
76 | /**
77 | * 生命周期函数--监听页面隐藏
78 | */
79 | onHide: function() {
80 |
81 | },
82 |
83 | /**
84 | * 生命周期函数--监听页面卸载
85 | */
86 | onUnload: function() {
87 |
88 | },
89 |
90 | /**
91 | * 页面相关事件处理函数--监听用户下拉动作
92 | */
93 | onPullDownRefresh: function() {
94 |
95 | },
96 |
97 | /**
98 | * 页面上拉触底事件的处理函数
99 | */
100 | onReachBottom: function() {
101 |
102 | },
103 |
104 | /**
105 | * 用户点击右上角分享
106 | */
107 | onShareAppMessage: function() {
108 |
109 | },
110 | // 同步显示到下方预览处
111 | bindKeyInput: function(e) {
112 | var str = e.detail.value;
113 | if (str.length > 0 && str.length <= 10) {
114 | this.setData({
115 | title: e.detail.value
116 | })
117 | } else if (str.length == 0) {
118 | this.setData({
119 | title: "请输入标题..."
120 | })
121 | } else {
122 | this.setData({
123 | title: str.substring(0, 9) + "..."
124 | })
125 | }
126 |
127 | },
128 | // 改变颜色
129 | changecolor: function(e) {
130 | var that = this;
131 | var color = e.currentTarget.dataset.color;
132 | this.setData({
133 | color: color
134 | })
135 | },
136 | // 改变角色
137 | changerole: function(e) {
138 | var that = this;
139 | var roleName = e.currentTarget.dataset.rolename;
140 | this.setData({
141 | roleName: roleName
142 | })
143 | },
144 | // 获取所有角色
145 | getrolegroups: function() {
146 | var that = this;
147 | var temp = that.data.roleGroups;
148 | for (var i in temp) {
149 | console.log(i)
150 | console.log(temp[i].roleName)
151 | }
152 | },
153 | // 获取当前日期
154 | getdate: function() {
155 | var that = this;
156 | var d = new Date();
157 | var startdate = convertDate.dateformat("yyyy-MM-dd", d);
158 | that.setData({
159 | startdate: startdate,
160 | enddate: startdate,
161 | nowdate: startdate
162 | })
163 | },
164 | // 触发起始日选择器
165 | bindDateStart: function(e) {
166 | var that = this;
167 | // console.log('picker发送选择改变,携带值为', e.detail.value)
168 | this.setData({
169 | startdate: e.detail.value
170 | })
171 | var days = util.getdays(that.data.startdate, that.data.nowdate);
172 | var alldays = util.getdays(that.data.startdate, that.data.enddate);
173 | var percent = parseInt(days / alldays * 100);
174 | // console.log(percent)
175 | that.setData({
176 | complete: days,
177 | days: alldays,
178 | percent: percent
179 | })
180 | },
181 | // 触发目标日选择器
182 | bindDateEnd: function(e) {
183 | // console.log('picker发送选择改变,携带值为', e.detail.value)
184 | var that = this;
185 | var d1 = e.detail.value
186 | var d2 = that.data.nowdate
187 | var days = util.getdays(that.data.startdate, d1);
188 | that.setData({
189 | days: days
190 | })
191 | var completedays = util.getdays(that.data.startdate, d2);
192 | var percent = parseInt(completedays / days * 100).toFixed(1);
193 | that.setData({
194 | enddate: e.detail.value,
195 | percent: percent
196 | })
197 | },
198 | // 保存选项
199 | formSubmit: function() {
200 | var that = this;
201 | that.addTimeCard();
202 | },
203 | // 创建一个新的卡片
204 | addTimeCard: function() {
205 | var that = this;
206 | /*
207 | 将卡片记录存储到数据库user-cards表中
208 | 返回的记录id,存储到user-cards-set表中
209 | */
210 | const db = wx.cloud.database();
211 | db.collection('user-cards').add({
212 | data: {
213 | carditem: {
214 | title: that.data.title,
215 | starttime: that.data.startdate,
216 | endtime: that.data.enddate,
217 | color: that.data.color,
218 | cardstype: that.data.cardstype,
219 | rolename: that.data.roleName
220 | }
221 | },
222 | success: res => {
223 | // 在返回结果中会包含新创建的记录的 _id
224 | var recordid = res._id;
225 | var userCardsset = wx.getStorageSync('userCardsset');
226 | userCardsset.push(recordid);
227 | // 更新本地数据库
228 | wx.setStorageSync('userCardsset', userCardsset)
229 | // 更新网络数据库中的user-cards-set
230 | db.collection('user-cards-set').doc(wx.getStorageSync('userCardsset_id')).update({
231 | // data 传入需要局部更新的数据
232 | data: {
233 | // 表示将 本地保存的卡片集添加新的数据并存储到数据库中
234 | cardsSet: userCardsset
235 | },
236 | success(res) {
237 | wx.setStorageSync('isNew', 1);
238 | // 新建成功,页面返回
239 | wx.navigateBack({
240 | delta: 1
241 | })
242 | }
243 | })
244 | },
245 | fail: err => {
246 | wx.showToast({
247 | icon: 'none',
248 | title: '登录失败,请重新尝试'
249 | })
250 | console.error('[数据库] [新增记录] 失败:', err)
251 | }
252 | })
253 | }
254 | })
--------------------------------------------------------------------------------
/miniprogram/pages/create/create.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "navbar": "../../components/navbar/navbar",
4 | "carditem": "../../components/carditem/carditem"
5 | }
6 | }
--------------------------------------------------------------------------------
/miniprogram/pages/create/create.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
86 |
--------------------------------------------------------------------------------
/miniprogram/pages/create/create.wxss:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 0 24rpx;
3 | }
4 |
5 | .title-groups {
6 | font-size: 32rpx;
7 | font-family: "pingfang";
8 | font-weight: bolder;
9 | color: #20bfe9;
10 | }
11 |
12 | .section {
13 | margin: 20rpx auto;
14 | /* 里面是input必须加上display与flex-direction */
15 | display: flex;
16 | flex-direction: row;
17 | justify-content: space-between;
18 | background-color: #fff;
19 | font-size: 35rpx;
20 | height: 76rpx;
21 | border-radius: 60rpx;
22 | width: 84%;
23 | padding: 0 32rpx;
24 | }
25 |
26 | .section input {
27 | margin: auto 0;
28 | width: 100%;
29 | color: #505050;
30 | }
31 |
32 | .section__title {
33 | display: flex;
34 | flex-direction: row;
35 | color: #666;
36 | }
37 |
38 | .calendar {
39 | width: 50rpx;
40 | height: 50rpx;
41 | margin: auto 0;
42 | }
43 |
44 | .picker {
45 | line-height: 76rpx;
46 | color: #505050;
47 | }
48 |
49 | .color-pick {
50 | margin: 15rpx auto;
51 | display: flex;
52 | flex-direction: row;
53 | justify-content: space-between;
54 | background-color: #fff;
55 | height: 76rpx;
56 | width: 93%;
57 | border-radius: 60rpx;
58 | }
59 |
60 | .colorpoint {
61 | width: 60rpx;
62 | height: 60rpx;
63 | border-radius: 50rpx;
64 | margin: auto 0;
65 | }
66 |
67 | .colorpointselected {
68 | width: 60rpx;
69 | height: 60rpx;
70 | border-radius: 50rpx;
71 | margin: auto 0;
72 | -webkit-box-shadow: 0px 0px 26rpx #333;
73 | }
74 |
75 | /* 角色选择 */
76 |
77 | .role-pick {
78 | margin: 15rpx auto;
79 | background-color: #fff;
80 | width: 93%;
81 | border-radius: 28rpx;
82 | }
83 |
84 | .role_scroll_x_box {
85 | width: 100%;
86 | height: 130rpx;
87 | white-space: nowrap;
88 | display: block;
89 | }
90 |
91 | ::-webkit-scrollbar {
92 | width: 0;
93 | height: 0;
94 | color: transparent;
95 | }
96 |
97 | .role-items {
98 | display: inline-flex;
99 | flex-direction: column;
100 | width: 104rpx;
101 | height: 120rpx;
102 | margin: auto 15rpx;
103 | }
104 | .role-items-selected {
105 | display: inline-flex;
106 | flex-direction: column;
107 | width: 104rpx;
108 | height: 120rpx;
109 | margin: auto 15rpx;
110 | border-bottom: 1rpx solid #333;
111 | }
112 |
113 | .role-items image {
114 | width: 80rpx;
115 | margin: auto;
116 | }
117 |
118 | .role-items-title {
119 | font-size: 22rpx;
120 | color: #505050;
121 | text-align: center;
122 | height: 35rpx;
123 | line-height: 20rpx;
124 | font-weight: lighter;
125 | }
126 |
127 | /* 保存按钮 */
128 |
129 | .submit {
130 | margin-top: 25rpx;
131 | background-color: #1968fc;
132 | left: 268rpx;
133 | border-radius: 50rpx;
134 | width: 145rpx;
135 | height: 70rpx;
136 | line-height: 70rpx;
137 | font-size: 35rpx;
138 | font-weight: bolder;
139 | Letter-spacing: 5rpx;
140 | color: #fbfbfb;
141 | }
142 |
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.js:
--------------------------------------------------------------------------------
1 | var util = require('../../utils/util.js');
2 | var convertDate = require('../../utils/convertDate.js');
3 | Page({
4 |
5 | /**
6 | * 页面的初始数据
7 | */
8 | data: {
9 | hideAddPopup: true,
10 | // 存放用户创建的卡片对应的记录id
11 | userCardsset: [],
12 | // 云端的记录此id
13 | userCardsset_id: '',
14 | // 存放所有用户创建的卡片(直接从云端获取的)
15 | cardsSet: [],
16 | // 存放处理后的用户卡片
17 | cardsPed: [],
18 | // 第一次进入该页面
19 | firstIn: true
20 | },
21 |
22 | /**
23 | * 生命周期函数--监听页面加载
24 | */
25 | onLoad: function(options) {
26 | var that = this;
27 | var cardsSet = wx.getStorageSync('cardsSet');
28 | that.getdate();
29 | if (cardsSet == '') {
30 | // 获取当前日期
31 | that.getCardsSet();
32 | if (wx.getStorageSync('userCardsset_id') == '') {
33 | // 获取用户卡片集_id
34 | that.getUserscardsSet();
35 | }
36 | } else {
37 | that.getCardsProgress(cardsSet);
38 | that.setData({
39 | cardsSet: cardsSet
40 | // cardsPed: wx.getStorageSync('cardsPed')
41 | })
42 | }
43 |
44 | },
45 |
46 | /**
47 | * 生命周期函数--监听页面初次渲染完成
48 | */
49 | onReady: function() {
50 | var that = this;
51 | that.aniAct();
52 | // 接收组件传递数据
53 | that.singList = that.selectComponent("#navComp");
54 | // console.log(that.singList)
55 |
56 | },
57 |
58 | /**
59 | * 生命周期函数--监听页面显示
60 | */
61 | onShow: function() {
62 | var that = this;
63 | if (!that.data.firstIn) {
64 | console.log("第一次显示")
65 | if (wx.getStorageSync('isNew') == 1) {
66 | that.getCardsSet();
67 | }
68 | console.log("执行了查询卡片操作")
69 | that.getCardsProgress(wx.getStorageSync('cardsSet'));
70 | }
71 | that.setData({
72 | firstIn: false
73 | })
74 |
75 | },
76 |
77 | /**
78 | * 生命周期函数--监听页面隐藏
79 | */
80 | onHide: function() {
81 |
82 | },
83 |
84 | /**
85 | * 生命周期函数--监听页面卸载
86 | */
87 | onUnload: function() {
88 |
89 | },
90 |
91 | /**
92 | * 页面相关事件处理函数--监听用户下拉动作
93 | */
94 | onPullDownRefresh: function() {
95 |
96 | },
97 |
98 | /**
99 | * 页面上拉触底事件的处理函数
100 | */
101 | onReachBottom: function() {
102 |
103 | },
104 |
105 | /**
106 | * 用户点击右上角分享
107 | */
108 | onShareAppMessage: function() {
109 |
110 | },
111 | switchAddPopup: function(e) {
112 | var that = this;
113 | // console.log(e);
114 | var temp = e.detail;
115 | if (!temp) {
116 | that.showAddPopup();
117 | } else {
118 | that.closeAddPopup();
119 | }
120 | },
121 | // 关闭Add弹出框
122 | closeAddPopup: function() {
123 | var that = this;
124 | // 运行组件navbar中的方法
125 | that.singList.createButtonHandle();
126 | // Add菜单下滑动画
127 | that.aniPopup.bottom("-380rpx").step();
128 | // 遮罩层动画
129 | that.aniMask.backgroundColor("#FFF").opacity(0).step();
130 | that.setData({
131 | aniPopupA: that.aniPopup.export(),
132 | aniMaskA: that.aniMask.export(),
133 | })
134 | setTimeout(function() {
135 | that.setData({
136 | hideAddPopup: !that.data.hideAddPopup
137 | })
138 | }, 1000)
139 |
140 | },
141 | // 显示Add弹出框
142 | showAddPopup() {
143 | // console.log(e) //可以从e中得到传过来信息
144 | var that = this;
145 | that.setData({
146 | hideAddPopup: !that.data.hideAddPopup
147 | });
148 | // Add菜单上滑动画
149 | that.aniPopup.bottom("0rpx").step();
150 | // 遮罩层动画
151 | that.aniMask.backgroundColor("#333").opacity(0.5).step();
152 | that.setData({
153 | aniPopupA: that.aniPopup.export(),
154 | aniMaskA: that.aniMask.export(),
155 | });
156 | },
157 | /*
158 | 跳转到创建卡片页面
159 | */
160 | oncreate: function(e) {
161 | var that = this;
162 | that.closeAddPopup();
163 | var cardstype = e.target.dataset.type;
164 | // console.log(cardstype)
165 | wx.navigateTo({
166 | url: '/pages/create/create?cardstype=' + cardstype,
167 | })
168 | },
169 | // 创建动画总函数
170 | aniAct: function() {
171 | var that = this;
172 | // 定义遮罩层动画
173 | that.aniMask = wx.createAnimation({
174 | duration: 1000,
175 | timingFunction: 'ease'
176 | });
177 | // 定义Add菜单上滑动画
178 | that.aniPopup = wx.createAnimation({
179 | duration: 500,
180 | timingFunction: 'ease',
181 | });
182 | },
183 | // 查询数据库中用户所创建的时间卡片
184 | // 查询数据库中的记录
185 | getUserscardsSet: function() {
186 | var that = this;
187 | console.log('执行了Query');
188 | const db = wx.cloud.database()
189 | // 查询当前用户所有的 users
190 | db.collection('user-cards-set').where({
191 | _openid: wx.getStorageSync('user-openid')
192 | }).get({
193 | success: res => {
194 | console.log(res);
195 | // 如果记录为空的的话就保存查询到的记录集id
196 |
197 | wx.setStorageSync('userCardsset_id', res.data[0]._id);
198 | var userCard = res.data[0];
199 | wx.setStorageSync('userCardsset', userCard.cardsSet);
200 | that.setData({
201 | userCardsset: userCard.cardsSet
202 | })
203 | },
204 | fail: err => {
205 | wx.showToast({
206 | icon: 'none',
207 | title: '查询记录失败'
208 | })
209 | console.error('[数据库] [查询记录] 失败:', err)
210 | }
211 | })
212 | },
213 | // 获取卡片集
214 | getCardsSet: function() {
215 | var cardsSet = [];
216 | var that = this;
217 | // 获取云端创建的所有卡片(默认:按创建时间排序)
218 | const db = wx.cloud.database()
219 | // 查询当前用户所有的 cards
220 | db.collection('user-cards').where({
221 | _openid: wx.getStorageSync('user-openid')
222 | }).get({
223 | success: res => {
224 | console.log("113")
225 | console.log(res)
226 | var cardsSet = res.data;
227 | that.getCardsProgress(cardsSet);
228 | wx.setStorageSync('cardsSet', cardsSet);
229 | // 更新标记设置为0
230 | wx.setStorageSync('isNew', 0);
231 | that.setData({
232 | cardsSet: cardsSet
233 | })
234 | },
235 | fail: err => {
236 | wx.showToast({
237 | icon: 'none',
238 | title: '查询记录失败'
239 | })
240 | console.error('[数据库] [查询记录] 失败:', err)
241 | }
242 | })
243 | },
244 | // 获取当前日期
245 | getdate: function() {
246 | var that = this;
247 | var d = new Date();
248 | var nowdate = convertDate.dateformat("yyyy-MM-dd", d);
249 | that.setData({
250 | nowdate: nowdate
251 | })
252 | },
253 | // 处理所得到了卡片
254 | getCardsProgress: function(cardsSet) {
255 | console.log("执行了卡片处理函数");
256 | var that = this;
257 | var cardsSet = cardsSet;
258 | var userCardsset = wx.getStorageSync('userCardsset');
259 | var cardsPed = [];
260 | for (var i in userCardsset) {
261 | for (var j in cardsSet) {
262 | /*
263 | 用户可定制顺序
264 | */
265 | // 用户创建的卡片对应的记录id与所有记录的id对应的存放到数组中
266 | if (userCardsset[i] == cardsSet[j]._id) {
267 | var carditem = cardsSet[j].carditem;
268 | var passeddays = util.getdays(carditem.starttime, that.data.nowdate);
269 | var alldays = util.getdays(carditem.starttime, carditem.endtime);
270 | var percent = ((passeddays / alldays) * 100).toFixed(1);
271 | var finished = false;
272 | // 使进度条的宽度不会超出
273 | if(percent > 100.0){
274 | percent = 100.0;
275 | finished = true;
276 | }
277 | var obj = {
278 | cardid: cardsSet[j]._id,
279 | cardtype: carditem.cardstype,
280 | cardcolor: carditem.color,
281 | cardendtime: carditem.endtime,
282 | cardrolename: carditem.rolename,
283 | cardstarttime: carditem.starttime,
284 | cardtitle: carditem.title,
285 | percent: percent,
286 | finished: finished
287 | }
288 | cardsPed.push(obj);
289 | }
290 | }
291 | }
292 | wx.setStorageSync('cardsPed', cardsPed)
293 | that.setData({
294 | cardsPed: cardsPed
295 | })
296 | }
297 | })
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "navbar": "../../components/navbar/navbar",
4 | "carditem": "../../components/carditem/carditem"
5 | }
6 | }
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/miniprogram/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /* 页面内容 */
2 | .container {
3 | display: flex;
4 | flex-direction: column;
5 | }
6 | .card-items {
7 | display: flex;
8 | flex-direction: column;
9 | position: relative;
10 | width: 92%;
11 | height: 300rpx;
12 | padding: 14rpx;
13 | margin: 18rpx auto;
14 | border-radius: 20rpx;
15 | background-color: #e63c56;
16 | box-shadow: 2px 2px 3px #999;
17 | }
18 |
19 | /* 事件标题、时间及操作 */
20 |
21 | .card-title-createtime-handle {
22 | display: flex;
23 | flex-direction: row;
24 | justify-content: space-between;
25 | width: 100%;
26 | }
27 |
28 | .card-title-createtime {
29 | display: flex;
30 | flex-direction: column;
31 | }
32 |
33 | .card-title {
34 | color: #fff;
35 | line-height: 50rpx;
36 | font-size: 48rpx;
37 | font-weight: bolder;
38 | font-family: "heiti";
39 | }
40 |
41 | .card-createtime {
42 | font-size: 24rpx;
43 | line-height: 40rpx;
44 | color: #eee8aa;
45 | }
46 |
47 | .card-handle image {
48 | width: 80rpx;
49 | height: 80rpx;
50 | }
51 |
52 | /* 进度条 */
53 |
54 | .card-man-progress {
55 | position: relative;
56 | width: 90%;
57 | margin: 18rpx auto 0;
58 | }
59 |
60 | .card-man image {
61 | width: 90rpx;
62 | margin-left: 80rpx;
63 | }
64 |
65 | .progress-con {
66 | position: relative;
67 | height: 18rpx;
68 | }
69 |
70 | .progress {
71 | position: absolute;
72 | top: 0;
73 | width: 20%;
74 | height: 18rpx;
75 | background-color: #fffbf3;
76 | border-radius: 10rpx;
77 | z-index: 4;
78 | }
79 |
80 | .progress-bott {
81 | position: absolute;
82 | top: 0;
83 | width: 100%;
84 | height: 18rpx;
85 | background-color: #505050;
86 | opacity: 0.5;
87 | border-radius: 10rpx;
88 | z-index: 3;
89 | }
90 |
91 | /* 结束时间样式与起始日相同 */
92 |
93 | .card-endtime {
94 | position: absolute;
95 | bottom: 40rpx;
96 | right: 10rpx;
97 | font-size: 24rpx;
98 | line-height: 40rpx;
99 | color: #eee8aa;
100 | text-align: right;
101 | }
102 |
103 | /* 标签 */
104 |
105 | .card-tag {
106 | display: flex;
107 | flex-direction: row;
108 | position: absolute;
109 | bottom: 10rpx;
110 | right: 5rpx;
111 | height: 36rpx;
112 | /* background- color: red; */
113 | }
114 |
115 | .tag-item {
116 | padding: 0 4rpx;
117 | font-size: 30rpx;
118 | color: #79a2a8;
119 | font-weight: bolder;
120 | line-height: 36rpx;
121 | background-color: #fffbf3;
122 | border-radius: 6rpx;
123 | margin: 0 8rpx;
124 | right: 0;
125 | }
126 |
127 | /* 弹出的添加操作框 */
128 |
129 | .show-popup {
130 | position: fixed;
131 | top: 0;
132 | left: 0;
133 | width: 100%;
134 | height: 100%;
135 | z-index: 96;
136 | }
137 |
138 | .popup-mask {
139 | position: fixed;
140 | top: 0;
141 | left: 0;
142 | width: 100%;
143 | height: 100%;
144 | /*透明色 */
145 | /* background-color: rgba(0, 0, 0, 0.5); */
146 | opacity: 0;
147 | z-index: 97;
148 | }
149 |
150 | .popup-contents {
151 | position: fixed;
152 | display: flex;
153 | flex-direction: column;
154 | left: 0;
155 | bottom: -380rpx;
156 | width: 100%;
157 | height: 380rpx;
158 | background-color: #fff;
159 | z-index: 98;
160 | }
161 |
162 | .popup-cancel {
163 | margin-top: 30rpx;
164 | }
165 |
166 | .popup-cancel .txt {
167 | float: right;
168 | margin-right: 40rpx;
169 | color: #666;
170 | }
171 |
172 | .popup-title {
173 | margin: 0 auto;
174 | font-size: 45rpx;
175 | font-weight: bolder;
176 | color: #333;
177 | border-bottom: 2rpx solid #666;
178 | }
179 |
180 | .button-container {
181 | margin: 70rpx auto 0 auto;
182 | display: flex;
183 | flex-direction: row;
184 | justify-content: space-between;
185 | width: 90%;
186 | }
187 |
188 | .button-img {
189 | width: 300rpx;
190 | height: 100rpx;
191 | background-color: #fff;
192 | border-radius: 15rpx;
193 | box-shadow: 4rpx 4rpx 6rpx #666;
194 | }
195 |
--------------------------------------------------------------------------------
/miniprogram/pages/login/login.js:
--------------------------------------------------------------------------------
1 | // pages/login/login.js
2 | const app = getApp();
3 | var convertDate = require('../../utils/convertDate.js');
4 | Page({
5 |
6 | /**
7 | * 页面的初始数据
8 | */
9 | data: {
10 | logged: false,
11 | loginStatus: 0,
12 | userInfo: {},
13 | cardsSet: []
14 | },
15 |
16 | /**
17 | * 生命周期函数--监听页面加载
18 | */
19 | onLoad: function(options) {
20 | var that = this;
21 | // 查看本地存储中的user-openid是否存在用户的openid
22 | var openid = wx.getStorageSync('user-openid');
23 | if (openid != '') {
24 | that.onQuery();
25 | }
26 | // 获取当前系统的宽高,并保存
27 | var a = wx.getSystemInfoSync();
28 | that.setData({
29 | screenHeight: a.screenHeight,
30 | screenWidth: a.screenWidth
31 | })
32 | // 按类获取元素的宽高
33 | var obj = wx.createSelectorQuery();
34 | obj.selectAll('.logo').boundingClientRect(function(rect) {
35 | that.setData({
36 | logoWidth: rect[0].width,
37 | logoHeight: rect[0].height
38 | })
39 | })
40 | obj.exec();
41 | // 获取本地卡片数组存储
42 | var cardsSet = wx.getStorageSync('cardsSet');
43 | if (cardsSet != '') {
44 | that.setData({
45 | cardsSet: cardsSet
46 | })
47 | }
48 | },
49 |
50 | /**
51 | * 生命周期函数--监听页面初次渲染完成
52 | */
53 | onReady: function() {
54 |
55 | },
56 |
57 | /**
58 | * 生命周期函数--监听页面显示
59 | */
60 | onShow: function() {
61 |
62 | },
63 |
64 | /**
65 | * 生命周期函数--监听页面隐藏
66 | */
67 | onHide: function() {
68 |
69 | },
70 |
71 | /**
72 | * 生命周期函数--监听页面卸载
73 | */
74 | onUnload: function() {
75 |
76 | },
77 |
78 | /**
79 | * 页面相关事件处理函数--监听用户下拉动作
80 | */
81 | onPullDownRefresh: function() {
82 |
83 | },
84 |
85 | /**
86 | * 页面上拉触底事件的处理函数
87 | */
88 | onReachBottom: function() {
89 |
90 | },
91 |
92 | /**
93 | * 用户点击右上角分享
94 | */
95 | onShareAppMessage: function() {
96 |
97 | },
98 | // 点击登录按钮要做的事情
99 | // 获取用户信息,并存到当前的Data中
100 | onGotUserInfo: function (e) {
101 | var that = this;
102 | // 设置按钮的样式
103 | that.setLoading();
104 | // 获取用户的openid
105 | that.onGetOpenid();
106 | console.log(e)
107 | if (!that.data.logged && e.detail.userInfo) {
108 | that.setData({
109 | logged: true,
110 | userInfo: e.detail.userInfo
111 | });
112 | // 在插入时检查数据库中是否已经存在
113 | setTimeout(function () {
114 | that.onQuery();
115 | }, 1000)
116 | }
117 | },
118 | /*
119 |
120 | 登录状态:0:未登录/登录失败,1:登录成功,2:登录中
121 | */
122 | // 按钮出显示加载图标
123 | setLoading: function(e) {
124 | var that = this;
125 | var loginStatus = that.data.loginStatus;
126 | if (loginStatus == 0) {
127 | that.setData({
128 | loading: !this.data.loading,
129 | loginStatus: 2
130 | })
131 | }
132 | },
133 | // 获取用户的openid
134 | onGetOpenid: function() {
135 | var that = this;
136 | // 调用云函数
137 | wx.cloud.callFunction({
138 | name: 'login',
139 | data: {},
140 | success: res => {
141 | console.log('[云函数] [login] user openid: ', res.result.openid)
142 | app.globalData.openid = res.result.openid;
143 | // 将openid存储到本地以便使用
144 | wx.setStorageSync("user-openid", res.result.openid)
145 | },
146 | fail: err => {
147 | console.error('[云函数] [login] 调用失败', err)
148 | that.setData({
149 | loginStatus: 0
150 | })
151 | wx.showToast({
152 | title: '登录失败',
153 | })
154 |
155 | }
156 | })
157 | },
158 |
159 | // 登录成功
160 | loginSuccess: function() {
161 | var that = this;
162 | that.setData({
163 | loginStatus: 1
164 | });
165 | // 显示登录成功延迟0.5秒跳转页面
166 | setTimeout(function() {
167 | wx.redirectTo({
168 | url: '../index/index',
169 | })
170 | }, 200);
171 | },
172 | // 向数据库中添加用户数据
173 | onAdd: function() {
174 | const db = wx.cloud.database()
175 | db.collection('users').add({
176 | data: {
177 | userInfo: this.data.userInfo
178 | },
179 | success: res => {
180 | // 在返回结果中会包含新创建的记录的 _id
181 | console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
182 | },
183 | fail: err => {
184 | wx.showToast({
185 | icon: 'none',
186 | title: '登录失败,请重新尝试'
187 | })
188 | console.error('[数据库] [新增记录] 失败:', err)
189 | }
190 | })
191 | },
192 | // 查询数据库中的记录
193 | onQuery: function() {
194 | var that = this;
195 | console.log('执行了Query');
196 | const db = wx.cloud.database()
197 | // 查询当前用户所有的 users
198 | db.collection('users').where({
199 | _openid: wx.getStorageSync('user-openid')
200 | }).get({
201 | success: res => {
202 | if (res.data.length != 0) {
203 | this.loginSuccess();
204 | this.setData({
205 | loginStatus: 1
206 | })
207 | } else {
208 | // 查询结果中没有存储用户的信息,将信息存储到云端
209 | if (that.data.loginStatus != 1 && wx.getStorageSync('user-openid') != '') {
210 | console.log("运行存储");
211 | // 添加用户信息、初始化卡片到数据库中
212 | this.onAdd();
213 | this.createFirst();
214 | }
215 | }
216 |
217 | },
218 | fail: err => {
219 | wx.showToast({
220 | icon: 'none',
221 | title: '查询记录失败'
222 | })
223 | console.error('[数据库] [查询记录] 失败:', err)
224 | }
225 | })
226 | },
227 | // 获取当前日期
228 | getdate: function() {
229 | var that = this;
230 | var d = new Date();
231 | var nowdate = convertDate.dateformat("yyyy-MM-dd", d);
232 | var year = convertDate.dateformat("yyyy", d);
233 | that.setData({
234 | startdate: year + '-01-01',
235 | enddate: year + '-12-31',
236 | nowdate: nowdate
237 | })
238 | },
239 | // 创建一个今年已经度过时间卡片
240 | createFirst: function() {
241 | var that = this;
242 | that.getdate();
243 | const db = wx.cloud.database();
244 | db.collection('user-cards').add({
245 | data: {
246 | carditem: {
247 | title: '距2019年结束',
248 | starttime: that.data.startdate,
249 | endtime: that.data.enddate,
250 | color: '#e63c56',
251 | cardstype: 'countback',
252 | rolename: 'Superman'
253 | }
254 | },
255 | success: res => {
256 | // 在返回结果中会包含新创建的记录的 _id
257 | var recordid = res._id;
258 | var cardsSet = that.data.cardsSet;
259 | cardsSet.push(recordid);
260 | db.collection('user-cards-set').add({
261 | data: {
262 | cardsSet: cardsSet
263 | },
264 | success: res => {
265 | // 在返回结果中会包含新创建的记录的 _id
266 | console.log('卡片集添加数据成功: ', res._id)
267 | // 将存放记录id存入到本地
268 | wx.setStorageSync('userCardsset_id', res._id)
269 | that.loginSuccess();
270 | },
271 | fail: err => {
272 | console.error('卡片集添加数据失败:', err)
273 | }
274 | })
275 | console.log('[数据库] [新增记录] 成功,记录 _id: ', res._id)
276 | },
277 | fail: err => {
278 | wx.showToast({
279 | icon: 'none',
280 | title: '登录失败,请重新尝试'
281 | })
282 | console.error('[数据库] [新增记录] 失败:', err)
283 | }
284 | })
285 | },
286 |
287 | })
--------------------------------------------------------------------------------
/miniprogram/pages/login/login.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {}
3 | }
--------------------------------------------------------------------------------
/miniprogram/pages/login/login.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 时光车站
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/miniprogram/pages/login/login.wxss:
--------------------------------------------------------------------------------
1 | /* pages/login/login.wxss */
2 |
3 | .container {
4 | position: relative;
5 | margin: 0;
6 | }
7 |
8 | .logo {
9 | position: absolute;
10 | top: 24%;
11 | font-size: 80rpx;
12 | text-indent : 30rpx;
13 | letter-spacing: 30rpx;
14 | font-weight: lighter;
15 | text-align: center;
16 |
17 | }
18 |
19 | .login-btn-container {
20 | position: absolute;
21 | bottom: 100rpx;
22 | }
23 |
24 | .login-btn {
25 | margin: 0 auto;
26 | }
27 |
--------------------------------------------------------------------------------
/miniprogram/sitemap.json:
--------------------------------------------------------------------------------
1 | {
2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3 | "rules": [{
4 | "action": "allow",
5 | "page": "*"
6 | }]
7 | }
--------------------------------------------------------------------------------
/miniprogram/style/guide.wxss:
--------------------------------------------------------------------------------
1 | page {
2 | background: #f6f6f6;
3 | display: flex;
4 | flex-direction: column;
5 | justify-content: flex-start;
6 | }
7 |
8 | .list {
9 | margin-top: 40rpx;
10 | height: auto;
11 | width: 100%;
12 | background: #fff;
13 | padding: 0 40rpx;
14 | border: 1px solid rgba(0, 0, 0, 0.1);
15 | border-left: none;
16 | border-right: none;
17 | transition: all 300ms ease;
18 | display: flex;
19 | flex-direction: column;
20 | align-items: stretch;
21 | box-sizing: border-box;
22 | }
23 |
24 | .list-item {
25 | width: 100%;
26 | padding: 0;
27 | line-height: 104rpx;
28 | font-size: 34rpx;
29 | color: #007aff;
30 | border-top: 1px solid rgba(0, 0, 0, 0.1);
31 | display: flex;
32 | flex-direction: row;
33 | align-content: center;
34 | justify-content: space-between;
35 | box-sizing: border-box;
36 | }
37 |
38 | .list-item:first-child {
39 | border-top: none;
40 | }
41 |
42 | .list-item image {
43 | max-width: 100%;
44 | max-height: 20vh;
45 | margin: 20rpx 0;
46 | }
47 |
48 | .request-text {
49 | color: #222;
50 | padding: 20rpx 0;
51 | font-size: 24rpx;
52 | line-height: 36rpx;
53 | word-break: break-all;
54 | }
55 |
56 | .guide {
57 | width: 100%;
58 | padding: 40rpx;
59 | box-sizing: border-box;
60 | display: flex;
61 | flex-direction: column;
62 | }
63 |
64 | .guide .headline {
65 | font-size: 34rpx;
66 | font-weight: bold;
67 | color: #555;
68 | line-height: 40rpx;
69 | }
70 |
71 | .guide .p {
72 | margin-top: 20rpx;
73 | font-size: 28rpx;
74 | line-height: 36rpx;
75 | color: #666;
76 | }
77 |
78 | .guide .code {
79 | margin-top: 20rpx;
80 | font-size: 28rpx;
81 | line-height: 36rpx;
82 | color: #666;
83 | background: white;
84 | white-space: pre;
85 | }
86 |
87 | .guide .code-dark {
88 | margin-top: 20rpx;
89 | background: rgba(0, 0, 0, 0.8);
90 | padding: 20rpx;
91 | font-size: 28rpx;
92 | line-height: 36rpx;
93 | border-radius: 6rpx;
94 | color: #fff;
95 | white-space: pre
96 | }
97 |
98 | .guide image {
99 | max-width: 100%;
100 | }
101 |
102 | .guide .image1 {
103 | margin-top: 20rpx;
104 | max-width: 100%;
105 | width: 356px;
106 | height: 47px;
107 | }
108 |
109 | .guide .image2 {
110 | margin-top: 20rpx;
111 | width: 264px;
112 | height: 100px;
113 | }
114 |
115 | .guide .flat-image {
116 | height: 100px;
117 | }
118 |
119 | .guide .code-image {
120 | max-width: 100%;
121 | }
122 |
123 | .guide .copyBtn {
124 | width: 180rpx;
125 | font-size: 20rpx;
126 | margin-top: 16rpx;
127 | margin-left: 0;
128 | }
129 |
130 | .guide .nav {
131 | margin-top: 50rpx;
132 | display: flex;
133 | flex-direction: row;
134 | align-content: space-between;
135 | }
136 |
137 | .guide .nav .prev {
138 | margin-left: unset;
139 | }
140 |
141 | .guide .nav .next {
142 | margin-right: unset;
143 | }
144 |
145 |
--------------------------------------------------------------------------------
/miniprogram/utils/convertDate.js:
--------------------------------------------------------------------------------
1 | // 对Date的扩展,将 Date 转化为指定格式的String
2 | // 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
3 | // 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
4 | // 例子:
5 | // (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
6 | // (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
7 | var dateformat = function dateFtt(fmt, date) { //author: meizz
8 | var o = {
9 | "M+": date.getMonth() + 1, //月份
10 | "d+": date.getDate(), //日
11 | "h+": date.getHours(), //小时
12 | "m+": date.getMinutes(), //分
13 | "s+": date.getSeconds(), //秒
14 | "q+": Math.floor((date.getMonth() + 3) / 3), //季度
15 | "S": date.getMilliseconds() //毫秒
16 | };
17 | if (/(y+)/.test(fmt))
18 | fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
19 | for (var k in o)
20 | if (new RegExp("(" + k + ")").test(fmt))
21 | fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
22 | return fmt;
23 | }
24 |
25 | // 要引用这个文件的函数或者变量,除了在要引用的的js文件中模块化之外(var utils=require('js地址')),
26 | // 在被引用的的js中要通过 module.exports={a:a}作为面向对象的变量输出函数如下:
27 | module.exports = {
28 | dateformat: dateformat//要引用的函数 xx:xx
29 | }
--------------------------------------------------------------------------------
/miniprogram/utils/util.js:
--------------------------------------------------------------------------------
1 | function formatTime(date) {
2 | var year = date.getFullYear()
3 | var month = date.getMonth() + 1
4 | var day = date.getDate()
5 |
6 | var hour = date.getHours()
7 | var minute = date.getMinutes()
8 | var second = date.getSeconds()
9 |
10 | return [year, month, day].map(formatNumber).join('')
11 | }
12 |
13 | function formatNumber(n) {
14 | n = n.toString()
15 | return n[1] ? n : '0' + n
16 | }
17 |
18 | function convertToStarsArray(stars) {
19 | var num = stars.toString().substring(0, 1);
20 | var array = [];
21 | for (var i = 1; i <= 5; i++) {
22 | if (i <= num) {
23 | array.push(1);
24 | } else {
25 | array.push(0);
26 | }
27 | }
28 | return array;
29 | }
30 |
31 | function http(url, callBack) {
32 | wx.request({
33 | url: url,
34 | method: 'GET',
35 | header: {
36 | "Content-Type": "json"
37 | },
38 | success: function(res) {
39 | callBack(res.data);
40 | },
41 | fail: function(error) {
42 | console.log(error)
43 | }
44 | })
45 | }
46 |
47 | function convertToCastString(casts) {
48 | var castsjoin = "";
49 | for (var idx in casts) {
50 | castsjoin = castsjoin + casts[idx].name + " / ";
51 | }
52 | return castsjoin.substring(0, castsjoin.length - 2);
53 | }
54 |
55 | function convertToCastInfos(casts) {
56 | var castsArray = []
57 | for (var idx in casts) {
58 | var cast = {
59 | img: casts[idx].avatars ? casts[idx].avatars.large : "",
60 | name: casts[idx].name
61 | }
62 | castsArray.push(cast);
63 | }
64 | return castsArray;
65 | }
66 |
67 | // 两日期相减得到相差天数
68 | function getdays(day1, day2) {
69 | var that = this;
70 | var d1 = day1;
71 | var d2 = day2;
72 | d1 = d1.replace(/\-/g, "/");
73 | d2 = d2.replace(/\-/g, "/");
74 | var date1 = new Date(d1);
75 | var date2 = new Date(d2);
76 | var days = Math.ceil((date2 - date1) / (24 * 60 * 60 * 1000));
77 | return days;
78 | }
79 |
80 |
81 |
82 |
83 | module.exports = {
84 | formatTime: formatTime,
85 | convertToStarsArray: convertToStarsArray,
86 | http: http,
87 | convertToCastString: convertToCastString,
88 | convertToCastInfos: convertToCastInfos,
89 | getdays: getdays
90 | }
--------------------------------------------------------------------------------
/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "miniprogramRoot": "miniprogram/",
3 | "cloudfunctionRoot": "cloudfunctions/",
4 | "setting": {
5 | "urlCheck": true,
6 | "es6": true,
7 | "postcss": true,
8 | "minified": true,
9 | "newFeature": true
10 | },
11 | "appid": "输入自己的",
12 | "projectname": "TimeCard",
13 | "libVersion": "2.2.5",
14 | "simulatorType": "wechat",
15 | "simulatorPluginLibVersion": {},
16 | "condition": {
17 | "search": {
18 | "current": -1,
19 | "list": []
20 | },
21 | "conversation": {
22 | "current": -1,
23 | "list": []
24 | },
25 | "plugin": {
26 | "current": -1,
27 | "list": []
28 | },
29 | "game": {
30 | "list": []
31 | },
32 | "miniprogram": {
33 | "current": 0,
34 | "list": [
35 | {
36 | "id": -1,
37 | "name": "db guide",
38 | "pathName": "pages/databaseGuide/databaseGuide"
39 | }
40 | ]
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------