@@ -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,92 @@ | |||
const {request} = require("../request/index") | |||
/** | |||
* 获取banner列表 | |||
* @param {*} params | |||
*/ | |||
export const getBanner = function(params) { | |||
return request({ | |||
url: '/ad/getHomeList', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取首页任务展示 | |||
* @param {*} params | |||
*/ | |||
export const getHomeData = function(params) { | |||
return request({ | |||
url: '/task/getTaskList', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取平台列表 | |||
* @param {*} params | |||
*/ | |||
export const getPlatform = function(params) { | |||
return request({ | |||
url: '/city/queryCityList', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取所有任务列表 | |||
* @param {*} params | |||
*/ | |||
export const getAllTask = function(params) { | |||
return request({ | |||
url: '/task/totalList', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取无人机列表 | |||
* @param {*} params | |||
*/ | |||
export const getEquipments = function(params) { | |||
return request({ | |||
url: '/equipment/equipments', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取所有运河列表 | |||
* @param {*} params | |||
*/ | |||
export const getCloudBox = function(params) { | |||
return request({ | |||
url: '/pilotCloudBox/cloudBoxs', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 获取挂载设备 | |||
* @param {*} params | |||
*/ | |||
export const getMounts = function(params) { | |||
return request({ | |||
url: '/equipmentMount/equipmentMounts', | |||
method: "GET", | |||
params | |||
}) | |||
} | |||
/** | |||
* 接单 | |||
*/ | |||
export const confirmOrder = function (data) { | |||
return request({ | |||
url: '/task/todoDetailTask', | |||
method: 'PUT', | |||
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,49 @@ | |||
{ | |||
"pages": [ | |||
"pages/task/task", | |||
"pages/mine/mine", | |||
"pages/login/login" | |||
], | |||
"tabBar": { | |||
"color": "#939393", | |||
"borderStyle": "white", | |||
"selectedColor": "#477DF3", | |||
"list": [ | |||
{ | |||
"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": [ | |||
"page/alltask/index", | |||
"page/TaskDetail/index" | |||
] | |||
}, | |||
{ | |||
"root": "package_B", | |||
"pages": [ | |||
"page/loginOut/index" | |||
] | |||
} | |||
], | |||
"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; | |||
} |
@@ -0,0 +1,39 @@ | |||
// components/BaseMap/index.js | |||
// const iconPath = require('../../assets/img/location.png') | |||
Component({ | |||
/** | |||
* 组件的属性列表 | |||
*/ | |||
properties: { | |||
pointList: { | |||
type: Object, | |||
value: [{ | |||
latitude: 32.534243, | |||
longitude: 118.431231, | |||
name: 'T.I.T 创意园', | |||
iconPath: '../../assets/img/location.png' | |||
}, | |||
{ | |||
latitude: 32.534243, | |||
longitude: 118.432231, | |||
name: 'T.I.T 创意园', | |||
iconPath: '../../assets/img/location.png' | |||
}] | |||
} | |||
}, | |||
/** | |||
* 组件的初始数据 | |||
*/ | |||
data: { | |||
lat: 32.534243, | |||
lon: 118.4312312 | |||
}, | |||
/** | |||
* 组件的方法列表 | |||
*/ | |||
methods: { | |||
} | |||
}) |
@@ -0,0 +1,4 @@ | |||
{ | |||
"component": true, | |||
"usingComponents": {} | |||
} |
@@ -0,0 +1,11 @@ | |||
<!--components/BaseMap/index.wxml--> | |||
<view class="map_container"> | |||
<map | |||
name="map" | |||
id="myMap" | |||
style="width: 100%;height: 440rpx;" | |||
markers="{{pointList}}" | |||
latitude="{{lat}}" | |||
longitude="{{lon}}" | |||
></map> | |||
</view> |
@@ -0,0 +1,5 @@ | |||
/* components/BaseMap/index.wxss */ | |||
.map_container { | |||
width: 100%; | |||
height: 100%; | |||
} |
@@ -0,0 +1,91 @@ | |||
// components/List/index.js | |||
import { getDataByPath } from "../../utils/util" | |||
import { get } from "../../utils/api" | |||
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, | |||
more: true, | |||
loading: false | |||
}, | |||
// 数据监听器 | |||
observers: { | |||
"url,params"(url) { | |||
if (!url) return | |||
this.resetPage(); | |||
}, | |||
}, | |||
/** | |||
* 组件的方法列表 | |||
*/ | |||
methods: { | |||
loadMore() { | |||
let page = this.data.page + 1; | |||
this.setData({ page }) | |||
this.getData(); | |||
}, | |||
getData() { | |||
if (!this.data.more) return | |||
if (!this.data.loading && (!this.data.params || Object.keys(this.data.params).length > 0)) { | |||
this.setData({ loading: true }) | |||
get(this.data.url, Object.assign({}, { page: this.data.page, limit: this.data.limit }, this.data.params || {})).then(res => { | |||
let records; | |||
if (res.code == 0) { | |||
records = getDataByPath(res, this.data.dataPath || "data.records") | |||
} else { | |||
records = []; | |||
} | |||
if (records.length < this.data.limit) { | |||
this.setData({ more: false }) | |||
} | |||
this.triggerEvent("update-list", records) | |||
}).catch(e => { | |||
wx.showToast({ | |||
title: e || '系统错误', | |||
duration: 1500, | |||
}); | |||
}).finally(() => { | |||
this.setData({ loading: false }) | |||
}) | |||
} | |||
}, | |||
resetPage() { | |||
this.setData({ more: true, page: 1 }) | |||
this.triggerEvent('reset-list') | |||
this.getData(); | |||
} | |||
} | |||
}) |
@@ -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" lower-threshold="80"> | |||
<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,39 @@ | |||
/* components/List/index.wxss */ | |||
.list { | |||
box-sizing: border-box; | |||
width: 100%; | |||
height: 100%; | |||
padding: 0 40rpx; | |||
} | |||
.min-height { | |||
height: 400rpx; | |||
} | |||
::-webkit-scrollbar { | |||
display: none; | |||
width: 0; | |||
height: 0; | |||
color: transparent; | |||
} | |||
.empty { | |||
display: flex; | |||
flex-direction: column; | |||
align-items: center; | |||
justify-content: center; | |||
transform: translateY(100rpx); | |||
} | |||
.empty .image { | |||
height: 201rpx; | |||
width: 306rpx; | |||
} | |||
.empty-text { | |||
font-size: 32rpx; | |||
font-family: "PingFangSC-Regular", "PingFang SC"; | |||
font-weight: normal; | |||
color: #B6CADC; | |||
margin-top: 26rpx; | |||
} |
@@ -0,0 +1,38 @@ | |||
// components/Select/index.js | |||
Component({ | |||
/** | |||
* 组件属性列表 | |||
*/ | |||
options: { | |||
styleIsolation: "isolated" | |||
}, | |||
properties: { | |||
data: { | |||
type: Array, | |||
}, | |||
current: { | |||
type: [Number, String] | |||
}, | |||
rangeKey: { | |||
type: String, | |||
default() { | |||
return '' | |||
} | |||
}, | |||
disabled: { | |||
type: Boolean, | |||
default() { | |||
return false | |||
} | |||
} | |||
}, | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: {}, | |||
methods: { | |||
updateChange(e) { | |||
this.triggerEvent('updateChange', {current:e.detail.value}) | |||
}, | |||
} | |||
}) |
@@ -0,0 +1,4 @@ | |||
{ | |||
"component": true, | |||
"usingComponents": {} | |||
} |
@@ -0,0 +1,12 @@ | |||
<!--components/Select/index.wxml--> | |||
<view class="select_box"> | |||
<picker bindchange="updateChange" value="{{current}}" data-current="{{current}}" range="{{data}}" range-key="{{rangeKey}}" disabled="{{disabled}}"> | |||
<view class="picker" wx:if="{{data[current][rangeKey]}}"> | |||
{{data[current][rangeKey]}} | |||
</view> | |||
<view wx:else class="picker" style="color: {{disabled? '#999999': '#333333'}};"> | |||
<text>请选择 </text> | |||
<image class="select_img" src="../../assets/img/select.png"></image> | |||
</view> | |||
</picker> | |||
</view> |
@@ -0,0 +1,33 @@ | |||
/* components/Select/index.wxss */ | |||
.select_box { | |||
width: 170rpx; | |||
padding: 22rpx 0; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
} | |||
picker { | |||
width: 100%; | |||
font-size: 28rpx; | |||
color: #333333; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-emphasis: ellipsis; | |||
} | |||
.picker { | |||
width: 170rpx; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
overflow: hidden; | |||
white-space: nowrap; | |||
text-emphasis: ellipsis; | |||
} | |||
.select_img { | |||
width: 16rpx; | |||
height: 10rpx; | |||
margin-left: 10rpx; | |||
} |
@@ -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,31 @@ | |||
// components/TaskInfo/index.js | |||
import {statusList} from '../../utils/data.js' | |||
Component({ | |||
/** | |||
* 组件的属性列表 | |||
*/ | |||
properties: { | |||
data: { | |||
type: Object, | |||
value: {} | |||
}, | |||
type: { | |||
type: String, | |||
value: '' | |||
} | |||
}, | |||
/** | |||
* 组件的初始数据 | |||
*/ | |||
data: { | |||
statusList | |||
}, | |||
/** | |||
* 组件的方法列表 | |||
*/ | |||
methods: { | |||
} | |||
}) |
@@ -0,0 +1,4 @@ | |||
{ | |||
"component": true, | |||
"usingComponents": {} | |||
} |
@@ -0,0 +1,11 @@ | |||
<!--components/TaskInfo/index.wxml--> | |||
<view class="info_container"> | |||
<view class="info_head"> | |||
<text style="color: rgba(0, 0, 0, 1)">{{data.platformName}}</text> | |||
<text wx:if="{{type === 'list'}}">{{data.createTime}}</text> | |||
</view> | |||
<view class="info_item">租户:{{data.tenantName}}</view> | |||
<view class="info_item">任务地点:{{data.patrolLocation}}</view> | |||
<view class="info_item">期望时间:{{data.taskStartName}}</view> | |||
<view wx:if="{{type === 'list'}}" class="info_item">任务状态:<text style="color: {{statusList[data.status].color}}">{{statusList[data.status].text}}</text></view> | |||
</view> |
@@ -0,0 +1,19 @@ | |||
/* components/TaskInfo/index.wxss */ | |||
.info_container { | |||
width: 100%; | |||
height: 100%; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: space-between; | |||
align-items: flex-start; | |||
color: #666666; | |||
} | |||
.info_head { | |||
width: 100%; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
.info_item { | |||
width: 100%; | |||
} |
@@ -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%; | |||
} |
@@ -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,96 @@ | |||
// package_A/page/TaskDetail/index.js | |||
import {statusList, baseRules, orderRules} from '../../../utils/data.js' | |||
Page({ | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: { | |||
taskIsLive: null, // 任务状态 | |||
dataSource: {}, | |||
statusList, | |||
messageList: [ | |||
{label: '任务执行时间', value: "taskStartTime", icon: ""}, | |||
{label: '任务地点', value: "patrolLocation", icon: ""}, | |||
{label: '任务发起人', value: "taskName", icon: ""}, | |||
{label: '租户名称', value: "tenantName", icon: ""}, | |||
{label: '需要直播', value: "isLive", icon: ""}, | |||
{label: '备注', value: "createTime", icon: ""} | |||
], | |||
form: {}, | |||
formRules: {}, | |||
formOptions: { | |||
equipmentId: {current: -1, list: [{value: 1, label: '倾斜摄影'}, | |||
{value: 2, label: '正射影像'}]}, | |||
equipmentMountId: {current: -1, list: [{value: 1, label: '倾斜摄影'}, | |||
{value: 2, label: '正射影像'}]}, | |||
photographyWay: {current: -1, list: [{value: 1, label: '倾斜摄影'}, | |||
{value: 2, label: '正射影像'}]}, | |||
cloudBoxId: {current: -1, list: [{value: 1, label: '倾斜摄影'}, | |||
{value: 2, label: '正射影像'}]} | |||
}, | |||
disabled: false | |||
}, | |||
/** | |||
* 生命周期函数--监听页面加载 | |||
*/ | |||
onLoad(options) { | |||
if(options.data) { | |||
let dataSource = this.data.dataSource | |||
dataSource = JSON.parse(options.data) | |||
let formRules = this.data.formRules | |||
if(dataSource.isLive === 0) { | |||
formRules = Object.assign(baseRules, {}) | |||
} else { | |||
formRules = Object.assign(baseRules, orderRules) | |||
} | |||
this.setData({dataSource, taskIsLive: dataSource.isLive, formRules}) | |||
} | |||
}, | |||
/** | |||
* | |||
* @param {*} e | |||
*/ | |||
updateChange(e) { | |||
console.log('事件触发'); | |||
let index = e.currentTarget.dataset.index | |||
let current = parseInt(e.detail.value) | |||
let value = this.data.formOptions[index].list[current].value | |||
let form = this.data.form | |||
form[index] = value | |||
let formOptions = this.data.formOptions | |||
formOptions[index].current = current | |||
this.setData({formOptions, form}) | |||
this.validate(index) | |||
}, | |||
validate(name) { | |||
let formRules = this.data.formRules; | |||
let validator = formRules[name].validator | |||
let result = validator ? !validator(this.data.form[name]) : false; | |||
formRules[name].warning = result | |||
this.setData({ | |||
formRules | |||
}) | |||
console.log(name, result); | |||
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) | |||
} | |||
}) | |||
}, | |||
}) |
@@ -0,0 +1,6 @@ | |||
{ | |||
"usingComponents": { | |||
"base-map": "../../../components/BaseMap/index" | |||
}, | |||
"navigationBarTitleText": "任务详情" | |||
} |
@@ -0,0 +1,47 @@ | |||
<!--package_A/page/TaskDetail/index.wxml--> | |||
<view class="detail_container"> | |||
<view class="detail_head"> | |||
<text>{{dataSource.platformName}}</text> | |||
<text>{{dataSource.createTime}}分配</text> | |||
</view> | |||
<!-- 地图区域 --> | |||
<view id="map" class="map_box"> | |||
<base-map></base-map> | |||
</view> | |||
<!-- 任务信息 --> | |||
<view class="task_message"> | |||
<text class="message_head">待接单任务</text> | |||
<view class="message_list"> | |||
<view class="message_item" wx:for="{{messageList}}" wx:key="index"> | |||
<image style="width: 28rpx;height: 28rpx;margin-right: 20rpx;" src="../../../assets/img/home.png"></image> | |||
<text>{{item.label}}:<text>{{item.value}}</text></text> | |||
</view> | |||
</view> | |||
</view> | |||
<!-- 表单区域 --> | |||
<view class="form_container"> | |||
<view class="form_item {{item.warning?'warning':''}}" wx:for="{{formRules}}" wx:key="index"> | |||
<text class="item_label">{{item.name}}</text> | |||
<picker bindchange="updateChange" data-index="{{index}}" value="{{formOptions[item.value].current}}" range="{{formOptions[item.value].list}}" range-key="{{item.rangeKey}}" disabled="{{disabled}}" class="picker_box"> | |||
<view class="picker" wx:if="{{formOptions[item.value].list[formOptions[item.value].current].label}}"> | |||
{{formOptions[item.value].list[formOptions[item.value].current].label}} | |||
</view> | |||
<view wx:else class="picker"> | |||
{{item.placeholder}} | |||
</view> | |||
</picker> | |||
<text class="tips">{{item.placeholder}}</text> | |||
</view> | |||
</view> | |||
<!-- 飞行信息 --> | |||
<view class="fly_message"> | |||
<text>飞行开始时间:{{dataSource.startTime}}</text> | |||
<text>飞行结束时间:{{dataSource.endTime}}</text> | |||
</view> | |||
<!-- 按钮区域 --> | |||
<view class="btn_list"> | |||
<view class="get_order">接单</view> | |||
<view class="get_order">开始飞行</view> | |||
<view class="get_order">结束飞行</view> | |||
</view> | |||
</view> |
@@ -0,0 +1,95 @@ | |||
/* package_A/page/TaskDetail/index.wxss */ | |||
.detail_container { | |||
width: 100%; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.detail_head { | |||
box-sizing: border-box; | |||
width: 100%; | |||
padding: 20rpx 40rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
.map_box { | |||
width: 100%; | |||
height: 440rpx; | |||
background-color: aliceblue; | |||
} | |||
.task_message { | |||
box-sizing: border-box; | |||
width: 100%; | |||
padding: 40rpx 60rpx 20rpx 60rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.message_head { | |||
width: 100%; | |||
margin-bottom: 30rpx; | |||
color: #000; | |||
font-size: 34rpx; | |||
font-weight: bold; | |||
} | |||
.message_list { | |||
box-sizing: border-box; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
color: #666666; | |||
} | |||
.message_item { | |||
width: 100%; | |||
margin-bottom: 30rpx; | |||
} | |||
.form_container { | |||
box-sizing: border-box; | |||
width: 100%; | |||
margin-bottom: 40rpx; | |||
padding: 30rpx 60rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
box-shadow: 0 4rpx 12rpx 0 #5251517a; | |||
} | |||
.form_item { | |||
box-sizing: border-box; | |||
width: 100%; | |||
margin-bottom: 30rpx; | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: center; | |||
color: #666666; | |||
font-size: 30rpx; | |||
position: relative; | |||
} | |||
.item_label { | |||
width: 170rpx; | |||
margin-right: 30rpx; | |||
} | |||
.picker_box { | |||
flex: 1; | |||
height: 50rpx; | |||
padding-left: 20rpx; | |||
line-height: 50rpx; | |||
border: 1rpx solid #dedede; | |||
} | |||
.tips{ | |||
position: absolute; | |||
bottom: -30rpx; | |||
left: 200rpx; | |||
color: red; | |||
font-size: 26rpx; | |||
display: none; | |||
} | |||
.warning.form_item .tips{ | |||
display: block; | |||
} |
@@ -0,0 +1,116 @@ | |||
// package_A/page/alltask/index.js | |||
import {getPlatform, getAllTask } from '../../../api/task.js' | |||
Page({ | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: { | |||
current: "", | |||
list:[ { | |||
"id":"2", | |||
"tenantName":"江宁区河湖张办公室", | |||
"patrolLocation":"七乡河", | |||
"platformName":"河湖长眼管理平台", | |||
"taskStartName":"2022/8/1", | |||
"status":15, | |||
"isLive":0, | |||
"createTime":"2022/7/9" | |||
}, | |||
{ | |||
"id":"3", | |||
"tenantName":"江宁区河湖张办公室", | |||
"patrolLocation":"七乡河", | |||
"platformName":"河湖长眼管理平台", | |||
"taskStartName":"2022/8/1", | |||
"status":20, | |||
"isLive":0, | |||
"createTime":"2022/7/9" | |||
}, | |||
{ | |||
"id":"3", | |||
"tenantName":"江宁区河湖张办公室", | |||
"patrolLocation":"七乡河", | |||
"platformName":"河湖长眼管理平台", | |||
"taskStartName":"2022/8/1", | |||
"status":20, | |||
"isLive":0, | |||
"createTime":"2022/7/9" | |||
}], | |||
params: {}, | |||
sortList:[ | |||
{label: '由远及近', value: 1}, | |||
{label: '由近到远', value: 2} | |||
], | |||
statusList:[ | |||
{label: '待接单', value: 10}, | |||
{label: '已接单待飞行', value: 15}, | |||
{label: '飞行中', value: 20}, | |||
{label: '已完成', value: 25} | |||
], | |||
platformOptions:[ | |||
{label: '河湖长眼管理平台', value: 1}, | |||
{label: '林场巡检平台', value: 2}, | |||
], | |||
sortCurrent: -1, | |||
statusCurrent: -1, | |||
platformCurrent: -1, | |||
date: '' | |||
}, | |||
/** | |||
* 获取平台列表 | |||
* @param {*} | |||
*/ | |||
getPlatformData() { | |||
}, | |||
/** | |||
* 选择 | |||
* @param {*} e | |||
*/ | |||
updatePicker(e) { | |||
const current = e.detail.current | |||
const type = e.target.dataset.type | |||
let params = this.data.params | |||
let value = this.data.sortList[current].value | |||
params[type] = value | |||
if(type === 'sort') { | |||
this.setData({ | |||
sortCurrent: current | |||
}) | |||
} else if(type === 'status') { | |||
this.setData({ | |||
statusCurrent: current | |||
}) | |||
} else if(type === 'platform') { | |||
this.setData({ | |||
platformCurrent: current | |||
}) | |||
} | |||
this.setData({ | |||
params: params | |||
}) | |||
}, | |||
selectTime(e) { | |||
let value = e.detail.value | |||
let params = this.data.params | |||
params.taskStartTime = value | |||
this.setData({ | |||
date: value, | |||
params | |||
}) | |||
}, | |||
/** | |||
* 跳转详情页 | |||
* @param {*} e | |||
*/ | |||
showDetail(e) { | |||
let data = e.currentTarget.dataset.item | |||
wx.navigateTo({ | |||
url: '/package_A/page/TaskDetail/index?data=' + JSON.stringify(data), | |||
}) | |||
} | |||
}) |
@@ -0,0 +1,8 @@ | |||
{ | |||
"usingComponents": { | |||
"List": "../../../components/List/index", | |||
"Select": "../../../components/Select/index", | |||
"task-info": "../../../components/TaskInfo/index" | |||
}, | |||
"navigationBarTitleText": "任务" | |||
} |
@@ -0,0 +1,22 @@ | |||
<!--package_A/page/alltask/index.wxml--> | |||
<view class="task_container"> | |||
<!-- 筛选条件 --> | |||
<view class="select_container"> | |||
<Select data="{{sortList}}" data-type="sort" rangeKey="label" current="{{sortCurrent}}" bind:updateChange="updatePicker"></Select> | |||
<Select data="{{statusList}}" data-type="status" rangeKey="label" current="{{statusCurrent}}" bind:updateChange="updatePicker"></Select> | |||
<Select data="{{platformOptions}}" data-type="platform" rangeKey="label" current="{{platformCurrent}}" bind:updateChange="updatePicker"></Select> | |||
<picker value="{{date}}" mode="date" bindchange="selectTime" style="width: 160rpx;padding-right: 20rpx;"> | |||
<view wx:if="{{date}}">{{date}}</view> | |||
<view wx:else>日期</view> | |||
</picker> | |||
</view> | |||
<!-- 列表 --> | |||
<List id="list" class="task_list" url="{{current}}" bind:update-list="updateList" list="{{list}}" bind:reset-list="resetList" params="{{params}}"> | |||
<view class="task_item" data-current="{{index}}" wx:for="{{list}}" wx:key="index"> | |||
<image style="width:60rpx;height:60rpx;border-radius:50%;" src="../../../assets/img/home.png"></image> | |||
<view class="task_main" data-item="{{item}}" bindtap="showDetail"> | |||
<task-info data="{{item}}" type="list"></task-info> | |||
</view> | |||
</view> | |||
</List> | |||
</view> |
@@ -0,0 +1,50 @@ | |||
/* package_A/page/alltask/index.wxss */ | |||
.task_container { | |||
box-sizing: border-box; | |||
width: 100%; | |||
height: 100vh; | |||
background-color: rgba(240, 242, 245, 1); | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: center; | |||
color: #333333; | |||
} | |||
.select_container { | |||
width: 100%; | |||
height: 90rpx; | |||
background-color: #fff; | |||
display: flex; | |||
justify-content: space-evenly; | |||
align-items: center; | |||
} | |||
/* 列表样式 */ | |||
.task_list { | |||
box-sizing: border-box; | |||
width: 100%; | |||
height: 100%; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.task_item { | |||
box-sizing: border-box; | |||
width: 100%; | |||
height: 320rpx; | |||
margin-top: 25rpx; | |||
padding: 20rpx 20rpx; | |||
background-color: #fff; | |||
border-radius: 10rpx; | |||
box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.25); | |||
display: flex; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.task_main { | |||
box-sizing: border-box; | |||
flex: 1; | |||
height: 100%; | |||
padding: 20rpx 0 20rpx 10rpx; | |||
} |
@@ -0,0 +1,66 @@ | |||
// package_B/page/loginOut/index.js | |||
Page({ | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面加载 | |||
*/ | |||
onLoad(options) { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面初次渲染完成 | |||
*/ | |||
onReady() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面显示 | |||
*/ | |||
onShow() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面隐藏 | |||
*/ | |||
onHide() { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面卸载 | |||
*/ | |||
onUnload() { | |||
}, | |||
/** | |||
* 页面相关事件处理函数--监听用户下拉动作 | |||
*/ | |||
onPullDownRefresh() { | |||
}, | |||
/** | |||
* 页面上拉触底事件的处理函数 | |||
*/ | |||
onReachBottom() { | |||
}, | |||
/** | |||
* 用户点击右上角分享 | |||
*/ | |||
onShareAppMessage() { | |||
} | |||
}) |
@@ -0,0 +1,3 @@ | |||
{ | |||
"usingComponents": {} | |||
} |
@@ -0,0 +1,2 @@ | |||
<!--package_B/page/loginOut/index.wxml--> | |||
<text>package_B/page/loginOut/index.wxml</text> |
@@ -0,0 +1 @@ | |||
/* package_B/page/loginOut/index.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,4 @@ | |||
{ | |||
"usingComponents": {}, | |||
"navigationBarTitleText": "我的" | |||
} |
@@ -0,0 +1,4 @@ | |||
<!--pages/mine/mine.wxml--> | |||
<view class="mine_container"> | |||
我的 | |||
</view> |
@@ -0,0 +1 @@ | |||
/* pages/mine/mine.wxss */ |
@@ -0,0 +1,96 @@ | |||
// pages/task/task.js | |||
Page({ | |||
/** | |||
* 页面的初始数据 | |||
*/ | |||
data: { | |||
bannerList: [ | |||
{cover: 'http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg'}, | |||
{cover: "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg"}, | |||
{cover: 'http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg'}, | |||
{cover: 'http://g.hiphotos.baidu.com/image/pic/item/6d81800a19d8bc3e770bd00d868ba61ea9d345f2.jpg'} | |||
], // 轮播图 | |||
dataSource: { | |||
platformName: '智慧河长管理平台', | |||
createTime: '2022-10-22', | |||
tenantName: '江宁租户', | |||
patrolLocation: '江宁区河湖长办公室', | |||
taskStartName: '2022-10-22', | |||
status: 20 | |||
} | |||
}, | |||
/** | |||
* 生命周期函数--监听页面加载 | |||
*/ | |||
onLoad: function (options) { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面初次渲染完成 | |||
*/ | |||
onReady: function () { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面显示 | |||
*/ | |||
onShow: function () {}, | |||
/** | |||
* 进入任务列表 | |||
*/ | |||
goTaskPage(e) { | |||
console.log(e.currentTarget.dataset.status); | |||
wx.navigateTo({ | |||
url: '/package_A/page/alltask/index', | |||
}) | |||
}, | |||
/** | |||
* 进入详情页面 | |||
*/ | |||
goTaskDetail(e) { | |||
let detail = e.currentTarget.dataset.detail | |||
wx.navigateTo({ | |||
url: '/package_A/page/TaskDetail/index?data=' + JSON.stringify(detail), | |||
}) | |||
}, | |||
/** | |||
* 生命周期函数--监听页面隐藏 | |||
*/ | |||
onHide: function () { | |||
}, | |||
/** | |||
* 生命周期函数--监听页面卸载 | |||
*/ | |||
onUnload: function () { | |||
}, | |||
/** | |||
* 页面相关事件处理函数--监听用户下拉动作 | |||
*/ | |||
onPullDownRefresh: function () { | |||
}, | |||
/** | |||
* 页面上拉触底事件的处理函数 | |||
*/ | |||
onReachBottom: function () { | |||
}, | |||
/** | |||
* 用户点击右上角分享 | |||
*/ | |||
onShareAppMessage: function () { | |||
} | |||
}) |
@@ -0,0 +1,6 @@ | |||
{ | |||
"usingComponents": { | |||
"task-info": "../../components/TaskInfo/index" | |||
}, | |||
"navigationBarTitleText": "首页" | |||
} |
@@ -0,0 +1,64 @@ | |||
<!--pages/task/task.wxml--> | |||
<view class="task_container"> | |||
<!-- 轮播 --> | |||
<view class="banner"> | |||
<swiper indicator-dots="{{false}}" autoplay="true" interval="5000" bindchange="setCurrent" duration="1000" | |||
circular="true" class="banner-swiper"> | |||
<block wx:for="{{bannerList}}" wx:key="index"> | |||
<swiper-item style="height: 100%"> | |||
<image class="banner-image" src="{{item.cover}}" mode="scaleToFill" data-current="{{index}}"> | |||
</image> | |||
</swiper-item> | |||
</block> | |||
</swiper> | |||
<view class="dots"> | |||
<block wx:for="{{bannerList}}" wx:key="index"> | |||
<view class="dot {{current==index?'active':''}}"> | |||
</view> | |||
</block> | |||
</view> | |||
</view> | |||
<!-- 任务 --> | |||
<view class="task_box"> | |||
<view class="all_task"> | |||
<text style="font-weight: bold; font-size: 34rpx;">所有任务</text> | |||
<text style="font-size: 26rpx; color: rgba(42, 130, 228, 1);" data-status="all" bindtap="goTaskPage">查看更多</text> | |||
</view> | |||
<view class="task_card"> | |||
<view class="card_head"> | |||
<view class="card_label"> | |||
<image class="task_icon" src="../../assets/img/home.png"></image> | |||
<text style="color:rgba(51, 51, 51, 1); font-size: 34rpx; font-weight: bold;">待接单任务</text> | |||
</view> | |||
<view class="more">更多 ></view> | |||
</view> | |||
<view class="task_main" bindtap="goTaskDetail" data-detail="{{dataSource}}"> | |||
<task-info data="{{dataSource}}" type="home"></task-info> | |||
</view> | |||
</view> | |||
<view class="task_card"> | |||
<view class="card_head"> | |||
<view class="card_label"> | |||
<image class="task_icon" src="../../assets/img/home.png"></image> | |||
<text style="color:rgba(51, 51, 51, 1); font-size: 34rpx; font-weight: bold;">已接单任务</text> | |||
</view> | |||
<view class="more">更多 ></view> | |||
</view> | |||
<view class="task_main" bindtap="goTaskDetail" data-detail="{{dataSource}}"> | |||
<task-info data="{{dataSource}}" type="home"></task-info> | |||
</view> | |||
</view> | |||
<view class="task_card"> | |||
<view class="card_head"> | |||
<view class="card_label"> | |||
<image class="task_icon" src="../../assets/img/home.png"></image> | |||
<text style="color:rgba(51, 51, 51, 1); font-size: 34rpx; font-weight: bold;">已完成任务</text> | |||
</view> | |||
<view class="more">更多 ></view> | |||
</view> | |||
<view class="task_main" bindtap="goTaskDetail" data-detail="{{dataSource}}"> | |||
<task-info data="{{dataSource}}" type="home"></task-info> | |||
</view> | |||
</view> | |||
</view> | |||
</view> |
@@ -0,0 +1,71 @@ | |||
/* pages/task/task.wxss */ | |||
.task_container { | |||
width: 100vw; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
background-color: rgba(240, 242, 245, 1); | |||
} | |||
.banner { | |||
width: 100%; | |||
height: 420rpx; | |||
margin-top: 20rpx; | |||
} | |||
.banner-swiper { | |||
height: 420rpx; | |||
} | |||
.banner-image { | |||
width: 100%; | |||
height: 420rpx; | |||
} | |||
.task_box { | |||
box-sizing: border-box; | |||
width: 100%; | |||
padding: 0 40rpx 80rpx 40rpx; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.all_task { | |||
width: 100%; | |||
margin: 20rpx 0; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
.task_card { | |||
box-sizing: border-box; | |||
width: 100%; | |||
height: 334rpx; | |||
padding: 30rpx; | |||
margin-bottom: 20rpx; | |||
background-color: #ffffff; | |||
border-radius: 10rpx; | |||
box-shadow: 0 4rpx 12rpx 0 rgba(0, 0, 0, 0.25); | |||
color: #666666; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: flex-start; | |||
align-items: flex-start; | |||
} | |||
.card_head { | |||
width: 100%; | |||
margin-bottom: 20rpx; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
} | |||
.task_icon { | |||
width: 34rpx; | |||
height: 40rpx; | |||
margin-right: 15rpx; | |||
} | |||
.more { | |||
font-size: 26rpx; | |||
color: #999999; | |||
} | |||
.task_main { | |||
flex: 1; | |||
} |
@@ -0,0 +1,75 @@ | |||
{ | |||
"description": "项目配置文件", | |||
"packOptions": { | |||
"ignore": [ | |||
{ | |||
"value": ".eslintrc.js", | |||
"type": "file" | |||
} | |||
], | |||
"include": [] | |||
}, | |||
"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, | |||
"babelSetting": { | |||
"ignore": [], | |||
"disablePlugins": [], | |||
"outputPath": "" | |||
} | |||
}, | |||
"compileType": "miniprogram", | |||
"libVersion": "2.19.4", | |||
"appid": "wx5cf7bb675cf45d28", | |||
"projectname": "weixin-app", | |||
"condition": { | |||
"search": { | |||
"list": [] | |||
}, | |||
"conversation": { | |||
"list": [] | |||
}, | |||
"game": { | |||
"list": [] | |||
}, | |||
"plugin": { | |||
"list": [] | |||
}, | |||
"gamePlugin": { | |||
"list": [] | |||
}, | |||
"miniprogram": { | |||
"list": [] | |||
} | |||
}, | |||
"editorSetting": { | |||
"tabIndent": "insertSpaces", | |||
"tabSize": 4 | |||
} | |||
} |
@@ -0,0 +1,26 @@ | |||
{ | |||
"condition": { | |||
"miniprogram": { | |||
"list": [ | |||
{ | |||
"name": "登录", | |||
"pathName": "pages/login/login", | |||
"query": "", | |||
"scene": null | |||
}, | |||
{ | |||
"name": "任务列表", | |||
"pathName": "package_A/page/alltask/index", | |||
"query": "", | |||
"launchMode": "default", | |||
"scene": null | |||
} | |||
] | |||
} | |||
}, | |||
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", | |||
"projectname": "weixin-app", | |||
"setting": { | |||
"urlCheck": false | |||
} | |||
} |
@@ -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,35 @@ | |||
const { request } = require("../request/index"); | |||
/** | |||
* get | |||
*/ | |||
export const get = function (url, params, showLoading = true) { | |||
return request({ | |||
url: url, | |||
method: "GET", | |||
data: params, | |||
showLoading | |||
}) | |||
} | |||
/** | |||
* post | |||
*/ | |||
export const post = function (url, params, showLoading = true) { | |||
return request({ | |||
url: url, | |||
method: "POST", | |||
data: params, | |||
showLoading | |||
}) | |||
} | |||
/** | |||
* put | |||
*/ | |||
export const put = function (url, params) { | |||
return request({ | |||
url: url, | |||
method: "PUT", | |||
data: params | |||
}) | |||
} |
@@ -0,0 +1,71 @@ | |||
// 任务状态 | |||
export const statusList = { | |||
10: {status: 10, text: '待接单', color: 'rgba(42, 130, 228, 1)'}, | |||
15: {status: 15, text: '已接单', color: 'rgba(6, 138, 58, 1)'}, | |||
20: {status: 20, text: '飞行中', color: 'rgba(255, 141, 26, 1)'}, | |||
25: {status: 25, text: '已完成', color: '#666666'} | |||
} | |||
// 任务详情展示信息 | |||
export const messageList = [ | |||
[ | |||
{label: '任务执行时间', value: "taskStartTime", icon: ""}, | |||
{label: '任务地点', value: "patrolLocation", icon: ""}, | |||
{label: '任务发起人', value: "taskName", icon: ""}, | |||
{label: '租户名称', value: "tenantName", icon: ""}, | |||
{label: '备注', value: "createTime", icon: ""} | |||
], | |||
[ | |||
{label: '任务执行时间', value: "taskStartTime", icon: ""}, | |||
{label: '任务地点', value: "patrolLocation", icon: ""}, | |||
{label: '任务发起人', value: "taskName", icon: ""}, | |||
{label: '租户名称', value: "tenantName", icon: ""}, | |||
{label: '需要直播', value: "isLive", icon: ""}, | |||
{label: '备注', value: "createTime", icon: ""} | |||
] | |||
] | |||
// 表单验证 | |||
export const baseRules = { | |||
equipmentId: { | |||
name: '执飞无人机', | |||
rangeKey: 'label', | |||
value: 'equipmentId', | |||
validator: function (value) { | |||
return value; | |||
}, | |||
placeholder: '请选择执飞无人机', | |||
warning: false | |||
}, | |||
equipmentMountId: { | |||
name: '挂载设备', | |||
rangeKey: 'label', | |||
value: 'equipmentMountId', | |||
validator: function (value) { | |||
return value; | |||
}, | |||
placeholder: '请选择挂载', | |||
warning: false | |||
}, | |||
photographyWay: { | |||
name: '拍摄方式', | |||
rangeKey: 'label', | |||
value: 'photographyWay', | |||
validator: function (value) { | |||
return value; | |||
}, | |||
placeholder: '请选择拍摄方式', | |||
warning: false | |||
} | |||
} | |||
export const orderRules = { | |||
cloudBoxId: { | |||
name: '盒子名称', | |||
rangeKey: 'label', | |||
value: 'cloudBoxId', | |||
validator: function (value) { | |||
return value; | |||
}, | |||
placeholder: '请选择盒子名称', | |||
warning: false | |||
} | |||
} |
@@ -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 | |||
} |