437c1c5a by simon

基础工程

0 parents
Showing 75 changed files with 3721 additions and 0 deletions
1 root = true;
2
3 [*]
4 # indent_style = tab
5 indent_style = space
6 # indent_size = 4
7 indent_size = 2
8 tab_width = 2
9 end_of_line = lf
10 trim_trailing_whitespace = true
11 insert_final_newline = true
12
13 # [*.{json,yml,wxml,html}]
14 # indent_style = tab
15 # indent_size = 4
16 # tab_width = 2
17
18
19 [README.md]
20 trim_trailing_whitespace = ignore
1 .idea
2 .DS_Store
3 dist
4 tmp
5 node_modules
6 _old
7 config.custom.js
8
9 src/assets/images/filetype.png
10
11 src/assets/images/filetype@2x.png
1 .gitignore
2 .editorconfig
3 .eslintrc
4 .idea
5 node_modules/
6 npm-debug.log
7 CHANGELOG.md
8 test
9 examples
10 gulpfile.js
11 .travis.yml
12 appveyor.yml
13 .DS_Store
14 dist
15 tmp
16 _old
17 config.custom.js
18 src/assets/images/filetype.png
19 src/assets/images/filetype@2x.png
1 sudo: false
2 language: node_js
3 node_js:
4 - "6"
5 - "7"
6 - "8"
7 - "stable"
8 before_script:
9 - npm install -g gulp@next
1 MIT License
2
3 Copyright (c) 2017 Jeff Ma
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.
1 ## 介绍
2
3 mp-gulp-framework 是一个专门为开发微信小程序打造的前端开发工作流,基于Gulp 4 开发,旨在通过工作流的方式解决微信小程序开发过程中写前端代码的痛点。
4
5 借鉴于:[https://github.com/Jeff2Ma/WeApp-Workflow](https://github.com/Jeff2Ma/WeApp-Workflow)
6 在此基础上作修改。
7
8 ## 功能
9
10 ### SCSS 实时编译为 WXSS
11
12 使用Sass 预处理器,让写CSS 更加顺畅。`.scss`文件会实时编译为微信小程序支持的`.wxss`文件。
13
14 ### WXSS(CSS) 中px 单位转小程序单位rpx
15
16 以官方推荐的iPhone 6 为标准设计格式,开发中直接写`px` 即可自动转换为`rpx`
17
18 其中屏幕铺满为750px。
19
20 ```css
21 // Input: src/pages/index/index.scss
22 .index__header {
23 font-size: 14px;
24 margin-top: 20PX; /* 如果为大写的`PX`单位则不会转换 */
25 }
26
27 // Output: dist/pages/index/index.wxss
28 .index__header {
29 font-size: 28rpx;
30 margin-top: 20PX; /* 如果为大写的`PX`单位则不会转换 */
31 }
32
33 ```
34
35 ### 图片压缩
36
37 实时压缩图片并采用增量方式防止被重复压缩。
38
39 ### 自动上传图片到CDN 并更新路径为https 绝对路径
40
41 小程序不支持相对路径的图片引用,仅支持带`https`协议头的绝对路径。本工作流可以将WXML 以及WXSS 文件中引用的相对路径图片上传到云存储CDN 或通过FTP/SFTP 协议上传到个人服务器空间。目前支持腾讯云,七牛云。
42
43 ```html
44 // Input: src/pages/index/index.wxml
45 <image src="%ASSETS_IMG%/t.png"></image>
46
47 // Output: dist/pages/index/index.wxml
48 <image src="https://cdn.devework.com/weapp/devework/t.png"></image>
49 ```
50
51 ### Font 文件转为base64 编码
52
53 小程序不支持相对路径的字体文件,本工作流可将CSS 中引用到的Font 文件转码为base64 并替换原路径。
54
55 ```
56 // Input: src/pages/index/index.scss
57 @font-face {
58 font-family: 'fontello';
59 src: url("assets/fonts/fontello.ttf") format('truetype');
60 }
61
62 // Output: dist/pages/index/index.wxss
63 @font-face {
64 font-family: 'fontello';
65 src: url(data:application/font-sfnt;charset=utf-8;base64,AAEAAAAPAIAA....FsASNsQIARAAA) format("truetype");
66 }
67
68 ```
69 ### 全自动构建雪碧图及生成相应CSS
70
71 本功能由[postcss-lazysprite](https://github.com/Jeff2Ma/postcss-lazysprite) 插件驱动。开发中准备好图片后仅仅写一句类似`@lazysprite "xxxx"`的代码,即可全自动构建雪碧图及生成相应CSS。
72
73 ```css
74 // Input: src/app.scss
75 @lazysprite "filetype";
76
77 // Output: dist/app.wxss
78 .icon-filetype-doc {
79 background-image: url(../sprites/filetype.png);
80 background-position: 0 0;
81 width: 80px;
82 height: 80px;
83 }
84
85 .icon-filetype-pdf {
86 background-image: url(../sprites/filetype.png);
87 background-position: -90px 0;
88 width: 80px;
89 height: 80px;
90 }
91
92 @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio:2) {
93 .icon-filetype-doc {
94 background-image: url(../sprites/filetype@2x.png);
95 background-position: 0 0;
96 background-size: 170px 170px;
97 }
98
99 .icon-filetype-pdf {
100 background-image: url(../sprites/filetype@2x.png);
101 background-position: -90px 0;
102 background-size: 170px 170px;
103 }
104 }
105 ```
106
107
108 ## 项目结构
109
110 ```
111 .
112 ├── config.custom.js // gulp自定义配置,会覆盖config.js
113 ├── config.js // gulp 配置文件
114 ├── gulpfile.js
115 ├── package.json
116 ├── src // 开发目录
117 │   ├── app.js
118 │   ├── app.json
119 │   ├── app.scss
120 │   ├── assets // 开发相关的静态文件原始资源
121 │  │   ├── fonts //字体文件
122 │  │   ├── images // 图片文件,可被上传到CDN
123 │  │   ├── scss // 一般放置SCSS 的minxins 等被import 的SCSS 文件
124 │  │   └── sprites // 生成雪碧图小图的目录
125 │   ├── image // 小程序专用的图片资源(如tabbar icon)目录
126 │   ├── pages
127 │   └── utils
128 ├── tmp // 通过src 目录编译后生成的缓存目录
129 └── dist // 通过src 目录编译后生成的文件目录,也是小程序开发的项目目录
130
131 ```
1 # Notes:
2 # - Minimal appveyor.yml file is an empty file. All sections are optional.
3 # - Indent each level of configuration with 2 spaces. Do not use tabs!
4 # - All section names are case-sensitive.
5 # - Section names should be unique on each level.
6
7 #---------------------------------#
8 # general configuration #
9 #---------------------------------#
10
11 # branches to build
12 #branches:
13 # # whitelist
14 # only:
15 # - master
16 # - test
17
18 # Do not build on tags (GitHub and BitBucket)
19 skip_tags: true
20
21 # Do not build feature branch with open Pull Requests
22 skip_branch_with_pr: true
23
24 # Build worker image (VM template)
25 image: Visual Studio 2015
26
27 environment:
28 matrix:
29 - nodejs_version: 4.7.0
30
31 # scripts that run after cloning repository
32 install:
33 # to run script as a PowerShell command prepend it with ps:
34 - ps: Install-Product node $env:nodejs_version
35 # batch commands start from cmd:
36 - npm cache clean
37 - npm i
38 - npm install -g gulp@next
39
40 # to run your custom scripts instead of automatic tests
41 test_script:
42 # Output useful info for debugging.
43 - node --version && npm --version
44 - npm i
45 - pwd
46 - gulp test
47
48 # Don't actually build.
49 build: off
50
51 matrix:
52 fast_finish: true
53
54 cache:
55 # local npm modules
56 - C:\Users\appveyor\AppData\Roaming\npm-cache -> package.json # npm cache
57 - node_modules -> package.json
1 /**
2 * ------------------------------------------------------------------
3 * 配置文件
4 *
5 * 建议复制一份并重命名为 config.custom.js ,即可在config.custom.js 上根据需求进行配置
6 * ------------------------------------------------------------------
7 *
8 */
9
10 module.exports = {
11 "enabledQcloud": false, //是否开启腾讯云COS 上传功能
12 // 腾讯云COS 上传功能配置表
13 "qcloud": {
14 "appid": "1111111",
15 "secretId": "xxx",
16 "secretKey": "xxxxx",
17 "bucket": "xxxx",
18 "region": "sh",
19 "prefix": "what-ever/you-want",
20 "overWrite": true,
21 "headers": {
22 "Cache-Control": "max-age=5184000"
23 }
24 },
25 // 静态资源CDN 域名,配合CDN 功能实用,线上请确保在mp管理端已经注册域名
26 "assetsCDN": "https://res.jianhui.org/"
27 };
1 /**
2 * ------------------------------------------------------------------
3 * gulpfile 文件
4 * ------------------------------------------------------------------
5 */
6
7 var path = require('path');
8 var gulp = require('gulp');
9 var sass = require('gulp-sass');
10 var rename = require('gulp-rename');
11 var imagemin = require('gulp-imagemin');
12 var sftp = require('gulp-sftp');
13 var del = require('del');
14 var replace = require('gulp-replace');
15 var postcss = require('gulp-postcss');
16 var qcloudUpload = require('gulp-qcloud-upload');
17 var gulpif = require('gulp-if');
18 var gutil = require('gulp-util');
19 var newer = require('gulp-newer');
20 var cache = require('gulp-cached');
21 var debug = require('gulp-debug');
22 var pxtorpx = require('postcss-px2rpx');
23 // var base64 = require('postcss-font-base64');
24 // var lazysprite = require('postcss-lazysprite');
25 var argv = require('yargs').argv;
26 var config = null;
27
28 // 获取用户配置
29 try {
30 config = require('./config.custom.js');
31 } catch (e) {
32 try {
33 config = require('./config.js');
34 } catch (e) {
35 log(gutil.colors.red('丢失配置文件(config.js/config.custom.js)'));
36 }
37 }
38
39 // 相关路径配置
40 var paths = {
41 src: {
42 baseDir: 'src',
43 imgDir: 'src/image',
44 spriteDir: 'src/assets/sprites',
45 scssDir: 'src/assets/scss',
46 imgFiles: 'src/image/**/*',
47 scssFiles: 'src/**/*.scss',
48 baseFiles: ['src/**/*.{png,js,json,wxml,wxss,wxs,ts,woff2}', '!src/assets/**/*', '!src/image/**/*'],
49 assetsDir: 'src/assets',
50 assetsImgFiles: 'src/assets/images/**/*.{png,jpg,jpeg,svg,gif}',
51 wxmlFiles: ['src/**/*.wxml'],
52 jsFiles: 'src/**/*.js'
53 },
54 dist: {
55 baseDir: 'dist',
56 imgDir: 'dist/image',
57 wxssFiles: 'dist/**/*.wxss',
58 },
59 tmp: {
60 baseDir: 'tmp',
61 imgDir: 'tmp/assets/images',
62 imgFiles: 'tmp/assets/images/**/*.{png,jpg,jpeg,svg,gif}'
63 }
64 };
65
66 // 雪碧图的配置
67 var lazyspriteConfig = {
68 imagePath: paths.src.spriteDir,
69 stylesheetInput: paths.src.scssDir,
70 stylesheetRelative: paths.src.assetsDir,
71 spritePath: paths.src.assetsDir + '/images',
72 smartUpdate: false,
73 cssSeparator: '-',
74 outputExtralCSS: true,
75 nameSpace: 'icon-'
76 };
77
78 // Log for output msg.
79 function log() {
80 var data = Array.prototype.slice.call(arguments);
81 gutil.log.apply(false, data);
82 }
83
84 // 压缩图片
85 function imageMin() {
86 // return gulp.src(paths.src.imgFiles, {si≤nce: gulp.lastRun(imageMin)})
87 return gulp.src(paths.src.imgFiles)
88 .pipe(newer(paths.dist.imgDir))
89 .pipe(imagemin({
90 progressive: true,
91 svgoPlugins: [{
92 removeViewBox: false
93 }]
94 }))
95 .pipe(gulp.dest(paths.dist.imgDir));
96 }
97
98 // assets 文件夹下的图片处理
99 function assetsImgMin() {
100 return gulp.src(paths.src.assetsImgFiles)
101 .pipe(newer(paths.tmp.imgDir))
102 .pipe(imagemin({
103 progressive: true,
104 svgoPlugins: [{
105 removeViewBox: false
106 }]
107 }))
108 .pipe(gulp.dest(paths.tmp.imgDir))
109 }
110
111 // Sass 编译
112 function sassCompile() {
113 var res = config.assetsCDN + config.qcloud.prefix + '/';
114 // 缩放比例 1为750
115 var pxtorpxOpts = {
116 times: 1
117 };
118 return gulp.src(paths.src.scssFiles)
119 .pipe(sass({
120 errLogToConsole: true,
121 outputStyle: 'expanded'
122 })
123 .on('error', sass.logError))
124 .pipe(gulpif(Boolean(argv.debug), debug({
125 title: '`sassCompile` Debug:'
126 })))
127 // .pipe(postcss([lazysprite(lazyspriteConfig), pxtorpx(pxtorpxOpts), base64()]))
128 .pipe(postcss([pxtorpx(pxtorpxOpts)]))
129 .pipe(rename({
130 'extname': '.wxss'
131 }))
132 .pipe(replace('.scss', '.wxss'))
133 .pipe(replace('%ASSETS_IMG%/', res))
134 .pipe(replace('src/assets/images', res)) // 雪碧图CSS RUL 中的图片路径
135 .pipe(gulp.dest(paths.dist.baseDir))
136 }
137
138
139 // 复制基础文件
140 function copyBasicFiles() {
141 return gulp.src(paths.src.baseFiles, {})
142 .pipe(gulp.dest(paths.dist.baseDir));
143 }
144
145 // 复制 WXML
146 function copyWXML() {
147 return gulp.src(paths.src.wxmlFiles, {})
148 .pipe(gulp.dest(paths.dist.baseDir));
149 }
150
151
152 // 重写WXML 中 image 标签中的图片路径
153 function wxmlImgRewrite() {
154 var res = config.assetsCDN + config.qcloud.prefix + '/';
155 // console.log(res);
156 return gulp.src(paths.src.wxmlFiles)
157 .pipe(replace('%ASSETS_IMG%/', res))
158 .pipe(gulp.dest(paths.dist.baseDir))
159 }
160
161 // clean 任务, dist 目录
162 function cleanDist() {
163 return del(paths.dist.baseDir);
164 }
165
166 // clean tmp 目录
167 function cleanTmp() {
168 return del(paths.tmp.baseDir);
169 }
170
171 // 腾讯云上传任务
172 function qcloudCDN(cb) {
173 if (config.enabledQcloud) {
174 // return gulp.src(paths.src.assetsImgFiles, {since: gulp.lastRun(qcloudCDN)})
175 return gulp.src(paths.tmp.imgFiles)
176 .pipe(cache('qcloudCache'))
177 .pipe(qcloudUpload({
178 appid: config.qcloud.appid,
179 secretId: config.qcloud.secretId,
180 secretKey: config.qcloud.secretKey,
181 bucket: config.qcloud.bucket,
182 region: config.qcloud.region,
183 prefix: config.qcloud.prefix,
184 overWrite: config.qcloud.overWrite,
185 headers: config.qcloud.headers
186 }));
187 }
188 cb();
189 }
190
191
192 var watchHandler = function (type, file) {
193 var extname = path.extname(file);
194 // SCSS 文件
195 if (extname === '.scss') {
196 if (type === 'removed') {
197 var tmp = file.replace('src/', 'dist/').replace(extname, '.wxss');
198 del([tmp]);
199 } else {
200 sassCompile();
201 }
202 }
203 // 图片文件
204 else if (extname === '.png' || extname === '.jpg' || extname === '.jpeg' || extname === '.svg' || extname === '.gif') {
205 if (type === 'removed') {
206 if (file.indexOf('assets') > -1) {
207 del([file.replace('src/', 'tmp/')]);
208 } else {
209 del([file.replace('src/', 'dist/')]);
210 }
211 } else {
212 imageMin();
213 assetsImgMin();
214 qcloudCDN();
215 wxmlImgRewrite();
216 }
217 }
218
219 // wxml
220 else if (extname === '.wxml') {
221 if (type === 'removed') {
222 var tmp = file.replace('src/', 'dist/')
223 del([tmp]);
224 } else {
225 copyWXML();
226 wxmlImgRewrite();
227 }
228 }
229
230 // 其余文件
231 else {
232 if (type === 'removed') {
233 var tmp = file.replace('src/', 'dist/');
234 del([tmp]);
235 } else {
236 copyBasicFiles();
237 // copyWXML();
238 // wxmlImgRewrite();
239 }
240 }
241 };
242
243 //监听文件
244 function watch(cb) {
245 var watcher = gulp.watch([
246 paths.src.baseDir,
247 paths.tmp.imgDir
248 ], {
249 ignored: /[\/\\]\./
250 });
251 watcher
252 .on('change', function (file) {
253 log(gutil.colors.yellow(file) + ' is changed');
254 watchHandler('changed', file);
255 })
256 .on('add', function (file) {
257 log(gutil.colors.yellow(file) + ' is added');
258 watchHandler('add', file);
259 })
260 .on('unlink', function (file) {
261 log(gutil.colors.yellow(file) + ' is deleted');
262 watchHandler('removed', file);
263 });
264
265 cb();
266 }
267
268 //注册默认任务
269 gulp.task('default', gulp.series(
270 cleanTmp,
271 copyBasicFiles,
272 gulp.parallel(
273 sassCompile,
274 imageMin,
275 copyWXML
276 ),
277 wxmlImgRewrite,
278 assetsImgMin,
279 qcloudCDN,
280 watch
281 ));
282
283 //注册测试任务
284 gulp.task('test', gulp.series(
285 cleanTmp,
286 copyBasicFiles,
287 gulp.parallel(
288 sassCompile,
289 imageMin,
290 copyWXML
291 ),
292 wxmlImgRewrite,
293 assetsImgMin,
294 qcloudCDN
295 ));
296
297 // 删除任务
298 gulp.task('clean', gulp.parallel(
299 cleanTmp,
300 cleanDist
301 ));
This diff could not be displayed because it is too large.
1 {
2 "name": "mp-gulp-frame-work",
3 "version": "0.0.5",
4 "description": "A workflow for better weapp developing.",
5 "main": "index.js",
6 "scripts": {
7 "test": "gulp test",
8 "dev": "gulp"
9 },
10 "repository": {
11 "type": "git",
12 "url": "http://admin@www.simonfungc.com:10086/r/mp/mp-gulp-framework.git"
13 },
14 "keywords": [
15 "gulp",
16 "gulpjs",
17 "workflow",
18 "weapp",
19 "wexin",
20 "wechat",
21 "css",
22 "wxml",
23 "wxss"
24 ],
25 "author": "SimonFungc",
26 "license": "MIT",
27 "bugs": {
28 "url": "https://www.simonfungc.com/"
29 },
30 "homepage": "https://www.simonfungc.com/",
31 "devDependencies": {
32 "del": "^4.0.0",
33 "gulp": "^4.0.0",
34 "gulp-cached": "^1.1.1",
35 "gulp-debug": "^4.0.0",
36 "gulp-if": "^2.0.2",
37 "gulp-imagemin": "^5.0.0",
38 "gulp-newer": "^1.3.0",
39 "gulp-postcss": "^8.0.0",
40 "gulp-qcloud-upload": "^2.2.0",
41 "gulp-rename": "^1.2.2",
42 "gulp-replace": "^1.0.0",
43 "gulp-sass": "^4.0.0",
44 "gulp-sftp": "^0.1.5",
45 "gulp-util": "^3.0.8",
46 "postcss-font-base64": "^1.0.4",
47 "postcss-lazysprite": "^2.0.0",
48 "postcss-px2rpx": "0.0.4",
49 "yargs": "^13.1.0"
50 }
51 }
1 {
2 "client": "./dist",
3 "svr": "./server",
4 "setting": {
5 "urlCheck": false,
6 "es6": true,
7 "postcss": true,
8 "minified": true,
9 "newFeature": true
10 },
11 "appid": "wxc57ed87f2569f701",
12 "projectname": "gulp-example",
13 "condition": {}
14 }
1 //app.js
2 let fetchApi = require('./http/fetch-api.js');
3 let api = require('./http/api');
4 let config = require('./config');
5 let router = require('./router/index');
6 let store = require('./utils/stroage');
7
8 require('./http/mock-data');
9
10 App({
11 get: fetchApi.fetch,
12 post: (params) => {
13 params.method = 'post';
14 return fetchApi.fetch(params);
15 },
16 api: api,
17 config: config,
18 router: router,
19 store: store,
20 onLaunch: function () {},
21 globalData: {
22 indexInfo: null,
23 userInfo: null
24 }
25 })
1 {
2 "pages": [
3 "pages/authorize/authorize",
4 "pages/index/index",
5 "pages/example/example",
6 "pages/more/more"
7 ],
8 "window": {
9 "backgroundTextStyle": "light",
10 "navigationBarBackgroundColor": "#fff",
11 "navigationBarTitleText": "mp-gulp-framework",
12 "navigationBarTextStyle": "black"
13 },
14 "tabBar": {
15 "color": "#7A7E83",
16 "selectedColor": "#CF4646",
17 "borderStyle": "black",
18 "backgroundColor": "#ffffff",
19 "list": [{
20 "pagePath": "pages/index/index",
21 "iconPath": "image/tabbar/home_D.png",
22 "selectedIconPath": "image/tabbar/home.png",
23 "text": "介绍"
24 },
25 {
26 "pagePath": "pages/more/more",
27 "iconPath": "image/tabbar/set_D.png",
28 "selectedIconPath": "image/tabbar/set.png",
29 "text": "更多"
30 }
31 ]
32 }
33 }
1 /**
2 * ------------------------------------------------------------------
3 * app.scss 入口文件
4 *
5 * ------------------------------------------------------------------
6 *
7 */
8
9 // 支持文件
10 @import "assets/scss/support";
11
12 // 原子类
13 @import "assets/scss/utils";
14
15 // 图标
16 // @import 'styles/iconfont.wxss';
17
18 // 雪碧图
19 // @lazysprite "filetype";
20
21 .test {
22 background-image: url(%ASSETS_IMG%/qr-r.jpg);
23 }
24
25 .app {
26 height: 100%;
27 justify-content: space-between;
28 // text-align: center;
29 box-sizing: border-box;
30 font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif, FZY3JW-GB1-0;
31 }
32
33 .app__width {
34 width: 750px;
35 }
36
37 .app__width {
38 width: 750px;
39 }
40
41 .app__inner {
42 margin: 20px;
43 }
44
45 .app__title {
46 font-size: $fontSize;
47 line-height: $fontSize + 4px;
48 font-weight: bold;
49 padding-bottom: 10px;
50 margin-bottom: 20px;
51 border-bottom: .5px solid #EEEEEE;
52 }
53
54 .app__desc {
55 font-size: $fontSizeSmaller;
56 line-height: $fontSizeSmaller +2px;
57 margin-bottom: 20px;
58 color: $colorGray;
59 }
60
61 .app__bgc {
62 position: fixed;
63 background-color: #ffffff;
64 width: 100%;
65 height: 100%;
66 }
67
68 .app__bg {
69 position: absolute;
70 width: 100%;
71 height: 100%;
72 }
73
74 .app__top-shadow {
75 position: fixed;
76 width: 750px;
77 height: 1px;
78 box-shadow: 0px 4px 0.9px 0.1px rgba(6, 0, 1, 0.07);
79 background-color: #ffffff;
80 }
81
82 .app__content {
83 position: relative;
84 }
85
86
87
88 // web font icon
89
90 @font-face {
91 font-family: "iconfont";
92 src:url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAOsAAsAAAAAB6gAAANdAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgqDDIJmATYCJAMMCwgABCAFhG0HORuvBsgOJUHBwIABAAlgPHyN/f7c3UVEk0mi+3QSQxJNJCoexUrxUhhKIyT4UsKbL89+kizTNWb3wyt7UkR96ayA4xev1q04fZzIa32ey/Gt5wc26luWy5iT9qKFAcYBBbQ3RgEFWiAJesPYlRdxn0C9YccRqxl5ZcBCYSwLxJFS3gwsUk6lpj7UCtUle4t4Yqo2XaeXAHj0vx//QUhYkFRlxtq1w/Q2kPRz+iOmhipDoM51Gx7PD3aIjBlAITZLgxuoMDODUq8YTerLqxUhjRU3GgFfqeqrzT88kiCqGbWNYAJlEz+nbQmJP1h91rUZVMPcGeAZM51XhqohJw97O/vO23paqy3T6coNhsqQ1esr3nVWF19mTZ3YnOwtWwPk5bvMfvYCQV11V+xUzZx02tPO6H02TtP0y4dn5a7M9ravfPvs/poNl43TTmVrW87O66dcKzd3myo2Tjo5rW07l6+fcXXd3KmUDdBKXH240GtvAAw49qfa2BeatkTevUsumTJX5pzRRVy781FXe+YP15YALi0+kkDHQRm8OLz2sP/U1NGjIPxKdyVpafxHpKWvbajtddvnaxmZHLP0XGY1d2wvLarJWrd3LMD6Q1DiSPHusrPgvOxtlAKDyt7bk32nH3emP+npcwo2dKU/Vj040Jn2+HTvAU5VFtOf5vZDf683NVrpbEvIO7N3IX421A40MRbmdVIPQGXQhMi7/+o3vjanTBtt4/7Vygr4/p/GIHW7aqBWorXqz7QVQMVYCK4xXLnISlup57Ntpvcth3Ju8j8aod2b/tauu8+FWl0xkhpDyGqNEIWZQZUG86hWawH1pmUebtBBQolShynjAKHVFSTNPpG1ekUU5jWqdPuGaq1Bod56OJ7ZYCyUdKqEmjFqgy3dUNkqCozlwXRQX4Lk7VyzlNT4XAWSNMo4DA4IyuYzkYCkMTZoOuQhGDOQkUQeZoDHEMeJUC2JKtSKAxQYq2MCA5myFwW0ijygrZAgzTCkDdSiG6TUSiRg3MEYnft8CUSuHaeZVNNTka6ASDSUo0PBAgS1IDKNQquea3lGo4NcCAxjQAyJiAdlgFkIhyOC1OWzVJBWWABFj5RajECzH9PWGDC/mX++Q1DPGJsjRY6i5hgx1hSNwhTxatwNAAAAAA==') format('woff2'),
93 }
94
95 .iconfont {
96 font-family: "iconfont" !important;
97 font-size: 16px;
98 font-style: normal;
99 -webkit-font-smoothing: antialiased;
100 -moz-osx-font-smoothing: grayscale;
101 }
102
103 .iconrefresh:before {
104 content: "\e874";
105 }
106
107 .iconempty:before {
108 content: "\e6a6";
109 }
110
111 .drop-down-item :last-child {
112 border-bottom: none;
113 }
1 /**
2 * ------------------------------------------------------------------
3 * Sass Minxins
4 *
5 * 参考收集:
6 * https://github.com/twbs/bootstrap-sass/tree/master/assets/stylesheets/bootstrap/mixins
7 * ------------------------------------------------------------------
8 *
9 */
10
11 // 文字截取
12 @mixin text-overflow() {
13 overflow: hidden;
14 white-space: normal;
15 text-overflow: ellipsis;
16 word-break: break-all;
17 word-wrap: normal;
18 }
19
20 @mixin word-break() {
21 word-break: break-all;
22 word-wrap: break-word;
23 white-space: normal;
24 }
25
26 // No wrap
27 @mixin no-wrap() {
28 word-break: normal;
29 word-wrap: normal;
30 white-space: nowrap;
31 }
32
33 // 清除浮动
34 @mixin clearfix() {
35 &:before,
36 &:after {
37 content: " "; // 1
38 display: table; // 2
39 }
40 &:after {
41 clear: both;
42 }
43 }
44
45 // Single side border-radius
46 @mixin border-top-radius($radius) {
47 border-top-right-radius: $radius;
48 border-top-left-radius: $radius;
49 }
50
51 @mixin border-right-radius($radius) {
52 border-bottom-right-radius: $radius;
53 border-top-right-radius: $radius;
54 }
55
56 @mixin border-bottom-radius($radius) {
57 border-bottom-right-radius: $radius;
58 border-bottom-left-radius: $radius;
59 }
60
61 @mixin border-left-radius($radius) {
62 border-bottom-left-radius: $radius;
63 border-top-left-radius: $radius;
64 }
65
66 // Center-align a block level element
67 @mixin center-block() {
68 display: block;
69 margin-left: auto;
70 margin-right: auto;
71 }
72
73 // CSS image replacement
74 // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
75 @mixin hide-text() {
76 font-size: 0;
77 line-height: 0;
78 color: transparent;
79 text-shadow: none;
80 background-color: transparent;
81 border: 0;
82 }
1 /**
2 * ------------------------------------------------------------------
3 * 支持文件
4 * 需要引用的地方均需要加上这个支持文件
5 *
6 * ------------------------------------------------------------------
7 *
8 */
9
10 @import "mixins";
11
12 @import "var";
1 /**
2 * ------------------------------------------------------------------
3 * 原子类
4 *
5 * ------------------------------------------------------------------
6 *
7 */
8 @import "support";
9
10 // Margin
11 .u-mt-smaller {
12 margin-top: $marginTopSmaller;
13 }
14
15 .u-mt-small {
16 margin-top: $marginTopSmall;
17 }
18
19 .u-mt-medium {
20 margin-top: $marginTopMedium;
21 }
22
23 .u-mt-large {
24 margin-top: $marginTopLarge;
25 }
26
27 .u-mt-larger {
28 margin-top: $marginTopLarger;
29 }
30
31 .u-mb-smaller {
32 margin-bottom: $marginTopSmaller;
33 }
34
35 .u-mb-small {
36 margin-bottom: $marginTopSmall;
37 }
38
39 .u-mb-medium {
40 margin-bottom: $marginTopMedium;
41 }
42
43 .u-mb-large {
44 margin-bottom: $marginTopLarge;
45 }
46
47 .u-mb-larger {
48 margin-bottom: $marginTopLarger;
49 }
50
51 // Padding
52 .u-pt-smaller {
53 padding-top: $paddingTopSmaller;
54 }
55
56 .u-pt-small {
57 padding-top: $paddingTopSmall;
58 }
59
60 .u-pt-medium {
61 padding-top: $paddingTopMedium;
62 }
63
64 .u-pt-large {
65 padding-top: $paddingTopLarge;
66 }
67
68 .u-pt-larger {
69 padding-top: $paddingTopLarger;
70 }
71
72 .u-pb-smaller {
73 padding-bottom: $paddingTopSmaller;
74 }
75
76 .u-pb-small {
77 padding-bottom: $paddingTopSmall;
78 }
79
80 .u-pb-medium {
81 padding-bottom: $paddingTopMedium;
82 }
83
84 .u-pb-large {
85 padding-bottom: $paddingTopLarge;
86 }
87
88 .u-pb-larger {
89 padding-bottom: $paddingTopLarger;
90 }
91
92 // 布局方位
93 .u-ta-c {
94 text-align: center !important;
95 }
96
97 .u-ta-l {
98 text-align: left !important;
99 }
100
101 .u-ta-r {
102 text-align: right !important;
103 }
104
105 .u-fl-l {
106 float: left;
107 }
108
109 .u-fl-n {
110 float: none;
111 }
112
113 .u-fl-r {
114 float: right;
115 }
116
117 .u-d-b {
118 display: block;
119 }
120
121 .u-d-i {
122 display: inline !important;
123 }
124
125 .u-d-ib {
126 display: inline-block !important;
127 }
128
129 .u-d-n {
130 display: none !important;
131 }
132
133 .u-d-t {
134 display: table;
135 table-layout: fixed;
136 }
137
138 .u-d-tc {
139 display: table-cell;
140 }
141
142 .u-va-b {
143 vertical-align: bottom;
144 }
145
146 .u-va-m {
147 vertical-align: middle;
148 }
149
150 .u-va-t {
151 vertical-align: top;
152 }
153
154 // clearfix
155 .u-clearfix {
156 @include clearfix;
157 }
158
159 // 虚拟格式
160 .u-cur-d {
161 cursor: default;
162 }
163
164 .u-cur-p {
165 cursor: pointer;
166 }
167
168 // flex
169 .u-flex {
170 display: -webkit-box;
171 display: -webkit-flex;
172 display: flex;
173 }
174
175 .u-flex-item {
176 -webkit-box-flex: 1;
177 -webkit-flex: 1;
178 flex: 1;
179 }
180
181 // 小程序中模拟ul、li
182 .u-ul {
183 padding-left: 30px;
184 text-align: left;
185 display: block;
186 }
187
188 .u-li {
189 position: relative;
190 font-size: $fontSizeSmall;
191 line-height: $fontSizeSmall + 4px;
192 margin-bottom: $marginTopSmall;
193 &:before {
194 position: absolute;
195 content: " ";
196 top: 14px;
197 left: -20px;
198 width: 8px;
199 height: 8px;
200 border-radius: 8px;
201 background-color: $colorBlack;
202 }
203 }
204
1 /**
2 * ------------------------------------------------------------------
3 * Sass 变量
4 *
5 * ------------------------------------------------------------------
6 *
7 */
8
9 // Margin
10 $marginTopSmaller: 20px;
11 $marginTopSmall: 30px;
12 $marginTopMedium: 40px;
13 $marginTopLarge: 60px;
14 $marginTopLarger: 80px;
15
16 // Padding
17 $paddingTopSmaller: 20px;
18 $paddingTopSmall: 30px;
19 $paddingTopMedium: 40px;
20 $paddingTopLarge: 60px;
21 $paddingTopLarger: 80px;
22
23 // Color
24 $colorBlue: #20A0FF;
25 $colorGreen: #13CE66;
26 $colorGray: #475669;
27 $colorBlack: #000;
28 $colorRed: #FF4949;
29 $colorYellow: #F7BA2A;
30
31 $color: #787878;
32 $colorLink: #1D8CE0;
33
34 $backGroundColor: #fff;
35
36 // Font
37 $fontSize: 32px;
38 $fontSizeSmall: 28px;
39 $fontSizeSmaller: 24px;
40 $fontSizeLarge: 36px;
41 $fontSizeLarger: 44px;
1 Component({
2 properties: {
3 // 这里定义了innerText属性,属性值可以在组件使用时指定
4 innerText: {
5 type: String,
6 value: 'default value',
7 },
8 bottomVisible: {
9 type: Boolean,
10 value: false
11 }
12 },
13 data: {
14 // 这里是一些组件内部数据
15 someData: {}
16 },
17 methods: {
18 // 这里是一个自定义方法
19 customMethod() {}
20 }
21 })
1 // 底线
2 .bottom-tips {
3 position: relative;
4 padding: 40px 0;
5 width: 100%;
6 text-align: center;
7 color: #666666;
8
9 .line {
10 border-bottom: dashed 1px #cccccc;
11 width: 80%;
12 position: absolute;
13 top: 50%;
14 left: 0;
15 right: 0;
16 margin: 0 auto;
17 }
18
19 .tips-wrap {
20 position: relative;
21 font-size: 28px;
22
23 .tips {
24 padding: 0 20px;
25 background-color: #ffffff;
26 }
27 }
28 }
1 <view class="bottom-tips" wx:if="{{bottomVisible}}">
2 <view class="line"></view>
3 <view class="tips-wrap">
4 <text class="tips">我是有底线的</text>
5 </view>
6 </view>
1 Component({
2 properties: {
3 // 这里定义了innerText属性,属性值可以在组件使用时指定
4 innerText: {
5 type: String,
6 value: 'default value',
7 }
8 },
9 data: {
10 // 这里是一些组件内部数据
11 someData: {}
12 },
13 methods: {
14 // 这里是一个自定义方法
15 customMethod() {}
16 }
17 })
1 <view class="demo-item">demo-item</view>
1 Component({
2 options: {
3 styleIsolation: 'apply-shared' // 接受外部样式
4 },
5 properties: {
6 // 这里定义了innerText属性,属性值可以在组件使用时指定
7 innerText: {
8 type: String,
9 value: 'default value',
10 },
11 emptyVisible: {
12 type: Boolean,
13 value: false
14 }
15 },
16 data: {
17 // 这里是一些组件内部数据
18 someData: {}
19 },
20 methods: {
21 // 这里是一个自定义方法
22 customMethod() {}
23 }
24 })
1 //用的fixed 请确保 内容为空
2 .empty-tips {
3 position: fixed;
4 text-align: center;
5 color: #666666;
6 font-size: 32px;
7 width: 100%;
8 height: 100%;
9 display: flex;
10 justify-content: center;
11 top:35%;
12
13 .iconfont{
14 font-size: 100px;
15 }
16
17 .tips {
18 padding: 20px;
19 }
20 }
1 <view class="empty-tips" wx:if="{{emptyVisible}}">
2 <view class="tips">
3 <span class="iconfont iconempty"></span>
4 <view class="tips">这里空空如也~</view>
5 </view>
6 </view>
1 let ENV_CONFIG = require('./env/index');
2
3 const APPID = ''
4 /** ====每次发布版本记得修改此环境配置==== */
5 const ENV = 'Dev';
6 const NET_CONFIG = ENV_CONFIG[ENV];
7 const MOCKAPI = ENV_CONFIG.mockApi;
8
9 module.exports = {
10 APPID,
11 ENV,
12 NET_CONFIG,
13 MOCKAPI
14 }
1 module.exports = {
2 mockApi: 'http://mock.simonfungc.com',
3 Dev: {
4 baseApi: 'https://dev-api.xxx.com'
5 },
6 Test: {
7 baseApi: 'https://test-api.xxx.com'
8 },
9 Slave: {
10 baseApi: 'https://slave-api.xxx.com'
11 },
12 Prod: {
13 baseApi: 'https://api.xxx.com'
14 }
15 }
1 module.exports = {
2 index: '/xxx/index', // Index 接口
3 decrypt: '/xxx/decrypt', // 解析用户信息
4 }
1 let config = require('./../config');
2 let Store = require('./../utils/stroage');
3 const reason = '服务异常,请稍后重试';
4
5 // 检查并获取sessionid sid:是否需要验证sessionId
6 function checkSessionId(sid) {
7 return new Promise((resolve, reject) => {
8 if (!sid) {
9 resolve();
10 return;
11 }
12 let sessionId = Store.getItem('sessionId');
13 if (sessionId) {
14 resolve(sessionId);
15 } else {
16 // 身份失效
17 //登陆失效的回调
18 // Store.clear("sessionId");
19 // wx.reLaunch({
20 // // url: '/pages/authorize/authorize'
21 // url: '/pages/login/login',
22 // })
23 }
24 });
25 }
26
27 const fetch = function ({
28 loading = false,
29 toast = true,
30 sid = true,
31 mode,
32 isMock,
33 url,
34 data,
35 method
36 }) {
37 // 自定义参数
38 // const clientInfo = {
39 // user_id: 1
40 // }
41 // 日志埋点不需要出现loading
42 if (loading && mode != 'log') wx.showLoading();
43 // if (loading && mode != 'log') Util.showLoading();
44
45 // 新建promise对象
46 let promise = new Promise((resolve, reject) => {
47 /**
48 * isMock设置单个接口Mock开启
49 * mode:目前针对不同业务的接口进行处理,log标识本地埋点上传
50 */
51 let baseUrl = config.NET_CONFIG.baseApi;
52 if (isMock && mode != 'log') {
53 baseUrl = config.MOCKAPI; //环境配置
54 }
55
56 checkSessionId().then((result) => {
57 if (sid) {
58 url += "?sessionId=" + Store.getItem("sessionId")
59 }
60 // console.log("url:", url);
61 wx.request({
62 url: baseUrl + url, //请求地址
63 data: data, //自定义参数
64 method: method || 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
65 // header: {}, // 设置请求的 header的默认参数,根据项目需求添加
66 // header: {
67 // 'clientInfo': JSON.stringify(clientInfo),
68 // 'Server-Token':'xxx'
69 // },
70 success: function (result) {
71 // 日志上传不需要处理结果
72 if (mode == 'log') return;
73 let res = result.data;
74 // 登陆失效拦截,根据项目需要添加自己的配置
75 if (res.code == 404) {
76 // wx.showToast({
77 // title: '当前登陆失效,请重新登陆',
78 // icon: 'none',
79 // mask: true,
80 // success: () => {
81 // return;
82 // }
83 // })
84 //登陆失效的回调
85 Store.clear("sessionId");
86 wx.reLaunch({
87 url: '/pages/authorize/authorize'
88 })
89 }
90 // 内部统一的成功code拦截码
91 if (res.code === 200) {
92 if (loading) {
93 wx.hideLoading();
94 }
95 // resolve(res);
96 // 直接返回content
97 resolve(res.content);
98 } else {
99 // 有些特殊状况不需要toast 需要弹窗
100 if (toast) {
101 wx.showToast({
102 title: res.errMsg || errMsg,
103 icon: 'none'
104 })
105 } else {
106 wx.hideLoading();
107 }
108 // 返回错误信息
109 reject(res);
110 }
111 },
112 fail: function (e = {
113 CODE: -1,
114 msg: errMsg,
115 errMsg
116 }) {
117 let msg = e.errMsg;
118 if (e.errMsg == 'request:fail timeout') {
119 msg = '服务请求超时,请稍后重试'
120 }
121 wx.showToast({
122 title: msg,
123 icon: 'none'
124 });
125 reject(e)
126 },
127 complete: function () {
128 // complete
129 }
130 })
131 })
132
133
134 });
135 return promise;
136 }
137
138 module.exports = {
139 fetch
140 }
1 // https://github.com/webx32/WxMock
2
3 let Mock = require('../utils/mockSdk.js');
4
5 let config = require('../config')
6 let env = config.MOCKAPI;
7
8 Mock.mock(env + '/eatClassifyService', {
9 data: {
10 resultCode: 0,
11 content: function () {
12 return Mock.Random.ip();
13 }
14 }
15 });
1 let app = getApp();
2
3 Page({
4 data: {
5 barHeight: app.globalData.barHeight,
6 navbarData: {
7 showCapsule: 0, //是否显示左上角图标 1表示显示 0表示不显示
8 title: '微信授权' //导航栏 中间的标题
9 },
10 loginData: null,
11 authorized: false,
12 canIUse: wx.canIUse('button.open-type.getUserInfo'),
13 parentMemberCode: "",
14 },
15 onLoad(options) {},
16 onReady() {
17 app.store.clear("sessionId");
18 let _this = this;
19 wx.login({
20 success: function (res) {
21 _this.data.loginData = res;
22 }
23 });
24 },
25 bindGetUserInfo(e) {
26 wx.showLoading();
27 this.getUserInfo(e.detail);
28 },
29 getUserInfo(e) {
30 let _this = this;
31 app.globalData.userInfo = e.userInfo;
32 // console.log("loginData:",_this.data.loginData);
33 app.post({
34 url: app.api.register,
35 sid: false,
36 data: {
37 encryptedData: e.encryptedData,
38 iv: e.iv,
39 code: _this.data.loginData.code,
40 parentMemberCode: _this.data.parentMemberCode,
41 }
42 }).then((res2) => {
43 app.store.setItem('sessionId', res2.sessionId);
44 _this.setData({
45 authorized: true
46 })
47 _this.toIndex();
48 }).catch((err) => {
49 console.log("@authorize || err:", err);
50 })
51 },
52 toIndex() {
53 console.log("@authorize || toIndex ");
54 setTimeout(() => {
55 app.router.push({
56 path: "index",
57 query: {},
58 openType: "redirect"
59 })
60 wx.hideLoading();
61 }, 2000);
62 }
63 })
1 {
2 "usingComponents": {
3 "navbar": "../../component/navbar/index"
4 },
5 "navigationStyle": "custom"
6 }
1 @import '../../assets/scss/mixins';
2
3 .page {
4 position: relative;
5 overflow: hidden;
6
7 .bgc {
8 // background-color: transparent;
9 // background-color: black;
10 background-color: #fafafc;
11 }
12
13
14 .main {
15
16 position: relative;
17
18 .top-space {
19 height: 60px;
20 }
21
22
23 .login {
24 position: relative;
25 width: 650px;
26 margin: 0 auto;
27 text-align: center;
28
29 &-logo {
30 width: 140px;
31 height: 140px;
32 }
33
34 &-name {
35 margin-top: 32px;
36 font-size: 32px;
37 color: #333333;
38 }
39
40 &-line {
41 margin-top: 70px;
42 width: 650px;
43 height: 2px;
44 background-color: #eaeaec;
45 }
46
47 &-title {
48 margin-top: 40px;
49 font-size: 32px;
50 text-align: left;
51 color: #333333;
52 }
53
54
55 &-tips {
56 margin-top: 28px;
57 font-size: 26px;
58 text-align: left;
59 color: #666666;
60 }
61
62 &-btn {
63 margin-top: 102px;
64 width: 650px;
65 height: 90px;
66 line-height: 90px;
67 border-radius: 8px;
68 background-color: #00c200;
69 font-size: 32px;
70 color: #ffffff;
71 }
72
73 }
74
75 }
76
77 }
1 <navbar navbar-data='{{navbarData}}'></navbar>
2 <view style='height: {{barHeight}}px'></view>
3 <view class="page-authorize page">
4 <view class="app__bgc bgc"></view>
5 <view class="app__bg bg"></view>
6 <!-- <view class="app__top-shadow"></view> -->
7 <view class="app__content main">
8 <view class="top-space"></view>
9 <view class="login">
10 <image class="login-logo" src="../../image/logo.png" mode="aspectFit" />
11 <view class="login-name">美赞臣</view>
12 <view class="login-line"></view>
13 <view class="login-title">完整体验小程序功能,需要您的微信授权哦</view>
14 <view class="login-tips">· 获取您的公开信息(昵称、头像等)</view>
15 <button type="default" class="login-btn" wx:if="{{!authorized}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
16 确认授权
17 </button>
18 </view>
19 </view>
20 </view>
1 let app = getApp();
2
3 Page({
4 data: {
5 barHeight: app.globalData.barHeight,
6 navbarData: {
7 showCapsule: 0, //是否显示左上角图标 1表示显示 0表示不显示
8 title: '微信授权' //导航栏 中间的标题
9 },
10 loginData: null,
11 authorized: false,
12 canIUse: wx.canIUse('button.open-type.getUserInfo'),
13 parentMemberCode: "",
14 },
15 onLoad(options) {},
16 onReady() {
17 app.store.clear("sessionId");
18 let _this = this;
19 wx.login({
20 success: function (res) {
21 _this.data.loginData = res;
22 }
23 });
24 },
25 bindGetUserInfo(e) {
26 wx.showLoading();
27 this.getUserInfo(e.detail);
28 },
29 getUserInfo(e) {
30 let _this = this;
31 app.globalData.userInfo = e.userInfo;
32 // console.log("loginData:",_this.data.loginData);
33 app.post({
34 url: app.api.register,
35 sid: false,
36 data: {
37 encryptedData: e.encryptedData,
38 iv: e.iv,
39 code: _this.data.loginData.code,
40 parentMemberCode: _this.data.parentMemberCode,
41 }
42 }).then((res2) => {
43 app.store.setItem('sessionId', res2.sessionId);
44 _this.setData({
45 authorized: true
46 })
47 _this.toIndex();
48 }).catch((err) => {
49 console.log("@authorize || err:", err);
50 })
51 },
52 toIndex() {
53 console.log("@authorize || toIndex ");
54 setTimeout(() => {
55 app.router.push({
56 path: "index",
57 query: {},
58 openType: "redirect"
59 })
60 wx.hideLoading();
61 }, 2000);
62 }
63 })
1 {
2 "navigationStyle": "custom"
3 }
1 @import '../../assets/scss/mixins';
2
3 .page {
4 position: relative;
5 overflow: hidden;
6
7 .bgc {
8 // background-color: transparent;
9 // background-color: black;
10 background-color: #fafafc;
11 }
12
13
14 .main {
15
16 position: relative;
17
18 .top-space {
19 height: 60px;
20 }
21
22
23 .login {
24 position: relative;
25 width: 650px;
26 margin: 0 auto;
27 text-align: center;
28
29 &-logo {
30 width: 140px;
31 height: 140px;
32 }
33
34 &-name {
35 margin-top: 32px;
36 font-size: 32px;
37 color: #333333;
38 }
39
40 &-line {
41 margin-top: 70px;
42 width: 650px;
43 height: 2px;
44 background-color: #eaeaec;
45 }
46
47 &-title {
48 margin-top: 40px;
49 font-size: 32px;
50 text-align: left;
51 color: #333333;
52 }
53
54
55 &-tips {
56 margin-top: 28px;
57 font-size: 26px;
58 text-align: left;
59 color: #666666;
60 }
61
62 &-btn {
63 margin-top: 102px;
64 width: 650px;
65 height: 90px;
66 line-height: 90px;
67 border-radius: 8px;
68 background-color: #00c200;
69 font-size: 32px;
70 color: #ffffff;
71 }
72
73 }
74
75 }
76
77 }
1 <view class="page-authorize page">
2 <view class="app__bgc bgc"></view>
3 <view class="app__bg bg"></view>
4 <!-- <view class="app__top-shadow"></view> -->
5 <view class="app__content main">
6 <view class="top-space"></view>
7 <view class="login">
8 <image class="login-logo" src="../../image/logo.png" mode="aspectFit" />
9 <view class="login-name">小程序</view>
10 <view class="login-line"></view>
11 <view class="login-title">完整体验小程序功能,需要您的微信授权哦</view>
12 <view class="login-tips">· 获取您的公开信息(昵称、头像等)</view>
13 <button type="default" class="login-btn" wx:if="{{!authorized}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
14 确认授权
15 </button>
16 </view>
17 </view>
18 </view>
1 let app = getApp();
2 Page({
3 data: {},
4 onLoad(options) {}
5 })
1 {
2 "navigationBarTitleText": "more"
3 }
1 @import '../../assets/scss/mixins';
2 @import '../../assets/scss/utils';
3
4 .page {
5 .bgc {}
6
7 .bg {}
8
9 .main {
10 .top-space {
11 height: 0px;
12 }
13
14 .content {
15 position: relative;
16 }
17 }
18 }
1 <view class="page">
2 <view class="app__bgc bgc"></view>
3 <view class="app__bg bg"></view>
4 <!-- <view class="app__top-shadow"></view> -->
5 <view class="app__content main">
6 <view class="top-space"></view>
7 <view class="content"></view>
8 </view>
9 </view>
1 let app = getApp();
2 let Router = app.router;
3 let Store = app.store;
4 // import Notify from './../../ui/vant-weapp/notify/notify';
5
6 Page({
7 data: {},
8 onLoad: function (options = {}) {},
9 // 页面跳转
10 navHandler() {
11 // 默认navigateTo,可选 redirect reLaunch back,参照小程序跳转
12 // 配置在tabBar的页面不能用navigateTo,要用reLaunch
13 let openType = "reLaunch";
14 Router.push({
15 path: 'more',
16 query: {
17 id: 1
18 },
19 duration: 500,
20 openType
21 })
22 },
23 // 请求数据
24 reqHandler() {
25 // 是否使用本地模拟数据
26 let isMock = true;
27 app.post({
28 isMock,
29 url: '/eatClassifyService',
30 data: {}
31 }).then((res) => {
32 console.log("res:", res);
33 }).catch((err) => {
34 console.log("err:", err);
35 })
36 },
37 // 储存数据到本地
38 storeHandler() {
39 Store.setItem("id", 2);
40 },
41 // 使用有赞UI组件
42 showNotify() {
43 // Notify("vant notify提示");
44 }
45 })
1 {
2 "navigationBarTitleText": "example",
3 "usingComponents": {
4 "demo-item": "../../component/demo-item/demo-item"
5 }
6 }
1 <view class="page-example">
2 <button bindtap="navHandler">页面跳转</button>
3 <button bindtap="reqHandler">数据请求</button>
4 <button bindtap="storeHandler">储存数据到本地</button>
5 <button bindtap="showNotify">有赞提示</button>
6 <demo-item></demo-item>
7 </view>
8 <!-- <van-notify id="van-notify" /> -->
1 let app = getApp();
2 Page({
3 data: {},
4 onLoad(options) {}
5 })
1 {
2 "navigationBarTitleText": "index"
3 }
1 @import '../../assets/scss/mixins';
2 @import '../../assets/scss/utils';
3
4 .page {
5 .bgc {}
6
7 .bg {}
8
9 .main {
10 .top-space {
11 height: 0px;
12 }
13
14 .content {
15 position: relative;
16 }
17 }
18 }
1 <view class="page">
2 <view class="app__bgc bgc"></view>
3 <view class="app__bg bg"></view>
4 <!-- <view class="app__top-shadow"></view> -->
5 <view class="app__content main">
6 <view class="top-space"></view>
7 <view class="content"></view>
8 </view>
9 </view>
1 let app = getApp();
2 Page({
3 data: {},
4 onLoad(options) {}
5 })
1 {
2 "navigationBarTitleText": "demo"
3 }
1 @import '../../assets/scss/mixins';
2 @import '../../assets/scss/utils';
3
4 .page {
5 .bgc {}
6
7 .bg {}
8
9 .main {
10 .top-space {
11 height: 0px;
12 }
13
14 .content {
15 position: relative;
16 }
17 }
18 }
1 <view class="page">
2 <view class="app__bgc bgc"></view>
3 <view class="app__bg bg"></view>
4 <!-- <view class="app__top-shadow"></view> -->
5 <view class="app__content main">
6 <view class="top-space"></view>
7 <view class="content"></view>
8 </view>
9 </view>
1 let app = getApp();
2 Page({
3 data: {
4 isShow: false, // 控制组件显示隐藏
5 url: ''
6 },
7 onLoad: function (options = {}) {
8 let url = options.url;
9 if (url) {
10 this.setData({
11 url: url,
12 isShow: true
13 })
14 } else {
15 wx.showToast({
16 title: '未找到页面地址',
17 title: 'none',
18 });
19 }
20 }
21 })
1 {
2 "navigationBarTitleText": "webview"
3 }
1 <view class="loading-wrap">
2 <view class="loading">
3 <view class="icon"></view>
4 <view class="text">加载中...</view>
5 </view>
6 </view>
7 <web-view wx:if="{{isShow}}" src="{{url}}" bindload="loadSucc"/>
1 const routerPath = {
2 index: '/pages/index/index', // 首页
3 register: '/pages/register/register', // 注册
4 authorize: '/pages/authorize/authorize', // 授权
5 example: '/pages/example/example',
6 more: '/pages/more/more',
7 }
8
9 function parse(data) {
10 let tempArr = [];
11 for (let key in data) {
12 tempArr.push(key + '=' + encodeURIComponent(data[key]));
13 }
14 return tempArr.join('&');
15 }
16
17 function push(path, option = {}) {
18 if (typeof path == 'string') {
19 option.path = path; //兼容无参数路径
20 } else {
21 option = path;
22 }
23 // console.log("option:", option);
24 // 配置key值找到对应path
25 let url = routerPath[option.path] || routerPath['index'];
26 // console.log("url:", url);
27 // 读取传入的配置参数
28 let {
29 query = {}, openType = 'navigate', duration = 0
30 } = option;
31 // json 转换为 字符串拼接参数
32 let params = parse(query)
33 // console.log("params:", params);
34 if (params) {
35 url = url + '?' + params;
36 }
37 // 是否需要延时跳转
38 duration ? setTimeout(() => {
39 to(openType, url);
40 }, duration) : to(openType, url);
41 }
42
43 function to(openType, url) {
44 let obj = {
45 url
46 };
47
48 if (openType == 'redirect') {
49 wx.redirectTo(obj);
50 } else if (openType == 'reLaunch') {
51 wx.reLaunch(obj);
52 } else if (openType == 'switchTab') {
53 wx.switchTab(obj);
54 } else if (openType == 'back') {
55 wx.navigateBack({
56 delta: 1
57 });
58 } else {
59 wx.navigateTo(obj);
60 }
61 }
62
63 module.exports = {
64 parse,
65 push,
66 to
67 }
1 /**
2 * @version: 1.0 Alpha-1
3 * @author: Coolite Inc. http://www.coolite.com/
4 * @date: 2008-05-13
5 * @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
6 * @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
7 * @website: http://www.datejs.com/
8 */
9
10 Date.CultureInfo = {
11 name: "en-US",
12 englishName: "English (United States)",
13 nativeName: "English (United States)",
14 dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
15 abbreviatedDayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
16 shortestDayNames: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
17 firstLetterDayNames: ["S", "M", "T", "W", "T", "F", "S"],
18 monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
19 abbreviatedMonthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
20 amDesignator: "AM",
21 pmDesignator: "PM",
22 firstDayOfWeek: 0,
23 twoDigitYearMax: 2029,
24 dateElementOrder: "mdy",
25 formatPatterns: {
26 shortDate: "M/d/yyyy",
27 longDate: "dddd, MMMM dd, yyyy",
28 shortTime: "h:mm tt",
29 longTime: "h:mm:ss tt",
30 fullDateTime: "dddd, MMMM dd, yyyy h:mm:ss tt",
31 sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
32 universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
33 rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
34 monthDay: "MMMM dd",
35 yearMonth: "MMMM, yyyy"
36 },
37 regexPatterns: {
38 jan: /^jan(uary)?/i,
39 feb: /^feb(ruary)?/i,
40 mar: /^mar(ch)?/i,
41 apr: /^apr(il)?/i,
42 may: /^may/i,
43 jun: /^jun(e)?/i,
44 jul: /^jul(y)?/i,
45 aug: /^aug(ust)?/i,
46 sep: /^sep(t(ember)?)?/i,
47 oct: /^oct(ober)?/i,
48 nov: /^nov(ember)?/i,
49 dec: /^dec(ember)?/i,
50 sun: /^su(n(day)?)?/i,
51 mon: /^mo(n(day)?)?/i,
52 tue: /^tu(e(s(day)?)?)?/i,
53 wed: /^we(d(nesday)?)?/i,
54 thu: /^th(u(r(s(day)?)?)?)?/i,
55 fri: /^fr(i(day)?)?/i,
56 sat: /^sa(t(urday)?)?/i,
57 future: /^next/i,
58 past: /^last|past|prev(ious)?/i,
59 add: /^(\+|aft(er)?|from|hence)/i,
60 subtract: /^(\-|bef(ore)?|ago)/i,
61 yesterday: /^yes(terday)?/i,
62 today: /^t(od(ay)?)?/i,
63 tomorrow: /^tom(orrow)?/i,
64 now: /^n(ow)?/i,
65 millisecond: /^ms|milli(second)?s?/i,
66 second: /^sec(ond)?s?/i,
67 minute: /^mn|min(ute)?s?/i,
68 hour: /^h(our)?s?/i,
69 week: /^w(eek)?s?/i,
70 month: /^m(onth)?s?/i,
71 day: /^d(ay)?s?/i,
72 year: /^y(ear)?s?/i,
73 shortMeridian: /^(a|p)/i,
74 longMeridian: /^(a\.?m?\.?|p\.?m?\.?)/i,
75 timezone: /^((e(s|d)t|c(s|d)t|m(s|d)t|p(s|d)t)|((gmt)?\s*(\+|\-)\s*\d\d\d\d?)|gmt|utc)/i,
76 ordinalSuffix: /^\s*(st|nd|rd|th)/i,
77 timeContext: /^\s*(\:|a(?!u|p)|p)/i
78 },
79 timezones: [{
80 name: "UTC",
81 offset: "-000"
82 }, {
83 name: "GMT",
84 offset: "-000"
85 }, {
86 name: "EST",
87 offset: "-0500"
88 }, {
89 name: "EDT",
90 offset: "-0400"
91 }, {
92 name: "CST",
93 offset: "-0600"
94 }, {
95 name: "CDT",
96 offset: "-0500"
97 }, {
98 name: "MST",
99 offset: "-0700"
100 }, {
101 name: "MDT",
102 offset: "-0600"
103 }, {
104 name: "PST",
105 offset: "-0800"
106 }, {
107 name: "PDT",
108 offset: "-0700"
109 }]
110 };
111 (function () {
112 var $D = Date,
113 $P = $D.prototype,
114 $C = $D.CultureInfo,
115 p = function (s, l) {
116 if (!l) {
117 l = 2;
118 }
119 return ("000" + s).slice(l * -1);
120 };
121 $P.clearTime = function () {
122 this.setHours(0);
123 this.setMinutes(0);
124 this.setSeconds(0);
125 this.setMilliseconds(0);
126 return this;
127 };
128 $P.setTimeToNow = function () {
129 var n = new Date();
130 this.setHours(n.getHours());
131 this.setMinutes(n.getMinutes());
132 this.setSeconds(n.getSeconds());
133 this.setMilliseconds(n.getMilliseconds());
134 return this;
135 };
136 $D.today = function () {
137 return new Date().clearTime();
138 };
139 $D.compare = function (date1, date2) {
140 if (isNaN(date1) || isNaN(date2)) {
141 throw new Error(date1 + " - " + date2);
142 } else if (date1 instanceof Date && date2 instanceof Date) {
143 return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
144 } else {
145 throw new TypeError(date1 + " - " + date2);
146 }
147 };
148 $D.equals = function (date1, date2) {
149 return (date1.compareTo(date2) === 0);
150 };
151 $D.getDayNumberFromName = function (name) {
152 var n = $C.dayNames,
153 m = $C.abbreviatedDayNames,
154 o = $C.shortestDayNames,
155 s = name.toLowerCase();
156 for (var i = 0; i < n.length; i++) {
157 if (n[i].toLowerCase() == s || m[i].toLowerCase() == s || o[i].toLowerCase() == s) {
158 return i;
159 }
160 }
161 return -1;
162 };
163 $D.getMonthNumberFromName = function (name) {
164 var n = $C.monthNames,
165 m = $C.abbreviatedMonthNames,
166 s = name.toLowerCase();
167 for (var i = 0; i < n.length; i++) {
168 if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) {
169 return i;
170 }
171 }
172 return -1;
173 };
174 $D.isLeapYear = function (year) {
175 return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
176 };
177 $D.getDaysInMonth = function (year, month) {
178 return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
179 };
180 $D.getTimezoneAbbreviation = function (offset) {
181 var z = $C.timezones,
182 p;
183 for (var i = 0; i < z.length; i++) {
184 if (z[i].offset === offset) {
185 return z[i].name;
186 }
187 }
188 return null;
189 };
190 $D.getTimezoneOffset = function (name) {
191 var z = $C.timezones,
192 p;
193 for (var i = 0; i < z.length; i++) {
194 if (z[i].name === name.toUpperCase()) {
195 return z[i].offset;
196 }
197 }
198 return null;
199 };
200 $P.clone = function () {
201 return new Date(this.getTime());
202 };
203 $P.compareTo = function (date) {
204 return Date.compare(this, date);
205 };
206 $P.equals = function (date) {
207 return Date.equals(this, date || new Date());
208 };
209 $P.between = function (start, end) {
210 return this.getTime() >= start.getTime() && this.getTime() <= end.getTime();
211 };
212 $P.isAfter = function (date) {
213 return this.compareTo(date || new Date()) === 1;
214 };
215 $P.isBefore = function (date) {
216 return (this.compareTo(date || new Date()) === -1);
217 };
218 $P.isToday = function () {
219 return this.isSameDay(new Date());
220 };
221 $P.isSameDay = function (date) {
222 return this.clone().clearTime().equals(date.clone().clearTime());
223 };
224 $P.addMilliseconds = function (value) {
225 this.setMilliseconds(this.getMilliseconds() + value);
226 return this;
227 };
228 $P.addSeconds = function (value) {
229 return this.addMilliseconds(value * 1000);
230 };
231 $P.addMinutes = function (value) {
232 return this.addMilliseconds(value * 60000);
233 };
234 $P.addHours = function (value) {
235 return this.addMilliseconds(value * 3600000);
236 };
237 $P.addDays = function (value) {
238 this.setDate(this.getDate() + value);
239 return this;
240 };
241 $P.addWeeks = function (value) {
242 return this.addDays(value * 7);
243 };
244 $P.addMonths = function (value) {
245 var n = this.getDate();
246 this.setDate(1);
247 this.setMonth(this.getMonth() + value);
248 this.setDate(Math.min(n, $D.getDaysInMonth(this.getFullYear(), this.getMonth())));
249 return this;
250 };
251 $P.addYears = function (value) {
252 return this.addMonths(value * 12);
253 };
254 $P.add = function (config) {
255 if (typeof config == "number") {
256 this._orient = config;
257 return this;
258 }
259 var x = config;
260 if (x.milliseconds) {
261 this.addMilliseconds(x.milliseconds);
262 }
263 if (x.seconds) {
264 this.addSeconds(x.seconds);
265 }
266 if (x.minutes) {
267 this.addMinutes(x.minutes);
268 }
269 if (x.hours) {
270 this.addHours(x.hours);
271 }
272 if (x.weeks) {
273 this.addWeeks(x.weeks);
274 }
275 if (x.months) {
276 this.addMonths(x.months);
277 }
278 if (x.years) {
279 this.addYears(x.years);
280 }
281 if (x.days) {
282 this.addDays(x.days);
283 }
284 return this;
285 };
286 var $y, $m, $d;
287 $P.getWeek = function () {
288 var a, b, c, d, e, f, g, n, s, w;
289 $y = (!$y) ? this.getFullYear() : $y;
290 $m = (!$m) ? this.getMonth() + 1 : $m;
291 $d = (!$d) ? this.getDate() : $d;
292 if ($m <= 2) {
293 a = $y - 1;
294 b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
295 c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
296 s = b - c;
297 e = 0;
298 f = $d - 1 + (31 * ($m - 1));
299 } else {
300 a = $y;
301 b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
302 c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
303 s = b - c;
304 e = s + 1;
305 f = $d + ((153 * ($m - 3) + 2) / 5) + 58 + s;
306 }
307 g = (a + b) % 7;
308 d = (f + g - e) % 7;
309 n = (f + 3 - d) | 0;
310 if (n < 0) {
311 w = 53 - ((g - s) / 5 | 0);
312 } else if (n > 364 + s) {
313 w = 1;
314 } else {
315 w = (n / 7 | 0) + 1;
316 }
317 $y = $m = $d = null;
318 return w;
319 };
320 $P.getISOWeek = function () {
321 $y = this.getUTCFullYear();
322 $m = this.getUTCMonth() + 1;
323 $d = this.getUTCDate();
324 return p(this.getWeek());
325 };
326 $P.setWeek = function (n) {
327 return this.moveToDayOfWeek(1).addWeeks(n - this.getWeek());
328 };
329 $D._validate = function (n, min, max, name) {
330 if (typeof n == "undefined") {
331 return false;
332 } else if (typeof n != "number") {
333 throw new TypeError(n + " is not a Number.");
334 } else if (n < min || n > max) {
335 throw new RangeError(n + " is not a valid value for " + name + ".");
336 }
337 return true;
338 };
339 $D.validateMillisecond = function (value) {
340 return $D._validate(value, 0, 999, "millisecond");
341 };
342 $D.validateSecond = function (value) {
343 return $D._validate(value, 0, 59, "second");
344 };
345 $D.validateMinute = function (value) {
346 return $D._validate(value, 0, 59, "minute");
347 };
348 $D.validateHour = function (value) {
349 return $D._validate(value, 0, 23, "hour");
350 };
351 $D.validateDay = function (value, year, month) {
352 return $D._validate(value, 1, $D.getDaysInMonth(year, month), "day");
353 };
354 $D.validateMonth = function (value) {
355 return $D._validate(value, 0, 11, "month");
356 };
357 $D.validateYear = function (value) {
358 return $D._validate(value, 0, 9999, "year");
359 };
360 $P.set = function (config) {
361 if ($D.validateMillisecond(config.millisecond)) {
362 this.addMilliseconds(config.millisecond - this.getMilliseconds());
363 }
364 if ($D.validateSecond(config.second)) {
365 this.addSeconds(config.second - this.getSeconds());
366 }
367 if ($D.validateMinute(config.minute)) {
368 this.addMinutes(config.minute - this.getMinutes());
369 }
370 if ($D.validateHour(config.hour)) {
371 this.addHours(config.hour - this.getHours());
372 }
373 if ($D.validateMonth(config.month)) {
374 this.addMonths(config.month - this.getMonth());
375 }
376 if ($D.validateYear(config.year)) {
377 this.addYears(config.year - this.getFullYear());
378 }
379 if ($D.validateDay(config.day, this.getFullYear(), this.getMonth())) {
380 this.addDays(config.day - this.getDate());
381 }
382 if (config.timezone) {
383 this.setTimezone(config.timezone);
384 }
385 if (config.timezoneOffset) {
386 this.setTimezoneOffset(config.timezoneOffset);
387 }
388 if (config.week && $D._validate(config.week, 0, 53, "week")) {
389 this.setWeek(config.week);
390 }
391 return this;
392 };
393 $P.moveToFirstDayOfMonth = function () {
394 return this.set({
395 day: 1
396 });
397 };
398 $P.moveToLastDayOfMonth = function () {
399 return this.set({
400 day: $D.getDaysInMonth(this.getFullYear(), this.getMonth())
401 });
402 };
403 $P.moveToNthOccurrence = function (dayOfWeek, occurrence) {
404 var shift = 0;
405 if (occurrence > 0) {
406 shift = occurrence - 1;
407 } else if (occurrence === -1) {
408 this.moveToLastDayOfMonth();
409 if (this.getDay() !== dayOfWeek) {
410 this.moveToDayOfWeek(dayOfWeek, -1);
411 }
412 return this;
413 }
414 return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek, +1).addWeeks(shift);
415 };
416 $P.moveToDayOfWeek = function (dayOfWeek, orient) {
417 var diff = (dayOfWeek - this.getDay() + 7 * (orient || +1)) % 7;
418 return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff);
419 };
420 $P.moveToMonth = function (month, orient) {
421 var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12;
422 return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff);
423 };
424 $P.getOrdinalNumber = function () {
425 return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
426 };
427 $P.getTimezone = function () {
428 return $D.getTimezoneAbbreviation(this.getUTCOffset());
429 };
430 $P.setTimezoneOffset = function (offset) {
431 var here = this.getTimezoneOffset(),
432 there = Number(offset) * -6 / 10;
433 return this.addMinutes(there - here);
434 };
435 $P.setTimezone = function (offset) {
436 return this.setTimezoneOffset($D.getTimezoneOffset(offset));
437 };
438 $P.hasDaylightSavingTime = function () {
439 return (Date.today().set({
440 month: 0,
441 day: 1
442 }).getTimezoneOffset() !== Date.today().set({
443 month: 6,
444 day: 1
445 }).getTimezoneOffset());
446 };
447 $P.isDaylightSavingTime = function () {
448 return (this.hasDaylightSavingTime() && new Date().getTimezoneOffset() === Date.today().set({
449 month: 6,
450 day: 1
451 }).getTimezoneOffset());
452 };
453 $P.getUTCOffset = function () {
454 var n = this.getTimezoneOffset() * -10 / 6,
455 r;
456 if (n < 0) {
457 r = (n - 10000).toString();
458 return r.charAt(0) + r.substr(2);
459 } else {
460 r = (n + 10000).toString();
461 return "+" + r.substr(1);
462 }
463 };
464 $P.getElapsed = function (date) {
465 return (date || new Date()) - this;
466 };
467 if (!$P.toISOString) {
468 $P.toISOString = function () {
469 function f(n) {
470 return n < 10 ? '0' + n : n;
471 }
472 return '"' + this.getUTCFullYear() + '-' +
473 f(this.getUTCMonth() + 1) + '-' +
474 f(this.getUTCDate()) + 'T' +
475 f(this.getUTCHours()) + ':' +
476 f(this.getUTCMinutes()) + ':' +
477 f(this.getUTCSeconds()) + 'Z"';
478 };
479 }
480 $P._toString = $P.toString;
481 $P.toString = function (format) {
482 var x = this;
483 if (format && format.length == 1) {
484 var c = $C.formatPatterns;
485 x.t = x.toString;
486 switch (format) {
487 case "d":
488 return x.t(c.shortDate);
489 case "D":
490 return x.t(c.longDate);
491 case "F":
492 return x.t(c.fullDateTime);
493 case "m":
494 return x.t(c.monthDay);
495 case "r":
496 return x.t(c.rfc1123);
497 case "s":
498 return x.t(c.sortableDateTime);
499 case "t":
500 return x.t(c.shortTime);
501 case "T":
502 return x.t(c.longTime);
503 case "u":
504 return x.t(c.universalSortableDateTime);
505 case "y":
506 return x.t(c.yearMonth);
507 }
508 }
509 var ord = function (n) {
510 switch (n * 1) {
511 case 1:
512 case 21:
513 case 31:
514 return "st";
515 case 2:
516 case 22:
517 return "nd";
518 case 3:
519 case 23:
520 return "rd";
521 default:
522 return "th";
523 }
524 };
525 return format ? format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g, function (m) {
526 if (m.charAt(0) === "\\") {
527 return m.replace("\\", "");
528 }
529 x.h = x.getHours;
530 switch (m) {
531 case "hh":
532 return p(x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12));
533 case "h":
534 return x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12);
535 case "HH":
536 return p(x.h());
537 case "H":
538 return x.h();
539 case "mm":
540 return p(x.getMinutes());
541 case "m":
542 return x.getMinutes();
543 case "ss":
544 return p(x.getSeconds());
545 case "s":
546 return x.getSeconds();
547 case "yyyy":
548 return p(x.getFullYear(), 4);
549 case "yy":
550 return p(x.getFullYear());
551 case "dddd":
552 return $C.dayNames[x.getDay()];
553 case "ddd":
554 return $C.abbreviatedDayNames[x.getDay()];
555 case "dd":
556 return p(x.getDate());
557 case "d":
558 return x.getDate();
559 case "MMMM":
560 return $C.monthNames[x.getMonth()];
561 case "MMM":
562 return $C.abbreviatedMonthNames[x.getMonth()];
563 case "MM":
564 return p((x.getMonth() + 1));
565 case "M":
566 return x.getMonth() + 1;
567 case "t":
568 return x.h() < 12 ? $C.amDesignator.substring(0, 1) : $C.pmDesignator.substring(0, 1);
569 case "tt":
570 return x.h() < 12 ? $C.amDesignator : $C.pmDesignator;
571 case "S":
572 return ord(x.getDate());
573 default:
574 return m;
575 }
576 }) : this._toString();
577 };
578 }());
579 (function () {
580 var $D = Date,
581 $P = $D.prototype,
582 $C = $D.CultureInfo,
583 $N = Number.prototype;
584 $P._orient = +1;
585 $P._nth = null;
586 $P._is = false;
587 $P._same = false;
588 $P._isSecond = false;
589 $N._dateElement = "day";
590 $P.next = function () {
591 this._orient = +1;
592 return this;
593 };
594 $D.next = function () {
595 return $D.today().next();
596 };
597 $P.last = $P.prev = $P.previous = function () {
598 this._orient = -1;
599 return this;
600 };
601 $D.last = $D.prev = $D.previous = function () {
602 return $D.today().last();
603 };
604 $P.is = function () {
605 this._is = true;
606 return this;
607 };
608 $P.same = function () {
609 this._same = true;
610 this._isSecond = false;
611 return this;
612 };
613 $P.today = function () {
614 return this.same().day();
615 };
616 $P.weekday = function () {
617 if (this._is) {
618 this._is = false;
619 return (!this.is().sat() && !this.is().sun());
620 }
621 return false;
622 };
623 $P.at = function (time) {
624 return (typeof time === "string") ? $D.parse(this.toString("d") + " " + time) : this.set(time);
625 };
626 $N.fromNow = $N.after = function (date) {
627 var c = {};
628 c[this._dateElement] = this;
629 return ((!date) ? new Date() : date.clone()).add(c);
630 };
631 $N.ago = $N.before = function (date) {
632 var c = {};
633 c[this._dateElement] = this * -1;
634 return ((!date) ? new Date() : date.clone()).add(c);
635 };
636 var dx = ("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),
637 mx = ("january february march april may june july august september october november december").split(/\s/),
638 px = ("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),
639 pxf = ("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),
640 nth = ("final first second third fourth fifth").split(/\s/),
641 de;
642 $P.toObject = function () {
643 var o = {};
644 for (var i = 0; i < px.length; i++) {
645 o[px[i].toLowerCase()] = this["get" + pxf[i]]();
646 }
647 return o;
648 };
649 $D.fromObject = function (config) {
650 config.week = null;
651 return Date.today().set(config);
652 };
653 var df = function (n) {
654 return function () {
655 if (this._is) {
656 this._is = false;
657 return this.getDay() == n;
658 }
659 if (this._nth !== null) {
660 if (this._isSecond) {
661 this.addSeconds(this._orient * -1);
662 }
663 this._isSecond = false;
664 var ntemp = this._nth;
665 this._nth = null;
666 var temp = this.clone().moveToLastDayOfMonth();
667 this.moveToNthOccurrence(n, ntemp);
668 if (this > temp) {
669 throw new RangeError($D.getDayName(n) + " does not occur " + ntemp + " times in the month of " + $D.getMonthName(temp.getMonth()) + " " + temp.getFullYear() + ".");
670 }
671 return this;
672 }
673 return this.moveToDayOfWeek(n, this._orient);
674 };
675 };
676 var sdf = function (n) {
677 return function () {
678 var t = $D.today(),
679 shift = n - t.getDay();
680 if (n === 0 && $C.firstDayOfWeek === 1 && t.getDay() !== 0) {
681 shift = shift + 7;
682 }
683 return t.addDays(shift);
684 };
685 };
686 for (var i = 0; i < dx.length; i++) {
687 $D[dx[i].toUpperCase()] = $D[dx[i].toUpperCase().substring(0, 3)] = i;
688 $D[dx[i]] = $D[dx[i].substring(0, 3)] = sdf(i);
689 $P[dx[i]] = $P[dx[i].substring(0, 3)] = df(i);
690 }
691 var mf = function (n) {
692 return function () {
693 if (this._is) {
694 this._is = false;
695 return this.getMonth() === n;
696 }
697 return this.moveToMonth(n, this._orient);
698 };
699 };
700 var smf = function (n) {
701 return function () {
702 return $D.today().set({
703 month: n,
704 day: 1
705 });
706 };
707 };
708 for (var j = 0; j < mx.length; j++) {
709 $D[mx[j].toUpperCase()] = $D[mx[j].toUpperCase().substring(0, 3)] = j;
710 $D[mx[j]] = $D[mx[j].substring(0, 3)] = smf(j);
711 $P[mx[j]] = $P[mx[j].substring(0, 3)] = mf(j);
712 }
713 var ef = function (j) {
714 return function () {
715 if (this._isSecond) {
716 this._isSecond = false;
717 return this;
718 }
719 if (this._same) {
720 this._same = this._is = false;
721 var o1 = this.toObject(),
722 o2 = (arguments[0] || new Date()).toObject(),
723 v = "",
724 k = j.toLowerCase();
725 for (var m = (px.length - 1); m > -1; m--) {
726 v = px[m].toLowerCase();
727 if (o1[v] != o2[v]) {
728 return false;
729 }
730 if (k == v) {
731 break;
732 }
733 }
734 return true;
735 }
736 if (j.substring(j.length - 1) != "s") {
737 j += "s";
738 }
739 return this["add" + j](this._orient);
740 };
741 };
742 var nf = function (n) {
743 return function () {
744 this._dateElement = n;
745 return this;
746 };
747 };
748 for (var k = 0; k < px.length; k++) {
749 de = px[k].toLowerCase();
750 $P[de] = $P[de + "s"] = ef(px[k]);
751 $N[de] = $N[de + "s"] = nf(de);
752 }
753 $P._ss = ef("Second");
754 var nthfn = function (n) {
755 return function (dayOfWeek) {
756 if (this._same) {
757 return this._ss(arguments[0]);
758 }
759 if (dayOfWeek || dayOfWeek === 0) {
760 return this.moveToNthOccurrence(dayOfWeek, n);
761 }
762 this._nth = n;
763 if (n === 2 && (dayOfWeek === undefined || dayOfWeek === null)) {
764 this._isSecond = true;
765 return this.addSeconds(this._orient);
766 }
767 return this;
768 };
769 };
770 for (var l = 0; l < nth.length; l++) {
771 $P[nth[l]] = (l === 0) ? nthfn(-1) : nthfn(l);
772 }
773 }());
774 (function () {
775 Date.Parsing = {
776 Exception: function (s) {
777 this.message = "Parse error at '" + s.substring(0, 10) + " ...'";
778 }
779 };
780 var $P = Date.Parsing;
781 var _ = $P.Operators = {
782 rtoken: function (r) {
783 return function (s) {
784 var mx = s.match(r);
785 if (mx) {
786 return ([mx[0], s.substring(mx[0].length)]);
787 } else {
788 throw new $P.Exception(s);
789 }
790 };
791 },
792 token: function (s) {
793 return function (s) {
794 return _.rtoken(new RegExp("^\s*" + s + "\s*"))(s);
795 };
796 },
797 stoken: function (s) {
798 return _.rtoken(new RegExp("^" + s));
799 },
800 until: function (p) {
801 return function (s) {
802 var qx = [],
803 rx = null;
804 while (s.length) {
805 try {
806 rx = p.call(this, s);
807 } catch (e) {
808 qx.push(rx[0]);
809 s = rx[1];
810 continue;
811 }
812 break;
813 }
814 return [qx, s];
815 };
816 },
817 many: function (p) {
818 return function (s) {
819 var rx = [],
820 r = null;
821 while (s.length) {
822 try {
823 r = p.call(this, s);
824 } catch (e) {
825 return [rx, s];
826 }
827 rx.push(r[0]);
828 s = r[1];
829 }
830 return [rx, s];
831 };
832 },
833 optional: function (p) {
834 return function (s) {
835 var r = null;
836 try {
837 r = p.call(this, s);
838 } catch (e) {
839 return [null, s];
840 }
841 return [r[0], r[1]];
842 };
843 },
844 not: function (p) {
845 return function (s) {
846 try {
847 p.call(this, s);
848 } catch (e) {
849 return [null, s];
850 }
851 throw new $P.Exception(s);
852 };
853 },
854 ignore: function (p) {
855 return p ? function (s) {
856 var r = null;
857 r = p.call(this, s);
858 return [null, r[1]];
859 } : null;
860 },
861 product: function () {
862 var px = arguments[0],
863 qx = Array.prototype.slice.call(arguments, 1),
864 rx = [];
865 for (var i = 0; i < px.length; i++) {
866 rx.push(_.each(px[i], qx));
867 }
868 return rx;
869 },
870 cache: function (rule) {
871 var cache = {},
872 r = null;
873 return function (s) {
874 try {
875 r = cache[s] = (cache[s] || rule.call(this, s));
876 } catch (e) {
877 r = cache[s] = e;
878 }
879 if (r instanceof $P.Exception) {
880 throw r;
881 } else {
882 return r;
883 }
884 };
885 },
886 any: function () {
887 var px = arguments;
888 return function (s) {
889 var r = null;
890 for (var i = 0; i < px.length; i++) {
891 if (px[i] == null) {
892 continue;
893 }
894 try {
895 r = (px[i].call(this, s));
896 } catch (e) {
897 r = null;
898 }
899 if (r) {
900 return r;
901 }
902 }
903 throw new $P.Exception(s);
904 };
905 },
906 each: function () {
907 var px = arguments;
908 return function (s) {
909 var rx = [],
910 r = null;
911 for (var i = 0; i < px.length; i++) {
912 if (px[i] == null) {
913 continue;
914 }
915 try {
916 r = (px[i].call(this, s));
917 } catch (e) {
918 throw new $P.Exception(s);
919 }
920 rx.push(r[0]);
921 s = r[1];
922 }
923 return [rx, s];
924 };
925 },
926 all: function () {
927 var px = arguments,
928 _ = _;
929 return _.each(_.optional(px));
930 },
931 sequence: function (px, d, c) {
932 d = d || _.rtoken(/^\s*/);
933 c = c || null;
934 if (px.length == 1) {
935 return px[0];
936 }
937 return function (s) {
938 var r = null,
939 q = null;
940 var rx = [];
941 for (var i = 0; i < px.length; i++) {
942 try {
943 r = px[i].call(this, s);
944 } catch (e) {
945 break;
946 }
947 rx.push(r[0]);
948 try {
949 q = d.call(this, r[1]);
950 } catch (ex) {
951 q = null;
952 break;
953 }
954 s = q[1];
955 }
956 if (!r) {
957 throw new $P.Exception(s);
958 }
959 if (q) {
960 throw new $P.Exception(q[1]);
961 }
962 if (c) {
963 try {
964 r = c.call(this, r[1]);
965 } catch (ey) {
966 throw new $P.Exception(r[1]);
967 }
968 }
969 return [rx, (r ? r[1] : s)];
970 };
971 },
972 between: function (d1, p, d2) {
973 d2 = d2 || d1;
974 var _fn = _.each(_.ignore(d1), p, _.ignore(d2));
975 return function (s) {
976 var rx = _fn.call(this, s);
977 return [
978 [rx[0][0], r[0][2]], rx[1]
979 ];
980 };
981 },
982 list: function (p, d, c) {
983 d = d || _.rtoken(/^\s*/);
984 c = c || null;
985 return (p instanceof Array ? _.each(_.product(p.slice(0, -1), _.ignore(d)), p.slice(-1), _.ignore(c)) : _.each(_.many(_.each(p, _.ignore(d))), px, _.ignore(c)));
986 },
987 set: function (px, d, c) {
988 d = d || _.rtoken(/^\s*/);
989 c = c || null;
990 return function (s) {
991 var r = null,
992 p = null,
993 q = null,
994 rx = null,
995 best = [
996 [], s
997 ],
998 last = false;
999 for (var i = 0; i < px.length; i++) {
1000 q = null;
1001 p = null;
1002 r = null;
1003 last = (px.length == 1);
1004 try {
1005 r = px[i].call(this, s);
1006 } catch (e) {
1007 continue;
1008 }
1009 rx = [
1010 [r[0]], r[1]
1011 ];
1012 if (r[1].length > 0 && !last) {
1013 try {
1014 q = d.call(this, r[1]);
1015 } catch (ex) {
1016 last = true;
1017 }
1018 } else {
1019 last = true;
1020 }
1021 if (!last && q[1].length === 0) {
1022 last = true;
1023 }
1024 if (!last) {
1025 var qx = [];
1026 for (var j = 0; j < px.length; j++) {
1027 if (i != j) {
1028 qx.push(px[j]);
1029 }
1030 }
1031 p = _.set(qx, d).call(this, q[1]);
1032 if (p[0].length > 0) {
1033 rx[0] = rx[0].concat(p[0]);
1034 rx[1] = p[1];
1035 }
1036 }
1037 if (rx[1].length < best[1].length) {
1038 best = rx;
1039 }
1040 if (best[1].length === 0) {
1041 break;
1042 }
1043 }
1044 if (best[0].length === 0) {
1045 return best;
1046 }
1047 if (c) {
1048 try {
1049 q = c.call(this, best[1]);
1050 } catch (ey) {
1051 throw new $P.Exception(best[1]);
1052 }
1053 best[1] = q[1];
1054 }
1055 return best;
1056 };
1057 },
1058 forward: function (gr, fname) {
1059 return function (s) {
1060 return gr[fname].call(this, s);
1061 };
1062 },
1063 replace: function (rule, repl) {
1064 return function (s) {
1065 var r = rule.call(this, s);
1066 return [repl, r[1]];
1067 };
1068 },
1069 process: function (rule, fn) {
1070 return function (s) {
1071 var r = rule.call(this, s);
1072 return [fn.call(this, r[0]), r[1]];
1073 };
1074 },
1075 min: function (min, rule) {
1076 return function (s) {
1077 var rx = rule.call(this, s);
1078 if (rx[0].length < min) {
1079 throw new $P.Exception(s);
1080 }
1081 return rx;
1082 };
1083 }
1084 };
1085 var _generator = function (op) {
1086 return function () {
1087 var args = null,
1088 rx = [];
1089 if (arguments.length > 1) {
1090 args = Array.prototype.slice.call(arguments);
1091 } else if (arguments[0] instanceof Array) {
1092 args = arguments[0];
1093 }
1094 if (args) {
1095 for (var i = 0, px = args.shift(); i < px.length; i++) {
1096 args.unshift(px[i]);
1097 rx.push(op.apply(null, args));
1098 args.shift();
1099 return rx;
1100 }
1101 } else {
1102 return op.apply(null, arguments);
1103 }
1104 };
1105 };
1106 var gx = "optional not ignore cache".split(/\s/);
1107 for (var i = 0; i < gx.length; i++) {
1108 _[gx[i]] = _generator(_[gx[i]]);
1109 }
1110 var _vector = function (op) {
1111 return function () {
1112 if (arguments[0] instanceof Array) {
1113 return op.apply(null, arguments[0]);
1114 } else {
1115 return op.apply(null, arguments);
1116 }
1117 };
1118 };
1119 var vx = "each any all".split(/\s/);
1120 for (var j = 0; j < vx.length; j++) {
1121 _[vx[j]] = _vector(_[vx[j]]);
1122 }
1123 }());
1124 (function () {
1125 var $D = Date,
1126 $P = $D.prototype,
1127 $C = $D.CultureInfo;
1128 var flattenAndCompact = function (ax) {
1129 var rx = [];
1130 for (var i = 0; i < ax.length; i++) {
1131 if (ax[i] instanceof Array) {
1132 rx = rx.concat(flattenAndCompact(ax[i]));
1133 } else {
1134 if (ax[i]) {
1135 rx.push(ax[i]);
1136 }
1137 }
1138 }
1139 return rx;
1140 };
1141 $D.Grammar = {};
1142 $D.Translator = {
1143 hour: function (s) {
1144 return function () {
1145 this.hour = Number(s);
1146 };
1147 },
1148 minute: function (s) {
1149 return function () {
1150 this.minute = Number(s);
1151 };
1152 },
1153 second: function (s) {
1154 return function () {
1155 this.second = Number(s);
1156 };
1157 },
1158 meridian: function (s) {
1159 return function () {
1160 this.meridian = s.slice(0, 1).toLowerCase();
1161 };
1162 },
1163 timezone: function (s) {
1164 return function () {
1165 var n = s.replace(/[^\d\+\-]/g, "");
1166 if (n.length) {
1167 this.timezoneOffset = Number(n);
1168 } else {
1169 this.timezone = s.toLowerCase();
1170 }
1171 };
1172 },
1173 day: function (x) {
1174 var s = x[0];
1175 return function () {
1176 this.day = Number(s.match(/\d+/)[0]);
1177 };
1178 },
1179 month: function (s) {
1180 return function () {
1181 this.month = (s.length == 3) ? "jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s) / 4 : Number(s) - 1;
1182 };
1183 },
1184 year: function (s) {
1185 return function () {
1186 var n = Number(s);
1187 this.year = ((s.length > 2) ? n : (n + (((n + 2000) < $C.twoDigitYearMax) ? 2000 : 1900)));
1188 };
1189 },
1190 rday: function (s) {
1191 return function () {
1192 switch (s) {
1193 case "yesterday":
1194 this.days = -1;
1195 break;
1196 case "tomorrow":
1197 this.days = 1;
1198 break;
1199 case "today":
1200 this.days = 0;
1201 break;
1202 case "now":
1203 this.days = 0;
1204 this.now = true;
1205 break;
1206 }
1207 };
1208 },
1209 finishExact: function (x) {
1210 x = (x instanceof Array) ? x : [x];
1211 for (var i = 0; i < x.length; i++) {
1212 if (x[i]) {
1213 x[i].call(this);
1214 }
1215 }
1216 var now = new Date();
1217 if ((this.hour || this.minute) && (!this.month && !this.year && !this.day)) {
1218 this.day = now.getDate();
1219 }
1220 if (!this.year) {
1221 this.year = now.getFullYear();
1222 }
1223 if (!this.month && this.month !== 0) {
1224 this.month = now.getMonth();
1225 }
1226 if (!this.day) {
1227 this.day = 1;
1228 }
1229 if (!this.hour) {
1230 this.hour = 0;
1231 }
1232 if (!this.minute) {
1233 this.minute = 0;
1234 }
1235 if (!this.second) {
1236 this.second = 0;
1237 }
1238 if (this.meridian && this.hour) {
1239 if (this.meridian == "p" && this.hour < 12) {
1240 this.hour = this.hour + 12;
1241 } else if (this.meridian == "a" && this.hour == 12) {
1242 this.hour = 0;
1243 }
1244 }
1245 if (this.day > $D.getDaysInMonth(this.year, this.month)) {
1246 throw new RangeError(this.day + " is not a valid value for days.");
1247 }
1248 var r = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second);
1249 if (this.timezone) {
1250 r.set({
1251 timezone: this.timezone
1252 });
1253 } else if (this.timezoneOffset) {
1254 r.set({
1255 timezoneOffset: this.timezoneOffset
1256 });
1257 }
1258 return r;
1259 },
1260 finish: function (x) {
1261 x = (x instanceof Array) ? flattenAndCompact(x) : [x];
1262 if (x.length === 0) {
1263 return null;
1264 }
1265 for (var i = 0; i < x.length; i++) {
1266 if (typeof x[i] == "function") {
1267 x[i].call(this);
1268 }
1269 }
1270 var today = $D.today();
1271 if (this.now && !this.unit && !this.operator) {
1272 return new Date();
1273 } else if (this.now) {
1274 today = new Date();
1275 }
1276 var expression = !!(this.days && this.days !== null || this.orient || this.operator);
1277 var gap, mod, orient;
1278 orient = ((this.orient == "past" || this.operator == "subtract") ? -1 : 1);
1279 if (!this.now && "hour minute second".indexOf(this.unit) != -1) {
1280 today.setTimeToNow();
1281 }
1282 if (this.month || this.month === 0) {
1283 if ("year day hour minute second".indexOf(this.unit) != -1) {
1284 this.value = this.month + 1;
1285 this.month = null;
1286 expression = true;
1287 }
1288 }
1289 if (!expression && this.weekday && !this.day && !this.days) {
1290 var temp = Date[this.weekday]();
1291 this.day = temp.getDate();
1292 if (!this.month) {
1293 this.month = temp.getMonth();
1294 }
1295 this.year = temp.getFullYear();
1296 }
1297 if (expression && this.weekday && this.unit != "month") {
1298 this.unit = "day";
1299 gap = ($D.getDayNumberFromName(this.weekday) - today.getDay());
1300 mod = 7;
1301 this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
1302 }
1303 if (this.month && this.unit == "day" && this.operator) {
1304 this.value = (this.month + 1);
1305 this.month = null;
1306 }
1307 if (this.value != null && this.month != null && this.year != null) {
1308 this.day = this.value * 1;
1309 }
1310 if (this.month && !this.day && this.value) {
1311 today.set({
1312 day: this.value * 1
1313 });
1314 if (!expression) {
1315 this.day = this.value * 1;
1316 }
1317 }
1318 if (!this.month && this.value && this.unit == "month" && !this.now) {
1319 this.month = this.value;
1320 expression = true;
1321 }
1322 if (expression && (this.month || this.month === 0) && this.unit != "year") {
1323 this.unit = "month";
1324 gap = (this.month - today.getMonth());
1325 mod = 12;
1326 this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
1327 this.month = null;
1328 }
1329 if (!this.unit) {
1330 this.unit = "day";
1331 }
1332 if (!this.value && this.operator && this.operator !== null && this[this.unit + "s"] && this[this.unit + "s"] !== null) {
1333 this[this.unit + "s"] = this[this.unit + "s"] + ((this.operator == "add") ? 1 : -1) + (this.value || 0) * orient;
1334 } else if (this[this.unit + "s"] == null || this.operator != null) {
1335 if (!this.value) {
1336 this.value = 1;
1337 }
1338 this[this.unit + "s"] = this.value * orient;
1339 }
1340 if (this.meridian && this.hour) {
1341 if (this.meridian == "p" && this.hour < 12) {
1342 this.hour = this.hour + 12;
1343 } else if (this.meridian == "a" && this.hour == 12) {
1344 this.hour = 0;
1345 }
1346 }
1347 if (this.weekday && !this.day && !this.days) {
1348 var temp = Date[this.weekday]();
1349 this.day = temp.getDate();
1350 if (temp.getMonth() !== today.getMonth()) {
1351 this.month = temp.getMonth();
1352 }
1353 }
1354 if ((this.month || this.month === 0) && !this.day) {
1355 this.day = 1;
1356 }
1357 if (!this.orient && !this.operator && this.unit == "week" && this.value && !this.day && !this.month) {
1358 return Date.today().setWeek(this.value);
1359 }
1360 if (expression && this.timezone && this.day && this.days) {
1361 this.day = this.days;
1362 }
1363 return (expression) ? today.add(this) : today.set(this);
1364 }
1365 };
1366 var _ = $D.Parsing.Operators,
1367 g = $D.Grammar,
1368 t = $D.Translator,
1369 _fn;
1370 g.datePartDelimiter = _.rtoken(/^([\s\-\.\,\/\x27]+)/);
1371 g.timePartDelimiter = _.stoken(":");
1372 g.whiteSpace = _.rtoken(/^\s*/);
1373 g.generalDelimiter = _.rtoken(/^(([\s\,]|at|@|on)+)/);
1374 var _C = {};
1375 g.ctoken = function (keys) {
1376 var fn = _C[keys];
1377 if (!fn) {
1378 var c = $C.regexPatterns;
1379 var kx = keys.split(/\s+/),
1380 px = [];
1381 for (var i = 0; i < kx.length; i++) {
1382 px.push(_.replace(_.rtoken(c[kx[i]]), kx[i]));
1383 }
1384 fn = _C[keys] = _.any.apply(null, px);
1385 }
1386 return fn;
1387 };
1388 g.ctoken2 = function (key) {
1389 return _.rtoken($C.regexPatterns[key]);
1390 };
1391 g.h = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/), t.hour));
1392 g.hh = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/), t.hour));
1393 g.H = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/), t.hour));
1394 g.HH = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/), t.hour));
1395 g.m = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.minute));
1396 g.mm = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.minute));
1397 g.s = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.second));
1398 g.ss = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.second));
1399 g.hms = _.cache(_.sequence([g.H, g.m, g.s], g.timePartDelimiter));
1400 g.t = _.cache(_.process(g.ctoken2("shortMeridian"), t.meridian));
1401 g.tt = _.cache(_.process(g.ctoken2("longMeridian"), t.meridian));
1402 g.z = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
1403 g.zz = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
1404 g.zzz = _.cache(_.process(g.ctoken2("timezone"), t.timezone));
1405 g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([g.tt, g.zzz]));
1406 g.time = _.each(_.optional(_.ignore(_.stoken("T"))), g.hms, g.timeSuffix);
1407 g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), _.optional(g.ctoken2("ordinalSuffix"))), t.day));
1408 g.dd = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/), _.optional(g.ctoken2("ordinalSuffix"))), t.day));
1409 g.ddd = g.dddd = _.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"), function (s) {
1410 return function () {
1411 this.weekday = s;
1412 };
1413 }));
1414 g.M = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/), t.month));
1415 g.MM = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/), t.month));
1416 g.MMM = g.MMMM = _.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"), t.month));
1417 g.y = _.cache(_.process(_.rtoken(/^(\d\d?)/), t.year));
1418 g.yy = _.cache(_.process(_.rtoken(/^(\d\d)/), t.year));
1419 g.yyy = _.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/), t.year));
1420 g.yyyy = _.cache(_.process(_.rtoken(/^(\d\d\d\d)/), t.year));
1421 _fn = function () {
1422 return _.each(_.any.apply(null, arguments), _.not(g.ctoken2("timeContext")));
1423 };
1424 g.day = _fn(g.d, g.dd);
1425 g.month = _fn(g.M, g.MMM);
1426 g.year = _fn(g.yyyy, g.yy);
1427 g.orientation = _.process(g.ctoken("past future"), function (s) {
1428 return function () {
1429 this.orient = s;
1430 };
1431 });
1432 g.operator = _.process(g.ctoken("add subtract"), function (s) {
1433 return function () {
1434 this.operator = s;
1435 };
1436 });
1437 g.rday = _.process(g.ctoken("yesterday tomorrow today now"), t.rday);
1438 g.unit = _.process(g.ctoken("second minute hour day week month year"), function (s) {
1439 return function () {
1440 this.unit = s;
1441 };
1442 });
1443 g.value = _.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/), function (s) {
1444 return function () {
1445 this.value = s.replace(/\D/g, "");
1446 };
1447 });
1448 g.expression = _.set([g.rday, g.operator, g.value, g.unit, g.orientation, g.ddd, g.MMM]);
1449 _fn = function () {
1450 return _.set(arguments, g.datePartDelimiter);
1451 };
1452 g.mdy = _fn(g.ddd, g.month, g.day, g.year);
1453 g.ymd = _fn(g.ddd, g.year, g.month, g.day);
1454 g.dmy = _fn(g.ddd, g.day, g.month, g.year);
1455 g.date = function (s) {
1456 return ((g[$C.dateElementOrder] || g.mdy).call(this, s));
1457 };
1458 g.format = _.process(_.many(_.any(_.process(_.rtoken(/^(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|zz?z?)/), function (fmt) {
1459 if (g[fmt]) {
1460 return g[fmt];
1461 } else {
1462 throw $D.Parsing.Exception(fmt);
1463 }
1464 }), _.process(_.rtoken(/^[^dMyhHmstz]+/), function (s) {
1465 return _.ignore(_.stoken(s));
1466 }))), function (rules) {
1467 return _.process(_.each.apply(null, rules), t.finishExact);
1468 });
1469 var _F = {};
1470 var _get = function (f) {
1471 return _F[f] = (_F[f] || g.format(f)[0]);
1472 };
1473 g.formats = function (fx) {
1474 if (fx instanceof Array) {
1475 var rx = [];
1476 for (var i = 0; i < fx.length; i++) {
1477 rx.push(_get(fx[i]));
1478 }
1479 return _.any.apply(null, rx);
1480 } else {
1481 return _get(fx);
1482 }
1483 };
1484 g._formats = g.formats(["\"yyyy-MM-ddTHH:mm:ssZ\"", "yyyy-MM-ddTHH:mm:ssZ", "yyyy-MM-ddTHH:mm:ssz", "yyyy-MM-ddTHH:mm:ss", "yyyy-MM-ddTHH:mmZ", "yyyy-MM-ddTHH:mmz", "yyyy-MM-ddTHH:mm", "ddd, MMM dd, yyyy H:mm:ss tt", "ddd MMM d yyyy HH:mm:ss zzz", "MMddyyyy", "ddMMyyyy", "Mddyyyy", "ddMyyyy", "Mdyyyy", "dMyyyy", "yyyy", "Mdyy", "dMyy", "d"]);
1485 g._start = _.process(_.set([g.date, g.time, g.expression], g.generalDelimiter, g.whiteSpace), t.finish);
1486 g.start = function (s) {
1487 try {
1488 var r = g._formats.call({}, s);
1489 if (r[1].length === 0) {
1490 return r;
1491 }
1492 } catch (e) {}
1493 return g._start.call({}, s);
1494 };
1495 $D._parse = $D.parse;
1496 $D.parse = function (s) {
1497 var r = null;
1498 if (!s) {
1499 return null;
1500 }
1501 if (s instanceof Date) {
1502 return s;
1503 }
1504 try {
1505 r = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
1506 } catch (e) {
1507 return null;
1508 }
1509 return ((r[1].length === 0) ? r[0] : null);
1510 };
1511 $D.getParseFunction = function (fx) {
1512 var fn = $D.Grammar.formats(fx);
1513 return function (s) {
1514 var r = null;
1515 try {
1516 r = fn.call({}, s);
1517 } catch (e) {
1518 return null;
1519 }
1520 return ((r[1].length === 0) ? r[0] : null);
1521 };
1522 };
1523 $D.parseExact = function (s, fx) {
1524 return $D.getParseFunction(fx)(s);
1525 };
1526 }());
1527
1528 // module.exports = {
1529 // Date:Date
1530 // }
1531
1532 module.exports = Date;
...\ No newline at end of file ...\ No newline at end of file
This diff could not be displayed because it is too large.
1 var __request = wx.request;
2 var Mock = require("./mock.js");
3 // console.log('Mock', Mock)
4 Object.defineProperty(wx, "request", { writable: true }); wx.request = function (config) { if (typeof Mock._mocked[config.url] == "undefined") { __request(config); return } var resTemplate = Mock._mocked[config.url].template; var response = Mock.mock(resTemplate); if (typeof config.success == "function") { config.success(response) } if (typeof config.complete == "function") { config.complete(response) } }; module.exports = Mock;
1 function setItem(key, value, module_name) {
2 if (module_name) {
3 let module_name_info = getItem(module_name) || {};
4 module_name_info[key] = value;
5 try {
6 wx.setStorageSync(module_name, module_name_info);
7 } catch (e) {
8 wx.setStorage({
9 key: module_name,
10 data: module_name_info
11 })
12 }
13 } else {
14 try {
15 wx.setStorageSync(key, value);
16 } catch (e) {
17 wx.setStorage({
18 key: key,
19 data: value
20 })
21 }
22 }
23 }
24
25 function getItem(key, module_name) {
26 if (module_name) {
27 let val = getItem(module_name);
28 if (val) return val[key];
29 return '';
30 }
31 return wx.getStorageSync(key)
32 }
33
34 function clear(name) {
35 name ? wx.removeStorageSync(name) : wx.clearStorageSync()
36 }
37
38 module.exports = {
39 setItem,
40 getItem,
41 clear
42 }
1 // 手机正则
2 const REGEXPS = {
3 "mobile": /^1\d{10}$/
4 }
5 // 验证手机
6 function checkMobile(str) {
7 return REGEXPS.mobile.test(str);
8 }
9
10
11 function formatTime(date) {
12 var year = date.getFullYear()
13 var month = date.getMonth() + 1
14 var day = date.getDate()
15
16 var hour = date.getHours()
17 var minute = date.getMinutes()
18 var second = date.getSeconds()
19
20
21 return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
22 }
23
24 function formatNumber(n) {
25 n = n.toString()
26 return n[1] ? n : '0' + n
27 }
28
29
30
31
32 /**
33 * 获取屏幕剩余高度
34 * useHeight 单位是rpx
35 * 默认返回单位是rpx 可通过unit参数改为 px
36 */
37 function getLastScreenHeight(useHeight = 0, unit = 'rpx') {
38 let sysInfo = wx.getSystemInfoSync();
39 let clientHeight = sysInfo.windowHeight;
40 // 获取可使用窗口高度
41 let clientWidth = sysInfo.windowWidth;
42 // 算出比例
43 let ratio = 750 / clientWidth;
44 // 算出屏幕高度(单位rpx)
45 let height = clientHeight * ratio;
46 // 计算剩余高度
47 let lastHeight = height - useHeight;
48 // 可转换成px
49 if (unit == 'px') {
50 lastHeight = lastHeight / 750 * clientWidth
51 }
52 return lastHeight;
53 }
54
55 module.exports = {
56 formatTime: formatTime,
57 checkMobile: checkMobile,
58 getLastScreenHeight: getLastScreenHeight
59 }