2632c460 by simon

默认提交

0 parents
Showing 397 changed files with 3443 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": "1111111",
"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/"
};
# chmod u+x git.sh
unset msg
read -p "请输入commit提交的描述: " msg
if [[ $msg == "" ]]; then
msg="默认提交"
fi
git add -A
git commit -m $msg
git push
git status
/**
* ------------------------------------------------------------------
* gulpfile 文件
* ------------------------------------------------------------------
*/
var path = require('path');
var gulp = require('gulp');
var changed = require('gulp-changed');
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/**/*'],
busFiles: ['src/**/*.{js,json}', '!src/assets/**/*', '!src/image/**/*', '!src/ui/**/*'],
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 copyModifyFiles() {
return gulp.src(paths.src.busFiles)
.pipe(changed(paths.dist.baseDir))
.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 + '/';
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();
copyModifyFiles(); // 复制修改过的业务文件
// 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-changed": "^4.0.2",
"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(options) {
let scene = options.scene;
// 根据场景值判断分享入口
// https://developers.weixin.qq.com/miniprogram/dev/reference/scene-list.html
// 小程序由分享进入
// if (scene == 1007 || scene == 1008 || scene == 1011 || scene == 1012 || scene == 1013) {
// this.globalData.share = true
// } else {
// this.globalData.share = false
// };
const MenuRect = wx.getMenuButtonBoundingClientRect();
const statusBarHeight = wx.getSystemInfoSync().statusBarHeight;
const height = (MenuRect.top - statusBarHeight) * 2 + MenuRect.height + MenuRect.top;
this.globalData.statusBarHeight = wx.getSystemInfoSync().statusBarHeight;
this.globalData.barHeight = height;
this.share();
},
globalData: {
share: false,
indexInfo: null,
userInfo: null,
wxcode: store.getItem("wxcode"),
tlMemberCode: "",
},
//重写分享方法
share: function () {
//监听路由切换
//间接实现全局设置分享内容
wx.onAppRoute(function (res) {
//获取加载的页面
let pages = getCurrentPages();
//获取当前页面的对象
let view = pages[pages.length - 1];
let data;
if (view) {
data = view.data;
if (!data.isOverShare) {
data.isOverShare = true;
view.onShareAppMessage = function (res) {
//分享配置
return {
title: '模板标题',
path: 'pages/index/index',
// imageUrl: ''
};
};
}
}
})
},
})
{
"pages": [
"pages/index/index",
"pages/more/more",
"pages/poster-example/poster-example",
"pages/authorize/authorize",
"pages/demo/demo"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "mp-gulp-framework",
"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": "更多"
}
]
},
"usingComponents": {
"authorize-comp": "../../component/authorize-comp/authorize-comp",
"empty-tips": "../../component/empty-tips/empty-tips",
"van-popup": "../../ui/vant-weapp/popup/index"
}
}
/**
* ------------------------------------------------------------------
* 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;
}
// 居中按钮样式
@mixin btn-center($width, $height) {
width: $width;
height: $height;
line-height: $height;
text-align: center;
}
// 超过多少行自动省略 默认一行
@mixin ellipsis($line:1) {
display: -webkit-box;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: $line;
overflow: hidden;
text-overflow: ellipsis;
}
// 文字截取
@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;
}
// 居中按钮样式
@mixin btc($width, $height) {
width: $width;
height: $height;
line-height: $height;
text-align: center;
}
// 通用按钮
@mixin cb($width:320px, $height:84px, $fontSize:32px) {
color: #FFFFFF;
position: relative;
width: $width;
height: $height;
line-height: $height;
text-align: center;
font-size: $fontSize;
border-radius: 8px;
background-color: #3680EB;
}
// 通用按钮
@mixin cb2($width:320px, $height:84px, $fontSize:32px) {
position: relative;
width: $width;
height: $height;
line-height: $height;
text-align: center;
font-size: $fontSize;
border-radius: 8px;
color: #3680EB;
border: solid 1PX #3680EB;
}
@mixin app-width() {
width: 750px;
}
@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;
// }
// }
.bis {
background-repeat: no-repeat;
background-size: 100% 100%;
}
//flex 布局和 子元素 对其方式
.fl {
display: flex;
}
.fj {
display: flex;
justify-content: space-between;
}
.fje {
display: flex;
justify-content: flex-end;
}
//水平和垂直居中
.fcc {
display: flex;
justify-content: center;
align-items: center;
}
// 为元素设定的宽度和高度决定了元素的边框盒。
.bb {
box-sizing: border-box;
}
// 满屏
.fullp {
width: 100%;
height: 100%;
}
.shadow {
box-shadow: 0 6px 18px 0 rgba(0, 0, 0, 0.10);
border-radius: 8px;
}
.linear {
background-image: linear-gradient(to right, #1bade8, #3680EB);
}
// // 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;
// // 主题颜色
$colorMain:#3680EB;
$pageBottom:80px;
let app = getApp();
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
},
// 用户拒绝授权后是否后退页面
cancelBack: {
type: Boolean,
value: false,
},
// 用户拒绝授权后描述
cancelDesc: {
type: String,
value: "同意授权才能获得更多体验哦~",
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {
this.triggerEvent('evtcomp', {
name: "_evt_custom"
})
},
// 隐藏蒙层
hideMask() {
this.triggerEvent('evtcomp', {
name: "_evt_hide_mask"
});
},
// 授权成功事件
authComplete() {
this.triggerEvent('evtcomp', {
name: "_evt_auth_complete"
});
},
// 点击暂不授权按钮
cancelAuth(e) {
this.hideMask();
// this.triggerEvent('evtcomp', {
// name: "_evt_auth_cancel"
// });
// if (this.properties.cancelBack) {
// wx.navigateBack({
// delta: 1
// });
// }
},
// 点击确认授权按钮
bindGetUserInfo(e) {
wx.showLoading();
this.getUserInfo(e.detail);
},
// 授权操作
getUserInfo(e) {
let _this = this;
if (e.encryptedData && e.iv) {
// 同意授权
app.post({
url: app.api.register,
sid: false,
data: {
encryptedData: e.encryptedData,
iv: e.iv,
code: app.store.getItem("wxcode"),
tlMemberCode: app.globalData.tlMemberCode
}
}).then((res2) => {
wx.hideLoading();
if (res2 && res2.sessionId) {
app.store.setItem('sessionId', res2.sessionId);
}
_this.hideMask();
_this.authComplete();
_this.initPage();
}).catch((err) => {})
} else {
// 取消授权
if (_this.properties.cancelBack) {
wx.navigateBack({
delta: 1
});
} else {
if (_this.properties.cancelDesc) {
wx.showToast({
title: _this.properties.cancelDesc,
icon: "none"
})
}
}
}
},
/**
* 尝试重拉信息
*/
initPage() {
let pages = getCurrentPages();
let view = pages[pages.length - 1];
console.log("@authorize-comp view:", view);
if (view) {
try {
view.hideMask();
console.log("@authorize-comp || hideMask");
} catch (error) {}
try {
view.initData();
console.log("@authorize-comp || initData");
} catch (error) {}
}
}
}
})
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.comp-item {
width: 650px;
min-height: 496px;
border-radius: 10px;
background-color: #ffffff;
.cspace {
height: 80px;
}
.cont {
text-align: center;
width: 520px;
margin: 0 auto;
.logo {
margin: 0 auto;
width: 200px;
height: 153px;
image {
width: 200px;
height: 153px;
}
}
.tit {
font-size: 40px;
color: #333333;
}
.tips {
margin-top: 28px;
font-size: 32px;
color: #333333;
padding-bottom: 244px;
}
}
.btn-wrap {
position: absolute;
left: 0;
right: 0;
bottom: 80px;
margin: 0 auto;
display: flex;
justify-content: center;
}
.btn {
@include cb(240px, 80px);
margin: 0 24px;
}
.btn2 {
@include cb2(240px, 80px);
}
}
<view class="comp-item">
<view class="cspace"></view>
<view class="cont">
<!-- <view class="logo">
<image mode="widthFix" src="../../image/logo.png" />
</view> -->
<view class="tit">深士照明</view>
<view class="tips">
<text>需要获取您的微信昵称等信息才可以获取积分和兑换奖品哦</text>
</view>
</view>
<view class="btn-wrap">
<button class="btn btn2" bindtap="cancelAuth">暂不授权</button>
<button class="btn" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">确认授权</button>
</view>
</view>
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>
let app = getApp();
Component({
// 样式隔离
// 详见 https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html
// isolated 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值);
// apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面;
// shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。(这个选项在插件中不可用。)
options: {
styleIsolation: 'isolated'
},
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这里是一些组件内部数据
someData: {}
},
methods: {
// 这里是一个自定义方法
customMethod() {
this.triggerEvent('evtcomp', {
name: "_evt_custom"
})
},
// 隐藏蒙层
hideMask() {
this.triggerEvent('evtcomp', {
name: "_evt_hide_product_detail_mask"
});
}
}
})
<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>
const app = getApp()
Component({
options: {
styleIsolation: 'apply-shared'
},
properties: {
navbarData: { //navbarData 由父页面传递的数据,变量名字自命名
type: Object,
value: {},
// observer: function (newVal, oldVal) {}
},
share: {
type: Boolean,
value: false
}
},
data: {
height: '',
barHeight: app.globalData.barHeight,
//默认值 默认显示左上角
// navbarData: {
// showCapsule: 1,
// }
},
attached: function () {
// 获取是否是通过分享进入的小程序
// this.setData({
// share: app.globalData.share
// })
// 定义导航栏的高度 方便对齐
this.setData({
statusBarHeight: app.globalData.statusBarHeight,
height: app.globalData.barHeight
})
},
methods: {
// 返回上一页面
_navback() {
wx.navigateBack()
},
//返回到首页
_backhome() {
app.router.push({
path: "index",
openType: "reLaunch"
})
// wx.navigateBack({
// delta: 999999
// })
}
},
ready() {
// console.log("navbarData.title}:", this.properties.navbarData.title);
}
})
{
"component": true
}
/* 顶部要固定定位 标题要居中 自定义按钮和标题要和右边微信原生的胶囊上下对齐 */
.nav-wrap {
position: fixed;
width: 100%;
top: 0;
background: #fff;
color: #000;
z-index: 999999;
}
/* 标题要居中 */
.nav-title {
position: absolute;
text-align: center;
max-width: 400px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
font-size: 32px;
color: #2c2b2b;
font-weight: 600;
}
.nav-capsule {
display: flex;
align-items: center;
margin-left: 30px;
width: 120px;
justify-content: space-between;
height: 100%;
}
.navbar-v-line {
width: 1px;
height: 32px;
background-color: #e5e5e5;
}
.back-pre,
.back-home {
width: 32px;
height: 36px;
line-height: 36px;
margin-top: 4px;
padding: 10px;
}
.nav-capsule .back-home {
width: 36px;
height: 40px;
margin-top: 3px;
}
.iconfont {
font-size: 40px;
}
<view class='nav-wrap' style='height: {{height}}px;'>
<view class='nav-title' style='line-height: {{height+statusBarHeight}}px;'>{{navbarData.title}}</view>
<view style='display: flex; justify-content: space-around;flex-direction: column'>
<view class='nav-capsule' style='height: {{height+statusBarHeight}}px;' wx:if='{{navbarData.showCapsule}}'>
<view bindtap='_navback' wx:if='{{!share}}'>
<span class="iconfont iconbackicon1"></span>
</view>
<view class='navbar-v-line' wx:if='{{!share}}'></view>
<view bindtap='_backhome'>
<span class="iconfont iconhome"></span>
</view>
</view>
</view>
</view>
let ENV_CONFIG = require('./env/index');
const APPID = ''
/** ====每次发布版本记得修改此环境配置==== */
const ENV = 'dev'; // Dev Prod
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://ow.go.qudone.com/xxx',
commonApi: 'https://api.k.wxpai.cn/bizproxy'
},
Test: {
baseApi: 'https://test-api.xxx.com'
},
Slave: {
baseApi: 'https://slave-api.xxx.com'
},
Prod: {
baseApi: 'https://api.k.wxpai.cn/bizproxy/xxx',
commonApi: 'https://api.k.wxpai.cn/bizproxy'
}
}
# chmod u+x git.sh
unset msg
read -p "请输入commit提交的描述: " msg
if [[ $msg == "" ]]; then
msg="默认提交"
fi
git add -A
git commit -m $msg
git push
git status
module.exports = {
login: "/login", // post 通过wxcode换取sessionId
register: '/register', // post 注册(用户授权)
dataList: '/dataList', // 测试接口
/**
* 通用接口
* 请求时 "mode"传"custom"
*/
areaQuery: 'https://api.k.wxpai.cn/bizproxy/kdapi/area', // post 区域查询
}
let config = require('./../config');
let Store = require('./../utils/stroage');
let Router = require('./../router/index');
const errMsg = '服务异常,请稍后重试';
// let isWxLogin = false;
function wxLogin() {
return new Promise((resolve, reject) => {
wx.login({
success: function (res) {
// isWxLogin = true;
Store.setItem('wxcode', res.code);
resolve();
}
});
});
}
// 检查并获取sessionid
function checkSessionId(sid) {
return new Promise((resolve, reject) => {
if (!sid) {
resolve();
return;
}
let sessionId = Store.getItem('sessionId');
if (sessionId) {
resolve();
} else {
// 没有sessionId则获取并埋值
login().then((result) => {
resolve();
}).catch((err) => {
reject();
});
}
});
}
// session丢失
function login() {
return new Promise((resolve, reject) => {
wxLogin().then((result) => {
let baseUrl = config.NET_CONFIG.baseApi;
wx.request({
url: baseUrl + '/login',
sid: false,
data: {
code: Store.getItem('wxcode')
},
method: 'POST',
success: function (res2) {
let {
code,
content
} = res2.data;
if (code == 200 && content.sessionId) {
Store.setItem('sessionId', content.sessionId);
resolve();
} else {
wx.hideLoading();
let pages = getCurrentPages();
let view = pages[pages.length - 1];
if (view) {
try {
wx.login({
success: function (res) {
Store.setItem('wxcode', res.code);
view.showAuth();
}
});
} catch (error) {}
}
reject();
}
}
})
})
});
}
const fetch = function ({
loading = true,
toast = true,
sid = true,
auth = true,
mode,
isMock,
url,
data,
method
}) {
if (loading && mode != 'log') wx.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; //环境配置
}
// 使用通用接口前缀
if (mode == "common") {
baseUrl = config.NET_CONFIG.commonApi
}
// 自定义前缀,即不使用前缀
if (mode == "custom") {
baseUrl = ""
}
checkSessionId(sid).then((result) => {
wx.request({
url: baseUrl + url, //请求地址
data: data, //自定义参数
method: method || 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
sessionId: Store.getItem("sessionId")
},
success: function (result) {
// 日志上传不需要处理结果
if (mode == 'log') return;
let res = result.data;
// 登陆失效拦截,根据项目需要添加自己的配置
if (res.code == 404) {
//登陆失效的回调
Store.clear("sessionId");
// wx.reLaunch({
// url: '/pages/index/index'
// })
// 404后拉取登陆后再做一次
login().then((resultLogin) => {
wx.request({
url: baseUrl + url, //请求地址
data: data, //自定义参数
method: method || 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
sessionId: Store.getItem("sessionId")
},
success: function (result) {
// 日志上传不需要处理结果
if (mode == 'log') return;
let res = result.data;
if (res.code === 200) {
if (loading) {
wx.hideLoading();
}
resolve(res.content);
} else {
// 有些特殊状况不需要toast 需要弹窗
if (toast) {
wx.showToast({
title: res.errMsg || errMsg,
icon: 'none'
})
} else {
wx.hideLoading();
}
// 返回错误信息
reject(res);
}
}
});
})
return;
}
// 内部统一的成功code拦截码
if (res.code === 200) {
if (loading) {
wx.hideLoading();
}
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();
Page({
data: {
barHeight: app.globalData.barHeight,
navbarData: {
showCapsule: 0, //是否显示左上角图标 1表示显示 0表示不显示
title: '微信授权' //导航栏 中间的标题
},
loginData: null,
authorized: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
parentMemberCode: "",
},
onLoad(options) {},
onReady() {
app.store.clear("sessionId");
let _this = this;
wx.login({
success: function (res) {
_this.data.loginData = res;
}
});
},
bindGetUserInfo(e) {
wx.showLoading();
this.getUserInfo(e.detail);
},
getUserInfo(e) {
let _this = this;
app.globalData.userInfo = e.userInfo;
// console.log("loginData:",_this.data.loginData);
app.post({
url: app.api.register,
sid: false,
data: {
encryptedData: e.encryptedData,
iv: e.iv,
code: _this.data.loginData.code,
parentMemberCode: _this.data.parentMemberCode,
}
}).then((res2) => {
app.store.setItem('sessionId', res2.sessionId);
_this.setData({
authorized: true
})
_this.toIndex();
}).catch((err) => {
console.log("@authorize || err:", err);
})
},
toIndex() {
console.log("@authorize || toIndex ");
setTimeout(() => {
app.router.push({
path: "index",
query: {},
openType: "redirect"
})
wx.hideLoading();
}, 2000);
}
})
{
"usingComponents": {
"navbar": "../../component/navbar/index"
},
"navigationStyle": "custom"
}
@import '../../assets/scss/mixins';
.page {
position: relative;
overflow: hidden;
.bgc {
// background-color: transparent;
// background-color: black;
background-color: #fafafc;
}
.main {
position: relative;
.top-space {
height: 60px;
}
.login {
position: relative;
width: 650px;
margin: 0 auto;
text-align: center;
&-logo {
width: 140px;
height: 140px;
}
&-name {
margin-top: 32px;
font-size: 32px;
color: #333333;
}
&-line {
margin-top: 70px;
width: 650px;
height: 2px;
background-color: #eaeaec;
}
&-title {
margin-top: 40px;
font-size: 32px;
text-align: left;
color: #333333;
}
&-tips {
margin-top: 28px;
font-size: 26px;
text-align: left;
color: #666666;
}
&-btn {
margin-top: 102px;
width: 650px;
height: 90px;
line-height: 90px;
border-radius: 8px;
background-color: #00c200;
font-size: 32px;
color: #ffffff;
}
}
}
}
<navbar navbar-data='{{navbarData}}'></navbar>
<view style='height: {{barHeight}}px'></view>
<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="top-space"></view>
<view class="login">
<image class="login-logo" src="../../image/logo.png" mode="aspectFit" />
<view class="login-name">美赞臣</view>
<view class="login-line"></view>
<view class="login-title">完整体验小程序功能,需要您的微信授权哦</view>
<view class="login-tips">· 获取您的公开信息(昵称、头像等)</view>
<button type="default" class="login-btn" wx:if="{{!authorized}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
确认授权
</button>
</view>
</view>
</view>
let app = getApp();
Page({
data: {
barHeight: app.globalData.barHeight,
navbarData: {
showCapsule: 0, //是否显示左上角图标 1表示显示 0表示不显示
title: '微信授权' //导航栏 中间的标题
},
loginData: null,
authorized: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
parentMemberCode: "",
},
onLoad(options) {},
onReady() {
app.store.clear("sessionId");
let _this = this;
wx.login({
success: function (res) {
_this.data.loginData = res;
}
});
},
bindGetUserInfo(e) {
wx.showLoading();
this.getUserInfo(e.detail);
},
getUserInfo(e) {
let _this = this;
app.globalData.userInfo = e.userInfo;
// console.log("loginData:",_this.data.loginData);
app.post({
url: app.api.register,
sid: false,
data: {
encryptedData: e.encryptedData,
iv: e.iv,
code: _this.data.loginData.code,
parentMemberCode: _this.data.parentMemberCode,
}
}).then((res2) => {
app.store.setItem('sessionId', res2.sessionId);
_this.setData({
authorized: true
})
_this.toIndex();
}).catch((err) => {
console.log("@authorize || err:", err);
})
},
toIndex() {
console.log("@authorize || toIndex ");
setTimeout(() => {
app.router.push({
path: "index",
query: {},
openType: "redirect"
})
wx.hideLoading();
}, 2000);
}
})
{
"navigationStyle": "custom"
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
position: relative;
overflow: hidden;
.bgc {}
.bg {
@include app-width;
image {
@include app-width;
}
}
// 右下角图标背景内容补充
.br-wrap {
$brWidth: 168px;
$brHeight: 172px;
width: $brWidth;
height: $brHeight;
position: fixed;
bottom: 0;
right: 0;
background-color: transparent;
image {
width: $brWidth;
height: $brHeight;
}
}
.main {
position: relative;
min-height: 1206px;
.content {
position: relative;
}
.login-wrap {
padding-top: 886px;
.terms-wrap {
margin-top: 24px;
display: flex;
justify-content: center;
margin-bottom: 16px;
font-size: 28px;
color: #333333;
.terms {
text-align: center;
padding: 0 12px;
.t1 {
color: #4bc2ed;
display: inline-block;
}
}
}
.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;
}
.gray {
color: #8f8f8f;
border-color: #8f8f8f;
}
}
}
}
.space1 {
height: 116px;
}
.terms-cont {
width: 690px;
height: 1000px;
position: relative;
background-color: #fff;
.cont {
position: relative;
width: 690px;
height: 900px;
overflow: auto;
padding: 28px;
@extend .bb;
font-size: 24px;
.tit {
text-align: center;
font-size: 32px;
font-weight: bold;
}
.desc {}
.t1 {
color: #4bc2ed;
display: inline-block;
margin-top: 16px;
}
}
.btn {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
}
<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="top-space"></view>
<view class="login">
<image class="login-logo" src="../../image/logo.png" mode="aspectFit" />
<view class="login-name">小程序</view>
<view class="login-line"></view>
<view class="login-title">完整体验小程序功能,需要您的微信授权哦</view>
<view class="login-tips">· 获取您的公开信息(昵称、头像等)</view>
<button type="default" class="login-btn" wx:if="{{!authorized}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">
确认授权
</button>
</view>
</view>
</view>
import {
getBindtapData
} from '../../utils/util';
let app = getApp();
Page({
data: {
authorizeVisible: false,
total: 0,
page: 1,
size: 10,
productList: [], // 产品列表
indexInfo: {},
userInfo: {},
},
onShareAppMessage() {},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {},
/**
* 基础方法
* 授权完毕重拉数据用
*/
initData() {
},
/**
* 到达底部
* 做加载更多操作
*/
onReachBottom() {
if (this.data.dataList.length < this.data.total) {
this.setData({
page: this.data.page + 1
});
this.queryDataList();
}
},
// 重置页面列表 点击搜索条件时需要
resetPage() {
this.setData({
page: 1,
dataList: []
})
},
/**
* 请求DataList
*/
queryDataList() {
return;
return new Promise((resolve, reject) => {
app.post({
sid: false,
url: app.api.dataList,
data: {
page: this.data.page,
size: this.data.size,
},
}).then((result) => {
let dataList = result.list;
dataList = this.data.dataList.concat(dataList);
this.setData({
dataList: dataList,
total: result.total
})
resolve();
})
});
},
/**
* 隐藏蒙层
*/
hideMask() {
this.setData({
productDetailVisible: false,
authorizeVisible: false,
})
},
/**
* 子组件事件
* @param {*} evt
*/
evtcomp(evt) {
let {
name,
data
} = evt.detail;
switch (name) {
// 隐藏蒙层
case "_evt_hide_mask":
this.hideMask();
break;
/**
* 重拉数据已在
*/
case "_evt_auth_complete":
// this.initData();
this.hideMask();
break;
default:
break;
}
},
})
{
"navigationBarTitleText": ""
}
@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__content main">
<view class="top-space"></view>
<view class="content"></view>
</view>
</view>
let app = getApp();
Page({
data: {},
onLoad(options) {
}
})
{
"navigationBarTitleText": "首页"
}
@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">index</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>
import {
getBindtapData
} from '../../utils/util';
// 二维码
import QR from '../../utils/qrcode'
// 海报
import Poster from '../../plugin/poster/poster/poster';
let app = getApp();
Page({
data: {
authorizeVisible: false,
},
onShareAppMessage() {},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {},
initData() {
this.initPoster();
this.initQrcode();
},
// 创建海报
initPoster() {
// 获取海报数据
let posterData = this.getPosterConfig();
// 绘制设置海报
this.onCreatePoster(posterData);
},
// 创建二维码
initQrcode() {
createQrCode('wxapp-qrcode', 'qrcode', 300, 300)
},
// ---- START 海报合成 ----
// 详情见: https://github.com/jasondu/wxa-plugin-canvas
// 海报合成成功
onPosterSuccess(e) {
wx.hideLoading();
const {
detail
} = e;
this.setData({
imageUrl: detail
})
},
// 合成失败
onPosterFail(err) {
wx.hideLoading();
console.error(err);
},
// 异步生成海报
onCreatePoster(posterConfig) {
this.setData({
posterConfig: posterConfig
}, () => {
Poster.create(true); // 入参:true为抹掉重新生成
});
},
// 获取海报数据
getPosterConfig() {
let blocks = [{
x: 0,
y: 0,
width: 690,
height: 900,
backgroundColor: "#ffffff",
borderRadius: 10,
}];
let images = [];
let lines = [];
let texts = [{
x: 690 / 2,
y: 192,
width: 690,
fontSize: 36,
color: "#3680EB",
textAlign: "center",
zIndex: 11,
text: "nickname",
}];
let posterData = {
width: 690,
height: 900,
debug: false,
blocks: blocks,
images: images,
lines: lines,
texts: texts,
}
return posterData;
},
// ---- END 海报合成 ----
/**
---------------- 分界线 ----------------
*/
// ---- START 二维码生成 ----
// 详情见: https://github.com/demi520/wxapp-qrcode
// 创建二维码
createQrCode(content, canvasId, cavW, cavH) {
//调用插件中的draw方法,绘制二维码图片
QR.api.draw(content, canvasId, cavW, cavH);
this.canvasToTempImage(canvasId);
},
//获取临时缓存图片路径,存入data中
canvasToTempImage(canvasId) {
let that = this;
wx.canvasToTempFilePath({
canvasId, // 这里canvasId即之前创建的canvas-id
success: function (res) {
let tempFilePath = res.tempFilePath;
console.log(tempFilePath);
that.setData({ // 如果采用mpvue,即 this.imagePath = tempFilePath
qrImagePath: tempFilePath,
});
},
fail: function (res) {
console.log(res);
}
});
},
//适配不同屏幕大小的canvas
setCanvasSize(sz) {
var size = {};
try {
var res = wx.getSystemInfoSync();
var scale = 750 / sz; //不同屏幕下canvas的适配比例;设计稿是750宽
var width = res.windowWidth / scale;
var height = width; //canvas画布为正方形
size.w = width;
size.h = height;
} catch (e) {
// Do something when catch error
console.log("获取设备信息失败" + e);
}
return size;
},
// ---- END 二维码生成 ----
})
{
"navigationBarTitleText": "海报合成/二维码示例",
"usingComponents": {
"poster": "/plugin/poster/poster/index"
}
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
.bgc {}
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
}
}
<poster id="poster" hide-loading="{{true}}" preload="{{false}}" config="{{posterConfig}}" bind:success="onPosterSuccess" bind:fail="onPosterFail"></poster>
<canvas canvas-id="qrcode" style="width: 200rpx;height: 200rpx;background:#0f0f0f;" />
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<view class="app__content main">
<view class="top-space"></view>
<view class="content">poster</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"/>
{
"component": true
}
\ No newline at end of file
<!--index.wxml-->
<view class="container">
<canvas canvas-id='canvasid' class="canvas {{debug ? 'debug' : 'pro'}}" style='width: {{pxWidth}}px; height: {{pxHeight}}px;'></canvas>
</view>
.canvas {
width: 750rpx;
height: 750rpx;
}
.canvas.pro {
position: absolute;
bottom: 0;
left: 0;
transform: translate3d(-9999rpx, 0, 0);
}
.canvas.debug {
position: absolute;
bottom: 0;
left: 0;
border: 1rpx solid #ccc;
}
\ No newline at end of file
Component({
properties: {
config: {
type: Object,
value: {},
},
preload: { // 是否预下载图片资源
type: Boolean,
value: false,
},
hideLoading: { // 是否隐藏loading
type: Boolean,
value: false,
}
},
ready() {
if (this.data.preload) {
const poster = this.selectComponent('#poster');
this.downloadStatus = 'doing';
poster.downloadResource(this.data.config.images).then(() => {
this.downloadStatus = 'success';
this.trigger('downloadSuccess');
}).catch((e) => {
this.downloadStatus = 'fail';
this.trigger('downloadFail', e);
});
}
},
methods: {
trigger(event, data) {
if (this.listener && typeof this.listener[event] === 'function') {
this.listener[event](data);
}
},
once(event, fun) {
if (typeof this.listener === 'undefined') {
this.listener = {};
}
this.listener[event] = fun;
},
downloadResource(reset) {
return new Promise((resolve, reject) => {
if (reset) {
this.downloadStatus = null;
}
const poster = this.selectComponent('#poster');
if (this.downloadStatus && this.downloadStatus !== 'fail') {
if (this.downloadStatus === 'success') {
resolve();
} else {
this.once('downloadSuccess', () => resolve());
this.once('downloadFail', (e) => reject(e));
}
} else {
poster.downloadResource(this.data.config.images)
.then(() => {
this.downloadStatus = 'success';
resolve();
})
.catch((e) => reject(e));
}
})
},
onCreate(reset = false) {
!this.data.hideLoading && wx.showLoading({ mask: true, title: '生成中' });
return this.downloadResource(typeof reset === 'boolean' && reset).then(() => {
!this.data.hideLoading && wx.hideLoading();
const poster = this.selectComponent('#poster');
poster.create(this.data.config);
})
.catch((err) => {
!this.data.hideLoading && wx.hideLoading();
wx.showToast({ icon: 'none', title: err.errMsg || '生成失败' });
console.error(err);
this.triggerEvent('fail', err);
})
},
onCreateSuccess(e) {
const { detail } = e;
this.triggerEvent('success', detail);
},
onCreateFail(err) {
console.error(err);
this.triggerEvent('fail', err);
}
}
})
\ No newline at end of file
{
"component": true,
"usingComponents": {
"we-canvas": "../index/index"
}
}
\ No newline at end of file
<view bindtap='onCreate'>
<slot/>
</view>
<we-canvas id="poster" bind:success="onCreateSuccess" bind:fail="onCreateFail"/>
\ No newline at end of file
const defaultOptions = {
selector: '#poster'
};
function Poster(options = {}) {
options = {
...defaultOptions,
...options,
};
const pages = getCurrentPages();
const ctx = pages[pages.length - 1];
const poster = ctx.selectComponent(options.selector);
delete options.selector;
return poster;
};
Poster.create = (reset = false) => {
const poster = Poster();
if (!poster) {
console.error('请设置组件的id="poster"!!!');
} else {
return Poster().onCreate(reset);
}
}
export default Poster;
\ No newline at end of file
const routerPath = {
index: '/pages/index/index',
authorize: '/pages/authorize/authorize', // 授权
example: '/pages/example/example',
more: '/pages/more/more',
}
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
}
import { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area';
VantComponent({
mixins: [safeArea()],
props: {
show: Boolean,
title: String,
cancelText: String,
zIndex: {
type: Number,
value: 100
},
actions: {
type: Array,
value: []
},
overlay: {
type: Boolean,
value: true
},
closeOnClickOverlay: {
type: Boolean,
value: true
}
},
methods: {
onSelect(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.actions[index];
if (item && !item.disabled && !item.loading) {
this.$emit('select', item);
}
},
onCancel() {
this.$emit('cancel');
},
onClose() {
this.$emit('close');
}
}
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-popup": "../popup/index",
"van-loading": "../loading/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<van-popup
show="{{ show }}"
position="bottom"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
custom-class="van-action-sheet"
safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClose"
>
<view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header">
{{ title }}
<van-icon
name="close"
custom-class="van-action-sheet__close"
bind:click="onClose"
/>
</view>
<view wx:if="{{ actions && actions.length }}">
<!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
<button
wx:for="{{ actions }}"
wx:key="index"
open-type="{{ item.openType }}"
class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}"
hover-class="van-action-sheet__item--hover"
data-index="{{ index }}"
bind:tap="onSelect"
>
<block wx:if="{{ !item.loading }}">
{{ item.name }}
<text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text>
</block>
<van-loading wx:else size="20px" />
</button>
</view>
<slot />
<view
wx:if="{{ cancelText }}"
class="van-action-sheet__cancel"
hover-class="van-action-sheet__cancel--hover"
hover-stay-time="70"
bind:tap="onCancel"
>
{{ cancelText }}
</view>
</van-popup>
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;color:#333}.van-action-sheet__cancel,.van-action-sheet__item{height:50px;font-size:16px;line-height:50px;text-align:center;background-color:#fff}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5}.van-action-sheet__cancel{height:60px}.van-action-sheet__cancel:before{display:block;height:10px;background-color:#f8f8f8;content:" "}.van-action-sheet__item--disabled{color:#c9c9c9}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff}.van-action-sheet__subname{margin-left:5px;font-size:12px;color:#7d7e80}.van-action-sheet__header{font-size:16px;font-weight:500;line-height:44px;text-align:center}.van-action-sheet__close{position:absolute!important;top:0;right:0;padding:0 15px;font-size:18px!important;line-height:inherit!important;color:#999}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: {
title: String,
value: String,
loading: Boolean,
cancelButtonText: String,
confirmButtonText: String,
itemHeight: {
type: Number,
value: 44
},
visibleItemCount: {
type: Number,
value: 5
},
columnsNum: {
type: [String, Number],
value: 3
},
areaList: {
type: Object,
value: {}
}
},
data: {
columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }]
},
watch: {
value(value) {
this.code = value;
this.setValues();
},
areaList: 'setValues',
columnsNum(value) {
this.set({
displayColumns: this.data.columns.slice(0, +value)
});
}
},
methods: {
getPicker() {
if (this.picker == null) {
this.picker = this.selectComponent('.van-area__picker');
}
return this.picker;
},
onCancel(event) {
this.emit('cancel', event.detail);
},
onConfirm(event) {
this.emit('confirm', event.detail);
},
emit(type, detail) {
detail.values = detail.value;
delete detail.value;
this.$emit(type, detail);
},
onChange(event) {
const { index, picker, value } = event.detail;
this.code = value[index].code;
this.setValues().then(() => {
this.$emit('change', {
picker,
values: picker.getValues(),
index
});
});
},
getConfig(type) {
const { areaList } = this.data;
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
let result = [];
if (type !== 'province' && !code) {
return result;
}
const list = this.getConfig(type);
result = Object.keys(list).map(code => ({
code,
name: list[code]
}));
if (code) {
// oversea code
if (code[0] === '9' && type === 'city') {
code = '9';
}
result = result.filter(item => item.code.indexOf(code) === 0);
}
return result;
},
getIndex(type, code) {
let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
const list = this.getList(type, code.slice(0, compareNum - 2));
// oversea code
if (code[0] === '9' && type === 'province') {
compareNum = 1;
}
code = code.slice(0, compareNum);
for (let i = 0; i < list.length; i++) {
if (list[i].code.slice(0, compareNum) === code) {
return i;
}
}
return 0;
},
setValues() {
const county = this.getConfig('county');
let code = this.code || Object.keys(county)[0] || '';
const province = this.getList('province');
const city = this.getList('city', code.slice(0, 2));
const picker = this.getPicker();
if (!picker) {
return;
}
const stack = [];
stack.push(picker.setColumnValues(0, province, false));
stack.push(picker.setColumnValues(1, city, false));
if (city.length && code.slice(2, 4) === '00') {
;
[{ code }] = city;
}
stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false));
return Promise.all(stack)
.catch(() => { })
.then(() => picker.setIndexes([
this.getIndex('province', code),
this.getIndex('city', code),
this.getIndex('county', code)
]))
.catch(() => { });
},
getValues() {
const picker = this.getPicker();
return picker ? picker.getValues().filter(value => !!value) : [];
},
getDetail() {
const values = this.getValues();
const area = {
code: '',
country: '',
province: '',
city: '',
county: ''
};
if (!values.length) {
return area;
}
const names = values.map((item) => item.name);
area.code = values[values.length - 1].code;
if (area.code[0] === '9') {
area.country = names[1] || '';
area.province = names[2] || '';
}
else {
area.province = names[0] || '';
area.city = names[1] || '';
area.county = names[2] || '';
}
return area;
},
reset() {
this.code = '';
return this.setValues();
}
}
});
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
<van-picker
class="van-area__picker"
active-class="active-class"
toolbar-class="toolbar-class"
column-class="column-class"
show-toolbar
value-key="name"
title="{{ title }}"
loading="{{ loading }}"
columns="{{ displayColumns }}"
item-height="{{ itemHeight }}"
visible-item-count="{{ visibleItemCount }}"
cancel-button-text="{{ cancelButtonText }}"
confirm-button-text="{{ confirmButtonText }}"
bind:change="onChange"
bind:confirm="onConfirm"
bind:cancel="onCancel"
/>
@import '../common/index.wxss';
\ No newline at end of file
This diff could not be displayed because it is too large.