初始化
This commit is contained in:
commit
9b7a26c80a
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Eslint config file
|
||||
* Documentation: https://eslint.org/docs/user-guide/configuring/
|
||||
* Install the Eslint extension before using this feature.
|
||||
*/
|
||||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
ecmaFeatures: {
|
||||
modules: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
globals: {
|
||||
wx: true,
|
||||
App: true,
|
||||
Page: true,
|
||||
getCurrentPages: true,
|
||||
getApp: true,
|
||||
Component: true,
|
||||
requirePlugin: true,
|
||||
requireMiniProgram: true,
|
||||
},
|
||||
// extends: 'eslint:recommended',
|
||||
rules: {},
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
const {request} = require("../request/index")
|
||||
|
||||
export const userLogin = function (data) {
|
||||
return request({
|
||||
url: '/member/user',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// app.js
|
||||
App({
|
||||
onLaunch() {
|
||||
// 展示本地存储能力
|
||||
const logs = wx.getStorageSync('logs') || []
|
||||
logs.unshift(Date.now())
|
||||
wx.setStorageSync('logs', logs)
|
||||
|
||||
// 登录
|
||||
wx.login({
|
||||
success: res => {
|
||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||
}
|
||||
})
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"pages": [
|
||||
"pages/home/home",
|
||||
"pages/task/task",
|
||||
"pages/mine/mine",
|
||||
"pages/login/login"
|
||||
],
|
||||
"tabBar": {
|
||||
"color": "#939393",
|
||||
"borderStyle": "white",
|
||||
"selectedColor": "#477DF3",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/home/home",
|
||||
"text": "首页",
|
||||
"iconPath": "./assets/tabBar/home.png",
|
||||
"selectedIconPath": "./assets/tabBar/home_selected.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/task/task",
|
||||
"text": "任务",
|
||||
"iconPath": "./assets/tabBar/task.png",
|
||||
"selectedIconPath": "./assets/tabBar/task_selected.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/mine/mine",
|
||||
"text": "我的",
|
||||
"iconPath": "./assets/tabBar/mine.png",
|
||||
"selectedIconPath": "./assets/tabBar/mine_selected.png"
|
||||
}
|
||||
]
|
||||
},
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "package_A",
|
||||
"pages":[]
|
||||
},
|
||||
{
|
||||
"root": "package_B",
|
||||
"pages":[]
|
||||
},
|
||||
{
|
||||
"root": "package_C",
|
||||
"pages":[]
|
||||
}
|
||||
],
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#fff",
|
||||
"navigationBarTitleText": "Weixin",
|
||||
"navigationBarTextStyle": "black"
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json"
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/**app.wxss**/
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
|
|
@ -0,0 +1,48 @@
|
|||
// components/List/index.js
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
url: {
|
||||
type: String
|
||||
},
|
||||
dataPath: {
|
||||
type: String
|
||||
},
|
||||
list: {
|
||||
type: Array
|
||||
},
|
||||
params: {
|
||||
type: Object,
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
value: 10
|
||||
},
|
||||
scrolling:{
|
||||
type:Boolean,
|
||||
value:true,
|
||||
},
|
||||
emptyText:{
|
||||
type:String,
|
||||
value:""
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
loading: false
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!--components/List/index.wxml-->
|
||||
<scroll-view class="list {{list.length>0?'':'min-height'}}" scroll-y="{{scrolling}}" bindscrolltolower="loadMore">
|
||||
<slot></slot>
|
||||
<view class="empty" wx:if="{{!loading && list.length==0}}">
|
||||
<image class="image" src="/assets/img/empty.png" mode="aspectFit" lazy-load="false">
|
||||
</image>
|
||||
<view class="empty-text" wx:if="{{emptyText}}">
|
||||
{{emptyText}}
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* components/List/index.wxss */
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// components/Select/index.js
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<!--components/Select/index.wxml-->
|
||||
<text>components/Select/index.wxml</text>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* components/Select/index.wxss */
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// components/Tab/index.js
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<!--components/Tab/index.wxml-->
|
||||
<text>components/Tab/index.wxml</text>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* components/Tab/index.wxss */
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// package_C/component/table/table.js
|
||||
Component({
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
data: {type: Array},
|
||||
columns: {type: Array}
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<!--package_C/component/table/table.wxml-->
|
||||
<view class="table_container">
|
||||
<view class="table_title">
|
||||
<text class="table_item" style="width:{{item.width}}" wx:for="{{columns}}" wx:key="index">{{item.title}}</text>
|
||||
</view>
|
||||
<view class="table_data">
|
||||
<view style="background: {{ index%2 == 1 ? '#F5F7F9' : '#fff' }}" class="data_item" wx:for="{{data}}" wx:key="index">
|
||||
<view class="table_item" style="width: {{columns[0].width}}">{{item.name}}</view>
|
||||
<view class="table_item" style="width: {{columns[1].width}}">{{item.y}}/{{item.countQu || item.sumqu}}</view>
|
||||
<view class="table_item" style="width: {{columns[2].width}}">{{item.a}}</view>
|
||||
<view class="table_item" style="width: {{columns[3].width}}">{{item.b}}</view>
|
||||
<view class="table_item" style="width: {{columns[4].width}}">{{item.c}}</view>
|
||||
<view class="table_item" style="width: {{columns[5].width}}">{{item.d}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* package_C/component/table/table.wxss */
|
||||
.table_container {
|
||||
width: 100%;
|
||||
margin: 24rpx 0;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
border: 1rpx solid #efefef;
|
||||
}
|
||||
.table_title{
|
||||
width: 100%;
|
||||
padding: 22rpx;
|
||||
background-color: #F5F7F9;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 27rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
.table_data {
|
||||
width: 100%;
|
||||
color: rgba(51, 51, 51, 1);
|
||||
font-size: 26rpx;
|
||||
}
|
||||
.data_item {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.table_item {
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
import WxCanvas from './wx-canvas';
|
||||
import * as echarts from './echarts';
|
||||
|
||||
let ctx;
|
||||
|
||||
function compareVersion(v1, v2) {
|
||||
v1 = v1.split('.')
|
||||
v2 = v2.split('.')
|
||||
const len = Math.max(v1.length, v2.length)
|
||||
|
||||
while (v1.length < len) {
|
||||
v1.push('0')
|
||||
}
|
||||
while (v2.length < len) {
|
||||
v2.push('0')
|
||||
}
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const num1 = parseInt(v1[i])
|
||||
const num2 = parseInt(v2[i])
|
||||
|
||||
if (num1 > num2) {
|
||||
return 1
|
||||
} else if (num1 < num2) {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
Component({
|
||||
properties: {
|
||||
canvasId: {
|
||||
type: String,
|
||||
value: 'ec-canvas'
|
||||
},
|
||||
|
||||
ec: {
|
||||
type: Object
|
||||
},
|
||||
|
||||
forceUseOldCanvas: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
isUseNewCanvas: false
|
||||
},
|
||||
|
||||
ready: function () {
|
||||
// Disable prograssive because drawImage doesn't support DOM as parameter
|
||||
// See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html
|
||||
echarts.registerPreprocessor(option => {
|
||||
if (option && option.series) {
|
||||
if (option.series.length > 0) {
|
||||
option.series.forEach(series => {
|
||||
series.progressive = 0;
|
||||
});
|
||||
}
|
||||
else if (typeof option.series === 'object') {
|
||||
option.series.progressive = 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!this.data.ec) {
|
||||
console.warn('组件需绑定 ec 变量,例:<ec-canvas id="mychart-dom-bar" '
|
||||
+ 'canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.data.ec.lazyLoad) {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
init: function (callback) {
|
||||
const version = wx.getSystemInfoSync().SDKVersion
|
||||
|
||||
const canUseNewCanvas = compareVersion(version, '2.9.0') >= 0;
|
||||
const forceUseOldCanvas = this.data.forceUseOldCanvas;
|
||||
const isUseNewCanvas = canUseNewCanvas && !forceUseOldCanvas;
|
||||
this.setData({ isUseNewCanvas });
|
||||
|
||||
if (forceUseOldCanvas && canUseNewCanvas) {
|
||||
console.warn('开发者强制使用旧canvas,建议关闭');
|
||||
}
|
||||
|
||||
if (isUseNewCanvas) {
|
||||
// console.log('微信基础库版本大于2.9.0,开始使用<canvas type="2d"/>');
|
||||
// 2.9.0 可以使用 <canvas type="2d"></canvas>
|
||||
this.initByNewWay(callback);
|
||||
} else {
|
||||
const isValid = compareVersion(version, '1.9.91') >= 0
|
||||
if (!isValid) {
|
||||
console.error('微信基础库版本过低,需大于等于 1.9.91。'
|
||||
+ '参见:https://github.com/ecomfe/echarts-for-weixin'
|
||||
+ '#%E5%BE%AE%E4%BF%A1%E7%89%88%E6%9C%AC%E8%A6%81%E6%B1%82');
|
||||
return;
|
||||
} else {
|
||||
console.warn('建议将微信基础库调整大于等于2.9.0版本。升级后绘图将有更好性能');
|
||||
this.initByOldWay(callback);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
initByNewWay(callback) {
|
||||
// version >= 2.9.0:使用新的方式初始化
|
||||
const query = wx.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('.ec-canvas')
|
||||
.fields({ node: true, size: true })
|
||||
.exec(res => {
|
||||
const canvasNode = res[0].node
|
||||
this.canvasNode = canvasNode
|
||||
|
||||
const canvasDpr = wx.getSystemInfoSync().pixelRatio
|
||||
const canvasWidth = res[0].width
|
||||
const canvasHeight = res[0].height
|
||||
|
||||
const ctx = canvasNode.getContext('2d')
|
||||
|
||||
const canvas = new WxCanvas(ctx, this.data.canvasId, true, canvasNode)
|
||||
echarts.setCanvasCreator(() => {
|
||||
return canvas
|
||||
})
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this.chart = callback(canvas, canvasWidth, canvasHeight, canvasDpr)
|
||||
} else if (this.data.ec && typeof this.data.ec.onInit === 'function') {
|
||||
this.chart = this.data.ec.onInit(canvas, canvasWidth, canvasHeight, canvasDpr)
|
||||
} else {
|
||||
this.triggerEvent('init', {
|
||||
canvas: canvas,
|
||||
width: canvasWidth,
|
||||
height: canvasHeight,
|
||||
dpr: canvasDpr
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
canvasToTempFilePath(opt) {
|
||||
if (this.data.isUseNewCanvas) {
|
||||
// 新版
|
||||
const query = wx.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('.ec-canvas')
|
||||
.fields({ node: true, size: true })
|
||||
.exec(res => {
|
||||
const canvasNode = res[0].node
|
||||
opt.canvas = canvasNode
|
||||
wx.canvasToTempFilePath(opt)
|
||||
})
|
||||
} else {
|
||||
// 旧的
|
||||
if (!opt.canvasId) {
|
||||
opt.canvasId = this.data.canvasId;
|
||||
}
|
||||
ctx.draw(true, () => {
|
||||
wx.canvasToTempFilePath(opt, this);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
touchStart(e) {
|
||||
if (this.chart && e.touches.length > 0) {
|
||||
var touch = e.touches[0];
|
||||
var handler = this.chart.getZr().handler;
|
||||
handler.dispatch('mousedown', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'start');
|
||||
}
|
||||
},
|
||||
|
||||
touchMove(e) {
|
||||
if (this.chart && e.touches.length > 0) {
|
||||
var touch = e.touches[0];
|
||||
var handler = this.chart.getZr().handler;
|
||||
handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'change');
|
||||
}
|
||||
},
|
||||
|
||||
touchEnd(e) {
|
||||
if (this.chart) {
|
||||
const touch = e.changedTouches ? e.changedTouches[0] : {};
|
||||
var handler = this.chart.getZr().handler;
|
||||
handler.dispatch('mouseup', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.dispatch('click', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
handler.processGesture(wrapTouch(e), 'end');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function wrapTouch(event) {
|
||||
for (let i = 0; i < event.touches.length; ++i) {
|
||||
const touch = event.touches[i];
|
||||
touch.offsetX = touch.x;
|
||||
touch.offsetY = touch.y;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!-- 新的:接口对其了H5 -->
|
||||
<canvas wx:if="{{isUseNewCanvas}}" type="2d" class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas>
|
||||
<!-- 旧的 -->
|
||||
<canvas wx:else class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.ec-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,105 @@
|
|||
export default class WxCanvas {
|
||||
constructor(ctx, canvasId, isNew, canvasNode) {
|
||||
this.ctx = ctx;
|
||||
this.canvasId = canvasId;
|
||||
this.chart = null;
|
||||
this.isNew = isNew
|
||||
if (isNew) {
|
||||
this.canvasNode = canvasNode;
|
||||
}
|
||||
else {
|
||||
this._initStyle(ctx);
|
||||
}
|
||||
|
||||
// this._initCanvas(zrender, ctx);
|
||||
|
||||
this._initEvent();
|
||||
}
|
||||
|
||||
getContext(contextType) {
|
||||
if (contextType === '2d') {
|
||||
return this.ctx;
|
||||
}
|
||||
}
|
||||
|
||||
// canvasToTempFilePath(opt) {
|
||||
// if (!opt.canvasId) {
|
||||
// opt.canvasId = this.canvasId;
|
||||
// }
|
||||
// return wx.canvasToTempFilePath(opt, this);
|
||||
// }
|
||||
|
||||
setChart(chart) {
|
||||
this.chart = chart;
|
||||
}
|
||||
|
||||
attachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
detachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
_initCanvas(zrender, ctx) {
|
||||
zrender.util.getContext = function () {
|
||||
return ctx;
|
||||
};
|
||||
|
||||
zrender.util.$override('measureText', function (text, font) {
|
||||
ctx.font = font || '12px sans-serif';
|
||||
return ctx.measureText(text);
|
||||
});
|
||||
}
|
||||
|
||||
_initStyle(ctx) {
|
||||
ctx.createRadialGradient = () => {
|
||||
return ctx.createCircularGradient(arguments);
|
||||
};
|
||||
}
|
||||
|
||||
_initEvent() {
|
||||
this.event = {};
|
||||
const eventNames = [{
|
||||
wxName: 'touchStart',
|
||||
ecName: 'mousedown'
|
||||
}, {
|
||||
wxName: 'touchMove',
|
||||
ecName: 'mousemove'
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'mouseup'
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'click'
|
||||
}];
|
||||
|
||||
eventNames.forEach(name => {
|
||||
this.event[name.wxName] = e => {
|
||||
const touch = e.touches[0];
|
||||
this.chart.getZr().handler.dispatch(name.ecName, {
|
||||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
|
||||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
set width(w) {
|
||||
if (this.canvasNode) this.canvasNode.width = w
|
||||
}
|
||||
set height(h) {
|
||||
if (this.canvasNode) this.canvasNode.height = h
|
||||
}
|
||||
|
||||
get width() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.width
|
||||
return 0
|
||||
}
|
||||
get height() {
|
||||
if (this.canvasNode)
|
||||
return this.canvasNode.height
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
const __request_base_url__ = {
|
||||
develop: "https://api.gongche.dev.taauav.com/api",
|
||||
trial: "https://api.gongche.dev.taauav.com/api",
|
||||
release: "https://api.gongche.taauav.com/api"
|
||||
}
|
||||
const platform = wx.getSystemInfoSync().platform
|
||||
const envVersion = wx.getAccountInfoSync().miniProgram.envVersion
|
||||
const env = platform === 'devtools' ? 'develop' : ( envVersion || 'release' )
|
||||
|
||||
const baseurl = __request_base_url__[env]
|
||||
export default baseurl
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
// pages/home/home.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
let arr = [1, 2, 3, 4, 5]
|
||||
let k = 4, x = 3
|
||||
/** *
|
||||
* @param {number[]} arr
|
||||
* @param {number} k
|
||||
* @param {number} x
|
||||
* @return {number[]}
|
||||
* */
|
||||
var findClosestElements = function(arr, k, x) {
|
||||
var getCloseIndex = function(left,right){
|
||||
if(left>=right) return left;
|
||||
let mid=(left+right)>>1;
|
||||
let result
|
||||
if(arr[mid]>=x){
|
||||
result=getCloseIndex(left,mid-1)
|
||||
}else{
|
||||
result=getCloseIndex(mid+1,right)
|
||||
}
|
||||
return result
|
||||
}
|
||||
const len=arr.length;
|
||||
let right=getCloseIndex(0,len-1);
|
||||
let left=0;
|
||||
if(right>0&&arr[right]>x) right--;
|
||||
if(right+1>=k) left=right+1-k; else right+=(k-(right+1));
|
||||
while(right<len-1&&((x-arr[left])>(arr[right+1]-x))){ left++; right++; } return arr.slice(left,right+1);
|
||||
}
|
||||
const res = findClosestElements(arr, k, x)
|
||||
console.log(res);
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!--pages/home/home.wxml-->
|
||||
<view class="home_container">
|
||||
|
||||
</view>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* pages/home/home.wxss */
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
// pages/login/login.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
form: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
remember: false,
|
||||
formRules: {
|
||||
username: {
|
||||
validator: function(value) {
|
||||
return value.trim() != ''
|
||||
},
|
||||
tips: '请输入用户名',
|
||||
placeholder: '请输入用户名'
|
||||
},
|
||||
password: {
|
||||
validator: function(value) {
|
||||
return value.trim() != ''
|
||||
},
|
||||
tips: '请输入密码',
|
||||
placeholder: '请输入密码'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
// 隐藏返回图标
|
||||
wx.hideHomeButton();
|
||||
},
|
||||
checkboxChange(e) {
|
||||
let checked = this.data.remember
|
||||
this.setData({remember: !checked})
|
||||
},
|
||||
bindValue(e) {
|
||||
let name = e.currentTarget.dataset.name;
|
||||
let form = this.data.form;
|
||||
form[name] = e.detail.value;
|
||||
this.setData({
|
||||
form,
|
||||
})
|
||||
this.validate(name, e.detail.value)
|
||||
},
|
||||
validate(name) {
|
||||
let formRules = this.data.formRules;
|
||||
let validator = this.data.formRules[name].validator
|
||||
let result = validator ? !validator(this.data.form[name]) : false;
|
||||
formRules[name].warning = result
|
||||
this.setData({
|
||||
formRules
|
||||
})
|
||||
return result
|
||||
},
|
||||
validateForm() {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let formRules = this.data.formRules;
|
||||
let result = false;
|
||||
for (let key in formRules) {
|
||||
let temp = this.validate(key)
|
||||
if (temp) {
|
||||
result = temp
|
||||
}
|
||||
}
|
||||
resolve(!result)
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
},
|
||||
submitForm() {
|
||||
this.validateForm().then(res => {
|
||||
if (res) {
|
||||
wx.showLoading({title: "登录中", mask:true});
|
||||
// 判断是否有记住密码
|
||||
if(this.data.remember) {
|
||||
wx.setStorageSync('remember', true)
|
||||
wx.setStorageSync('loginForm', this.data.form)
|
||||
} else {
|
||||
wx.removeStorageSync('remember')
|
||||
wx.removeStorageSync('loginForm')
|
||||
}
|
||||
wx.request({
|
||||
url: baseURL+"/member/login",
|
||||
method: "POST",
|
||||
data: this.data.form,
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
success(res) {
|
||||
if (res.data.code == 0) {
|
||||
// 以token获取用户信息
|
||||
let token = res.data.data
|
||||
wx.setStorageSync('token', token) // token存入storage
|
||||
wx.request({
|
||||
url: baseURL+'/member/user',
|
||||
method: "POST",
|
||||
header: {
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
"authorization": token
|
||||
},
|
||||
success: (res) => {
|
||||
wx.setStorageSync('userInfo', res.data.data)
|
||||
let app=getApp();
|
||||
let observe=app.globalData.observe;
|
||||
let getToDoNum=app.getToDoNum;
|
||||
// 跳转至tabBar
|
||||
wx.switchTab({
|
||||
url: '/pages/home/home'
|
||||
})
|
||||
getToDoNum(observe).then((res)=>{
|
||||
if(res){
|
||||
if (observe.value > 0) {
|
||||
wx.setTabBarBadge({
|
||||
index: 1,
|
||||
text: observe.value + "",
|
||||
})
|
||||
} else {
|
||||
wx.removeTabBarBadge({
|
||||
index: 1,
|
||||
})
|
||||
}
|
||||
}else{
|
||||
wx.removeTabBarBadge({
|
||||
index: 1,
|
||||
})
|
||||
}
|
||||
}).catch(e=>{console.log(e)});
|
||||
},
|
||||
fail: (res) => {
|
||||
},
|
||||
complete: (res) => {
|
||||
wx.hideLoading()
|
||||
},
|
||||
})
|
||||
}
|
||||
else{
|
||||
wx.hideLoading()
|
||||
wx.showToast({
|
||||
title: res.data.msg,
|
||||
icon: 'error',
|
||||
image: '',
|
||||
duration: 1500,
|
||||
});
|
||||
}
|
||||
},
|
||||
fail(error) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
title:error.errMsg,
|
||||
icon:"error",
|
||||
duration:1000,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<!--pages/login/login.wxml-->
|
||||
<view class="login_box">
|
||||
<form class="form_box" bindsubmit="submitForm">
|
||||
<view class="form-item {{item.warning?'warning':''}}" wx:for="{{formRules}}" wx:key="index">
|
||||
<text>{{item.title}}</text>
|
||||
<input type="{{item.type||'text'}}" placeholder="{{item.placeholder}}" value="{{form[index]}}"
|
||||
password="{{item.isPassword}}" data-name="{{index}}" bindinput="bindValue" name="{{index}}" bindblur="bindValue" />
|
||||
<text class="tips">{{item.tips}}</text>
|
||||
</view>
|
||||
<view class="check_contanier">
|
||||
<label class="check_lable" bindtap="checkboxChange">
|
||||
<checkbox checked="{{rememberChecked}}" class="check_box" />记住密码
|
||||
</label>
|
||||
</view>
|
||||
<button size="default" style="width: 100%; height: 80rpx;" class="login_btn" formType="submit">登 录</button>
|
||||
</form>
|
||||
</view>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* pages/login/login.wxss */
|
||||
.login_box {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form_box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.login_box .form-item{
|
||||
padding-bottom:50rpx;
|
||||
position: relative;
|
||||
}
|
||||
.login_box .form-item input{
|
||||
width: 532rpx;
|
||||
height: 80rpx;
|
||||
padding-left: 20px;
|
||||
border-radius: 39rpx;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.login_box .tips{
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
color: red;
|
||||
font-size:26rpx;
|
||||
transform: translate(20rpx,-10rpx);
|
||||
display: none;
|
||||
}
|
||||
.login_box .form-item.warning .tips{
|
||||
display: block;
|
||||
}
|
||||
.check_lable {
|
||||
box-sizing: border-box;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
.check_contanier {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
.check_box {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
radio-group {
|
||||
width: 200rpx;
|
||||
align-self: flex-end !important;
|
||||
}
|
||||
checkbox .wx-checkbox-input {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
.login_btn {
|
||||
margin-top: 80rpx;
|
||||
color: #fff;
|
||||
font-weight: normal;
|
||||
border-radius: 39rpx;
|
||||
background-color: #477DF3;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// pages/mine/mine.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!--pages/mine/mine.wxml-->
|
||||
<view class="mine_container">
|
||||
|
||||
</view>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* pages/mine/mine.wxss */
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
// pages/task/task.js
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
console.log('======================');
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"usingComponents": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!--pages/task/task.wxml-->
|
||||
<view class="mine_container">
|
||||
|
||||
</view>
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* pages/task/task.wxss */
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"description": "项目配置文件",
|
||||
"packOptions": {
|
||||
"ignore": [
|
||||
{
|
||||
"type": "file",
|
||||
"value": ".eslintrc.js"
|
||||
}
|
||||
]
|
||||
},
|
||||
"setting": {
|
||||
"bundle": false,
|
||||
"userConfirmedBundleSwitch": false,
|
||||
"urlCheck": true,
|
||||
"scopeDataCheck": false,
|
||||
"coverView": true,
|
||||
"es6": true,
|
||||
"postcss": true,
|
||||
"compileHotReLoad": false,
|
||||
"lazyloadPlaceholderEnable": false,
|
||||
"preloadBackgroundData": false,
|
||||
"minified": true,
|
||||
"autoAudits": false,
|
||||
"newFeature": false,
|
||||
"uglifyFileName": false,
|
||||
"uploadWithSourceMap": true,
|
||||
"useIsolateContext": true,
|
||||
"nodeModules": false,
|
||||
"enhance": true,
|
||||
"useMultiFrameRuntime": true,
|
||||
"useApiHook": true,
|
||||
"useApiHostProcess": true,
|
||||
"showShadowRootInWxmlPanel": true,
|
||||
"packNpmManually": false,
|
||||
"enableEngineNative": false,
|
||||
"packNpmRelationList": [],
|
||||
"minifyWXSS": true,
|
||||
"showES6CompileOption": false,
|
||||
"minifyWXML": true
|
||||
},
|
||||
"compileType": "miniprogram",
|
||||
"libVersion": "2.19.4",
|
||||
"appid": "wx0ba562a60cd958b4",
|
||||
"projectname": "weixin-app",
|
||||
"debugOptions": {
|
||||
"hidedInDevtools": []
|
||||
},
|
||||
"scripts": {},
|
||||
"staticServerOptions": {
|
||||
"baseURL": "",
|
||||
"servePath": ""
|
||||
},
|
||||
"isGameTourist": false,
|
||||
"condition": {
|
||||
"search": {
|
||||
"list": []
|
||||
},
|
||||
"conversation": {
|
||||
"list": []
|
||||
},
|
||||
"game": {
|
||||
"list": []
|
||||
},
|
||||
"plugin": {
|
||||
"list": []
|
||||
},
|
||||
"gamePlugin": {
|
||||
"list": []
|
||||
},
|
||||
"miniprogram": {
|
||||
"list": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"condition": {
|
||||
"plugin": {
|
||||
"list": []
|
||||
},
|
||||
"game": {
|
||||
"list": []
|
||||
},
|
||||
"gamePlugin": {
|
||||
"list": []
|
||||
},
|
||||
"miniprogram": {
|
||||
"list": [
|
||||
{
|
||||
"name": "登录",
|
||||
"pathName": "pages/login/login",
|
||||
"query": "",
|
||||
"scene": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import baseurl from '../environments.js'
|
||||
import {isWithoutToken} from './whiteList.js'
|
||||
export const request = function(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(data.showLoading) {
|
||||
wx.showLoading({
|
||||
title: '加载中',
|
||||
mask: true
|
||||
})
|
||||
}
|
||||
// 接口api拼接环境地址
|
||||
data.url = baseurl + data.url
|
||||
// 处理需要token的请求
|
||||
if(!isWithoutToken(data)) {
|
||||
let baseHeader = {authorization: wx.getStorageSync('token')}
|
||||
data.header = Object.assign(data.header || {}, baseHeader)
|
||||
}
|
||||
wx.request({
|
||||
...data,
|
||||
success: function(res) {
|
||||
// 处理请求
|
||||
if(res.data.code == 0) { // 请求成功状态码
|
||||
resolve(res.data)
|
||||
} else if ((res.data.code == 401) || (res.data.code == 402)) { // token过期状态码
|
||||
reject(res.data.msg)
|
||||
// 重新登录
|
||||
wx.reLaunch({
|
||||
url: '/pages/login/login',
|
||||
})
|
||||
} else {
|
||||
reject(res.data.msg)
|
||||
}
|
||||
},
|
||||
fail: function (error) {
|
||||
reject(error)
|
||||
},
|
||||
complete: function () {
|
||||
if (data.showLoading) {
|
||||
wx.hideLoading()
|
||||
}
|
||||
}
|
||||
})
|
||||
}).catch(e => {
|
||||
wx.showToast({
|
||||
icon: "error",
|
||||
title: e || '系统错误',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
const WITHOUT_TOKEN_API = [{url: '/member/login', method: 'POST'}]
|
||||
|
||||
export const isWithoutToken = function({url, method=''}){
|
||||
return WITHOUT_TOKEN_API.some((item) => item.url === url && item.method === method.toUpperCase())
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
|
||||
"rules": [{
|
||||
"action": "allow",
|
||||
"page": "*"
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
const formatTime = date => {
|
||||
const year = date.getFullYear()
|
||||
const month = date.getMonth() + 1
|
||||
const day = date.getDate()
|
||||
const hour = date.getHours()
|
||||
const minute = date.getMinutes()
|
||||
const second = date.getSeconds()
|
||||
|
||||
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
|
||||
}
|
||||
|
||||
const formatNumber = n => {
|
||||
n = n.toString()
|
||||
return n[1] ? n : `0${n}`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
formatTime
|
||||
}
|
||||
Loading…
Reference in New Issue