437c1c5a by simon

基础工程

0 parents
Showing 75 changed files with 2189 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 }
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 }