a09fad57 by simon

基础工程

0 parents
Showing 70 changed files with 3541 additions and 0 deletions
root = true;
[*]
# indent_style = tab
indent_style = space
# indent_size = 4
indent_size = 2
tab_width = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
# [*.{json,yml,wxml,html}]
# indent_style = tab
# indent_size = 4
# tab_width = 2
[README.md]
trim_trailing_whitespace = ignore
.idea
.DS_Store
dist
tmp
node_modules
_old
config.custom.js
src/assets/images/filetype.png
src/assets/images/filetype@2x.png
.gitignore
.editorconfig
.eslintrc
.idea
node_modules/
npm-debug.log
CHANGELOG.md
test
examples
gulpfile.js
.travis.yml
appveyor.yml
.DS_Store
dist
tmp
_old
config.custom.js
src/assets/images/filetype.png
src/assets/images/filetype@2x.png
sudo: false
language: node_js
node_js:
- "6"
- "7"
- "8"
- "stable"
before_script:
- npm install -g gulp@next
MIT License
Copyright (c) 2017 Jeff Ma
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## 介绍
mp-gulp-framework 是一个专门为开发微信小程序打造的前端开发工作流,基于Gulp 4 开发,旨在通过工作流的方式解决微信小程序开发过程中写前端代码的痛点。
借鉴于:[https://github.com/Jeff2Ma/WeApp-Workflow](https://github.com/Jeff2Ma/WeApp-Workflow)
在此基础上作修改。
## 功能
### SCSS 实时编译为 WXSS
使用Sass 预处理器,让写CSS 更加顺畅。`.scss`文件会实时编译为微信小程序支持的`.wxss`文件。
### WXSS(CSS) 中px 单位转小程序单位rpx
以官方推荐的iPhone 6 为标准设计格式,开发中直接写`px` 即可自动转换为`rpx`
其中屏幕铺满为750px。
```css
// Input: src/pages/index/index.scss
.index__header {
font-size: 14px;
margin-top: 20PX; /* 如果为大写的`PX`单位则不会转换 */
}
// Output: dist/pages/index/index.wxss
.index__header {
font-size: 28rpx;
margin-top: 20PX; /* 如果为大写的`PX`单位则不会转换 */
}
```
### 图片压缩
实时压缩图片并采用增量方式防止被重复压缩。
### 自动上传图片到CDN 并更新路径为https 绝对路径
小程序不支持相对路径的图片引用,仅支持带`https`协议头的绝对路径。本工作流可以将WXML 以及WXSS 文件中引用的相对路径图片上传到云存储CDN 或通过FTP/SFTP 协议上传到个人服务器空间。目前支持腾讯云,七牛云。
```html
// Input: src/pages/index/index.wxml
<image src="%ASSETS_IMG%/t.png"></image>
// Output: dist/pages/index/index.wxml
<image src="https://cdn.devework.com/weapp/devework/t.png"></image>
```
### Font 文件转为base64 编码
小程序不支持相对路径的字体文件,本工作流可将CSS 中引用到的Font 文件转码为base64 并替换原路径。
```
// Input: src/pages/index/index.scss
@font-face {
font-family: 'fontello';
src: url("assets/fonts/fontello.ttf") format('truetype');
}
// Output: dist/pages/index/index.wxss
@font-face {
font-family: 'fontello';
src: url(data:application/font-sfnt;charset=utf-8;base64,AAEAAAAPAIAA....FsASNsQIARAAA) format("truetype");
}
```
### 全自动构建雪碧图及生成相应CSS
本功能由[postcss-lazysprite](https://github.com/Jeff2Ma/postcss-lazysprite) 插件驱动。开发中准备好图片后仅仅写一句类似`@lazysprite "xxxx"`的代码,即可全自动构建雪碧图及生成相应CSS。
```css
// Input: src/app.scss
@lazysprite "filetype";
// Output: dist/app.wxss
.icon-filetype-doc {
background-image: url(../sprites/filetype.png);
background-position: 0 0;
width: 80px;
height: 80px;
}
.icon-filetype-pdf {
background-image: url(../sprites/filetype.png);
background-position: -90px 0;
width: 80px;
height: 80px;
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio:2) {
.icon-filetype-doc {
background-image: url(../sprites/filetype@2x.png);
background-position: 0 0;
background-size: 170px 170px;
}
.icon-filetype-pdf {
background-image: url(../sprites/filetype@2x.png);
background-position: -90px 0;
background-size: 170px 170px;
}
}
```
## 项目结构
```
.
├── config.custom.js // gulp自定义配置,会覆盖config.js
├── config.js // gulp 配置文件
├── gulpfile.js
├── package.json
├── src // 开发目录
│   ├── app.js
│   ├── app.json
│   ├── app.scss
│   ├── assets // 开发相关的静态文件原始资源
│  │   ├── fonts //字体文件
│  │   ├── images // 图片文件,可被上传到CDN
│  │   ├── scss // 一般放置SCSS 的minxins 等被import 的SCSS 文件
│  │   └── sprites // 生成雪碧图小图的目录
│   ├── image // 小程序专用的图片资源(如tabbar icon)目录
│   ├── pages
│   └── utils
├── tmp // 通过src 目录编译后生成的缓存目录
└── dist // 通过src 目录编译后生成的文件目录,也是小程序开发的项目目录
```
# Notes:
# - Minimal appveyor.yml file is an empty file. All sections are optional.
# - Indent each level of configuration with 2 spaces. Do not use tabs!
# - All section names are case-sensitive.
# - Section names should be unique on each level.
#---------------------------------#
# general configuration #
#---------------------------------#
# branches to build
#branches:
# # whitelist
# only:
# - master
# - test
# Do not build on tags (GitHub and BitBucket)
skip_tags: true
# Do not build feature branch with open Pull Requests
skip_branch_with_pr: true
# Build worker image (VM template)
image: Visual Studio 2015
environment:
matrix:
- nodejs_version: 4.7.0
# scripts that run after cloning repository
install:
# to run script as a PowerShell command prepend it with ps:
- ps: Install-Product node $env:nodejs_version
# batch commands start from cmd:
- npm cache clean
- npm i
- npm install -g gulp@next
# to run your custom scripts instead of automatic tests
test_script:
# Output useful info for debugging.
- node --version && npm --version
- npm i
- pwd
- gulp test
# Don't actually build.
build: off
matrix:
fast_finish: true
cache:
# local npm modules
- C:\Users\appveyor\AppData\Roaming\npm-cache -> package.json # npm cache
- node_modules -> package.json
/**
* ------------------------------------------------------------------
* 配置文件
*
* 建议复制一份并重命名为 config.custom.js ,即可在config.custom.js 上根据需求进行配置
* ------------------------------------------------------------------
*
*/
module.exports = {
"enabledQcloud": false, //是否开启腾讯云COS 上传功能
// 腾讯云COS 上传功能配置表
"qcloud": {
"appid": "wxc57ed87f2569f701",
"secretId": "xxx",
"secretKey": "xxxxx",
"bucket": "xxxx",
"region": "sh",
"prefix": "what-ever/you-want",
"overWrite": true,
"headers": {
"Cache-Control": "max-age=5184000"
}
},
// 静态资源CDN 域名,配合CDN 功能实用,线上请确保在mp管理端已经注册域名
"assetsCDN": "https://res.jianhui.org/"
};
/**
* ------------------------------------------------------------------
* gulpfile 文件
* ------------------------------------------------------------------
*/
var path = require('path');
var gulp = require('gulp');
var sass = require('gulp-sass');
var rename = require('gulp-rename');
var imagemin = require('gulp-imagemin');
var sftp = require('gulp-sftp');
var del = require('del');
var replace = require('gulp-replace');
var postcss = require('gulp-postcss');
var qcloudUpload = require('gulp-qcloud-upload');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var newer = require('gulp-newer');
var cache = require('gulp-cached');
var debug = require('gulp-debug');
var pxtorpx = require('postcss-px2rpx');
// var base64 = require('postcss-font-base64');
// var lazysprite = require('postcss-lazysprite');
var argv = require('yargs').argv;
var config = null;
// 获取用户配置
try {
config = require('./config.custom.js');
} catch (e) {
try {
config = require('./config.js');
} catch (e) {
log(gutil.colors.red('丢失配置文件(config.js/config.custom.js)'));
}
}
// 相关路径配置
var paths = {
src: {
baseDir: 'src',
imgDir: 'src/image',
spriteDir: 'src/assets/sprites',
scssDir: 'src/assets/scss',
imgFiles: 'src/image/**/*',
scssFiles: 'src/**/*.scss',
baseFiles: ['src/**/*.{png,js,json,wxml,wxss,wxs,ts,woff2}', '!src/assets/**/*', '!src/image/**/*'],
assetsDir: 'src/assets',
assetsImgFiles: 'src/assets/images/**/*.{png,jpg,jpeg,svg,gif}',
wxmlFiles: ['src/**/*.wxml'],
jsFiles: 'src/**/*.js'
},
dist: {
baseDir: 'dist',
imgDir: 'dist/image',
wxssFiles: 'dist/**/*.wxss',
},
tmp: {
baseDir: 'tmp',
imgDir: 'tmp/assets/images',
imgFiles: 'tmp/assets/images/**/*.{png,jpg,jpeg,svg,gif}'
}
};
// 雪碧图的配置
var lazyspriteConfig = {
imagePath: paths.src.spriteDir,
stylesheetInput: paths.src.scssDir,
stylesheetRelative: paths.src.assetsDir,
spritePath: paths.src.assetsDir + '/images',
smartUpdate: false,
cssSeparator: '-',
outputExtralCSS: true,
nameSpace: 'icon-'
};
// Log for output msg.
function log() {
var data = Array.prototype.slice.call(arguments);
gutil.log.apply(false, data);
}
// 压缩图片
function imageMin() {
// return gulp.src(paths.src.imgFiles, {si≤nce: gulp.lastRun(imageMin)})
return gulp.src(paths.src.imgFiles)
.pipe(newer(paths.dist.imgDir))
.pipe(imagemin({
progressive: true,
svgoPlugins: [{
removeViewBox: false
}]
}))
.pipe(gulp.dest(paths.dist.imgDir));
}
// assets 文件夹下的图片处理
function assetsImgMin() {
return gulp.src(paths.src.assetsImgFiles)
.pipe(newer(paths.tmp.imgDir))
.pipe(imagemin({
progressive: true,
svgoPlugins: [{
removeViewBox: false
}]
}))
.pipe(gulp.dest(paths.tmp.imgDir))
}
// Sass 编译
function sassCompile() {
var res = config.assetsCDN + config.qcloud.prefix + '/';
// 缩放比例 1为750
var pxtorpxOpts = {
times: 1
};
return gulp.src(paths.src.scssFiles)
.pipe(sass({
errLogToConsole: true,
outputStyle: 'expanded'
})
.on('error', sass.logError))
.pipe(gulpif(Boolean(argv.debug), debug({
title: '`sassCompile` Debug:'
})))
// .pipe(postcss([lazysprite(lazyspriteConfig), pxtorpx(pxtorpxOpts), base64()]))
.pipe(postcss([pxtorpx(pxtorpxOpts)]))
.pipe(rename({
'extname': '.wxss'
}))
.pipe(replace('.scss', '.wxss'))
.pipe(replace('%ASSETS_IMG%/', res))
.pipe(replace('src/assets/images', res)) // 雪碧图CSS RUL 中的图片路径
.pipe(gulp.dest(paths.dist.baseDir))
}
// 复制基础文件
function copyBasicFiles() {
return gulp.src(paths.src.baseFiles, {})
.pipe(gulp.dest(paths.dist.baseDir));
}
// 复制 WXML
function copyWXML() {
return gulp.src(paths.src.wxmlFiles, {})
.pipe(gulp.dest(paths.dist.baseDir));
}
// 重写WXML 中 image 标签中的图片路径
function wxmlImgRewrite() {
var res = config.assetsCDN + config.qcloud.prefix + '/';
// console.log(res);
return gulp.src(paths.src.wxmlFiles)
.pipe(replace('%ASSETS_IMG%/', res))
.pipe(gulp.dest(paths.dist.baseDir))
}
// clean 任务, dist 目录
function cleanDist() {
return del(paths.dist.baseDir);
}
// clean tmp 目录
function cleanTmp() {
return del(paths.tmp.baseDir);
}
// 腾讯云上传任务
function qcloudCDN(cb) {
if (config.enabledQcloud) {
// return gulp.src(paths.src.assetsImgFiles, {since: gulp.lastRun(qcloudCDN)})
return gulp.src(paths.tmp.imgFiles)
.pipe(cache('qcloudCache'))
.pipe(qcloudUpload({
appid: config.qcloud.appid,
secretId: config.qcloud.secretId,
secretKey: config.qcloud.secretKey,
bucket: config.qcloud.bucket,
region: config.qcloud.region,
prefix: config.qcloud.prefix,
overWrite: config.qcloud.overWrite,
headers: config.qcloud.headers
}));
}
cb();
}
var watchHandler = function (type, file) {
var extname = path.extname(file);
// SCSS 文件
if (extname === '.scss') {
if (type === 'removed') {
var tmp = file.replace('src/', 'dist/').replace(extname, '.wxss');
del([tmp]);
} else {
sassCompile();
}
}
// 图片文件
else if (extname === '.png' || extname === '.jpg' || extname === '.jpeg' || extname === '.svg' || extname === '.gif') {
if (type === 'removed') {
if (file.indexOf('assets') > -1) {
del([file.replace('src/', 'tmp/')]);
} else {
del([file.replace('src/', 'dist/')]);
}
} else {
imageMin();
assetsImgMin();
qcloudCDN();
wxmlImgRewrite();
}
}
// wxml
else if (extname === '.wxml') {
if (type === 'removed') {
var tmp = file.replace('src/', 'dist/')
del([tmp]);
} else {
copyWXML();
wxmlImgRewrite();
}
}
// 其余文件
else {
if (type === 'removed') {
var tmp = file.replace('src/', 'dist/');
del([tmp]);
} else {
copyBasicFiles();
// copyWXML();
// wxmlImgRewrite();
}
}
};
//监听文件
function watch(cb) {
var watcher = gulp.watch([
paths.src.baseDir,
paths.tmp.imgDir
], {
ignored: /[\/\\]\./
});
watcher
.on('change', function (file) {
log(gutil.colors.yellow(file) + ' is changed');
watchHandler('changed', file);
})
.on('add', function (file) {
log(gutil.colors.yellow(file) + ' is added');
watchHandler('add', file);
})
.on('unlink', function (file) {
log(gutil.colors.yellow(file) + ' is deleted');
watchHandler('removed', file);
});
cb();
}
//注册默认任务
gulp.task('default', gulp.series(
cleanTmp,
copyBasicFiles,
gulp.parallel(
sassCompile,
imageMin,
copyWXML
),
wxmlImgRewrite,
assetsImgMin,
qcloudCDN,
watch
));
//注册测试任务
gulp.task('test', gulp.series(
cleanTmp,
copyBasicFiles,
gulp.parallel(
sassCompile,
imageMin,
copyWXML
),
wxmlImgRewrite,
assetsImgMin,
qcloudCDN
));
// 删除任务
gulp.task('clean', gulp.parallel(
cleanTmp,
cleanDist
));
This diff could not be displayed because it is too large.
{
"name": "mp-gulp-frame-work",
"version": "0.0.5",
"description": "A workflow for better weapp developing.",
"main": "index.js",
"scripts": {
"test": "gulp test",
"dev": "gulp"
},
"repository": {
"type": "git",
"url": "http://admin@www.simonfungc.com:10086/r/mp/mp-gulp-framework.git"
},
"keywords": [
"gulp",
"gulpjs",
"workflow",
"weapp",
"wexin",
"wechat",
"css",
"wxml",
"wxss"
],
"author": "SimonFungc",
"license": "MIT",
"bugs": {
"url": "https://www.simonfungc.com/"
},
"homepage": "https://www.simonfungc.com/",
"devDependencies": {
"del": "^4.0.0",
"gulp": "^4.0.0",
"gulp-cached": "^1.1.1",
"gulp-debug": "^4.0.0",
"gulp-if": "^2.0.2",
"gulp-imagemin": "^5.0.0",
"gulp-newer": "^1.3.0",
"gulp-postcss": "^8.0.0",
"gulp-qcloud-upload": "^2.2.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^1.0.0",
"gulp-sass": "^4.0.0",
"gulp-sftp": "^0.1.5",
"gulp-util": "^3.0.8",
"postcss-font-base64": "^1.0.4",
"postcss-lazysprite": "^2.0.0",
"postcss-px2rpx": "0.0.4",
"yargs": "^13.1.0"
}
}
{
"client": "./dist",
"svr": "./server",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true,
"newFeature": true
},
"appid": "wxc57ed87f2569f701",
"projectname": "gulp-example",
"condition": {}
}
//app.js
let fetchApi = require('./http/fetch-api.js');
let api = require('./http/api');
let config = require('./config');
let router = require('./router/index');
let store = require('./utils/stroage');
require('./http/mock-data');
App({
get: fetchApi.fetch,
post: (params) => {
params.method = 'post';
return fetchApi.fetch(params);
},
api: api,
config: config,
router: router,
store: store,
onLaunch: function () {},
globalData: {
indexInfo: null,
userInfo: null
}
})
{
"pages": [
"pages/index/index",
"pages/example/example",
"pages/more/more"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "心愿单",
"navigationBarTextStyle": "black"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#CF4646",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "image/tabbar/home_D.png",
"selectedIconPath": "image/tabbar/home.png",
"text": "介绍"
},
{
"pagePath": "pages/more/more",
"iconPath": "image/tabbar/set_D.png",
"selectedIconPath": "image/tabbar/set.png",
"text": "更多"
}
]
}
}
/**
* ------------------------------------------------------------------
* app.scss 入口文件
*
* ------------------------------------------------------------------
*
*/
// 支持文件
@import "assets/scss/support";
// 原子类
@import "assets/scss/utils";
// 图标
// @import 'styles/iconfont.wxss';
// 雪碧图
// @lazysprite "filetype";
.test {
background-image: url(%ASSETS_IMG%/qr-r.jpg);
}
.app {
height: 100%;
justify-content: space-between;
// text-align: center;
box-sizing: border-box;
font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif, FZY3JW-GB1-0;
}
.app__width {
width: 750px;
}
.app__width {
width: 750px;
}
.app__inner {
margin: 20px;
}
.app__title {
font-size: $fontSize;
line-height: $fontSize + 4px;
font-weight: bold;
padding-bottom: 10px;
margin-bottom: 20px;
border-bottom: .5px solid #EEEEEE;
}
.app__desc {
font-size: $fontSizeSmaller;
line-height: $fontSizeSmaller +2px;
margin-bottom: 20px;
color: $colorGray;
}
.app__bgc {
position: fixed;
background-color: #ffffff;
width: 100%;
height: 100%;
}
.app__bg {
position: absolute;
width: 100%;
height: 100%;
}
.app__top-shadow {
position: fixed;
width: 750px;
height: 1px;
box-shadow: 0px 4px 0.9px 0.1px rgba(6, 0, 1, 0.07);
background-color: #ffffff;
}
.app__content {
position: relative;
}
// web font icon
@font-face {
font-family: "iconfont";
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'),
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconrefresh:before {
content: "\e874";
}
.iconempty:before {
content: "\e6a6";
}
.drop-down-item :last-child {
border-bottom: none;
}
/**
* ------------------------------------------------------------------
* Sass Minxins
*
* 参考收集:
* https://github.com/twbs/bootstrap-sass/tree/master/assets/stylesheets/bootstrap/mixins
* ------------------------------------------------------------------
*
*/
// 文字截取
@mixin text-overflow() {
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
word-break: break-all;
word-wrap: normal;
}
@mixin word-break() {
word-break: break-all;
word-wrap: break-word;
white-space: normal;
}
// No wrap
@mixin no-wrap() {
word-break: normal;
word-wrap: normal;
white-space: nowrap;
}
// 清除浮动
@mixin clearfix() {
&:before,
&:after {
content: " "; // 1
display: table; // 2
}
&:after {
clear: both;
}
}
// Single side border-radius
@mixin border-top-radius($radius) {
border-top-right-radius: $radius;
border-top-left-radius: $radius;
}
@mixin border-right-radius($radius) {
border-bottom-right-radius: $radius;
border-top-right-radius: $radius;
}
@mixin border-bottom-radius($radius) {
border-bottom-right-radius: $radius;
border-bottom-left-radius: $radius;
}
@mixin border-left-radius($radius) {
border-bottom-left-radius: $radius;
border-top-left-radius: $radius;
}
// Center-align a block level element
@mixin center-block() {
display: block;
margin-left: auto;
margin-right: auto;
}
// CSS image replacement
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
@mixin hide-text() {
font-size: 0;
line-height: 0;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
/**
* ------------------------------------------------------------------
* 支持文件
* 需要引用的地方均需要加上这个支持文件
*
* ------------------------------------------------------------------
*
*/
@import "mixins";
@import "var";
/**
* ------------------------------------------------------------------
* 原子类
*
* ------------------------------------------------------------------
*
*/
@import "support";
// Margin
.u-mt-smaller {
margin-top: $marginTopSmaller;
}
.u-mt-small {
margin-top: $marginTopSmall;
}
.u-mt-medium {
margin-top: $marginTopMedium;
}
.u-mt-large {
margin-top: $marginTopLarge;
}
.u-mt-larger {
margin-top: $marginTopLarger;
}
.u-mb-smaller {
margin-bottom: $marginTopSmaller;
}
.u-mb-small {
margin-bottom: $marginTopSmall;
}
.u-mb-medium {
margin-bottom: $marginTopMedium;
}
.u-mb-large {
margin-bottom: $marginTopLarge;
}
.u-mb-larger {
margin-bottom: $marginTopLarger;
}
// Padding
.u-pt-smaller {
padding-top: $paddingTopSmaller;
}
.u-pt-small {
padding-top: $paddingTopSmall;
}
.u-pt-medium {
padding-top: $paddingTopMedium;
}
.u-pt-large {
padding-top: $paddingTopLarge;
}
.u-pt-larger {
padding-top: $paddingTopLarger;
}
.u-pb-smaller {
padding-bottom: $paddingTopSmaller;
}
.u-pb-small {
padding-bottom: $paddingTopSmall;
}
.u-pb-medium {
padding-bottom: $paddingTopMedium;
}
.u-pb-large {
padding-bottom: $paddingTopLarge;
}
.u-pb-larger {
padding-bottom: $paddingTopLarger;
}
// 布局方位
.u-ta-c {
text-align: center !important;
}
.u-ta-l {
text-align: left !important;
}
.u-ta-r {
text-align: right !important;
}
.u-fl-l {
float: left;
}
.u-fl-n {
float: none;
}
.u-fl-r {
float: right;
}
.u-d-b {
display: block;
}
.u-d-i {
display: inline !important;
}
.u-d-ib {
display: inline-block !important;
}
.u-d-n {
display: none !important;
}
.u-d-t {
display: table;
table-layout: fixed;
}
.u-d-tc {
display: table-cell;
}
.u-va-b {
vertical-align: bottom;
}
.u-va-m {
vertical-align: middle;
}
.u-va-t {
vertical-align: top;
}
// clearfix
.u-clearfix {
@include clearfix;
}
// 虚拟格式
.u-cur-d {
cursor: default;
}
.u-cur-p {
cursor: pointer;
}
// flex
.u-flex {
display: -webkit-box;
display: -webkit-flex;
display: flex;
}
.u-flex-item {
-webkit-box-flex: 1;
-webkit-flex: 1;
flex: 1;
}
// 小程序中模拟ul、li
.u-ul {
padding-left: 30px;
text-align: left;
display: block;
}
.u-li {
position: relative;
font-size: $fontSizeSmall;
line-height: $fontSizeSmall + 4px;
margin-bottom: $marginTopSmall;
&:before {
position: absolute;
content: " ";
top: 14px;
left: -20px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $colorBlack;
}
}
/**
* ------------------------------------------------------------------
* Sass 变量
*
* ------------------------------------------------------------------
*
*/
// Margin
$marginTopSmaller: 20px;
$marginTopSmall: 30px;
$marginTopMedium: 40px;
$marginTopLarge: 60px;
$marginTopLarger: 80px;
// Padding
$paddingTopSmaller: 20px;
$paddingTopSmall: 30px;
$paddingTopMedium: 40px;
$paddingTopLarge: 60px;
$paddingTopLarger: 80px;
// Color
$colorBlue: #20A0FF;
$colorGreen: #13CE66;
$colorGray: #475669;
$colorBlack: #000;
$colorRed: #FF4949;
$colorYellow: #F7BA2A;
$color: #787878;
$colorLink: #1D8CE0;
$backGroundColor: #fff;
// Font
$fontSize: 32px;
$fontSizeSmall: 28px;
$fontSizeSmaller: 24px;
$fontSizeLarge: 36px;
$fontSizeLarger: 44px;
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
},
bottomVisible: {
type: Boolean,
value: false
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {}
}
})
// 底线
.bottom-tips {
position: relative;
padding: 40px 0;
width: 100%;
text-align: center;
color: #666666;
.line {
border-bottom: dashed 1px #cccccc;
width: 80%;
position: absolute;
top: 50%;
left: 0;
right: 0;
margin: 0 auto;
}
.tips-wrap {
position: relative;
font-size: 28px;
.tips {
padding: 0 20px;
background-color: #ffffff;
}
}
}
<view class="bottom-tips" wx:if="{{bottomVisible}}">
<view class="line"></view>
<view class="tips-wrap">
<text class="tips">我是有底线的</text>
</view>
</view>
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {}
}
})
<view class="demo-item">demo-item</view>
Component({
options: {
styleIsolation: 'apply-shared' // 接受外部样式
},
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
},
emptyVisible: {
type: Boolean,
value: false
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {}
}
})
//用的fixed 请确保 内容为空
.empty-tips {
position: fixed;
text-align: center;
color: #666666;
font-size: 32px;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
top:35%;
.iconfont{
font-size: 100px;
}
.tips {
padding: 20px;
}
}
<view class="empty-tips" wx:if="{{emptyVisible}}">
<view class="tips">
<span class="iconfont iconempty"></span>
<view class="tips">这里空空如也~</view>
</view>
</view>
let ENV_CONFIG = require('./env/index');
const APPID = ''
/** ====每次发布版本记得修改此环境配置==== */
const ENV = 'Dev';
const NET_CONFIG = ENV_CONFIG[ENV];
const MOCKAPI = ENV_CONFIG.mockApi;
module.exports = {
APPID,
ENV,
NET_CONFIG,
MOCKAPI
}
module.exports = {
mockApi: 'http://mock.simonfungc.com',
Dev: {
baseApi: 'https://dev-api.xxx.com'
},
Test: {
baseApi: 'https://test-api.xxx.com'
},
Slave: {
baseApi: 'https://slave-api.xxx.com'
},
Prod: {
baseApi: 'https://api.xxx.com'
}
}
module.exports = {
index: '/xxx/index', // Index 接口
decrypt: '/xxx/decrypt', // 解析用户信息
}
let config = require('./../config');
let Store = require('./../utils/stroage');
const reason = '服务异常,请稍后重试';
// 检查并获取sessionid sid:是否需要验证sessionId
function checkSessionId(sid) {
return new Promise((resolve, reject) => {
if (!sid) {
resolve();
return;
}
let sessionId = Store.getItem('sessionId');
if (sessionId) {
resolve(sessionId);
} else {
// 身份失效
//登陆失效的回调
// Store.clear("sessionId");
// wx.reLaunch({
// // url: '/pages/authorize/authorize'
// url: '/pages/login/login',
// })
}
});
}
const fetch = function ({
loading = false,
toast = true,
sid = true,
mode,
isMock,
url,
data,
method
}) {
// 自定义参数
// const clientInfo = {
// user_id: 1
// }
// 日志埋点不需要出现loading
if (loading && mode != 'log') wx.showLoading();
// if (loading && mode != 'log') Util.showLoading();
// 新建promise对象
let promise = new Promise((resolve, reject) => {
/**
* isMock设置单个接口Mock开启
* mode:目前针对不同业务的接口进行处理,log标识本地埋点上传
*/
let baseUrl = config.NET_CONFIG.baseApi;
if (isMock && mode != 'log') {
baseUrl = config.MOCKAPI; //环境配置
}
checkSessionId().then((result) => {
if (sid) {
url += "?sessionId=" + Store.getItem("sessionId")
}
// console.log("url:", url);
wx.request({
url: baseUrl + url, //请求地址
data: data, //自定义参数
method: method || 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
// header: {}, // 设置请求的 header的默认参数,根据项目需求添加
// header: {
// 'clientInfo': JSON.stringify(clientInfo),
// 'Server-Token':'xxx'
// },
success: function (result) {
// 日志上传不需要处理结果
if (mode == 'log') return;
let res = result.data;
// 登陆失效拦截,根据项目需要添加自己的配置
if (res.code == 404) {
// wx.showToast({
// title: '当前登陆失效,请重新登陆',
// icon: 'none',
// mask: true,
// success: () => {
// return;
// }
// })
//登陆失效的回调
Store.clear("sessionId");
wx.reLaunch({
url: '/pages/authorize/authorize'
})
}
// 内部统一的成功code拦截码
if (res.code === 200) {
if (loading) {
wx.hideLoading();
}
// resolve(res);
// 直接返回content
resolve(res.content);
} else {
// 有些特殊状况不需要toast 需要弹窗
if (toast) {
wx.showToast({
title: res.errMsg || errMsg,
icon: 'none'
})
} else {
wx.hideLoading();
}
// 返回错误信息
reject(res);
}
},
fail: function (e = {
CODE: -1,
msg: errMsg,
errMsg
}) {
let msg = e.errMsg;
if (e.errMsg == 'request:fail timeout') {
msg = '服务请求超时,请稍后重试'
}
wx.showToast({
title: msg,
icon: 'none'
});
reject(e)
},
complete: function () {
// complete
}
})
})
});
return promise;
}
module.exports = {
fetch
}
// https://github.com/webx32/WxMock
let Mock = require('../utils/mockSdk.js');
let config = require('../config')
let env = config.MOCKAPI;
Mock.mock(env + '/eatClassifyService', {
data: {
resultCode: 0,
content: function () {
return Mock.Random.ip();
}
}
});
let app = getApp();
let config = require('../../config');
Page({
data: {
authorized: true,
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
onLoad(options) {},
onReady() {
wx.showLoading();
this.autoAuth();
},
bindGetUserInfo(e) {
wx.showLoading();
this.getUserInfo(e.detail);
},
// 点openType==userInfo 手动登陆
getUserInfo(e) {
let _this = this;
// 直接就能拿到 userInfo
app.globalData.userInfo = e.userInfo;
wx.login({
success: function (res) {
app.post({
url: app.api.decrypt,
data: {
encryptedData: e.encryptedData,
iv: e.iv,
code: res.code
}
}).then((res2) => {
_this.autoAuth();
}).catch((err) => {})
}
});
},
// 刷新首页数据
refreshIndexData() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.index,
data: {}
}).then((res) => {
app.globalData.indexInfo = res;
resolve(res)
}).catch((err) => {
console.log("index err:", err);
});
});
},
// 判断结果去首页
autoAuth() {
// 调用自动登陆方法
let _this = this;
this.refreshIndexData().then((result) => {
let indexInfo = app.globalData.indexInfo;
// 自动登陆成功
let loginSuc = true;
if (loginSuc) {
// 登陆成功跳转到首页
setTimeout(() => {
app.router.push({
path: 'index',
query: {},
duration: 0,
openType: "redirect"
})
wx.hideLoading();
}, 3000);
} else {
// 登陆失败,隐藏loading自动登陆
wx.hideLoading();
this.setData({
authorized: false
})
}
});
}
})
@import '../../assets/scss/mixins';
.page {
position: relative;
overflow: hidden;
.bgc {}
.bg {}
.main {
.login-wrap {
padding-top: 946px;
.login-btn {
width: 340px;
height: 80px;
line-height: 80px;
border-radius: 40px;
border: solid 3px #4bc2ed;
margin: 0 auto;
font-size: 36px;
color: #4bc2ed;
text-align: center;
background-color: transparent;
}
}
}
}
<view class="page-authorize page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<!-- <view class="app__top-shadow"></view> -->
<view class="app__content main">
<view class="login-wrap">
<button class="login-btn" wx:if="{{!authorized}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
同意微信授权
</button>
</view>
</view>
</view>
let app = getApp();
Page({
data: {},
onLoad(options) {}
})
{
"navigationBarTitleText": "more"
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
.bgc {}
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
}
}
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<!-- <view class="app__top-shadow"></view> -->
<view class="app__content main">
<view class="top-space"></view>
<view class="content"></view>
</view>
</view>
let app = getApp();
let Router = app.router;
let Store = app.store;
// import Notify from './../../ui/vant-weapp/notify/notify';
Page({
data: {},
onLoad: function (options = {}) {},
// 页面跳转
navHandler() {
// 默认navigateTo,可选 redirect reLaunch back,参照小程序跳转
// 配置在tabBar的页面不能用navigateTo,要用reLaunch
let openType = "reLaunch";
Router.push({
path: 'more',
query: {
id: 1
},
duration: 500,
openType
})
},
// 请求数据
reqHandler() {
// 是否使用本地模拟数据
let isMock = true;
app.post({
isMock,
url: '/eatClassifyService',
data: {}
}).then((res) => {
console.log("res:", res);
}).catch((err) => {
console.log("err:", err);
})
},
// 储存数据到本地
storeHandler() {
Store.setItem("id", 2);
},
// 使用有赞UI组件
showNotify() {
// Notify("vant notify提示");
}
})
{
"navigationBarTitleText": "example",
"usingComponents": {
"demo-item": "../../component/demo-item/demo-item"
}
}
<view class="page-example">
<button bindtap="navHandler">页面跳转</button>
<button bindtap="reqHandler">数据请求</button>
<button bindtap="storeHandler">储存数据到本地</button>
<button bindtap="showNotify">有赞提示</button>
<demo-item></demo-item>
</view>
<!-- <van-notify id="van-notify" /> -->
let app = getApp();
Page({
data: {},
onLoad(options) {}
})
{
"navigationBarTitleText": "index"
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
.bgc {}
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
}
}
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<!-- <view class="app__top-shadow"></view> -->
<view class="app__content main">
<view class="top-space"></view>
<view class="content"></view>
</view>
</view>
let app = getApp();
Page({
data: {},
onLoad(options) {}
})
{
"navigationBarTitleText": "demo"
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
.bgc {}
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
}
}
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<!-- <view class="app__top-shadow"></view> -->
<view class="app__content main">
<view class="top-space"></view>
<view class="content"></view>
</view>
</view>
let app = getApp();
Page({
data: {
isShow: false, // 控制组件显示隐藏
url: ''
},
onLoad: function (options = {}) {
let url = options.url;
if (url) {
this.setData({
url: url,
isShow: true
})
} else {
wx.showToast({
title: '未找到页面地址',
title: 'none',
});
}
}
})
{
"navigationBarTitleText": "webview"
}
<view class="loading-wrap">
<view class="loading">
<view class="icon"></view>
<view class="text">加载中...</view>
</view>
</view>
<web-view wx:if="{{isShow}}" src="{{url}}" bindload="loadSucc"/>
const routerPath = {
index: '/pages/index/index', // 首页
wish: '/pages/wish/wish', // 创建心愿单
createWish: '/pages/create-wish/create-wish', // 创建心愿单
newWelfare: '/pages/new-welfare/new-welfare', // 新人福利
userTable: '/pages/user-table/user-table', // 用户表单
rank: '/pages/rank/rank', // 排行榜
index: '/pages/poster/poster', // 海报页
coop: '/pages/coop/coop', // 协作页/好友查看
register: '/pages/register/register', // 注册
authorize: '/pages/authorize/authorize', // 授权
example: '/pages/example/example',
more: '/pages/more/more',
// 组件 蒙层/提示
// rule 规则
// tips 会员登陆/注册提示
// tips 重复登陆提示
// tips 创建心愿单提示
// tips new-question-tips 新人答题提示
// tips shake 摇手机提示
// tips award-old 老会员获得积分提示
// tips award-new 老会员获得积分提示
// tips award-coupon 领取代金券
// tips new-award-coupon 新人答题领取代金券
// comp nearby-store 附近门店查询
}
function parse(data) {
let tempArr = [];
for (let key in data) {
tempArr.push(key + '=' + encodeURIComponent(data[key]));
}
return tempArr.join('&');
}
function push(path, option = {}) {
if (typeof path == 'string') {
option.path = path; //兼容无参数路径
} else {
option = path;
}
// console.log("option:", option);
// 配置key值找到对应path
let url = routerPath[option.path] || routerPath['index'];
// console.log("url:", url);
// 读取传入的配置参数
let {
query = {}, openType = 'navigate', duration = 0
} = option;
// json 转换为 字符串拼接参数
let params = parse(query)
// console.log("params:", params);
if (params) {
url = url + '?' + params;
}
// 是否需要延时跳转
duration ? setTimeout(() => {
to(openType, url);
}, duration) : to(openType, url);
}
function to(openType, url) {
let obj = {
url
};
if (openType == 'redirect') {
wx.redirectTo(obj);
} else if (openType == 'reLaunch') {
wx.reLaunch(obj);
} else if (openType == 'switchTab') {
wx.switchTab(obj);
} else if (openType == 'back') {
wx.navigateBack({
delta: 1
});
} else {
wx.navigateTo(obj);
}
}
module.exports = {
parse,
push,
to
}
/**
* @version: 1.0 Alpha-1
* @author: Coolite Inc. http://www.coolite.com/
* @date: 2008-05-13
* @copyright: Copyright (c) 2006-2008, Coolite Inc. (http://www.coolite.com/). All rights reserved.
* @license: Licensed under The MIT License. See license.txt and http://www.datejs.com/license/.
* @website: http://www.datejs.com/
*/
Date.CultureInfo = {
name: "en-US",
englishName: "English (United States)",
nativeName: "English (United States)",
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
abbreviatedDayNames: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
shortestDayNames: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
firstLetterDayNames: ["S", "M", "T", "W", "T", "F", "S"],
monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
abbreviatedMonthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
amDesignator: "AM",
pmDesignator: "PM",
firstDayOfWeek: 0,
twoDigitYearMax: 2029,
dateElementOrder: "mdy",
formatPatterns: {
shortDate: "M/d/yyyy",
longDate: "dddd, MMMM dd, yyyy",
shortTime: "h:mm tt",
longTime: "h:mm:ss tt",
fullDateTime: "dddd, MMMM dd, yyyy h:mm:ss tt",
sortableDateTime: "yyyy-MM-ddTHH:mm:ss",
universalSortableDateTime: "yyyy-MM-dd HH:mm:ssZ",
rfc1123: "ddd, dd MMM yyyy HH:mm:ss GMT",
monthDay: "MMMM dd",
yearMonth: "MMMM, yyyy"
},
regexPatterns: {
jan: /^jan(uary)?/i,
feb: /^feb(ruary)?/i,
mar: /^mar(ch)?/i,
apr: /^apr(il)?/i,
may: /^may/i,
jun: /^jun(e)?/i,
jul: /^jul(y)?/i,
aug: /^aug(ust)?/i,
sep: /^sep(t(ember)?)?/i,
oct: /^oct(ober)?/i,
nov: /^nov(ember)?/i,
dec: /^dec(ember)?/i,
sun: /^su(n(day)?)?/i,
mon: /^mo(n(day)?)?/i,
tue: /^tu(e(s(day)?)?)?/i,
wed: /^we(d(nesday)?)?/i,
thu: /^th(u(r(s(day)?)?)?)?/i,
fri: /^fr(i(day)?)?/i,
sat: /^sa(t(urday)?)?/i,
future: /^next/i,
past: /^last|past|prev(ious)?/i,
add: /^(\+|aft(er)?|from|hence)/i,
subtract: /^(\-|bef(ore)?|ago)/i,
yesterday: /^yes(terday)?/i,
today: /^t(od(ay)?)?/i,
tomorrow: /^tom(orrow)?/i,
now: /^n(ow)?/i,
millisecond: /^ms|milli(second)?s?/i,
second: /^sec(ond)?s?/i,
minute: /^mn|min(ute)?s?/i,
hour: /^h(our)?s?/i,
week: /^w(eek)?s?/i,
month: /^m(onth)?s?/i,
day: /^d(ay)?s?/i,
year: /^y(ear)?s?/i,
shortMeridian: /^(a|p)/i,
longMeridian: /^(a\.?m?\.?|p\.?m?\.?)/i,
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,
ordinalSuffix: /^\s*(st|nd|rd|th)/i,
timeContext: /^\s*(\:|a(?!u|p)|p)/i
},
timezones: [{
name: "UTC",
offset: "-000"
}, {
name: "GMT",
offset: "-000"
}, {
name: "EST",
offset: "-0500"
}, {
name: "EDT",
offset: "-0400"
}, {
name: "CST",
offset: "-0600"
}, {
name: "CDT",
offset: "-0500"
}, {
name: "MST",
offset: "-0700"
}, {
name: "MDT",
offset: "-0600"
}, {
name: "PST",
offset: "-0800"
}, {
name: "PDT",
offset: "-0700"
}]
};
(function () {
var $D = Date,
$P = $D.prototype,
$C = $D.CultureInfo,
p = function (s, l) {
if (!l) {
l = 2;
}
return ("000" + s).slice(l * -1);
};
$P.clearTime = function () {
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
this.setMilliseconds(0);
return this;
};
$P.setTimeToNow = function () {
var n = new Date();
this.setHours(n.getHours());
this.setMinutes(n.getMinutes());
this.setSeconds(n.getSeconds());
this.setMilliseconds(n.getMilliseconds());
return this;
};
$D.today = function () {
return new Date().clearTime();
};
$D.compare = function (date1, date2) {
if (isNaN(date1) || isNaN(date2)) {
throw new Error(date1 + " - " + date2);
} else if (date1 instanceof Date && date2 instanceof Date) {
return (date1 < date2) ? -1 : (date1 > date2) ? 1 : 0;
} else {
throw new TypeError(date1 + " - " + date2);
}
};
$D.equals = function (date1, date2) {
return (date1.compareTo(date2) === 0);
};
$D.getDayNumberFromName = function (name) {
var n = $C.dayNames,
m = $C.abbreviatedDayNames,
o = $C.shortestDayNames,
s = name.toLowerCase();
for (var i = 0; i < n.length; i++) {
if (n[i].toLowerCase() == s || m[i].toLowerCase() == s || o[i].toLowerCase() == s) {
return i;
}
}
return -1;
};
$D.getMonthNumberFromName = function (name) {
var n = $C.monthNames,
m = $C.abbreviatedMonthNames,
s = name.toLowerCase();
for (var i = 0; i < n.length; i++) {
if (n[i].toLowerCase() == s || m[i].toLowerCase() == s) {
return i;
}
}
return -1;
};
$D.isLeapYear = function (year) {
return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
};
$D.getDaysInMonth = function (year, month) {
return [31, ($D.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
};
$D.getTimezoneAbbreviation = function (offset) {
var z = $C.timezones,
p;
for (var i = 0; i < z.length; i++) {
if (z[i].offset === offset) {
return z[i].name;
}
}
return null;
};
$D.getTimezoneOffset = function (name) {
var z = $C.timezones,
p;
for (var i = 0; i < z.length; i++) {
if (z[i].name === name.toUpperCase()) {
return z[i].offset;
}
}
return null;
};
$P.clone = function () {
return new Date(this.getTime());
};
$P.compareTo = function (date) {
return Date.compare(this, date);
};
$P.equals = function (date) {
return Date.equals(this, date || new Date());
};
$P.between = function (start, end) {
return this.getTime() >= start.getTime() && this.getTime() <= end.getTime();
};
$P.isAfter = function (date) {
return this.compareTo(date || new Date()) === 1;
};
$P.isBefore = function (date) {
return (this.compareTo(date || new Date()) === -1);
};
$P.isToday = function () {
return this.isSameDay(new Date());
};
$P.isSameDay = function (date) {
return this.clone().clearTime().equals(date.clone().clearTime());
};
$P.addMilliseconds = function (value) {
this.setMilliseconds(this.getMilliseconds() + value);
return this;
};
$P.addSeconds = function (value) {
return this.addMilliseconds(value * 1000);
};
$P.addMinutes = function (value) {
return this.addMilliseconds(value * 60000);
};
$P.addHours = function (value) {
return this.addMilliseconds(value * 3600000);
};
$P.addDays = function (value) {
this.setDate(this.getDate() + value);
return this;
};
$P.addWeeks = function (value) {
return this.addDays(value * 7);
};
$P.addMonths = function (value) {
var n = this.getDate();
this.setDate(1);
this.setMonth(this.getMonth() + value);
this.setDate(Math.min(n, $D.getDaysInMonth(this.getFullYear(), this.getMonth())));
return this;
};
$P.addYears = function (value) {
return this.addMonths(value * 12);
};
$P.add = function (config) {
if (typeof config == "number") {
this._orient = config;
return this;
}
var x = config;
if (x.milliseconds) {
this.addMilliseconds(x.milliseconds);
}
if (x.seconds) {
this.addSeconds(x.seconds);
}
if (x.minutes) {
this.addMinutes(x.minutes);
}
if (x.hours) {
this.addHours(x.hours);
}
if (x.weeks) {
this.addWeeks(x.weeks);
}
if (x.months) {
this.addMonths(x.months);
}
if (x.years) {
this.addYears(x.years);
}
if (x.days) {
this.addDays(x.days);
}
return this;
};
var $y, $m, $d;
$P.getWeek = function () {
var a, b, c, d, e, f, g, n, s, w;
$y = (!$y) ? this.getFullYear() : $y;
$m = (!$m) ? this.getMonth() + 1 : $m;
$d = (!$d) ? this.getDate() : $d;
if ($m <= 2) {
a = $y - 1;
b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
s = b - c;
e = 0;
f = $d - 1 + (31 * ($m - 1));
} else {
a = $y;
b = (a / 4 | 0) - (a / 100 | 0) + (a / 400 | 0);
c = ((a - 1) / 4 | 0) - ((a - 1) / 100 | 0) + ((a - 1) / 400 | 0);
s = b - c;
e = s + 1;
f = $d + ((153 * ($m - 3) + 2) / 5) + 58 + s;
}
g = (a + b) % 7;
d = (f + g - e) % 7;
n = (f + 3 - d) | 0;
if (n < 0) {
w = 53 - ((g - s) / 5 | 0);
} else if (n > 364 + s) {
w = 1;
} else {
w = (n / 7 | 0) + 1;
}
$y = $m = $d = null;
return w;
};
$P.getISOWeek = function () {
$y = this.getUTCFullYear();
$m = this.getUTCMonth() + 1;
$d = this.getUTCDate();
return p(this.getWeek());
};
$P.setWeek = function (n) {
return this.moveToDayOfWeek(1).addWeeks(n - this.getWeek());
};
$D._validate = function (n, min, max, name) {
if (typeof n == "undefined") {
return false;
} else if (typeof n != "number") {
throw new TypeError(n + " is not a Number.");
} else if (n < min || n > max) {
throw new RangeError(n + " is not a valid value for " + name + ".");
}
return true;
};
$D.validateMillisecond = function (value) {
return $D._validate(value, 0, 999, "millisecond");
};
$D.validateSecond = function (value) {
return $D._validate(value, 0, 59, "second");
};
$D.validateMinute = function (value) {
return $D._validate(value, 0, 59, "minute");
};
$D.validateHour = function (value) {
return $D._validate(value, 0, 23, "hour");
};
$D.validateDay = function (value, year, month) {
return $D._validate(value, 1, $D.getDaysInMonth(year, month), "day");
};
$D.validateMonth = function (value) {
return $D._validate(value, 0, 11, "month");
};
$D.validateYear = function (value) {
return $D._validate(value, 0, 9999, "year");
};
$P.set = function (config) {
if ($D.validateMillisecond(config.millisecond)) {
this.addMilliseconds(config.millisecond - this.getMilliseconds());
}
if ($D.validateSecond(config.second)) {
this.addSeconds(config.second - this.getSeconds());
}
if ($D.validateMinute(config.minute)) {
this.addMinutes(config.minute - this.getMinutes());
}
if ($D.validateHour(config.hour)) {
this.addHours(config.hour - this.getHours());
}
if ($D.validateMonth(config.month)) {
this.addMonths(config.month - this.getMonth());
}
if ($D.validateYear(config.year)) {
this.addYears(config.year - this.getFullYear());
}
if ($D.validateDay(config.day, this.getFullYear(), this.getMonth())) {
this.addDays(config.day - this.getDate());
}
if (config.timezone) {
this.setTimezone(config.timezone);
}
if (config.timezoneOffset) {
this.setTimezoneOffset(config.timezoneOffset);
}
if (config.week && $D._validate(config.week, 0, 53, "week")) {
this.setWeek(config.week);
}
return this;
};
$P.moveToFirstDayOfMonth = function () {
return this.set({
day: 1
});
};
$P.moveToLastDayOfMonth = function () {
return this.set({
day: $D.getDaysInMonth(this.getFullYear(), this.getMonth())
});
};
$P.moveToNthOccurrence = function (dayOfWeek, occurrence) {
var shift = 0;
if (occurrence > 0) {
shift = occurrence - 1;
} else if (occurrence === -1) {
this.moveToLastDayOfMonth();
if (this.getDay() !== dayOfWeek) {
this.moveToDayOfWeek(dayOfWeek, -1);
}
return this;
}
return this.moveToFirstDayOfMonth().addDays(-1).moveToDayOfWeek(dayOfWeek, +1).addWeeks(shift);
};
$P.moveToDayOfWeek = function (dayOfWeek, orient) {
var diff = (dayOfWeek - this.getDay() + 7 * (orient || +1)) % 7;
return this.addDays((diff === 0) ? diff += 7 * (orient || +1) : diff);
};
$P.moveToMonth = function (month, orient) {
var diff = (month - this.getMonth() + 12 * (orient || +1)) % 12;
return this.addMonths((diff === 0) ? diff += 12 * (orient || +1) : diff);
};
$P.getOrdinalNumber = function () {
return Math.ceil((this.clone().clearTime() - new Date(this.getFullYear(), 0, 1)) / 86400000) + 1;
};
$P.getTimezone = function () {
return $D.getTimezoneAbbreviation(this.getUTCOffset());
};
$P.setTimezoneOffset = function (offset) {
var here = this.getTimezoneOffset(),
there = Number(offset) * -6 / 10;
return this.addMinutes(there - here);
};
$P.setTimezone = function (offset) {
return this.setTimezoneOffset($D.getTimezoneOffset(offset));
};
$P.hasDaylightSavingTime = function () {
return (Date.today().set({
month: 0,
day: 1
}).getTimezoneOffset() !== Date.today().set({
month: 6,
day: 1
}).getTimezoneOffset());
};
$P.isDaylightSavingTime = function () {
return (this.hasDaylightSavingTime() && new Date().getTimezoneOffset() === Date.today().set({
month: 6,
day: 1
}).getTimezoneOffset());
};
$P.getUTCOffset = function () {
var n = this.getTimezoneOffset() * -10 / 6,
r;
if (n < 0) {
r = (n - 10000).toString();
return r.charAt(0) + r.substr(2);
} else {
r = (n + 10000).toString();
return "+" + r.substr(1);
}
};
$P.getElapsed = function (date) {
return (date || new Date()) - this;
};
if (!$P.toISOString) {
$P.toISOString = function () {
function f(n) {
return n < 10 ? '0' + n : n;
}
return '"' + this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z"';
};
}
$P._toString = $P.toString;
$P.toString = function (format) {
var x = this;
if (format && format.length == 1) {
var c = $C.formatPatterns;
x.t = x.toString;
switch (format) {
case "d":
return x.t(c.shortDate);
case "D":
return x.t(c.longDate);
case "F":
return x.t(c.fullDateTime);
case "m":
return x.t(c.monthDay);
case "r":
return x.t(c.rfc1123);
case "s":
return x.t(c.sortableDateTime);
case "t":
return x.t(c.shortTime);
case "T":
return x.t(c.longTime);
case "u":
return x.t(c.universalSortableDateTime);
case "y":
return x.t(c.yearMonth);
}
}
var ord = function (n) {
switch (n * 1) {
case 1:
case 21:
case 31:
return "st";
case 2:
case 22:
return "nd";
case 3:
case 23:
return "rd";
default:
return "th";
}
};
return format ? format.replace(/(\\)?(dd?d?d?|MM?M?M?|yy?y?y?|hh?|HH?|mm?|ss?|tt?|S)/g, function (m) {
if (m.charAt(0) === "\\") {
return m.replace("\\", "");
}
x.h = x.getHours;
switch (m) {
case "hh":
return p(x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12));
case "h":
return x.h() < 13 ? (x.h() === 0 ? 12 : x.h()) : (x.h() - 12);
case "HH":
return p(x.h());
case "H":
return x.h();
case "mm":
return p(x.getMinutes());
case "m":
return x.getMinutes();
case "ss":
return p(x.getSeconds());
case "s":
return x.getSeconds();
case "yyyy":
return p(x.getFullYear(), 4);
case "yy":
return p(x.getFullYear());
case "dddd":
return $C.dayNames[x.getDay()];
case "ddd":
return $C.abbreviatedDayNames[x.getDay()];
case "dd":
return p(x.getDate());
case "d":
return x.getDate();
case "MMMM":
return $C.monthNames[x.getMonth()];
case "MMM":
return $C.abbreviatedMonthNames[x.getMonth()];
case "MM":
return p((x.getMonth() + 1));
case "M":
return x.getMonth() + 1;
case "t":
return x.h() < 12 ? $C.amDesignator.substring(0, 1) : $C.pmDesignator.substring(0, 1);
case "tt":
return x.h() < 12 ? $C.amDesignator : $C.pmDesignator;
case "S":
return ord(x.getDate());
default:
return m;
}
}) : this._toString();
};
}());
(function () {
var $D = Date,
$P = $D.prototype,
$C = $D.CultureInfo,
$N = Number.prototype;
$P._orient = +1;
$P._nth = null;
$P._is = false;
$P._same = false;
$P._isSecond = false;
$N._dateElement = "day";
$P.next = function () {
this._orient = +1;
return this;
};
$D.next = function () {
return $D.today().next();
};
$P.last = $P.prev = $P.previous = function () {
this._orient = -1;
return this;
};
$D.last = $D.prev = $D.previous = function () {
return $D.today().last();
};
$P.is = function () {
this._is = true;
return this;
};
$P.same = function () {
this._same = true;
this._isSecond = false;
return this;
};
$P.today = function () {
return this.same().day();
};
$P.weekday = function () {
if (this._is) {
this._is = false;
return (!this.is().sat() && !this.is().sun());
}
return false;
};
$P.at = function (time) {
return (typeof time === "string") ? $D.parse(this.toString("d") + " " + time) : this.set(time);
};
$N.fromNow = $N.after = function (date) {
var c = {};
c[this._dateElement] = this;
return ((!date) ? new Date() : date.clone()).add(c);
};
$N.ago = $N.before = function (date) {
var c = {};
c[this._dateElement] = this * -1;
return ((!date) ? new Date() : date.clone()).add(c);
};
var dx = ("sunday monday tuesday wednesday thursday friday saturday").split(/\s/),
mx = ("january february march april may june july august september october november december").split(/\s/),
px = ("Millisecond Second Minute Hour Day Week Month Year").split(/\s/),
pxf = ("Milliseconds Seconds Minutes Hours Date Week Month FullYear").split(/\s/),
nth = ("final first second third fourth fifth").split(/\s/),
de;
$P.toObject = function () {
var o = {};
for (var i = 0; i < px.length; i++) {
o[px[i].toLowerCase()] = this["get" + pxf[i]]();
}
return o;
};
$D.fromObject = function (config) {
config.week = null;
return Date.today().set(config);
};
var df = function (n) {
return function () {
if (this._is) {
this._is = false;
return this.getDay() == n;
}
if (this._nth !== null) {
if (this._isSecond) {
this.addSeconds(this._orient * -1);
}
this._isSecond = false;
var ntemp = this._nth;
this._nth = null;
var temp = this.clone().moveToLastDayOfMonth();
this.moveToNthOccurrence(n, ntemp);
if (this > temp) {
throw new RangeError($D.getDayName(n) + " does not occur " + ntemp + " times in the month of " + $D.getMonthName(temp.getMonth()) + " " + temp.getFullYear() + ".");
}
return this;
}
return this.moveToDayOfWeek(n, this._orient);
};
};
var sdf = function (n) {
return function () {
var t = $D.today(),
shift = n - t.getDay();
if (n === 0 && $C.firstDayOfWeek === 1 && t.getDay() !== 0) {
shift = shift + 7;
}
return t.addDays(shift);
};
};
for (var i = 0; i < dx.length; i++) {
$D[dx[i].toUpperCase()] = $D[dx[i].toUpperCase().substring(0, 3)] = i;
$D[dx[i]] = $D[dx[i].substring(0, 3)] = sdf(i);
$P[dx[i]] = $P[dx[i].substring(0, 3)] = df(i);
}
var mf = function (n) {
return function () {
if (this._is) {
this._is = false;
return this.getMonth() === n;
}
return this.moveToMonth(n, this._orient);
};
};
var smf = function (n) {
return function () {
return $D.today().set({
month: n,
day: 1
});
};
};
for (var j = 0; j < mx.length; j++) {
$D[mx[j].toUpperCase()] = $D[mx[j].toUpperCase().substring(0, 3)] = j;
$D[mx[j]] = $D[mx[j].substring(0, 3)] = smf(j);
$P[mx[j]] = $P[mx[j].substring(0, 3)] = mf(j);
}
var ef = function (j) {
return function () {
if (this._isSecond) {
this._isSecond = false;
return this;
}
if (this._same) {
this._same = this._is = false;
var o1 = this.toObject(),
o2 = (arguments[0] || new Date()).toObject(),
v = "",
k = j.toLowerCase();
for (var m = (px.length - 1); m > -1; m--) {
v = px[m].toLowerCase();
if (o1[v] != o2[v]) {
return false;
}
if (k == v) {
break;
}
}
return true;
}
if (j.substring(j.length - 1) != "s") {
j += "s";
}
return this["add" + j](this._orient);
};
};
var nf = function (n) {
return function () {
this._dateElement = n;
return this;
};
};
for (var k = 0; k < px.length; k++) {
de = px[k].toLowerCase();
$P[de] = $P[de + "s"] = ef(px[k]);
$N[de] = $N[de + "s"] = nf(de);
}
$P._ss = ef("Second");
var nthfn = function (n) {
return function (dayOfWeek) {
if (this._same) {
return this._ss(arguments[0]);
}
if (dayOfWeek || dayOfWeek === 0) {
return this.moveToNthOccurrence(dayOfWeek, n);
}
this._nth = n;
if (n === 2 && (dayOfWeek === undefined || dayOfWeek === null)) {
this._isSecond = true;
return this.addSeconds(this._orient);
}
return this;
};
};
for (var l = 0; l < nth.length; l++) {
$P[nth[l]] = (l === 0) ? nthfn(-1) : nthfn(l);
}
}());
(function () {
Date.Parsing = {
Exception: function (s) {
this.message = "Parse error at '" + s.substring(0, 10) + " ...'";
}
};
var $P = Date.Parsing;
var _ = $P.Operators = {
rtoken: function (r) {
return function (s) {
var mx = s.match(r);
if (mx) {
return ([mx[0], s.substring(mx[0].length)]);
} else {
throw new $P.Exception(s);
}
};
},
token: function (s) {
return function (s) {
return _.rtoken(new RegExp("^\s*" + s + "\s*"))(s);
};
},
stoken: function (s) {
return _.rtoken(new RegExp("^" + s));
},
until: function (p) {
return function (s) {
var qx = [],
rx = null;
while (s.length) {
try {
rx = p.call(this, s);
} catch (e) {
qx.push(rx[0]);
s = rx[1];
continue;
}
break;
}
return [qx, s];
};
},
many: function (p) {
return function (s) {
var rx = [],
r = null;
while (s.length) {
try {
r = p.call(this, s);
} catch (e) {
return [rx, s];
}
rx.push(r[0]);
s = r[1];
}
return [rx, s];
};
},
optional: function (p) {
return function (s) {
var r = null;
try {
r = p.call(this, s);
} catch (e) {
return [null, s];
}
return [r[0], r[1]];
};
},
not: function (p) {
return function (s) {
try {
p.call(this, s);
} catch (e) {
return [null, s];
}
throw new $P.Exception(s);
};
},
ignore: function (p) {
return p ? function (s) {
var r = null;
r = p.call(this, s);
return [null, r[1]];
} : null;
},
product: function () {
var px = arguments[0],
qx = Array.prototype.slice.call(arguments, 1),
rx = [];
for (var i = 0; i < px.length; i++) {
rx.push(_.each(px[i], qx));
}
return rx;
},
cache: function (rule) {
var cache = {},
r = null;
return function (s) {
try {
r = cache[s] = (cache[s] || rule.call(this, s));
} catch (e) {
r = cache[s] = e;
}
if (r instanceof $P.Exception) {
throw r;
} else {
return r;
}
};
},
any: function () {
var px = arguments;
return function (s) {
var r = null;
for (var i = 0; i < px.length; i++) {
if (px[i] == null) {
continue;
}
try {
r = (px[i].call(this, s));
} catch (e) {
r = null;
}
if (r) {
return r;
}
}
throw new $P.Exception(s);
};
},
each: function () {
var px = arguments;
return function (s) {
var rx = [],
r = null;
for (var i = 0; i < px.length; i++) {
if (px[i] == null) {
continue;
}
try {
r = (px[i].call(this, s));
} catch (e) {
throw new $P.Exception(s);
}
rx.push(r[0]);
s = r[1];
}
return [rx, s];
};
},
all: function () {
var px = arguments,
_ = _;
return _.each(_.optional(px));
},
sequence: function (px, d, c) {
d = d || _.rtoken(/^\s*/);
c = c || null;
if (px.length == 1) {
return px[0];
}
return function (s) {
var r = null,
q = null;
var rx = [];
for (var i = 0; i < px.length; i++) {
try {
r = px[i].call(this, s);
} catch (e) {
break;
}
rx.push(r[0]);
try {
q = d.call(this, r[1]);
} catch (ex) {
q = null;
break;
}
s = q[1];
}
if (!r) {
throw new $P.Exception(s);
}
if (q) {
throw new $P.Exception(q[1]);
}
if (c) {
try {
r = c.call(this, r[1]);
} catch (ey) {
throw new $P.Exception(r[1]);
}
}
return [rx, (r ? r[1] : s)];
};
},
between: function (d1, p, d2) {
d2 = d2 || d1;
var _fn = _.each(_.ignore(d1), p, _.ignore(d2));
return function (s) {
var rx = _fn.call(this, s);
return [
[rx[0][0], r[0][2]], rx[1]
];
};
},
list: function (p, d, c) {
d = d || _.rtoken(/^\s*/);
c = c || null;
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)));
},
set: function (px, d, c) {
d = d || _.rtoken(/^\s*/);
c = c || null;
return function (s) {
var r = null,
p = null,
q = null,
rx = null,
best = [
[], s
],
last = false;
for (var i = 0; i < px.length; i++) {
q = null;
p = null;
r = null;
last = (px.length == 1);
try {
r = px[i].call(this, s);
} catch (e) {
continue;
}
rx = [
[r[0]], r[1]
];
if (r[1].length > 0 && !last) {
try {
q = d.call(this, r[1]);
} catch (ex) {
last = true;
}
} else {
last = true;
}
if (!last && q[1].length === 0) {
last = true;
}
if (!last) {
var qx = [];
for (var j = 0; j < px.length; j++) {
if (i != j) {
qx.push(px[j]);
}
}
p = _.set(qx, d).call(this, q[1]);
if (p[0].length > 0) {
rx[0] = rx[0].concat(p[0]);
rx[1] = p[1];
}
}
if (rx[1].length < best[1].length) {
best = rx;
}
if (best[1].length === 0) {
break;
}
}
if (best[0].length === 0) {
return best;
}
if (c) {
try {
q = c.call(this, best[1]);
} catch (ey) {
throw new $P.Exception(best[1]);
}
best[1] = q[1];
}
return best;
};
},
forward: function (gr, fname) {
return function (s) {
return gr[fname].call(this, s);
};
},
replace: function (rule, repl) {
return function (s) {
var r = rule.call(this, s);
return [repl, r[1]];
};
},
process: function (rule, fn) {
return function (s) {
var r = rule.call(this, s);
return [fn.call(this, r[0]), r[1]];
};
},
min: function (min, rule) {
return function (s) {
var rx = rule.call(this, s);
if (rx[0].length < min) {
throw new $P.Exception(s);
}
return rx;
};
}
};
var _generator = function (op) {
return function () {
var args = null,
rx = [];
if (arguments.length > 1) {
args = Array.prototype.slice.call(arguments);
} else if (arguments[0] instanceof Array) {
args = arguments[0];
}
if (args) {
for (var i = 0, px = args.shift(); i < px.length; i++) {
args.unshift(px[i]);
rx.push(op.apply(null, args));
args.shift();
return rx;
}
} else {
return op.apply(null, arguments);
}
};
};
var gx = "optional not ignore cache".split(/\s/);
for (var i = 0; i < gx.length; i++) {
_[gx[i]] = _generator(_[gx[i]]);
}
var _vector = function (op) {
return function () {
if (arguments[0] instanceof Array) {
return op.apply(null, arguments[0]);
} else {
return op.apply(null, arguments);
}
};
};
var vx = "each any all".split(/\s/);
for (var j = 0; j < vx.length; j++) {
_[vx[j]] = _vector(_[vx[j]]);
}
}());
(function () {
var $D = Date,
$P = $D.prototype,
$C = $D.CultureInfo;
var flattenAndCompact = function (ax) {
var rx = [];
for (var i = 0; i < ax.length; i++) {
if (ax[i] instanceof Array) {
rx = rx.concat(flattenAndCompact(ax[i]));
} else {
if (ax[i]) {
rx.push(ax[i]);
}
}
}
return rx;
};
$D.Grammar = {};
$D.Translator = {
hour: function (s) {
return function () {
this.hour = Number(s);
};
},
minute: function (s) {
return function () {
this.minute = Number(s);
};
},
second: function (s) {
return function () {
this.second = Number(s);
};
},
meridian: function (s) {
return function () {
this.meridian = s.slice(0, 1).toLowerCase();
};
},
timezone: function (s) {
return function () {
var n = s.replace(/[^\d\+\-]/g, "");
if (n.length) {
this.timezoneOffset = Number(n);
} else {
this.timezone = s.toLowerCase();
}
};
},
day: function (x) {
var s = x[0];
return function () {
this.day = Number(s.match(/\d+/)[0]);
};
},
month: function (s) {
return function () {
this.month = (s.length == 3) ? "jan feb mar apr may jun jul aug sep oct nov dec".indexOf(s) / 4 : Number(s) - 1;
};
},
year: function (s) {
return function () {
var n = Number(s);
this.year = ((s.length > 2) ? n : (n + (((n + 2000) < $C.twoDigitYearMax) ? 2000 : 1900)));
};
},
rday: function (s) {
return function () {
switch (s) {
case "yesterday":
this.days = -1;
break;
case "tomorrow":
this.days = 1;
break;
case "today":
this.days = 0;
break;
case "now":
this.days = 0;
this.now = true;
break;
}
};
},
finishExact: function (x) {
x = (x instanceof Array) ? x : [x];
for (var i = 0; i < x.length; i++) {
if (x[i]) {
x[i].call(this);
}
}
var now = new Date();
if ((this.hour || this.minute) && (!this.month && !this.year && !this.day)) {
this.day = now.getDate();
}
if (!this.year) {
this.year = now.getFullYear();
}
if (!this.month && this.month !== 0) {
this.month = now.getMonth();
}
if (!this.day) {
this.day = 1;
}
if (!this.hour) {
this.hour = 0;
}
if (!this.minute) {
this.minute = 0;
}
if (!this.second) {
this.second = 0;
}
if (this.meridian && this.hour) {
if (this.meridian == "p" && this.hour < 12) {
this.hour = this.hour + 12;
} else if (this.meridian == "a" && this.hour == 12) {
this.hour = 0;
}
}
if (this.day > $D.getDaysInMonth(this.year, this.month)) {
throw new RangeError(this.day + " is not a valid value for days.");
}
var r = new Date(this.year, this.month, this.day, this.hour, this.minute, this.second);
if (this.timezone) {
r.set({
timezone: this.timezone
});
} else if (this.timezoneOffset) {
r.set({
timezoneOffset: this.timezoneOffset
});
}
return r;
},
finish: function (x) {
x = (x instanceof Array) ? flattenAndCompact(x) : [x];
if (x.length === 0) {
return null;
}
for (var i = 0; i < x.length; i++) {
if (typeof x[i] == "function") {
x[i].call(this);
}
}
var today = $D.today();
if (this.now && !this.unit && !this.operator) {
return new Date();
} else if (this.now) {
today = new Date();
}
var expression = !!(this.days && this.days !== null || this.orient || this.operator);
var gap, mod, orient;
orient = ((this.orient == "past" || this.operator == "subtract") ? -1 : 1);
if (!this.now && "hour minute second".indexOf(this.unit) != -1) {
today.setTimeToNow();
}
if (this.month || this.month === 0) {
if ("year day hour minute second".indexOf(this.unit) != -1) {
this.value = this.month + 1;
this.month = null;
expression = true;
}
}
if (!expression && this.weekday && !this.day && !this.days) {
var temp = Date[this.weekday]();
this.day = temp.getDate();
if (!this.month) {
this.month = temp.getMonth();
}
this.year = temp.getFullYear();
}
if (expression && this.weekday && this.unit != "month") {
this.unit = "day";
gap = ($D.getDayNumberFromName(this.weekday) - today.getDay());
mod = 7;
this.days = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
}
if (this.month && this.unit == "day" && this.operator) {
this.value = (this.month + 1);
this.month = null;
}
if (this.value != null && this.month != null && this.year != null) {
this.day = this.value * 1;
}
if (this.month && !this.day && this.value) {
today.set({
day: this.value * 1
});
if (!expression) {
this.day = this.value * 1;
}
}
if (!this.month && this.value && this.unit == "month" && !this.now) {
this.month = this.value;
expression = true;
}
if (expression && (this.month || this.month === 0) && this.unit != "year") {
this.unit = "month";
gap = (this.month - today.getMonth());
mod = 12;
this.months = gap ? ((gap + (orient * mod)) % mod) : (orient * mod);
this.month = null;
}
if (!this.unit) {
this.unit = "day";
}
if (!this.value && this.operator && this.operator !== null && this[this.unit + "s"] && this[this.unit + "s"] !== null) {
this[this.unit + "s"] = this[this.unit + "s"] + ((this.operator == "add") ? 1 : -1) + (this.value || 0) * orient;
} else if (this[this.unit + "s"] == null || this.operator != null) {
if (!this.value) {
this.value = 1;
}
this[this.unit + "s"] = this.value * orient;
}
if (this.meridian && this.hour) {
if (this.meridian == "p" && this.hour < 12) {
this.hour = this.hour + 12;
} else if (this.meridian == "a" && this.hour == 12) {
this.hour = 0;
}
}
if (this.weekday && !this.day && !this.days) {
var temp = Date[this.weekday]();
this.day = temp.getDate();
if (temp.getMonth() !== today.getMonth()) {
this.month = temp.getMonth();
}
}
if ((this.month || this.month === 0) && !this.day) {
this.day = 1;
}
if (!this.orient && !this.operator && this.unit == "week" && this.value && !this.day && !this.month) {
return Date.today().setWeek(this.value);
}
if (expression && this.timezone && this.day && this.days) {
this.day = this.days;
}
return (expression) ? today.add(this) : today.set(this);
}
};
var _ = $D.Parsing.Operators,
g = $D.Grammar,
t = $D.Translator,
_fn;
g.datePartDelimiter = _.rtoken(/^([\s\-\.\,\/\x27]+)/);
g.timePartDelimiter = _.stoken(":");
g.whiteSpace = _.rtoken(/^\s*/);
g.generalDelimiter = _.rtoken(/^(([\s\,]|at|@|on)+)/);
var _C = {};
g.ctoken = function (keys) {
var fn = _C[keys];
if (!fn) {
var c = $C.regexPatterns;
var kx = keys.split(/\s+/),
px = [];
for (var i = 0; i < kx.length; i++) {
px.push(_.replace(_.rtoken(c[kx[i]]), kx[i]));
}
fn = _C[keys] = _.any.apply(null, px);
}
return fn;
};
g.ctoken2 = function (key) {
return _.rtoken($C.regexPatterns[key]);
};
g.h = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2]|[1-9])/), t.hour));
g.hh = _.cache(_.process(_.rtoken(/^(0[0-9]|1[0-2])/), t.hour));
g.H = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3]|[0-9])/), t.hour));
g.HH = _.cache(_.process(_.rtoken(/^([0-1][0-9]|2[0-3])/), t.hour));
g.m = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.minute));
g.mm = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.minute));
g.s = _.cache(_.process(_.rtoken(/^([0-5][0-9]|[0-9])/), t.second));
g.ss = _.cache(_.process(_.rtoken(/^[0-5][0-9]/), t.second));
g.hms = _.cache(_.sequence([g.H, g.m, g.s], g.timePartDelimiter));
g.t = _.cache(_.process(g.ctoken2("shortMeridian"), t.meridian));
g.tt = _.cache(_.process(g.ctoken2("longMeridian"), t.meridian));
g.z = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
g.zz = _.cache(_.process(_.rtoken(/^((\+|\-)\s*\d\d\d\d)|((\+|\-)\d\d\:?\d\d)/), t.timezone));
g.zzz = _.cache(_.process(g.ctoken2("timezone"), t.timezone));
g.timeSuffix = _.each(_.ignore(g.whiteSpace), _.set([g.tt, g.zzz]));
g.time = _.each(_.optional(_.ignore(_.stoken("T"))), g.hms, g.timeSuffix);
g.d = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1]|\d)/), _.optional(g.ctoken2("ordinalSuffix"))), t.day));
g.dd = _.cache(_.process(_.each(_.rtoken(/^([0-2]\d|3[0-1])/), _.optional(g.ctoken2("ordinalSuffix"))), t.day));
g.ddd = g.dddd = _.cache(_.process(g.ctoken("sun mon tue wed thu fri sat"), function (s) {
return function () {
this.weekday = s;
};
}));
g.M = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d|\d)/), t.month));
g.MM = _.cache(_.process(_.rtoken(/^(1[0-2]|0\d)/), t.month));
g.MMM = g.MMMM = _.cache(_.process(g.ctoken("jan feb mar apr may jun jul aug sep oct nov dec"), t.month));
g.y = _.cache(_.process(_.rtoken(/^(\d\d?)/), t.year));
g.yy = _.cache(_.process(_.rtoken(/^(\d\d)/), t.year));
g.yyy = _.cache(_.process(_.rtoken(/^(\d\d?\d?\d?)/), t.year));
g.yyyy = _.cache(_.process(_.rtoken(/^(\d\d\d\d)/), t.year));
_fn = function () {
return _.each(_.any.apply(null, arguments), _.not(g.ctoken2("timeContext")));
};
g.day = _fn(g.d, g.dd);
g.month = _fn(g.M, g.MMM);
g.year = _fn(g.yyyy, g.yy);
g.orientation = _.process(g.ctoken("past future"), function (s) {
return function () {
this.orient = s;
};
});
g.operator = _.process(g.ctoken("add subtract"), function (s) {
return function () {
this.operator = s;
};
});
g.rday = _.process(g.ctoken("yesterday tomorrow today now"), t.rday);
g.unit = _.process(g.ctoken("second minute hour day week month year"), function (s) {
return function () {
this.unit = s;
};
});
g.value = _.process(_.rtoken(/^\d\d?(st|nd|rd|th)?/), function (s) {
return function () {
this.value = s.replace(/\D/g, "");
};
});
g.expression = _.set([g.rday, g.operator, g.value, g.unit, g.orientation, g.ddd, g.MMM]);
_fn = function () {
return _.set(arguments, g.datePartDelimiter);
};
g.mdy = _fn(g.ddd, g.month, g.day, g.year);
g.ymd = _fn(g.ddd, g.year, g.month, g.day);
g.dmy = _fn(g.ddd, g.day, g.month, g.year);
g.date = function (s) {
return ((g[$C.dateElementOrder] || g.mdy).call(this, s));
};
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) {
if (g[fmt]) {
return g[fmt];
} else {
throw $D.Parsing.Exception(fmt);
}
}), _.process(_.rtoken(/^[^dMyhHmstz]+/), function (s) {
return _.ignore(_.stoken(s));
}))), function (rules) {
return _.process(_.each.apply(null, rules), t.finishExact);
});
var _F = {};
var _get = function (f) {
return _F[f] = (_F[f] || g.format(f)[0]);
};
g.formats = function (fx) {
if (fx instanceof Array) {
var rx = [];
for (var i = 0; i < fx.length; i++) {
rx.push(_get(fx[i]));
}
return _.any.apply(null, rx);
} else {
return _get(fx);
}
};
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"]);
g._start = _.process(_.set([g.date, g.time, g.expression], g.generalDelimiter, g.whiteSpace), t.finish);
g.start = function (s) {
try {
var r = g._formats.call({}, s);
if (r[1].length === 0) {
return r;
}
} catch (e) {}
return g._start.call({}, s);
};
$D._parse = $D.parse;
$D.parse = function (s) {
var r = null;
if (!s) {
return null;
}
if (s instanceof Date) {
return s;
}
try {
r = $D.Grammar.start.call({}, s.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1"));
} catch (e) {
return null;
}
return ((r[1].length === 0) ? r[0] : null);
};
$D.getParseFunction = function (fx) {
var fn = $D.Grammar.formats(fx);
return function (s) {
var r = null;
try {
r = fn.call({}, s);
} catch (e) {
return null;
}
return ((r[1].length === 0) ? r[0] : null);
};
};
$D.parseExact = function (s, fx) {
return $D.getParseFunction(fx)(s);
};
}());
// module.exports = {
// Date:Date
// }
module.exports = Date;
\ No newline at end of file
This diff could not be displayed because it is too large.
var __request = wx.request;
var Mock = require("./mock.js");
// console.log('Mock', Mock)
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;
function setItem(key, value, module_name) {
if (module_name) {
let module_name_info = getItem(module_name) || {};
module_name_info[key] = value;
try {
wx.setStorageSync(module_name, module_name_info);
} catch (e) {
wx.setStorage({
key: module_name,
data: module_name_info
})
}
} else {
try {
wx.setStorageSync(key, value);
} catch (e) {
wx.setStorage({
key: key,
data: value
})
}
}
}
function getItem(key, module_name) {
if (module_name) {
let val = getItem(module_name);
if (val) return val[key];
return '';
}
return wx.getStorageSync(key)
}
function clear(name) {
name ? wx.removeStorageSync(name) : wx.clearStorageSync()
}
module.exports = {
setItem,
getItem,
clear
}
// 手机正则
const REGEXPS = {
"mobile": /^1\d{10}$/
}
// 验证手机
function checkMobile(str) {
return REGEXPS.mobile.test(str);
}
function formatTime(date) {
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var hour = date.getHours()
var minute = date.getMinutes()
var second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
function formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
}
/**
* 获取屏幕剩余高度
* useHeight 单位是rpx
* 默认返回单位是rpx 可通过unit参数改为 px
*/
function getLastScreenHeight(useHeight = 0, unit = 'rpx') {
let sysInfo = wx.getSystemInfoSync();
let clientHeight = sysInfo.windowHeight;
// 获取可使用窗口高度
let clientWidth = sysInfo.windowWidth;
// 算出比例
let ratio = 750 / clientWidth;
// 算出屏幕高度(单位rpx)
let height = clientHeight * ratio;
// 计算剩余高度
let lastHeight = height - useHeight;
// 可转换成px
if (unit == 'px') {
lastHeight = lastHeight / 750 * clientWidth
}
return lastHeight;
}
module.exports = {
formatTime: formatTime,
checkMobile: checkMobile,
getLastScreenHeight: getLastScreenHeight
}