Commit 668c3b91 by iambtr

改成租赁商和站点

parents
const { api, imgName, getUserInfo, wxLogin} =require('./lib/util.js')
App({
onLaunch: function () {
/**
*
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取用户信息
wx.getSetting({
success: res => {
console.log(res)
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
console.log(res)
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
*/
},
globalData: {
authSetting:null,
userInfo: null,
}
})
\ No newline at end of file
{
"pages": [
"pages/welcome2/welcome2",
"pages/pay/pay",
"pages/user_index/user_index",
"pages/user_travel_path/user_travel_path",
"pages/server_point/server_point",
"pages/server_detail/server_detail",
"pages/server/server",
"pages/my/my",
"pages/device_bind/device_bind",
"pages/settting/setting",
"pages/path_detail/path_detail",
"pages/forgetpassword/forgetpassword",
"pages/user_device_message/user_device_message",
"pages/agreement_use/agreement_use",
"pages/user_car_loc/user_car_loc",
"pages/user_message/user_message",
"pages/qr_code/qr_code",
"pages/register2/register2",
"pages/point_detail/point_detail"
],
"window": {
"backgroundTextStyle": "dark",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTitleText": "智租侠",
"navigationBarTextStyle": "black"
},
"networkTimeout": {
"request": 5000
}
}
\ No newline at end of file
page{
min-height: 100%;
box-sizing: border-box;
}
view{
box-sizing: border-box;
font-size: 32rpx
}
button{
color: #ffffff;
}
\ No newline at end of file
// pages/star/star.js
const { imgName } = require('../../lib/util.js')
Component({
/**
* 组件的属性列表
*/
properties: {
score: { // 属性名
type: Number, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: 5, // 属性初始值(可选),如果未指定则会根据类型选择一个
observer: function (newVal, oldVal) {
this.setData({
selfScore: newVal
})
this._setStar()
} // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange'
},
edit:{
type: Boolean, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型)
value: false, // 属性初始值(可选),如果未指定则会根据类型选择一个
}
},
/**
* 组件的初始数据
*/
data: {
selfScore:5,
starList:[
imgName('score2.png'),
imgName('score2.png'),
imgName('score2.png'),
imgName('score2.png'),
imgName('score2.png')
]
},
/**
* 组件的方法列表
*/
methods: {
//点击改变分数的函数
changeScore(e){
// var myEventDetail = {} // detail对象,提供给事件监听函数
// var myEventOption = {} // 触发事件的选项
if(!this.data.edit) return
this.setData(
{
selfScore:Number(e.target.id)+1
}
)
this._setStar()
this.triggerEvent('scoreChange', { socre: this.data.selfScore})
},
_setStar(){
let newVal=this.data.selfScore
let starList = null
if (parseInt(newVal) != newVal) {
starList = this.data.starList.map((item, index) => {
if (index + 1 <= newVal) {
return item
} else {
if (index + 1 == parseInt(newVal) + 1) {
return imgName('score1.png')
} else {
return imgName('score0.png')
}
}
})
} else {
starList = this.data.starList.map((item, index) => {
if (index + 1 <= newVal) {
return imgName('score2.png')
} else {
return imgName('score0.png')
}
})
}
this.setData({
starList,
})
}
}
})
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<!--pages/star/star.wxml-->
<view class='box'>
<block wx:for='{{starList}}' wx:key="unique">
<image src='{{item}}' catchtap='changeScore' id='{{index}}'></image>
</block>
<text>{{selfScore}}分</text>
</view>
\ No newline at end of file
/* pages/star/star.wxss */
.box{
display: flex;
height: 40rpx;
font-size: 34rpx;
align-items: center;
}
image{
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
\ No newline at end of file
const type = 'dev'
// const type = 'pro'
var config = {
dev: {
appid: 'wx2adf345dae23b51b',
appSecret: '73abd12083691a26638f15f412b5030b',
api: 'https://zhizuxia.zhizukj.com/ydb/app/',
rapi: 'http://114.116.54.143:8081/repair/app/',//repair
version: 'v1.0.00',
imgPath: '/static/image/',
key: '3URBZ-FX6KD-H654D-H25M2-YVGJO-UAFXD'
},
pro: {
appid: 'wx2adf345dae23b51b',
appSecret: '73abd12083691a26638f15f412b5030b',
api: 'https://zhizuxia.zhizukj.com/ydb/app/',
rapi: 'http://114.116.54.143:8081/repair/app/',//repair
version: 'v1.0.00',
imgPath: '/static/image/',
key: 'G5DBZ-NH5KD-D3A4F-HK246-D7SJZ-H3BDB'
}
}
module.exports = config[type]
\ No newline at end of file
const StateMachine=require('./state-machine.min.js')
const jsbuffer=require('./jsbuffer.min.js')
const deepcopy = require('./deepcopy.min.js')
/**
* 蓝牙接收类解决多数据包 组包和校验的返回完整数据hex
* iambtr
* option{
* timer:超时时长
* protocolHead:头部
* protocolType:协议编号
* }
*/
class BlueReadBuffer {
constructor(option) {
this.checkTimer = null
this.fsm=null
this.msgType=null
this.hexData=''
this.useData=[]
this.dataLength=null
this.checkSum = new Uint8Array(new ArrayBuffer(2))
this.opt={
timer:5000,
protocolHead: 'ffaa',
protocolType:'fa',
byteLength:47
}
this.init(option)
return this
}
init(option) {
deepcopy(this.opt,option)
this.fsm = new StateMachine({
init: 'HEAD',
transitions: [
{ name: 'head', from: 'HEAD', to: 'TYPE' },
{ name: 'type', from: 'TYPE', to: 'DATA' },
{ name: 'data', from: 'DATA', to: 'CHECK' },
{ name: 'ckeck', from: ['HEAD', 'TYPE', 'DATA', 'CHECK', 'DATA', 'END'], to: 'HEAD' }
]
});
}
reduceProcess(buff, successCallBack, failCallBack) {
//检查超时
this.check_timer(failCallBack);
let jsbuff=new jsbuffer().read(buff)
this.hexData+=jsbuff.hex
for (var i = 0; i < jsbuff.uint8array.length; i++) {
var chr = jsbuff.get[i];
switch (this.fsm.state) {
case 'HEAD':
if (chr == Number(`${this.opt.protocolHead}.slice(0,2)`)) {
this.useData.push(chr)
break
}
if ((chr == Number(`${this.opt.protocolHead}.slice(2)`))&&this.useData.length!=0) {
this.useData.push(chr)
this.fsm.head();
break
}
this.clear()
break
case 'TYPE':
if (this.useData.length==2) {
this.useData.push(chr)
break
}
else if(this.useData.length==3) {
this.useData.push(chr)
this.dataLength=chr
this.fsm.type()
break
}
this.clear()
break
case 'DATA':
if (this.useData.length < this.dataLength+4){
this.useData.push(chr)
if (this.useData.length == this.dataLngth + 4) {
this.fsm.data()
}
break
}
this.clear()
break
case 'CHECK':
if (this.useData.length < this.opt.byteLength) {
this.useData.push(chr)
if (this.useData.length == this.opt.byteLength) {
this.checkSum[0] = this.useData.pop()
this.checkSum[1] = this.useData.pop()
let cSum = new Uint16Array(this.checkSum.buffer)
let sum=this.useData.reduce((pre,cur)=>{
return pre + cur
})
if (cSum == sum) {
successCallBack && successCallBack(this.useData, this.hexData);
} else {
failCallBack && failCallBack('校验位不对')
}
this.clear()
}
}
break
case 'END':
if (this.use_data_cnt < this.use_data_len) {
this.use_data[this.use_data_cnt + 4] = chr;
this.use_data_cnt++;
}
if (this.use_data_cnt == this.use_data_len) {
this.fsm.sum1();
}
break;
}
}
}
clear() {
this.fsm.check()
clearTimeout(this.checkTimer)
this.useData = []
this.msgType = null
this.hexData = ''
this.dataLength = null
this.checkSum = new ArrayBuffer(2)
}
check_timer(failCallBack) {
clearTimeout(this.checkTimer)
this.checkTimer = setTimeout(() => {
this.clear();
failCallBack && failCallBack('帧解析数据超时')
}, this.opt.timer)
}
}
module.exports = BlueReadBuffer
\ No newline at end of file
/**
*create by iambtr
**/
"use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function extend(t,o){if(0==Object.getOwnPropertyNames(o))return t;var r=JSON.parse(JSON.stringify(o));return function t(o,r){for(var n in r)o.hasOwnProperty(n)&&("object"===_typeof(o[n])?o[n].constructor===Array?o[n]=r[n]:t(o[n],r[n]):o[n]=r[n]);return o}(t,r),r=null,t}
\ No newline at end of file
/**
*create by wr
**/
"use strict";var _createClass=function(){function n(t,r){for(var e=0;e<r.length;e++){var n=r[e];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(t,r,e){return r&&n(t.prototype,r),e&&n(t,e),t}}();function _classCallCheck(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}var jsbuffer=function(){function t(){return _classCallCheck(this,t),this.buffer=null,this.hex=null,this.uint8array=null,this}return _createClass(t,[{key:"from",value:function(t,r){var n=this;if(r&&"hex"==r)this.hex=t,this.buffer=new ArrayBuffer(t.length/2),this.uint8array=new Uint8Array(this.buffer),t.match(/.{2}/g).forEach(function(t,r){n.uint8array[r]=Number("0x"+t)});else{var e=t.split("");this.buffer=new ArrayBuffer(e.length),this.uint8array=new Uint8Array(this.buffer),this.hex="",e.forEach(function(t,r){var e=t.charCodeAt(0);e=1==e.toString(16).length?"0"+e.toString(16):e.toString(16),n.hex+=e,n.uint8array[r]=Number("0x"+e)})}return this}},{key:"read",value:function(t){return this.buffer=t,this.uint8array=new Uint8Array(this.buffer),this.setHex(),this}},{key:"set",value:function(t,r){return this.uint8array[t]=r,this.setHex(),this}},{key:"get",value:function(t,r){var e=this.uint8array[t];return r&&/hex/i.test(r)?1==e.toString(16).length?"0"+e.toString(16):e.toString(16):e}},{key:"setHex",value:function(){var r=this;this.hex="",this.uint8array.forEach(function(t){r.hex+=1==t.toString(16).length?"0"+t.toString(16):t.toString(16)})}}]),t}();module.exports=jsbuffer;
\ No newline at end of file
This diff is collapsed. Click to expand it.
!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("StateMachine",[],n):"object"==typeof exports?exports.StateMachine=n():t.StateMachine=n()}(this,function(){return function(t){function n(e){if(i[e])return i[e].exports;var s=i[e]={i:e,l:!1,exports:{}};return t[e].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var i={};return n.m=t,n.c=i,n.i=function(t){return t},n.d=function(t,i,e){n.o(t,i)||Object.defineProperty(t,i,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(i,"a",i),i},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=5)}([function(t,n,i){"use strict";t.exports=function(t,n){var i,e,s;for(i=1;i<arguments.length;i++){e=arguments[i];for(s in e)e.hasOwnProperty(s)&&(t[s]=e[s])}return t}},function(t,n,i){"use strict";var e=i(0);t.exports={build:function(t,n){var i,s,r,o=n.plugins;for(i=0,s=o.length;i<s;i++)r=o[i],r.methods&&e(t,r.methods),r.properties&&Object.defineProperties(t,r.properties)},hook:function(t,n,i){var e,s,r,o,a=t.config.plugins,f=[t.context];for(i&&(f=f.concat(i)),e=0,s=a.length;e<s;e++)o=a[e],(r=a[e][n])&&r.apply(o,f)}}},function(t,n,i){"use strict";function e(t){if(0===t.length)return t;var n,i,e=t.split(/[_-]/);if(1===e.length&&e[0][0].toLowerCase()===e[0][0])return t;for(i=e[0].toLowerCase(),n=1;n<e.length;n++)i=i+e[n].charAt(0).toUpperCase()+e[n].substring(1).toLowerCase();return i}e.prepended=function(t,n){return n=e(n),t+n[0].toUpperCase()+n.substring(1)},t.exports=e},function(t,n,i){"use strict";function e(t,n){t=t||{},this.options=t,this.defaults=n.defaults,this.states=[],this.transitions=[],this.map={},this.lifecycle=this.configureLifecycle(),this.init=this.configureInitTransition(t.init),this.data=this.configureData(t.data),this.methods=this.configureMethods(t.methods),this.map[this.defaults.wildcard]={},this.configureTransitions(t.transitions||[]),this.plugins=this.configurePlugins(t.plugins,n.plugin)}var s=i(0),r=i(2);s(e.prototype,{addState:function(t){this.map[t]||(this.states.push(t),this.addStateLifecycleNames(t),this.map[t]={})},addStateLifecycleNames:function(t){this.lifecycle.onEnter[t]=r.prepended("onEnter",t),this.lifecycle.onLeave[t]=r.prepended("onLeave",t),this.lifecycle.on[t]=r.prepended("on",t)},addTransition:function(t){this.transitions.indexOf(t)<0&&(this.transitions.push(t),this.addTransitionLifecycleNames(t))},addTransitionLifecycleNames:function(t){this.lifecycle.onBefore[t]=r.prepended("onBefore",t),this.lifecycle.onAfter[t]=r.prepended("onAfter",t),this.lifecycle.on[t]=r.prepended("on",t)},mapTransition:function(t){var n=t.name,i=t.from,e=t.to;return this.addState(i),"function"!=typeof e&&this.addState(e),this.addTransition(n),this.map[i][n]=t,t},configureLifecycle:function(){return{onBefore:{transition:"onBeforeTransition"},onAfter:{transition:"onAfterTransition"},onEnter:{state:"onEnterState"},onLeave:{state:"onLeaveState"},on:{transition:"onTransition"}}},configureInitTransition:function(t){return"string"==typeof t?this.mapTransition(s({},this.defaults.init,{to:t,active:!0})):"object"==typeof t?this.mapTransition(s({},this.defaults.init,t,{active:!0})):(this.addState(this.defaults.init.from),this.defaults.init)},configureData:function(t){return"function"==typeof t?t:"object"==typeof t?function(){return t}:function(){return{}}},configureMethods:function(t){return t||{}},configurePlugins:function(t,n){t=t||[];var i,e,s;for(i=0,e=t.length;i<e;i++)s=t[i],"function"==typeof s&&(t[i]=s=s()),s.configure&&s.configure(this);return t},configureTransitions:function(t){var n,i,e,s,r,o=this.defaults.wildcard;for(i=0;i<t.length;i++)for(e=t[i],s=Array.isArray(e.from)?e.from:[e.from||o],r=e.to||o,n=0;n<s.length;n++)this.mapTransition({name:e.name,from:s[n],to:r})},transitionFor:function(t,n){var i=this.defaults.wildcard;return this.map[t][n]||this.map[i][n]},transitionsFor:function(t){var n=this.defaults.wildcard;return Object.keys(this.map[t]).concat(Object.keys(this.map[n]))},allStates:function(){return this.states},allTransitions:function(){return this.transitions}}),t.exports=e},function(t,n,i){function e(t,n){this.context=t,this.config=n,this.state=n.init.from,this.observers=[t]}var s=i(0),r=i(6),o=i(1),a=[null,[]];s(e.prototype,{init:function(t){if(s(this.context,this.config.data.apply(this.context,t)),o.hook(this,"init"),this.config.init.active)return this.fire(this.config.init.name,[])},is:function(t){return Array.isArray(t)?t.indexOf(this.state)>=0:this.state===t},isPending:function(){return this.pending},can:function(t){return!this.isPending()&&!!this.seek(t)},cannot:function(t){return!this.can(t)},allStates:function(){return this.config.allStates()},allTransitions:function(){return this.config.allTransitions()},transitions:function(){return this.config.transitionsFor(this.state)},seek:function(t,n){var i=this.config.defaults.wildcard,e=this.config.transitionFor(this.state,t),s=e&&e.to;return"function"==typeof s?s.apply(this.context,n):s===i?this.state:s},fire:function(t,n){return this.transit(t,this.state,this.seek(t,n),n)},transit:function(t,n,i,e){var s=this.config.lifecycle,r=this.config.options.observeUnchangedState||n!==i;return i?this.isPending()?this.context.onPendingTransition(t,n,i):(this.config.addState(i),this.beginTransit(),e.unshift({transition:t,from:n,to:i,fsm:this.context}),this.observeEvents([this.observersForEvent(s.onBefore.transition),this.observersForEvent(s.onBefore[t]),r?this.observersForEvent(s.onLeave.state):a,r?this.observersForEvent(s.onLeave[n]):a,this.observersForEvent(s.on.transition),r?["doTransit",[this]]:a,r?this.observersForEvent(s.onEnter.state):a,r?this.observersForEvent(s.onEnter[i]):a,r?this.observersForEvent(s.on[i]):a,this.observersForEvent(s.onAfter.transition),this.observersForEvent(s.onAfter[t]),this.observersForEvent(s.on[t])],e)):this.context.onInvalidTransition(t,n,i)},beginTransit:function(){this.pending=!0},endTransit:function(t){return this.pending=!1,t},failTransit:function(t){throw this.pending=!1,t},doTransit:function(t){this.state=t.to},observe:function(t){if(2===t.length){var n={};n[t[0]]=t[1],this.observers.push(n)}else this.observers.push(t[0])},observersForEvent:function(t){for(var n,i=0,e=this.observers.length,s=[];i<e;i++)n=this.observers[i],n[t]&&s.push(n);return[t,s,!0]},observeEvents:function(t,n,i,e){if(0===t.length)return this.endTransit(void 0===e||e);var s=t[0][0],r=t[0][1],a=t[0][2];if(n[0].event=s,s&&a&&s!==i&&o.hook(this,"lifecycle",n),0===r.length)return t.shift(),this.observeEvents(t,n,s,e);var f=r.shift(),c=f[s].apply(f,n);return c&&"function"==typeof c.then?c.then(this.observeEvents.bind(this,t,n,s)).catch(this.failTransit.bind(this)):!1===c?this.endTransit(!1):this.observeEvents(t,n,s,c)},onInvalidTransition:function(t,n,i){throw new r("transition is invalid in current state",t,n,i,this.state)},onPendingTransition:function(t,n,i){throw new r("transition is invalid while previous transition is still in progress",t,n,i,this.state)}}),t.exports=e},function(t,n,i){"use strict";function e(t){return r(this||{},t)}function s(){var t,n;"function"==typeof arguments[0]?(t=arguments[0],n=arguments[1]||{}):(t=function(){this._fsm.apply(this,arguments)},n=arguments[0]||{});var i=new u(n,e);return o(t.prototype,i),t.prototype._fsm.config=i,t}function r(t,n){return o(t,new u(n,e)),t._fsm(),t}function o(t,n){if("object"!=typeof t||Array.isArray(t))throw Error("StateMachine can only be applied to objects");c.build(t,n),Object.defineProperties(t,d),a(t,l),a(t,n.methods),n.allTransitions().forEach(function(n){t[f(n)]=function(){return this._fsm.fire(n,[].slice.call(arguments))}}),t._fsm=function(){this._fsm=new h(this,n),this._fsm.init(arguments)}}var a=i(0),f=i(2),c=i(1),u=i(3),h=i(4),l={is:function(t){return this._fsm.is(t)},can:function(t){return this._fsm.can(t)},cannot:function(t){return this._fsm.cannot(t)},observe:function(){return this._fsm.observe(arguments)},transitions:function(){return this._fsm.transitions()},allTransitions:function(){return this._fsm.allTransitions()},allStates:function(){return this._fsm.allStates()},onInvalidTransition:function(t,n,i){return this._fsm.onInvalidTransition(t,n,i)},onPendingTransition:function(t,n,i){return this._fsm.onPendingTransition(t,n,i)}},d={state:{configurable:!1,enumerable:!0,get:function(){return this._fsm.state},set:function(t){throw Error("use transitions to change state")}}};e.version="3.0.1",e.factory=s,e.apply=r,e.defaults={wildcard:"*",init:{name:"init",from:"none"}},t.exports=e},function(t,n,i){"use strict";t.exports=function(t,n,i,e,s){this.message=t,this.transition=n,this.from=i,this.to=e,this.current=s}}])});
\ No newline at end of file
This diff is collapsed. Click to expand it.
const { api, imgName, getUserInfo } = require('../../lib/util.js')
Page({
data: {
msg: 'agreement_use'
},
onLoad: function () {
console.log('agreement_use')
},
onShow: function () {
console.log('agreement_use show')
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view>
{{msg}}
</view>
\ No newline at end of file
/**index.wxss**/
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 200px;
}
\ No newline at end of file
const { api,alertTip} = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
deviceId:null,
userList:[],
master:false
},
onLoad: function (query) {
this.setData({
deviceId:Number(query.id),
master:Number(query.master)==wx.getStorageSync('user').userId
})
this.getUsers(this.data.deviceId)
},
onPullDownRefresh: function () {
this.getUsers(this.data.deviceId)
},
getUsers(id){
let that=this
api.get('api/vehicle/vehicleBindingUser.json', { userVehicleId:id})
.then(res=>{
console.log(res.items)
that.setData({
userList: res.items.map(item => {
item.mobile = item.mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
return item
})
})
})
.catch(err=>{
console.error(err)
alertTip(err)
})
},
unbindUser(e) {
let that = this
let userId = Number(e.currentTarget.id)
wx.showModal({
title: '警告',
content: '确定解除该用户的绑定?',
success: function (res) {
if (res.confirm) {
api.post('api/vehicle/removeBinding.json', { userVehicleId: that.data.deviceId, removeUserId: userId })
.then(res => {
console.log(res)
that.getUsers(that.data.deviceId)
})
.catch(err => {
alertTip(err)
})
}
}
})
}
})
\ No newline at end of file
{
"enablePullDownRefresh": true,
"navigationBarTitleText": "用户列表"
}
\ No newline at end of file
<view class='con'>
<view wx:for='{{userList}}' class='user-item'>
<view>用户手机号:<text>{{item.mobile}}</text></view>
<view id='{{item.userId}}' catchtap='unbindUser' class='unbind' hidden='{{!master}}'>解绑</view>
</view>
</view>
page {
height: 100%;
background-color: #f7f7f7;
}
.user-item{
background-color: #ffffff;
margin: 20rpx 0;
height: 104rpx;
padding:0 30rpx;
display: flex;
align-items: center;
font-size: 32rpx;
justify-content: space-between;
}
.user-item text{
color: #a5a5a5;
}
.unbind{
width: 162rpx;
height: 56rpx;
color: #000000;
border-radius: 28rpx;
letter-spacing: 8rpx;
line-height: 56rpx;
text-align: center;
background-color: #d7193c;
}
\ No newline at end of file
// pages/device_bind/device_bind.js
const { api, wxscan, rapi, userLocation, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, getProtocol } = require('../../lib/util.js')
let timer=null
Page({
data: {
//img
imgTip: imgName('imgtip.png'),
imgScan:imgName('imgscan.png'),
modelScan:true,
frameNo: null,
userId:null,
rentType:0,//0团租 1个租
status:'normal',//normal 和 pedding
user:null,
agreeUserCar:true,
id:null,//申请id
// 站点地图
markers: [],
longitude: 120.126593,
latitude: 30.342009,
},
onLoad() {
let user = wx.getStorageSync('user')
let { userMapp } = user
if (!user) {
wx.redirectTo({
url: '/pages/welcome2/welcome2',
})
return
}
this.setData({
user,
rentType: userMapp.userType==1 ? 1 : 0,
userId: userMapp.id
})
this.getStatus(this.data.rentType)
},
onHide(){
clearInterval(timer)
},
onUnload(){
clearInterval(timer)
},
onShow() {
//团个租
// this.getStatus(this.data.rentType)
if (this.data.rentType==1){
this.getPointLists()
}
},
scanImg(){
let This =this
if (!This.data.agreeUserCar){
alertTip('请同意租车协议')
return false
}
wxscan()
.then(frameNo=>{
This.setData({
frameNo
})
This.apiUseCar()
})
.catch(err=>{
alertTip(err)
})
},
apiUseCar(){
let This = this
if (!this.data.frameNo) {
alertTip('请输入车辆编码')
return false
}
if (!this.data.agreeUserCar) {
alertTip('请同意租车协议')
return false
}
let { frameNo, userId, rentType}=This.data
api.post('message/requestJoinCar', {
frameNo, userId, rentType
})
.then(res => {
//等待。。
//团租
// if (rentType==0){
alertTip(res.message)
This.getStatus(rentType)
timer = setInterval(() => {
This.getStatus(rentType)
}, 5000)
return
// }
//个租租车逻辑
})
.catch(err => {
alertTip(err)
console.error(err)
})
},
getStatus(userType){
let This=this
let msgType=[2,3]
api.get('message/getMessageInfo',{
userId:This.data.userId,
messageType: msgType[userType]//申请用车
},{},true)
.then(res=>{
let { state ,id } = res.data
if (!This.data.id){
This.setData({
id
})
}
switch(state){
//待审核
case 0:
This.setData({
status: 'pedding',//normal 和 pedding
})
if (!timer){
timer = setInterval(() => {
This.getStatus(userType)
}, 5000)
}
break;
//审核通过去首页
case 1:
wx.redirectTo({
url: '/pages/user_index/user_index',
})
break;
//正常页面
default:
This.setData({
status: 'normal',//normal 和 pedding
})
clearInterval(timer)
}
})
.catch(err=>{
console.error(err)
})
},
backScan(){
this.setData({
modelScan: true
})
},
bindByHand(){
this.setData({
modelScan:false
})
},
deviceInput(e) {
this.setData({
frameNo: e.detail.value
})
},
giveUp() {
//放弃申请
let that = this
wx.showModal({
title: '提示',
content: '是否放弃申请',
success: function (res) {
if (res.confirm) {
let { frameNo, userId, id } = that.data
api.post('message/cancelJoinCar',{
id
}).then(res=>{
that.setData({
status: 'normal',
modelScan: true
})
clearInterval(timer)
}).catch(err=>{
alertTip(err)
})
}
}
})
},
//同意租车协议
hascheck(e){
this.setData({
agreeUserCar: !this.data.agreeUserCar
})
},
//进入租车协议
toProtocol(){
console.log(this.data.rentType)
getProtocol(3)
.then(res => {
console.log(res)
})
.catch(err => {
console.error(err)
alertTip(err.errMsg || err)
})
},
//进入个人页 退押金之类
toMy() {
wx.navigateTo({
url: '/pages/my/my',
})
},
//获取站点列表
getPointLists() {
let curPage =1
let that = this
userLocation()
.then(res => {
let { longitude: lng, latitude: lat } = res
that.setData({
longitude: lng,
latitude: lat,
})
rapi.get('userOrder/getNodeList', {
lng,
lat,
curPage
})
.then(({ items}) => {
let markers=[]
items.map(item => {
let oMarker = { iconPath: '/static/image/pointloc.png', width:25, height:25}
oMarker.latitude = item.nodeLat
oMarker.longitude = item.nodeLng
markers.push(oMarker)
return item
})
console.log(markers)
that.setData({
markers,
})
wx.createMapContext('myMap').includePoints({
padding: [10],
points: markers
})
})
.catch(err => {
console.log(err)
})
})
.catch(err => {
alertTip(err)
})
},
toServerPoint(){
wx.navigateTo({
url: '/pages/server_point/server_point',
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "车辆租赁"
}
\ No newline at end of file
<view class='con' wx:if='{{status=="normal"}}'>
<!--扫描 -->
<map id="myMap" catchtap='toServerPoint' wx:if='{{rentType}}' class='points' show-location longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}'></map>
<view class='con' wx:if='{{modelScan}}'>
<image src='{{imgScan}}' class='img-scan' bindtap='scanImg'></image>
<text class='title scan-title' bindtap='scanImg'>扫码用车</text>
<view class='insurance agree'>
<radio checked='{{agreeUserCar}}' catchtap='hascheck' color='#d7193c'></radio>
我同意智租科技
<text bindtap='toProtocol'> 《租车协议》</text>
</view>
<!-- <map id="myMap" catchtap='toServerPoint' wx:if='{{rentType}}' class='points' show-location longitude='{{longitude}}' latitude='{{latitude}}' markers='{{markers}}'></map> -->
<text class='scan' bindtap='bindByHand'>如果扫描失败,试试手动输入</text>
</view>
<!--手动输入 -->
<view class='con tip' wx:else>
<input placeholder='请输入二维码下方的编码' bindinput='deviceInput'></input>
<view class='insurance agree'>
<radio checked='{{agreeUserCar}}' catchtap='hascheck' color='#d7193c'></radio>
我同意智租科技
<text bindtap='toProtocol'>《租车协议》</text>
</view>
<button bindtap='apiUseCar' class='btn-bind'>开始用车</button>
<text class='scan' bindtap='backScan'>返回扫描添加</text>
</view>
<view class='my' catchtap='toMy'>我的</view>
</view>
<view class='con' wx:else>
<view class='wait-auto'>等待站点同意授权中...</view>
<view class='giveup'>
<text catchtap='giveUp'>放弃申请?</text>
</view>
</view>
\ No newline at end of file
/* pages/device_bind/device_bind.wxss */
page {
height: 100%;
}
.con {
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
height: 100%;
width: 100%;
}
.con.tip{
background-color: #f8f8f8;
width: 100%;
}
.img-scan {
margin-top: 106rpx;
width: 210rpx;
height: 210rpx;
}
.my{
position: absolute;
bottom: 40rpx;
left: 0;
padding: 30rpx 50rpx 30rpx 30rpx;
color: #fff;
background-color: #d7193c;
border-radius: 0 50rpx 50rpx 0;
}
.img-tip {
margin-top: 176rpx;
width: 480rpx;
height: 190rpx;
}
.title {
font-size: 21px;
line-height: 60rpx;
}
.scan-title {
margin-top: 40rpx;
}
.des {
color: #989898;
font-size: 13px;
line-height: 60rpx;
}
.tip-title{
margin-top: 60rpx;
}
.scan {
color: #d7193c;
box-sizing: border-box;
border: 2px solid #d7193c;
height: 64rpx;
margin-top: 50rpx;
padding: 0rpx 26rpx;
border-radius: 32rpx;
line-height: 60rpx;
font-size: 13px;
}
input{
box-sizing: border-box;
width: 100%;
padding: 0 30rpx;
line-height: 110rpx;
height: 110rpx;
background-color: #fff;
font-size: 14px;
margin-top: 12px;
}
.btn-bind{
background-color: #d7193c;
font-size: 17px;
width:695rpx;
height: 90rpx;
border-radius: 90rpx;
letter-spacing: 2px;
margin: 36rpx auto;
display: flex;
align-items: center;
justify-content: center;
}
.wait-auto{
color: #d7193c;
font-size: 50rpx;
margin: 60rpx 0;
}
.giveup{
color: #666666;
font-size: 30rpx;
display: flex;
justify-content: space-between;
padding: 0 80rpx;
}
.insurance {
padding: 20rpx 0;
}
.insurance text {
color: #d7193c;
}
.points{
width: 100%;
height: 400rpx
}
\ No newline at end of file
const { api, alertTip } = require('../../lib/util.js')
var t = {}
Page({
data: {
inputPhone: null,
inputMeg: null,
inputPassword: null,
receiveMsg:'',
inputPasswordAgain: null,
msgLoading: false,
setTimeSec: 60,
limitSec: 60
},
onLoad: function (query) {
},
onShow: function () {
},
numInput(e) {
this.setData({
[e.target.id]: e.detail.value
})
},
getMsg() {
let _this = this
if (!/^1\d{10}/.test(this.data.inputPhone)) {
alertTip('请输入正确的手机号!')
return
}
_this.timer()
//请求验证码api
api.get('user/message', { mobile: Number(this.data.inputPhone) })
.then(res => {
this.setData({
receiveMsg: res.data
})
})
.catch(err => {
alertTip('获取验证码请求失败')
clearInterval(t)
_this.setData({
msgLoading: false
})
})
},
bindPhone() {
let This = this
//绑定手机号
if (This.canBind(true)) {
if (This.data.inputMeg != This.data.receiveMsg) {
alertTip('验证码不正确,修改失败!')
return
}
api.post('user/editPassBymobile', {
mobile: Number(This.data.inputPhone),
newPass: This.data.inputPassword
})
.then(res => {
console.log('成功', res)
wx.showLoading({
title: '修改密码成功',
})
wx.redirectTo({
url: '/pages/welcome2/welcome2',
})
})
.catch(err => {
alertTip(err)
})
}
},
canBind(willTip) {
if (!/^1\d{10}/.test(this.data.inputPhone)) {
willTip && alertTip('请输入正确的手机号!')
return false
}
if (!/\d{4}/i.test(this.data.inputMeg)) {
willTip && alertTip('请输入4位数字的验证码!')
return false
}
if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,}$/.test(this.data.inputPassword)) {
willTip && alertTip('请输入6-12位包含数字和字母的密码!')
return false
}
if (this.data.inputPasswordAgain != this.data.inputPassword) {
willTip && alertTip('两次输入的密码不一样!')
return false
}
return true
},
// 重发验证码定时器
timer: function () {
var count = this.data.setTimeSec
var that = this
that.setData({
limitSec: count,
msgLoading: true
})
clearInterval(t)
t = setInterval(function () {
if (count != 0) {
count--
that.setData({
limitSec: count
})
} else {
clearInterval(t)
that.setData({
limitSec: count,
msgLoading: false
})
}
}, 1000)
}
})
\ No newline at end of file
{
"navigationBarTitleText": "忘记密码"
}
\ No newline at end of file
<view class='con'>
<view class='form-box'>
<view class='phone list'>
<text class='form-tip'>手机号码</text>
<input type='number' id='inputPhone' placeholder='填写手机号码' maxlength='11' bindinput='numInput'></input>
<text class='msg' wx:if='{{!msgLoading}}' bindtap='getMsg'>获取验证码</text>
<text class='msg des' wx:else>{{limitSec}}s</text>
</view>
<view class='phone-sure list'>
<text class='form-tip'>验证码</text>
<input type='number' id='inputMeg' placeholder='输入验证码' maxlength='8' bindinput='numInput'></input>
</view>
<view class='phone-sure list'>
<text class='form-tip'>新密码</text>
<input type='text' id='inputPassword' password placeholder='密码需是6-12字母和数字的组合' bindinput='numInput'></input>
</view>
<view class='phone-sure list'>
<text class='form-tip'>确认密码</text>
<input type='text' id='inputPasswordAgain' password placeholder='请再次输入密码' bindinput='numInput'></input>
</view>
</view>
<button bindtap='bindPhone'>确认</button>
</view>
\ No newline at end of file
@import '../register2/register2.wxss'
\ No newline at end of file
const { api,payApi,alertTip ,imgName } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
imgViplogo: imgName('viplogo.png'),
imgHeadshot: imgName('logo.png'),
imgMore: imgName('more.png'),
imgTip: imgName('tip.png'),
point1:'',
point2: '',
realName:null,
networkingStopTime: '0000-00-00',
networkingHasDay:null,
amount:0,//押金金额
person:1,//个租
vehicleName:null,
userItemList: [{
msg: 0,
name: '我的行程',
icon: imgName('journey.png'),
page: '/pages/user_travel_path/user_travel_path'
}, {
msg: 0,
name: '我的消息',
icon: imgName('message.png'),
page: '/pages/user_message/user_message'
}
// ,{
// msg: 0,
// name: '安防设置',
// icon: imgName('setting.png'),
// page: '/pages/user_setting/user_setting'
// }
, {
msg: 0,
name: '售后服务',
icon: imgName('server.png'),
page: '/pages/server_point/server_point'
}, {
msg: 0,
name: '其他',
icon: imgName('setting2.png'),
page: '/pages/settting/setting'
}]
},
onShow: function () {
let user = wx.getStorageSync('user').userMapp
let device = wx.getStorageSync('device')//可能不存在啊
if (!user) {
wx.redirectTo({
url: '/pages/welcome2/welcome2',
})
return
}
//获取站点
if(!this.data.point1){
api.get('user/getByUserId', { userId: user.id })
.then(({ data }) => {
this.setData({
point1: data.companyName,
point2: data.siteName,
})
})
.catch(err => {
console.error(err)
})
}
//个租
if (this.data.person==1){
this.updateDeposit()
}
this.setData({
realName:user.realName,
amount: user.depositAmount,//押金金额
person: user.userType,//个租
device,
})
//消息数量
// this.getFirstPage()
},
wxDepositRefund() {
// payApi.post('pay/wxRefund', {
// outRefundNo: '20180524194005033000337',
// outTradeNo: '20180524194005033000337'
// })
// .then(res => {
// alertTip('退款成功')
// console.log('退款', res)
// })
// .catch(err => {
// alertTip(err.err_code_des)
// console.error('退款', err)
// })
let that=this
payApi.post('pay/wxDepositRefund')
.then(res => {
alertTip('押金退款请求成功',()=>{
// that.updateDeposit()
wx.reLaunch({
url: '/pages/welcome2/welcome2',
})
})
})
.catch(err => {
alertTip(err.err_code_des || err.return_msg)
console.error('退款', err)
})
},
toDetailPage(e) {
let url = e.currentTarget.id
if(url==='') return
wx.navigateTo({
url: e.currentTarget.id
})
},
loginOut(){
api.get('api/user/logout.json')
.then(res => {
wx.reLaunch({ url: '/pages/welcome2/welcome2' })
})
.catch(err => {
alertTip(err)
})
},
//更新押金信息
updateDeposit(){
let that=this
//个人用户开始租车
let user = wx.getStorageSync('user')
// user.userMapp.depositAmount = 0
// wx.setStorageSync('user', user)
// this.setData({
// amount: 0
// })
setTimeout(()=>{
api.get('user/getByUserId', { userId: user.userMapp.id })
.then(res => {
user.userMapp.depositAmount = res.data.depositAmount
wx.setStorageSync('user', user)
that.setData({
amount: res.data.depositAmount
})
})
.catch(err => {
console.error(err)
})
},2500)
}
})
\ No newline at end of file
{"navigationBarTitleText": "个人中心"}
\ No newline at end of file
<view class='con'>
<view class='header-top'>
<view class='i header'>
<open-data class='image' type="userAvatarUrl"></open-data>
<!-- <image src='{{imgHeadshot}}'></image> -->
<text>{{realName}}</text>
</view>
<view class='top-des' wx:if='{{!person}}'>
<text>租赁商:{{point1}}</text>
<text>站点:{{point2}}</text>
</view>
</view>
<view class='i vip' hidden='{{!person}}'>
<view class='layout'>
<view class='left'>
押金金额:{{amount}}
</view>
<view class='right' catchtap='wxDepositRefund' wx:if='{{amount}}'>
<view>退押金</view>
</view>
</view>
</view>
<view class='i nav-item'>
<view class='layout item' wx:for="{{userItemList}}" wx:key='{{item.name}}' catchtap='toDetailPage' id='{{item.page}}'>
<view class='left'>
<image src='{{item.icon}}'></image>
<view>
<view>{{item.name}}</view>
</view>
</view>
<view class='right'>
<view class='msg-length' wx:if="{{item.msg!='0'}}">{{item.msg}}</view>
<image src='{{imgMore}}'></image>
</view>
</view>
</view>
<!-- <view class='tab' catchtap='loginOut'>
切换账号
</view> -->
</view>
\ No newline at end of file
page {
height: 100%;
}
.con {
height: 100%;
position: relative;
background-color: #f7f7f7;
font-size: 32rpx;
overflow: hidden;
}
.con .i {
background-color: #ffffff;
margin-bottom: 14rpx;
box-sizing: border-box;
padding: 0 28rpx;
}
.con .header {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.con .header .image {
width: 140rpx;
height: 140rpx;
border-radius: 50%;
overflow: hidden;
}
.con .header text {
padding-top: 28rpx;
}
.con .layout {
display: flex;
align-items: center;
justify-content: space-between;
}
.con .layout .left {
display: flex;
align-items: center;
}
.con .layout .left image {
width: 35rpx;
height: 35rpx;
margin-right: 36rpx;
}
.con .layout .right {
display: flex;
justify-content: flex-end;
align-items: center;
}
.con .layout .right image {
width: 22rpx;
height: 34rpx;
margin-left: 34rpx;
}
.con .vip {
height: 140rpx;
background-color: #ffffff;
}
.con .vip .layout {
height: 100%;
}
.con .vip .left .vip-title .des {
position: relative;
color: #999999;
font-size: 30rpx;
line-height: 60rpx;
}
.con .vip .left .vip-title .des .tip {
width: 70rpx;
height: 48rpx;
position: absolute;
top: -50rpx;
right: -36rpx;
}
.con .vip .right view {
width: 166rpx;
height: 64rpx;
line-height: 64rpx;
border-radius: 64rpx;
background-color: #d7193c;
text-align: center;
color: #ffffff;
letter-spacing: 12rpx;
}
.con .nav-item .item {
height: 110rpx;
margin-bottom: 2rpx;
position: relative;
}
.con .nav-item .item::after {
content: '';
width: 665rpx;
position: absolute;
right: -28rpx;
bottom: -2rpx;
border-bottom: 2rpx solid #f7f7f7;
}
.con .nav-item .msg-length {
width: 50rpx;
height: 34rpx;
background-color: #f43333;
font-size: 24rpx;
line-height: 34rpx;
border-radius: 17rpx;
text-align: center;
color: #ffffff;
}
.con .tab {
height: 110rpx;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
background-color: #d7193c;
color: #fff;
line-height: 110rpx;
text-align: center;
}
.header-top{
display: flex;
height: 280rpx;
background-color: #fff;
justify-content: center;
margin-bottom: 20rpx;
align-items: stretch
}
.header{
flex: 0 0 200rpx;
}
.top-des{
display: flex;
flex-direction: column;
align-items:flex-start;
justify-content: center;
margin-bottom: 100rpx;
}
\ No newline at end of file
Component({
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
navList: {
type: Array,
value: [{
id: '1',
title: '标题',
icon: ''
}, {
id: '2',
title: '标题',
icon: ''
}],
}
},
data: {
// 这里是一些组件内部数据
activeId:null
},
attached(){
this.setData({
activeId:this.data.navList[0].id
})
},
methods: {
// 这里是一个自定义方法
_selectItem: function (e) {
if (this.data.activeId === e.target.dataset.act){
return
}
this.setData({
activeId:e.target.dataset.act
})
this.triggerEvent('change', { id: e.target.dataset.act})
}
}
})
\ No newline at end of file
{
"component": true
}
\ No newline at end of file
<!--pages/nav_bar/nav_bar.wxml-->
<view class='nav-box'>
<block wx:for="{{navList}}" wx:key="*this">
<view class='nav-item' bindtap='_selectItem' id='{{item.id}}' data-act='{{item.id}}'>
<image class='img-icon' src='{{item.icon}}' data-act='{{item.id}}'></image>
<text class='nav-title {{item.id==activeId?"active":""}}' data-act='{{item.id}}'>{{item.title}}</text>
</view>
</block>
</view>
/* pages/nav_bar/nav_bar.wxss */
.nav-box{
height: 10%;
display: flex;
justify-content: space-around;
text-align: center;
align-items: stretch;
border-top:2rpx solid #7A7A7A;
position:fixed;
bottom: 0;
left:0;
width: 100%;
background-color: #FAFAFA;
}
.img-icon{
width: 40rpx;
height: 40rpx;
padding: 10rpx 0;
}
.nav-item{
flex-grow: 1;
display: flex;
flex-direction: column;
align-items: center;
}
.nav-title{
font-size: 16px;
color: #353535;
}
.nav-title.active{
color: #1fb922;
}
\ No newline at end of file
const { api, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
polyline:[],
markers:[],
longitude: 120.126593,
latitude: 30.342009,
tripId:null
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (query) {
this.setData({
tripId:query.id
})
this.getTrack()
},
getTrack(){
let that = this
api.get('device/getTrack.json',{
id: this.data.tripId
})
.then(({items})=>{
let polyline = [{ points: [], color: '#d7193cFF', arrowLine: true, width: 3}]
items.map(item=>{
polyline[0].points.push({ latitude: item.lat, longitude: item.lng })
return item
})
this.setData({
polyline,
longitude: items[0].lng,
latitude: items[0].lat,
})
})
.catch(err=>{
console.log(err)
})
}
})
\ No newline at end of file
{"enablePullDownRefresh": true}
\ No newline at end of file
<map longitude='{{longitude}}' latitude='{{latitude}}' polyline='{{polyline}}'></map>
page{
height: 100%
}
map{
height: 100%;
width:100%
}
\ No newline at end of file
// pages/pay/pay.js
const { api, imgName, wxLogin, payApi, alertTip } = require('../../lib/util.js')
Page({
data: {
price:'--',
payType: 'rent',//deposit rent
success:true,//
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let payType=options.type
this.setData({
payType,
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
onPullDownRefresh: function () {
if(this.data.success){
wx.stopPullDownRefresh()
}else{
//重新请求
}
},
payMoney(){
//租金
if (this.data.payType=='rent'){
this.payRent()
}else{
this.payDeposit()
}
},
payDeposit() {
// 原需要 订单号
// wxLogin()
// .then(code=>{
// payApi.get('pay/getOpenId.json',{
// code
// })
// .then(res=>{
// console.log('openid',res)
// let openId = res.openId
// wx.setStorageSync('openid', openId)
// payApi.post('pay/miniAppUnifiedOrder',{
// openId,
// outTradeNo: '20180524194005033000337'
// })
// .then(res => {
// console.log('miniAppUnifiedOrder', res)
// let { timeStamp, nonce_str: nonceStr, signType, prepay_id,paySign } = res
// //统一下单了
// wx.requestPayment({
// timeStamp,
// nonceStr,
// 'package': prepay_id,
// 'signType': 'MD5',
// paySign,
// 'success': function (res) {
// console.log(res)
// },
// 'fail': function (res) {
// console.error(res)
// }
// })
// })
// .catch(err => {
// alertTip(err.err_code_des)
// console.error(err)
// })
// })
// .catch(err=>{
// alertTip(err.remark)
// console.error('openid', err)
// })
// })
// .catch(err=>{
// console.log(err)
// })
wxLogin()
.then(code=>{
payApi.get('pay/getOpenId.json',{
code
})
.then(res=>{
console.log('openid',res)
let openId = res.openId
wx.setStorageSync('openid', openId)
payApi.post('pay/miniAppDepositOrder',{
openId
})
.then(res => {
console.log('miniAppUnifiedOrder', res)
let { timeStamp, nonce_str: nonceStr, signType, prepay_id,paySign } = res
//统一下单了
wx.requestPayment({
timeStamp,
nonceStr,
'package': prepay_id,
'signType': 'MD5',
paySign,
'success': function (res) {
alertTip('押金支付成功,开始租车',function(){
wx.navigateBack()
})
},
'fail': function (res) {
console.error(res)
}
})
})
.catch(err => {
alertTip(err.err_code_des || err.return_msg)
console.error(err)
})
})
.catch(err=>{
alertTip(err.remark)
console.error('openid', err)
})
})
.catch(err=>{
console.error(err)
})
},
payRent() {
// 租金
wxLogin()
.then(code=>{
payApi.get('pay/getOpenId.json',{
code
})
.then(res=>{
let openId = res.openId
wx.setStorageSync('openid', openId)
payApi.post('pay/miniAppUnifiedOrder',{
openId,
outTradeNo: '20180524194005033000337'
})
.then(res => {
console.log('miniAppUnifiedOrder', res)
let { timeStamp, nonce_str: nonceStr, signType, prepay_id,paySign } = res
//统一下单了
wx.requestPayment({
timeStamp,
nonceStr,
'package': prepay_id,
'signType': 'MD5',
paySign,
'success': function (res) {
alertTip('租金支付成功!', function () {
wx.navigateBack()
})
console.log(res)
},
'fail': function (res) {
console.error(res)
}
})
})
.catch(err => {
alertTip(err.err_code_des)
console.error(err)
})
})
.catch(err=>{
alertTip(err.remark)
console.error('openid', err)
})
})
.catch(err=>{
console.log(err)
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "押金支付",
"enablePullDownRefresh": true
}
\ No newline at end of file
<view class='con'>
<view wx:if='{{success}}'>
<view class='item'>
<text>支付类型:</text>
<text class='tip'>{{payType=='deposit'?"押金":"租金"}}</text>
</view>
<view wx:if='{{payType=="deposit"}}'>
<view class='item'>
<text>支付金额:</text>
<text class='tip'>¥{{price}}元</text>
</view>
<view class='item' wx:if='{{payType=="deposit"}}'>
<text>提示:</text>
<text class='tip2 tip'>押金可以在租车结束后退还。</text>
</view>
</view>
<!--租金 -->
<view wx:else>
<view class='item' wx:if='{{payType=="deposit"}}'>
<text>订单:</text>
<text class='tip2 tip'>押金可以在租车结束后退还。</text>
</view>
<view class='item'>
<text>支付金额:</text>
<text class='tip'>¥{{price}}元</text>
</view>
</view>
<!-- <button open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button> -->
<view class='btn'>
<button catchtap='payMoney'>付款</button>
<!-- <button catchtap='returnMoney'>退款</button> -->
</view>
</view>
<view wx:else class='tip'>
网络开小差了,请下拉刷新一下。
</view>
</view>
\ No newline at end of file
/* pages/pay/pay.wxss */
.page{
height: 100%;
flex-direction: column;
}
.con{
padding: 0 40rpx;
}
.tip{
display: flex;
justify-content: center;
align-items: center;
font-size: 40rpx;
color: #d7193c;
}
.item{
display: flex;
align-content: stretch;
height: 80rpx;
align-items: center;
border-bottom: 2rpx solid #eee;
}
.item text:nth-of-type(1){
flex: 0 0 180rpx;
}
.btn{
position: absolute;
bottom: 50rpx;
width: 90%;
}
button{
background-color: #d7193c;
}
.item-body{
display: flex;
height: 100%;
flex-direction: column;
justify-content: space-between
}
.tip2{
font-size: 32rpx;
}
\ No newline at end of file
// pages/point_detail/point_detail.js
const { api, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
pointId: null,
look: false,//false预约服务 true导航查看个租使用
// time: '0:0',//运营时间
locMap: {
latitude: 30.334546,
longitude: 120.121121,
markers: []
},
point:{},//站点
imgToloc: imgName('toloc.png'),
imgLoc: imgName('pointloc.png'),
imgToPoint: imgName('timeline_location.png'),
imgPhone: imgName('security_settings_telephone_active.png'),
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.setData({
look: options.look ? true : false
})
let point=wx.getStorageSync('point')
//获取站点信息
this.data.locMap.longitude=point.nodeLng
this.data.locMap.latitude = point.nodeLat
let pointMaker={
id: point.id,
latitude: point.nodeLat,
longitude: point.nodeLng,
iconPath:'/static/image/pointloc.png',
width:30,
height: 30
}
this.data.locMap.markers.push(pointMaker)
this.setData({
point,
locMap: this.data.locMap
})
},
onUnload: function () {
},
showMyLoc() {
if (!this.mapCtx) {
this.mapCtx = wx.createMapContext('carMap')
}
this.mapCtx.moveToLocation()
},
//站点
toPoint() {
let that = this
wx.openLocation({
latitude: Number(that.data.locMap.latitude),
longitude: Number(that.data.locMap.longitude),
scale: 28
})
},
//拨打电话
callPointPhone(e) {
wx.makePhoneCall({
phoneNumber: e.currentTarget.id
})
},
//需要服务
needServer(){
let hasCar=wx.getStorageSync('user').userMapp.isUseVehicle
if(hasCar){
wx.navigateTo({
url: `/pages/server/server?pointId=${this.data.pointId}`,
})
}else{
alertTip('你当前并没有使用车辆')
}
}
})
\ No newline at end of file
{
"usingComponents": {
"star-score": "/components/star/star"
}
}
\ No newline at end of file
<!--pages/point_detail/point_detail.wxml-->
<view class='con'>
<map id='carMap' scale='13' markers='{{locMap.markers}}' show-location bindmarkertap='markersTap' longitude='{{locMap.longitude}}' latitude='{{locMap.latitude}}'>
<cover-view class='map-controltap'>
<cover-image src='{{imgToPoint}}' catchtap='toPoint'></cover-image>
<cover-image src='{{imgToloc}}' catchtap='showMyLoc'></cover-image>
</cover-view>
</map>
<view class='map-des'>
<view class='point-box'>
<view class='point-left' id='{{point.id}}' catchtap='toPointDetail'>
<text>{{point.nodeName}}</text>
<!-- <star-score score='2.6'></star-score> -->
<view>
<image src='{{imgLoc}}'></image>
<text>{{point.city}}市{{point.area}}区{{point.nodeAddress}}</text>
</view>
</view>
<view class='point-right'>
<text class='tip' id='{{point.id}}' catchtap='toPointDetail'>{{point.distance}} km</text>
<view id='{{point.servicePhone}}' catchtap='callPointPhone'>
<image src='{{imgPhone}}'></image>
<text>拨打电话</text>
</view>
</view>
</view>
<!-- <view class='time'>运营时间:{{time}}</view> -->
<view class='server' hidden='{{look}}' catchtap='needServer'>预约服务</view>
</view>
</view>
\ No newline at end of file
/* pages/point_detail/point_detail.wxss */
page{
height: 100%;
}
.con{
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
}
map{
flex: 1 0 auto;
width: 100%;
}
.map-controltap{
display: flex;
justify-content: space-between;
padding: 0 40rpx;
width: 100%;
position: absolute;
box-sizing: border-box;
bottom: 50rpx;
}
.map-controltap cover-image{
width: 50rpx;
height: 50rpx;
}
.time{
line-height: 80rpx;
font-size: 40rpx;
text-align: center;
}
.server{
line-height: 80rpx;
background-color: #d7193c;
color: #fff;
text-align: center;
}
.tip{
color: #d7193c;
}
.point-box{
display: flex;
justify-content: space-between;
align-items: stretch;
height: 140rpx;
padding: 20rpx 30rpx;
border-bottom: 1px solid #eee;
}
.point-left,.point-right{
display: flex;
flex-direction: column;
justify-content: space-between;
}
.point-left view,.point-right view{
display: flex;
}
.point-right{
align-items: flex-end;
}
.point-right .tip{
font-size: 40rpx;
}
.point-left{
flex:0 0 500rpx;
}
.time{
}
\ No newline at end of file
const qrcode = require('../../lib/qrcode.js')
Page({
/**
* 页面的初始数据
*/
data: {
carCode:''
},
onLoad: function (options) {
let size = this.setCanvasSize();//动态设置画布大小
qrcode.draw(options.vcu, 'qrcCanvas', size.w, size.h);
},
backList(){
wx.navigateBack()
},
//适配不同屏幕大小的canvas
setCanvasSize: function () {
var size = {};
try {
var res = wx.getSystemInfoSync();
var scale = 750 / 500;//不同屏幕下canvas的适配比例;设计稿是750宽
var width = res.windowWidth / scale;
var height = width;//canvas画布为正方形
size.w = width;
size.h = height;
} catch (e) {
// Do something when catch error
console.log("获取设备信息失败" + e);
}
return size;
},
})
\ No newline at end of file
{}
\ No newline at end of file
<canvas class='qrcode' catchtap='backList' canvas-id="qrcCanvas"/>
\ No newline at end of file
/* pages/test/test.wxss */
page{
height: 100%;
}
.qrcode{
width: 500rpx;
height: 500rpx;
position: absolute;
top: 50%;
left: 50%;
margin-top: -250rpx;
margin-left:-250rpx;
background:#f1f1f1;
}
\ No newline at end of file
const { api, alertTip, getProtocol } = require('../../lib/util.js')
var t = {}
Page({
data: {
inputPhone: null,
inputMeg: null,
receiveMsg:null,
inputPassword: null,
inputPasswordAgain: null,
inputName: null,
inputId: null,
msgLoading: false,
idPhoto:'',
// mode:false,//true 'group'
agree: true,
setTimeSec: 60,
limitSec: 60,
phoneNum: null,//输入的号码
// pointIndex:0,
// pointArray: ['厂1', '厂2', '厂23'],
sex:'1',
sexs:[
{ name: '0', value: '女' },
{ name: '1', value: '男', checked: 'true' },
]
},
onLoad: function (query) {
},
onShow: function () {
},
numInput(e) {
this.setData({
[e.target.id]: e.detail.value
})
},
getMsg() {
let inputPhone = this.data.inputPhone
let _this = this
if (!/^1\d{10}/.test(inputPhone)) {
alertTip('请输入正确的手机号!')
return
}
_this.timer()
//请求验证码api
api.get('user/message', { mobile: Number(this.data.inputPhone) })
.then(res => {
this.setData({
receiveMsg:res.data
})
})
.catch(err => {
alertTip('获取验证码请求失败')
clearInterval(t)
_this.setData({
msgLoading: false
})
})
},
hascheck(e) {
console.log(this.data.agree)
this.setData({
agree: !this.data.agree
})
},
toProtocol: function () {
getProtocol(1)
.then(res => {
console.log(res)
})
.catch(err => {
console.error(err)
alertTip(err.errMsg || err)
})
},
bindPhone() {
let This = this
//绑定手机号
if (This.canBind(true)) {
//个租
api.post('user/register', {
mobile: Number(This.data.inputPhone),
password: This.data.inputPassword,
sex: This.data.sex,
mobile: This.data.inputPhone,
idNumber: This.data.inputId,
realName: This.data.inputName,
idImg: This.data.idPhoto
})
.then(res => {
wx.showModal({
title: '提示',
content: res.message,
showCancel: false,
success: function (res) {
if (res.confirm) {
wx.reLaunch({
url: '/pages/welcome2/welcome2',
})
}
}
})
})
.catch(err => {
alertTip(err)
})
}
},
canBind(willTip) {
if (!/^1\d{10}/.test(this.data.inputPhone)) {
willTip && alertTip('请输入正确的手机号!')
return false
}
if (!/\d{4}/i.test(this.data.inputMeg)) {
willTip && alertTip('请输入4位数字的验证码!')
return false
}
if (this.data.inputMeg != this.data.receiveMsg) {
willTip && alertTip('验证码不正确!')
return false
}
if (!this.data.inputName) {
willTip && alertTip('请输入姓名!')
return false
}
if (!this.data.inputId) {
willTip && alertTip('请输入身份证号!')
return false
}
if (!this.data.idPhoto) {
willTip && alertTip('请上传身份证半身照!')
return false
}
if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,}$/.test(this.data.inputPassword)) {
willTip && alertTip('请输入6-12位包含数字和字母的密码!')
return false
}
if (this.data.inputPasswordAgain != this.data.inputPassword) {
willTip && alertTip('两次输入的密码不一样!')
return false
}
if (!/\d{17}/i.test(this.data.inputId)) {
willTip && alertTip('请输入正确的身份证号!')
return false
}
if (!this.data.idPhoto) {
willTip && alertTip('请上传手持身份证半身照!')
return false
}
if (!this.data.agree) {
willTip && alertTip('请同意用户使用协议!')
return false
}
return true
},
// 重发验证码定时器
timer: function () {
var count = this.data.setTimeSec
var that = this
that.setData({
limitSec: count,
msgLoading: true
})
clearInterval(t)
t = setInterval(function () {
if (count != 0) {
count--
that.setData({
limitSec: count
})
} else {
clearInterval(t)
that.setData({
limitSec: count,
msgLoading: false
})
}
}, 1000)
},
//网点模式
beGroup(e){
this.setData({
mode:e.detail.value
})
},
//站点
pointChange(e){
this.setData({
pointIndex: e.detail.value
})
},
radioChange: function (e) {
this.setData({
sex: e.detail.value
})
},
uploadIdPhoto(){
let that = this
wx.chooseImage({
count: 1, // 默认9
sizeType: ['original'], // 可以指定是原图还是压缩图,默认二者都有
success: function (res) {
// 返回选定照片的本地文件路径列表,tempFilePath可以作为img标签的src属性显示图片
let tempFilePath = res.tempFilePaths[0]
console.log(tempFilePath)
wx.showLoading({
title: '上传中。。',
})
wx.uploadFile({
url: 'https://zhizuxia.zhizukj.com/ydb/app/manage/file/upload.json',
filePath: tempFilePath,
name: 'file',
success(res){
that.setData({
idPhoto: JSON.parse(res.data).picUrl
})
console.log(that.data.idPhoto)
},
fail(err){
alertTip('上传失败')
},
complete(res) {
wx.hideLoading()
}
})
}
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "用户注册"
}
\ No newline at end of file
<view class='con'>
<view class='form-box'>
<!-- <view class='mode list agree {{mode?"":"insurance"}}'>
<switch bindchange="beGroup" color='#ffd200'/> 我是团租用户
</view> -->
<view class='phone list'>
<text class='form-tip'>手机号码</text>
<input type='number' id='inputPhone' placeholder='填写手机号码' maxlength='11' bindinput='numInput'></input>
<text class='msg' wx:if='{{!msgLoading}}' bindtap='getMsg'>获取验证码</text>
<text class='msg des' wx:else>{{limitSec}}s</text>
</view>
<view class='phone-sure list'>
<text class='form-tip'>验证码</text>
<input type='number' id='inputMeg' placeholder='输入验证码' maxlength='8' bindinput='numInput'></input>
</view>
<view class='phone-sure list'>
<text class='form-tip'>性别</text>
<radio-group class="radio-group" bindchange="radioChange">
<label class="radio" wx:for="{{sexs}}">
<radio value="{{item.name}}" checked="{{item.checked}}" color='#d7193c'/>{{item.value}}
</label>
</radio-group>
</view>
<view class='phone-sure list'>
<text class='form-tip'>真实姓名</text>
<input id='inputName' placeholder='请输入身份证上姓名' bindinput='numInput'></input>
</view>
<view class='phone-sure list'>
<text class='form-tip'>身份证</text>
<input type='idcard' id='inputId' placeholder='请输入身份证' bindinput='numInput'></input>
</view>
<view class='phone-sure list' catchtap='uploadIdPhoto'>
<text class='form-tip'>半身照</text>
<input wx:if='{{!idPhoto}}' id='idPhoto' disabled placeholder='请上传手持身份证半身照'></input>
<view wx:else>已上传(点击修改)</view>
</view>
<view class='phone-sure list'>
<text class='form-tip'>密码</text>
<input type='text' id='inputPassword' password placeholder='密码需是6-12字母和数字的组合' bindinput='numInput'></input>
</view>
<view class='phone-sure list'>
<text class='form-tip'>确认密码</text>
<input type='text' id='inputPasswordAgain' password placeholder='请再次输入密码' bindinput='numInput'></input>
</view>
<!-- <view wx:if='{{mode}}'>
<view class='phone-sure list'>
<text class='form-tip'>所属站点</text>
<picker class='point' bindchange="pointChange" value="{{pointIndex}}" range="{{pointArray}}">
<view>{{pointArray[pointIndex]}}</view>
</picker>
</view>
</view>-->
</view>
<button bindtap='bindPhone'>注册</button>
<view class='insurance agree'>
<radio checked='{{agree}}' catchtap='hascheck' color='#d7193c'></radio >
我同意智租科技
<text bindtap='toProtocol'> 《用户服务协议》</text>
</view>
</view>
\ No newline at end of file
page{
position: relative;
min-height: 100%;
padding-bottom: 50rpx;
background-color: #f8f8f8;
}
.con {
min-height: 100%;
padding: 14px 30rpx 0;
text-align: left;
}
.con text,.con view{
font-size: 28rpx;
}
.form-box {
width:750rpx;
margin-left: -30rpx;
background-color: #fff;
}
.form-tip{
flex-basis: 220rpx;
flex-shrink: 0;
}
.phone {
width: 100%;
}
.list {
height: 110rpx;
display: flex;
align-items: center;
padding: 0 30rpx;
border-bottom: 2rpx solid #f8f8f8;
}
.list input{
flex-grow: 1;
}
.msg {
color: #ffffff;
background-color: #2f2f2f;
border-radius: 62rpx;
padding: 18rpx 26rpx;
flex: 0 0 auto;
}
.msg.des{
color:#eee;
}
.insurance {
display: flex;
color: #7d7d7d;
}
.agree{
display: flex;
justify-content: center;
align-items: center;
}
.insurance text {
color: #d7193c;
}
.radio{
margin-right:10rpx;
}
button {
background-color: #d7193c;
border-radius: 90rpx;
letter-spacing: 4px;
margin: 36rpx auto;
}
.mode{
justify-content: flex-start;
}
.point{
flex: 1;
}
\ No newline at end of file
const config = require('../../config/index.js')
const { api, rapi, mapApi, mockApi, imgName, getUserInfo, wxLogin, alertTip, wxscan, authAgainByUser, userLocation } = require('../../lib/util.js')
// user point device
let carTimer = null
Page({
/**
* 页面的初始数据
*/
data: {
tab: '',//tab是列表
//详情页数据
username:'',//用户名
userId:'',//用户id
userPhone: '',//手机号
comment:'',
user: null,
time: '',//时间
date: '',//日期
img_arr: [], //上传图片数组
pics:'',//图片线上路径数组
imgScan: imgName('imgscan.png'),
imgClose: imgName('close.png'),
imgLogo: imgName('logo.png'),
showList:[],//我的服务列表
page: 1,//当前页面
hasMorePage: false,//更多页面
},
onShow: function () {
},
//tab切换
tabCarMenu(e) {
let id = e.target.id
if (e.target.id === this.data.tab) return
let tab = this.data.tab === '' ? 'tab' : ''
//服务列表
if (tab == 'tab' && this.data.page == 1){
//当前页是第一页 获取第一页
this.getMyOrderList(1)
}
this.setData({
tab
})
},
onLoad: function () {
let {userMapp}=wx.getStorageSync('user')
let { model } = wx.getStorageSync('device')
this.setData({
username: userMapp.realName,//用户名
userPhone: userMapp.mobile,//手机号
cartype: model,//手机号
userId: userMapp.id
})
},
onUnload() {
wx.setStorageSync('carLists', this.data.carLists)
},
carTypeChange(e) {
},
numInput(e) {
this.setData({
[e.target.id]: e.detail.value
})
},
bindDateChange: function (e) {
this.setData({
date: e.detail.value
})
},
bindTimeChange: function (e) {
this.setData({
time: e.detail.value
})
},
//提交工单
submitServer(){
let { username, userPhone, comment, date, time, userId}=this.data
let { id: nodeId } = wx.getStorageSync('point')
// let { vcuNo, frameNo, model:vehicleModel } = wx.getStorageSync('device')
// 图片
if (!comment){
alertTip('请简单描述下问题')
return false
}
if (!time||!date) {
alertTip('选择预约时间')
return false
}
Promise.all(this.uploadIdPhoto())
.then(res=>{
let pics=res.join(',')||''
let orderTime = date.replace('-', '/') + " " + time + ":00"
rapi.get('userOrder/commitOrder',{
userId,
nodeId,
username,
userPhone,
comment,
vcuNo,
frameNo,
vehicleModel,
pics,
orderTime
})
})
.catch(err=>{
console.log(err)
})
},
//选择图片
upimg: function () {
var that = this;
let hasImgLength = this.data.img_arr.length
if (hasImgLength < 3) {
wx.chooseImage({
count: 3 - hasImgLength, // 默认9
sizeType: ['original', 'compressed'],
success: function (res) {
let img_arr= that.data.img_arr.concat(res.tempFilePaths)
that.setData({
img_arr
})
console.log(img_arr)
}
})
} else {
alertTip('最多上传三张图片')
}
},
//删除图片
deleteImg(e){
let index=Number(e.currentTarget.id)
this.data.img_arr.splice(index,1)
this.setData({
img_arr: this.data.img_arr
})
},
bindTextAreaBlur(e){
let comment=e.detail.value
this.setData({
comment
})
},
//上传图片
uploadIdPhoto() {
let that=this
if (that.data.img_arr.length==0){
return [Promise.resolve()]
}else{
wx.showLoading({
title: '上传图片中',
mask: true,
})
return that.data.img_arr.map(item=>{
return new Promise((resolve,reject)=>{
wx.uploadFile({
url: 'https://zhizuxia.zhizukj.com/ydb/app/manage/file/upload.json',
filePath: item,
name: 'file',
success(res) {
resolve(JSON.parse(res.data).picUrl)
},
fail(err) {
reject('图片上传失败')
},
complete(res) {
wx.hideLoading()
}
})
})
})
}
},
//获取服务工单
getMyOrderList(page){
let curPage = page || this.data.page
let that = this
// rapi.get('userOrder/myOrderList',{
// userId: this.data.userId,
// curPage,
// }).then(res=>{
// console.log(res)
// let listArrays = res.items.map(item => { item.pics = item.pics.split(',')[0]; return item })
// //首页
// if (curPage == 1) {
// this.setData({
// showList: listArrays,
// page: curPage + 1,
// hasMorePage: res.model.haveMore
// })
// } else {
// let newArrays = that.data.pointLists.concat(listArrays)
// this.setData({
// showList: newPoints,
// page: curPage + 1,
// hasMorePage: res.model.haveMore
// })
// }
// }).catch(err=>{
// console.log(err)
// })
mockApi.get('http://result.eolinker.com/t2TvftRd7db394452f6fdee0541724f3fdde187fc6c117d?uri=repair/app/userOrder/myOrderList',{
userId: this.data.userId,
curPage,
}).then(res=>{
console.log(res)
let listArrays = res.items.map(item => {
item.pics = item.pics.split(',')[0]
let stateArray = ['已下单', '已接单', '已完成', '已完成','已取消']
item.state =stateArray[item.state]
item.orderTime = new Date(item.orderTime).toLocaleString()
return item
})
//首页
if (curPage == 1) {
this.setData({
showList: listArrays,
page: curPage + 1,
hasMorePage: res.model.haveMore
})
} else {
let newArrays = that.data.showList.concat(listArrays)
this.setData({
showList: newArrays,
page: curPage + 1,
hasMorePage: res.model.haveMore
})
}
}).catch(err=>{
console.log(err)
})
},
//获取服务详情
toServerDetail(e){
let serverId=e.currentTarget.id
wx.navigateTo({
url: `/pages/server_detail/server_detail?id=${serverId}`,
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "预约服务"
}
\ No newline at end of file
<!--pages/user_index/user_index.wxml-->
<view class='con'>
<view class='tab-header'>
<view class='main' catchtap='tabCarMenu'>
<view class='item {{tab===""? "active":""}}'>提交工单</view>
<view class='item {{tab==="tab"? "active":""}}' id='tab'>我的服务</view>
</view>
</view>
<view class='body-box {{tab}}'>
<view class='tab-map'>
<view>
<view class='phone list'>
<text>报修人:</text>
<input class='input-text' id='username' value='{{username}}' placeholder='请输入报修人姓名' bindinput='numInput'></input>
</view>
<view class='phone list'>
<text>联系电话:</text>
<input class='input-text' id='userPhone' value='{{userPhone}}' placeholder='请输入联系电话' bindinput='numInput'></input>
</view>
<view class='problem list'>
<text>问题描述:</text>
<textarea bindblur="bindTextAreaBlur" placeholder="请输入问题原因" />
</view>
<view class='phone list'>
<text>预约时间:</text>
<picker class='input-text point' mode="date" value="{{date}}" bindchange="bindDateChange">
<view>{{date?date:'选择日期'}}</view>
</picker>
<picker class='input-text point' mode="time" value="{{time}}" start="08:00" end="18:00" bindchange="bindTimeChange">
<view>{{time?time:'选择时间'}}</view>
</picker>
</view>
<view class='phone list'>
<text>上传图片:</text>
<view class='input-text' bindinput='numInput'>
<view class="big-logos">
<block wx:for="{{img_arr}}" wx:key="unique">
<view class='logoinfo'>
<image class='close' id='{{index}}' src='{{imgClose}}' catchtap='deleteImg'></image>
<image src='{{item}}'></image>
</view>
</block>
<image bindtap="upimg" src='{{imgScan}}'></image>
</view>
</view>
</view>
</view>
<view class='option'>
<button catchtap='submitServer'>预约</button>
</view>
</view>
<view class='tab-detail'>
<scroll-view scroll-y class='device-list'>
<view wx:if='{{showList.length!=0}}'>
<view class='list-item' wx:for='{{showList}}' wx:key='{{item.id}}' id='{{item.id}}' catchtap='toServerDetail'>
<image src='{{item.pics||imgLogo}}'></image>
<view class='item-des item-text'>
<text>{{item.frameNo}}</text>
<text class='low-text'>{{item.vehicleModel}}</text>
</view>
<view class='item-state item-text'>
<text class='tip2'>{{item.state}}</text>
<text class='low-text'>{{item.orderTime}}</text>
</view>
</view>
<view class='btn' wx:if='{{hasMorePage}}'>
<button catchtap='getMyOrderList'>加载更多</button>
</view>
</view>
<view wx:else class='no-list'>
<text class='tip2'>不存在任何工单</text>
</view>
</scroll-view>
</view>
</view>
</view>
\ No newline at end of file
page {
height: 100%;
overflow: hidden;
}
page .con {
height: 100%;
overflow: hidden;
position: relative;
}
page .con .tab-header {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: stretch;
padding: 28rpx 28rpx 0 28rpx;
height: 103rpx;
color: #686868;
border-bottom: 2rpx solid #e9e9e9;
}
page .con .tab-header .person {
height: 100%;
width: 42rpx;
}
page .con .tab-header .main {
height: 100%;
flex: 1;
display: flex;
justify-content: space-between;
position: relative;
transform: translateY(2rpx);
}
page .con .tab-header .main .item {
font-size: 32rpx;
text-align: center;
flex: 1 0 auto;
border-bottom: 6rpx solid transparent;
}
page .con .tab-header .item.active {
color: #d7193c;
border-bottom-color: #d7193c;
}
page .con .body-box {
height: 1111rpx;
width: 200%;
box-sizing: border-box;
transform: translateX(0);
transition: all 0.2s;
display: flex;
}
page .con .body-box .tab-map {
width: 50%;
display: flex;
flex-direction: column;
/* justify-content: space-between; */
}
page .con .body-box .tab-detail {
width: 50%;
height: 100%;
box-sizing: border-box;
/* padding: 0 40rpx 50rpx; */
}
page .con .tab {
transform: translateX(-50%);
}
.phone {
width: 100%;
}
.list {
height: 110rpx;
display: flex;
align-items: center;
padding: 0 30rpx;
border-bottom: 2rpx solid #f8f8f8;
}
.list image{
width: 50rpx;
height: 50rpx;
}
.list text{
flex-basis: 160rpx;
flex-shrink: 0;
}
.list .input-text{
flex: 1;
}
.insurance{
color: #d7193c;
}
.option{
display: flex;
margin-top: 50rpx;
}
.option button{
background-color: #d7193c;
font-size: 32rpx;
flex-basis:500rpx;
color: #fff;
}
.list-title,.list-tr{
display: flex;
padding: 20rpx 30rpx;
width: 1310rpx;
border-bottom: 2px solid #f8f8f8;
align-items: center;
}
.list-title text,.list-tr .list-td{
flex:0 0 250rpx;
text-align: center;
word-break: break-all;
}
.list-tr{
border-bottom: 1px solid #f8f8f8;
}
.option2{
display: flex;
flex-direction: column;
}
.option2 text{
padding: 10rpx 20rpx;
background-color: #d7193c;
border-radius:10rpx;
}
.option2 text:nth-of-type(1){
margin-bottom: 20rpx;
}
.submit-sys{
position: fixed;
background-color: rgba(214, 25, 59, 0.7);
left: 50%;
bottom: 100rpx;
padding: 30rpx 50rpx 30rpx 10rpx;
border-top-right-radius: 46rpx;
border-bottom-right-radius: 46rpx;
}
.device-list{
width: 100%;
height: 100%;
overflow: scroll;
}
.fresh-car{
padding: 10rpx 20rpx;
background-color: #d7193c;
border-radius:10rpx;
text-align: center;
color: #fff;
}
button,.option2,.submit-sys{
color: #fff;
}
.big-logos{
display: flex;
}
.big-logos image{
width: 100rpx;
height: 100rpx;
margin-right:20rpx;
}
.logoinfo{
position: relative;
}
.big-logos image.close{
position: absolute;
top: 0;
right: 0;
width:50rpx;
height: 50rpx;
}
.problem textarea{
height: 100rpx;
}
.problem text{
align-self: flex-start;
}
.list-item{
padding: 30rpx;
border-bottom:2rpx solid #eeeeee;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
}
.list-item image{
flex: 0 0 auto;
width: 80rpx;
height: 80rpx;
margin-right: 30rpx;
}
.item-text{
display: flex;
flex-direction: column;
justify-content: space-around;
align-self: stretch;
}
.item-state{
align-items: flex-end;
flex: 0 0 300rpx;
flex-wrap: wrap;
text-align: right;
white-space: pre-wrap;
}
.low-text{
color: #cccccc;
}
.tip2{
color: #d7193c;
}
.no-list{
padding: 50rpx;
text-align: center;
}
.btn{
padding: 30rpx;
}
.btn button{
background-color: #d7193c;
}
\ No newline at end of file
// pages/server_detail/server_detail.js.
const { api, rapi, mapApi, mockApi, imgName, alertTip } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
imgLogo: imgName('logo.png'),
order:{},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let id = options.id
console.log(id)
this.getMyOrderDetail(id)
},
onShow: function () {
},
getMyOrderDetail(id){
rapi.get('userOrder/myOrderDetail', {
id
}).then(res => {
let order = res.data
let stateArray = ['已下单', '已接单', '已完成', '已完成', '已取消']
order.state = stateArray[order.state]
order.pics = order.pics.split(',')
order.orderTime = new Date(order.orderTime).toLocaleString() || ''
order.receiveTime = new Date(order.receiveTime).toLocaleString() || ''
order.completeTime = new Date(order.completeTime).toLocaleString() || ''
this.setData({
order: res.data
})
}).catch(err => {
console.log(err)
})
},
// 预览问题图片
lookPic(e) {
let src = e.currentTarget.dataset.src;//获取data-src
let imgList = e.currentTarget.dataset.list;//获取data-list
//图片预览
wx.previewImage({
current: src, // 当前显示图片的http链接
urls: imgList // 需要预览的图片http链接列表
})
},
//取消订单
cancleOrder(){
rapi.get('userOrder/cancleOrder', {
userId: wx.getStorageSync('user').userMapp.id,
id:this.data.order.id
}).then(res => {
alertTip(res)
this.getMyOrderDetail(this.data.order.id)
}).catch(err => {
alertTip(err)
})
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view class='con'>
<view class='item'>
<view class='item-title'>订单编号:</view>
<view class='item-body'>{{order.orderNo}}</view>
</view>
<view class='item'>
<view class='item-title'>订单状态:</view>
<view class='item-body tip'>{{order.state}}</view>
</view>
<view class='item'>
<view class='item-title'>服务站点:</view>
<view class='item-body'>{{order.nodeName}}</view>
</view>
<view class='item'>
<view class='item-title'>车型名称:</view>
<view class='item-body'>{{order.vehicleModel}}</view>
</view>
<view class='item'>
<view class='item-title'>车架号:</view>
<view class='item-body'>{{order.frameNo}}</view>
</view>
<view class='item'>
<view class='item-title'>中控号:</view>
<view class='item-body'>{{order.vcuNo}}</view>
</view>
<view class='item'>
<view class='item-title'>保修人:</view>
<view class='item-body'>{{order.userName}}</view>
</view>
<view class='item'>
<view class='item-title'>手机号:</view>
<view class='item-body'>{{order.userPhone}}</view>
</view>
<view class='item'>
<view class='item-title'>预约时间:</view>
<view class='item-body'>{{order.orderTime}}</view>
</view>
<view class='item' wx:if='{{order.state=="已完成"||order.state=="已接单"}}'>
<view class='item-title'>接单时间:</view>
<view class='item-body'>{{order.receiveTime}}</view>
</view>
<view class='item' wx:if='{{order.state=="已完成"}}'>
<view class='item-title'>完成时间:</view>
<view class='item-body'>{{order.completeTime}}</view>
</view>
<view class='item'>
<view class='item-title'>问题描述:</view>
<view class='item-body'>{{order.comment}}</view>
</view>
<view class='item'>
<view class='item-title'>服务描述:</view>
<view class='item-body'>{{order.repairComment||"没有描述"}}</view>
</view>
<view class='item'>
<view class='item-title'>图片:</view>
<view class='item-body img'>
<image wx:for='{{order.pics}}' data-src="{{item}}" data-list="{{order.pics}}" srcwx:key='{{item}}' src='{{item}}' catchtap='lookPic'></image>
</view>
</view>
<view class='item' wx:if='{{order.state=="已完成"}}'>
<view class='item-title'>收费:</view>
<view class='item-body'>
<view>总工时:{{order.manHoursFee}}小时</view>
<view>总费用:<text class='tip'>¥{{order.price}}</text>元</view>
</view>
</view>
<view class='item' wx:if='{{order.state=="已完成"}}'>
<view class='item-title'>计价细目:</view>
<view class='item-body'>
<view class='item' wx:for='{{order.itemList}}' wx:key='{{item.id}}'>
<view class='min-title'>{{item.itemName}}</view>
<view class='item-body'>
<view>工时:¥{{item.manHours}}小时</view>
<view>小计:<text class='tip'>¥{{item.materialFee}}</text>元</view>
</view>
</view>
</view>
</view>
<view class='btn' wx:if='{{order.state!="已完成"}}'>
<button catchtap='cancleOrder'>取消工单</button>
</view>
</view>
\ No newline at end of file
/* pages/server_detail/server_detail.wxss */
.con{
overflow: hidden;
}
.btn{
padding: 30rpx;
}
.btn button{
background-color: #d7193c;
}
.item{
padding: 30rpx;
display: flex;
border-bottom: 1px solid #eee;
}
.item-title{
flex: 0 0 150rpx;
text-align: right
}
.item-body{
flex: 0 0 550rpx;
flex-wrap: wrap;
padding-left: 40rpx;
}
.img image{
width: 60px;
height: 60px;
}
.tip{
color: #d7193c;
}
.min-title{
flex: 0 0 180rpx;
}
\ No newline at end of file
// pages/server_point/server_point.js
const { api, rapi,imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
first:true,
imgLoc: imgName('pointloc.png'),
imgPhone: imgName('security_settings_telephone_active.png'),
page: 1,//当前页面
hasMorePage: false,//更多页面
pointLists:[]//站点列表
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getPointLists(1)
},
//获取站点列表
getPointLists(page){
let curPage = page || this.data.page
let that=this
userLocation()
.then(res=>{
let { longitude:lng, latitude:lat}=res
rapi.get('userOrder/getNodeList', {
lng,
lat,
curPage
})
.then(res => {
let listArrays = res.items.map(item => { item.distance=item.distance.toFixed(1); return item})
//首页
if (curPage==1){
this.setData({
pointLists:listArrays,
page: curPage + 1,
hasMorePage:res.model.haveMore
})
}else{
let newPoints = that.data.pointLists.concat(listArrays)
this.setData({
pointLists: newPoints,
page: curPage+1,
hasMorePage: res.model.haveMore
})
}
})
.catch(err => {
console.log(err)
})
})
.catch(err=>{
alertTip('你拒绝了地理定位,请打开后重试')
wx.navigateBack()
})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
onReachBottom: function () {
console.log('到底了')
},
//分数改变
scoreChange(e){
console.log(e.detail)
},
//拨打电话
callPointPhone(e){
wx.makePhoneCall({
phoneNumber: e.currentTarget.id
})
},
//显示站点详细信息
toPointDetail(e){
let pointId=e.currentTarget.id
let index=e.currentTarget.dataset.index
wx.setStorageSync('point', this.data.pointLists[index])
//站点详情&look=false
wx.navigateTo({
url: `/pages/point_detail/point_detail`,
})
}
})
\ No newline at end of file
{
"navigationBarTitleText": "售后站点",
"usingComponents": {
"star-score": "/components/star/star"
}
}
\ No newline at end of file
<view class='con'>
<scroll-view class='item-body' scroll-y>
<view class='point-item' wx:for='{{pointLists}}' wx:key="{{item.id}}">
<view class='tip' wx:if='{{index==0}}'>距你最近的服务商:</view>
<view class='point-box'>
<view class='point-left' id='{{item.id}}' data-index='{{index}}' catchtap='toPointDetail'>
<text>{{item.nodeName}}</text>
<!-- <star-score score='2.6'></star-score> -->
<view>
<image src='{{imgLoc}}'></image>
<text>{{item.city}}市{{item.area}}区{{item.nodeAddress}}</text>
</view>
</view>
<view class='point-right'>
<text class='tip' id='{{item.id}}' data-index='{{index}}' catchtap='toPointDetail'>{{item.distance}} km</text>
<view id='{{item.servicePhone}}' catchtap='callPointPhone'>
<image src='{{imgPhone}}'></image>
<text>拨打电话</text>
</view>
</view>
</view>
</view>
<view class='btn' wx:if='{{hasMorePage}}'>
<button catchtap='getPointLists'>加载更多</button>
</view>
</scroll-view>
</view>
\ No newline at end of file
/* pages/server_point/server_point.wxss */
page{
font-size: 28rpx;
color: #000;
height: 100%;
}
.con{
height: 100%;
}
.item-body{
height: 100%;
overflow: hidden;
}
.tip{
padding: 20rpx 0;
}
.tip{
color: #d7193c;
}
.point-item{
padding: 20rpx;
border-bottom: 1px solid #eee;
}
.point-box{
display: flex;
justify-content: space-between;
align-items: stretch;
height: 130rpx;
}
.point-left,.point-right{
display: flex;
flex-direction: column;
justify-content: space-between;
}
.point-left view,.point-right view{
display: flex;
}
.point-right{
align-items: flex-end;
}
.point-right .tip{
font-size: 40rpx;
}
.point-left{
flex:0 0 500rpx;
}
.btn{
padding: 30rpx;
}
.btn button{
background-color: #d7193c;
}
\ No newline at end of file
const { api, alertTip, imgName, getProtocol } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
imgMore: imgName('more.png'),
protocols: ['用车协议', '押金协议', '租车协议', '用户服务协议', '保险协议','智租协议'],
others: ['官网', '微信公众号', '微信公众号', '微信公众号']
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
readProtocol(e){
let id=e.currentTarget.id
console.log(id)
getProtocol(id)
.then(res=>{
console.log(res)
})
.catch(err=>{
console.error(err)
alertTip(err.errMsg||err)
})
},
loginOut(){
wx.redirectTo({
url: '/pages/welcome2/welcome2',
})
},
//详情页面
toDetail(){
let id = e.currentTarget.id
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view class='con'>
<scroll-view class='scro' scroll-y>
<view class='i nav-item'>
<view class='layout'>
<view class='left sub-title'>
用户协议
</view>
</view>
<view class='layout item' wx:for='{{protocols}}' wx:key='{{index}}' id='{{index+1}}' catchtap='readProtocol'>
<view class='left'>
{{item}}
</view>
<view class='right'>
<image src='{{imgMore}}'></image>
</view>
</view>
</view>
<view class='i nav-item'>
<view class='layout'>
<view class='left sub-title'>
关于
</view>
</view>
<view class='layout item' wx:for='{{others}}' wx:key='{{index}}' id='{{index+1}}' catchtap='toDetail'>
<view class='left'>
{{item}}
</view>
<view class='right'>
<image src='{{imgMore}}'></image>
</view>
</view>
</view>
</scroll-view>
<view class='bom' catchtap='loginOut'>
退出登录
</view>
</view>
\ No newline at end of file
@import '../my/my.wxss'
.con{
height: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
}
.bom{
background-color:#d7193c;
color:#fff;
line-height:110rpx;
text-align:center;
}
.scro{
height: 500rpx;
flex: 1 0 110rpx;
}
.tab{
flex: 0 0 110rpx,
}
.nav-item{
margin-top: 30rpx;
}
.sub-title{
font-size: 36rpx;
font-weight: bold;
line-height: 80rpx;
}
.item .left{
padding-left: 80rpx;
}
\ No newline at end of file
const { api, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
data: {
imgCheckOff: imgName('security_settings_unchecked.png'),
imgCheckOn: imgName('security_settings_unchecked_active.png'),
ignorealarmtimelen:0,
remindtimelength:0,
alarmSettings: [
{
id:0,
name: '无'
}, {
id:1,
name: '1分钟'
}, {
id:2,
name: '2分钟'
}, {
id:3,
name: '3分钟'
}, {
id: 4,
name: '4分钟'
}, {
id: 5,
name: '5分钟'
}],
/** alarmTimeSettings: [
{
id: 1,
name: '1分钟'
},
{
id: 3,
name: '3分钟'
},
{
id: 5,
name: '5分钟'
},
{
id: 10,
name: '10分钟'
},
{
id: 0,
name: '持续直到我处理报警提醒'
}
]*/
},
onLoad: function () {
},
onShow: function () {
this.getAlarmSetting()
},
getAlarmSetting() {
let that = this
api.post('api/user/userConfigInfo.json')
.then(res => {
let datamodel = res.data
that.setData({
ignorealarmtimelen: datamodel.ignorealarmtimelen,
remindtimelength: datamodel.remindtimelength
})
})
.catch(err => {
alertTip(err)
})
},
setSecure(e){
let that = this
let t = e.currentTarget
let data={}
data[t.dataset.type] = t.id
api.post('api/user/updateUserConfig.json', Object.assign({},data, { userid: wx.getStorageSync('user').userId }))
.then(res => {
that.getAlarmSetting()
})
.catch(err => {
alertTip(err)
})
}
})
\ No newline at end of file
<view class='con'>
<view class='set-box'>
<view class='setting-title'>
<view class='mode-title'>
<text>忽略相同类型提醒</text>
<view class='bar'></view>
</view>
<view class='mode-des'>收到车辆报警并选择忽略,一定时间内相同类型提醒不再提示。</view>
</view>
<view class='box-memu'>
<block wx:for='{{alarmSettings}}'>
<view class='box-item' id='{{item.id}}' data-type='ignorealarmtimelen' catchtap='setSecure'>
<text>{{item.name}}</text>
<view>
<image src='{{item.id==ignorealarmtimelen?imgCheckOn:imgCheckOff}}'></image>
</view>
</view>
</block>
</view>
</view>
</view>
\ No newline at end of file
page{
background-color: #f7f7f7;
}
.con{
border-top: 1px solid #ebebeb;
}
.set-box{
background-color: #ffffff;
}
.setting-title{
padding-left:50rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
height: 124rpx;
border-bottom: 1px solid #ebebeb;
}
.mode-title{
font-size: 34rpx;
line-height: 34rpx;
margin-bottom: 14rpx;
position: relative;
}
.bar{
position: absolute;
border-left: 3px solid #d7193c;
height: 34rpx;
top:0;
left: -23rpx;
}
.mode-des{
font-size: 22rpx;
line-height: 22rpx;
color: #afafaf;
}
.box-memu{
padding-left:50rpx;
}
.box-item{
border-bottom: 1px solid #ebebeb;
padding-right: 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
height: 82rpx;
font-size: 32rpx;
}
.box-item image{
width: 44rpx;
height: 44rpx;
}
.box-item:last-child{
border-bottom: none;
}
const { api, mapApi, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
/**
* 页面的初始数据
*/
data: {
imgPerson: imgName('logo.png')
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
\ No newline at end of file
{}
\ No newline at end of file
<view>
<view class='set-box'>
<view class='logo'>
<image src='{{imgPerson}}'></image>
<view>
<text>188****8888{{userPhone}}</text>
<text class='low-des'>有效期:2019-05-30</text>
</view>
</view>
</view>
<view class='set-box'>
<view class='setting-title'>
<text class='bar'></text>
<text class='title'>服务费续期</text>
</view>
<view class='setting-item'>
<view class='box-item' data-remindermode='1'>
<view class='text-mode'>
1年
<text class='mode-main'>25</text> 元
</view>
<text class='buy-server'>续费</text>
</view>
<view class='box-item' data-remindermode='3'>
<view class='text-mode'>
2年
<text class='mode-main'>96</text> 元
</view>
<text class='buy-server'>续费</text>
</view>
</view>
</view>
<view class='set-box'>
<view class='setting-title'>
<text class='bar'></text>
<text class='title'>超级VIP</text>
<text class='title-des'>服务费-保险</text>
</view>
<view class='setting-item'>
<view class='box-item' data-remindermode='1'>
<view class='text-mode'>
1年
<text class='mode-main'>25</text> 元
</view>
<text class='buy-server'>续费</text>
</view>
<view class='box-item' data-remindermode='3'>
<view class='text-mode'>
2年
<text class='mode-main'>96</text> 元
</view>
<text class='buy-server'>续费</text>
</view>
</view>
</view>
</view>
\ No newline at end of file
page{
background-color: #f7f7f7;
border-top: 1px solid #ebebeb;
}
.set-box{
background-color: #ffffff;
margin-bottom: 14px;
}
.setting-title{
display: flex;
align-items: center;
height: 90rpx;
box-sizing: border-box;
font-size: 34rpx;
border-bottom: 1px solid #ebebeb;
}
.setting-title .bar{
display: inline-block;
height:34rpx;
border-left: 3px solid #d7193c;
margin: 0 26rpx 0 30rpx;
flex: 0 0 auto;
}
.setting-title .title{
flex: 0 0 auto;
}
.setting-item{
padding-left: 50rpx;
}
.box-item{
display: flex;
box-sizing: border-box;
align-items: center;
font-size: 28rpx;
padding: 20rpx 40rpx 20rpx 0;
border-bottom: 1px solid #ebebeb;
justify-content: space-between;
}
.setting-item .box-item:last-child{
border-bottom: none;
}
.more image:nth-of-type(1){
margin-right: 0;
}
.box-item image:nth-of-type(1).more-img{
width: 16rpx;
height: 30rpx;
}
.text-mode{
width: 468rpx;
font-size: 28rpx;
}
.mode-main{
font-size: 28rpx;
color: #f43333;
padding-bottom: 12rpx;
}
.buy-server{
padding: 14rpx 44rpx;
background-color: #d7193c;
color: #ffffff;
border-radius: 28rpx;
letter-spacing: 4px;
}
.title-des{
font-size: 28rpx;
color: #999999;
margin: 4rpx 0 0 7px;
}
.logo{
padding: 34rpx 28rpx;
display: flex;
align-items: center;
}
.logo image{
width: 112rpx;
height: 112rpx;
border-radius: 50%;
margin-right: 28rpx;
}
.logo text{
font-size: 36rpx;
}
text.low-des{
font-size: 26rpx;
color: #adadad;
margin-top: 18rpx;
}
.logo view{
display: flex;
flex-direction: column;
}
\ No newline at end of file
const { api, mapApi, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
data: {
markers:[],
longitude:0,
latitude: 0,
controls:[],
imgLogo: imgName('logo.png'),
imgToLoc: imgName('toloc.png'),
title: '展示车:震动报警',
time:'2018-05-09 18:08:44',
},
onLoad(){
this.mapCtx = wx.createMapContext('myMap')
let carLoc=wx.getStorageSync('carLocAlarm')
this.setData({
longitude: Number(carLoc.longitude),
latitude: Number(carLoc.latitude),
markers:[{
latitude: Number(carLoc.latitude),
longitude: Number(carLoc.longitude),
iconPath: imgName('loc.png'),
width:40,
height:46
}],
title: carLoc.content,
time: carLoc.msgTime
})
},
focusCar(e){
this.mapCtx.moveToLocation()
},
findCar(){
let that=this
wx.openLocation({
latitude: Number(that.data.latitude),
longitude: Number(that.data.longitude),
scale: 28
})
},
onUnload(){
wx.removeStorageSync('carLocAlarm')
}
})
\ No newline at end of file
{}
\ No newline at end of file
<map id="myMap" show-location scale='13' markers='{{markers}}' longitude='{{longitude}}' latitude='{{latitude}}'>
<cover-view class='des'>
<cover-image class='img-des' src='{{imgLogo}}'></cover-image>
<cover-view class='bar'></cover-view>
<cover-view class='content'>
<cover-view>{{title}}</cover-view>
<cover-view class='time'>{{time}}</cover-view>
</cover-view>
<cover-view class='toloc' catchtap='findCar'>导航</cover-view>
</cover-view>
<cover-image src='{{imgToLoc}}' class='loc' catchtap='focusCar'></cover-image>
</map>
\ No newline at end of file
page {
height: 100%;
}
map {
height: 100%;
width: 100%;
position: relative;
}
.des {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 86rpx;
display: flex;
align-items: center;
background-color: #fff;
padding: 27rpx 0;
}
.img-des {
width: 86rpx;
height: 86rpx;
margin: 0 26rpx;
}
.content {
padding: 0 28rpx;
height: 86rpx;
font-size: 32rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
flex: 1 0 auto;
}
.bar {
height: 86rpx;
width: 2px;
background-color: #dfdfdf;
}
.time {
font-size: 28rpx;
color: #a8a8a8;
}
.loc {
width: 80rpx;
height: 80rpx;
position: absolute;
right: 30rpx;
bottom: 168rpx;
}
.toloc {
line-height: 36rpx;
font-size: 32rpx;
padding: 20rpx 30rpx;
background-color: #d7193c;
border-radius: 38rpx;
margin-right: 26rpx;
}
const { api, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
const qrcode = require('../../lib/qrcode.js')
Page({
data: {
deviceList: [{
detailList:[{
name:'请尝试下拉刷新'
}]
}],
imgUserIcon: imgName('userdevice.png'),
imgUserBg: imgName('devicebg.png'),
imgCheck: imgName('security_settings_unchecked_active.png'),
imgPencil: imgName('pencil.png'),
imgAdd: imgName('add.png'),
imgFind: imgName('search.png'),
inputValue:'',
modify:false,
modifyValue:'',
deviceId:null,
carCode: '',//二维码
canvasHide: true,//二维码隐藏
},
onLoad: function () {
this.getCarList()
},
onShow: function () {
console.log('welcome show')
},
getCarList(data){
let that = this
api.get('api/vehicle/myVehicle.json', data ? data:{})
.then(res => {
console.log(res.items)
that.setData({
deviceList: res.items.map(item=>{
item.networkingStopTime=item.networkingStopTime.slice(0, 10)
return item
})
})
wx.stopPullDownRefresh()
})
.catch(err => {
wx.stopPullDownRefresh()
alertTip(err)
})
},
addCar(){
wx.navigateTo({
url: '/pages/device_bind/device_bind',
})
},
onPullDownRefresh(){
this.getCarList()
},
changeCar(e) {
let that=this
let id=e.currentTarget.id
api.get('api/vehicle/switchingVehicle.json', { id: Number(id)})
.then(res => {
that.getCarList()
})
.catch(err => {
alertTip(err)
})
},
formSubmit: function (e) {
this.getCarList({ search: e.detail.value})
this.setData({
inputValue:''
})
},
unbindCar(e){
let that = this
let id = e.currentTarget.id
wx.showModal({
title: '警告',
content: '确定解除该设备的绑定?',
success: function (res) {
if (res.confirm) {
api.post('api/vehicle/removeBinding.json', { userVehicleId: Number(id), removeUserId: Number(wx.getStorageSync('user').userId) })
.then(res => {
that.getCarList()
})
.catch(err => {
alertTip(err)
})
}
}
})
},
carBindUser(e){
console.log(e)
wx.navigateTo({
url: `/pages/carusers/carusers?id=${e.currentTarget.id}&master=${e.currentTarget.dataset.master}`,
})
},
modify(e){
let that=this
if (Number(e.currentTarget.dataset.master)==wx.getStorageSync('user').userId){
that.setData({
modify: true,
deviceId: Number(e.currentTarget.id)
})
}else{
alertTip('您不是主车主,无法修改')
}
},
apiModify(e){
let that=this
api.post('api/vehicle/modifyVehicleInfo.json', { name: e.detail.value, otherFeatures: '', id: that.data.deviceId })
.then(res => {
that.setData({
modify: false,
modifyValue:''
})
that.getCarList()
})
.catch(err => {
alertTip(err)
})
},
giveUp(){
let that=this
wx.showModal({
title: '提示',
content: '确定放弃修改车辆昵称?',
success(res){
if(res.confirm){
that.setData({
modify: false,
modifyValue: ''
})
}
}
})
},
showCode(e) {
wx.navigateTo({
url: `/pages/qr_code/qr_code?vcu=${e.currentTarget.id}`,
})
},
//适配不同屏幕大小的canvas
setCanvasSize: function () {
var size = {};
try {
var res = wx.getSystemInfoSync();
var scale = 750 / 460;//不同屏幕下canvas的适配比例;设计稿是750宽
var width = res.windowWidth / scale;
var height = width;//canvas画布为正方形
size.w = width;
size.h = height;
} catch (e) {
// Do something when catch error
console.log("获取设备信息失败" + e);
}
return size;
},
})
\ No newline at end of file
{
"navigationBarTitleText": "我的设备",
"enablePullDownRefresh": true
}
\ No newline at end of file
<scroll-view class='con' wx:if='{{!modify}}' scroll-y>
<view class='search'>
<image class='search-icon' src='{{imgFind}}'></image>
<input name="search" class='search-car' confirm-type='search' placeholder="请输入车辆昵称" bindconfirm='formSubmit' value='{{inputValue}}' />
</view>
<block wx:for='{{deviceList}}'>
<view class='car-item'>
<view class='car-msg'>
<view class='msg-item'>
<view class='text-item' id='{{item.id}}' data-master='{{item.masterUser}}' catchtap='modify'>
<text>昵称:</text>
<text>{{item.name}} </text>
<image src='{{imgPencil}}' class='pencil'></image>
</view>
<view class='text-item'>
<text>设备号:</text>
<text>{{item.vcuNo}}</text>
</view>
<view class='text-item'>
<text>服务到期:</text>
<text class='high-light'>截止到{{item.networkingStopTime}}</text>
</view>
</view>
<view class='use-car'>
<image src='{{imgCheck}}' wx:if='{{item.use}}'></image>
</view>
</view>
<view class='car-change' wx:if='{{item.state}}'>
<text hidden='{{item.use}}' bindtap='changeCar' id='{{item.id}}'>使用</text>
<text catchtap='unbindCar' id='{{item.id}}'>解绑</text>
<text catchtap='carBindUser' id='{{item.id}}' data-master='{{item.masterUser}}'>用户列表</text>
<text catchtap='showCode' id='{{item.vcuNo}}'>二维码</text>
</view>
<view wx:else class='car-change'>
<text>等待授权</text>
</view>
</view>
</block>
</scroll-view>
<view wx:else class='con'>
<view class='search'>
<input name="search" class='search-car' placeholder="请输入要修改后的车辆昵称" bindconfirm='apiModify' value='{{modifyValue}}' />
</view>
<view class='addcar'>
<button type='primary' class='give-up' catchtap='giveUp'>放弃修改</button>
</view>
</view>
<view class='addcar' wx:if='{{!modify}}'>
<button bindtap='addCar'>
<image src='{{imgAdd}}'></image>
新增车辆</button>
</view>
\ No newline at end of file
page {
height: 100%;
overflow: hidden;
background-color: #f7f7f7;
position: relative;
}
.con {
box-sizing: border-box;
height: 100%;
padding-bottom: 84rpx;
}
.addcar{
position: absolute;
bottom:0;
left: 0;
width: 100%;
height: 140rpx;
background-color: #ffffff;
display: flex;
justify-content: center;
align-items: center;
}
.addcar button{
background-color: #d7193c;
height: 84rpx;
width: 694rpx;
font-size: 34rpx;
line-height: 34rpx;
display: flex;
justify-content: center;
align-items: center;
}
.addcar image{
width: 36rpx;
height: 36rpx;
margin-right: 20rpx;
}
.search{
background-color: #ffffff;
padding-left: 30rpx;
height: 70rpx;
width: 694rpx;
display: flex;
align-items: center;
border-radius: 35rpx;
margin: 14rpx auto;
}
.search-icon{
margin-right: 20rpx;
width: 30rpx;
height: 30rpx;
}
.search-car{
font-size: 26rpx;
flex: 1 0 auto;
}
.car-item{
height: 294rpx;
background-color: #ffffff;
margin-bottom: 14rpx;
padding: 0 28rpx;
}
.car-msg{
height: 196rpx;
border-bottom: 2px dotted #cfcfcf;
display: flex;
justify-content: space-between;
}
.msg-item{
display: flex;
flex-direction: column;
justify-content: space-between;
height: 196rpx;
padding: 28rpx 0;
flex: 0 0 450rpx;
}
.use-car{
width: 57rpx;
padding: 28rpx 0;
}
.use-car image{
width: 57rpx;
height: 57rpx;
}
.pencil{
width: 28rpx;
height: 28rpx;
}
.text-item{
display: flex
}
.text-item text:nth-of-type(1){
flex: 0 0 170rpx;
font-size: 32rpx;
line-height: 32rpx;
}
.text-item text:nth-of-type(2){
flex: 1 0 auto;
font-size: 32rpx;
line-height: 32rpx;
color: #cfcfcf;
}
.text-item text:nth-of-type(2).high-light{
color: #ff3333;
}
.car-change{
display: flex;
height: 98rpx;
align-items: center;
justify-content: flex-end;
}
.car-change text{
border:1px solid #cccccc;
border-radius: 28rpx;
width: 160rpx;
height: 56rpx;
font-size: 26rpx;
line-height: 56rpx;
letter-spacing: 4rpx;
color: #cccccc;
text-align: center;
margin-right: 18rpx;
}
.car-change text:last-child{
margin-right: 0;
}
\ No newline at end of file
const jsbuffer=require('../../lib/jsbuffer.min.js')
const { api, imgName, getUserInfo, wxLogin, alertTip, authAgainByUser, userLocation } = require('../../lib/util.js')
Page({
data: {
msg: 'welcome',
imgDotBig: imgName('mesgDot1.png'),
imgDotSmall: imgName('mesgDot2.png'),
imgAlarmBattery: imgName('alarm_battery.png'),
imgAlarmMove: imgName('alarm_move.png'),
imgArrowUp:imgName('arrowup.png'),
imgArrowDown:imgName('arrowdown.png'),
alarmClass:'alarm-warn',
alarmMsg:[{
id:'1',
open:false,
date:{
month:'二月',
day:'27'
},
mileage:'0km',
alarmNum:'35次',
travelTimes:'10次',
detail:[{
time:'09:43',
type:'battery',
msg:'电池移除',
warn:true
}, {
time: '12:43',
type: 'battery',
msg:'电池接入',
warn: false
}, {
time: '13:53',
type: 'move',
msg:'车辆轻微震动',
warn: false
}, {
time: '14:53',
type: 'move',
msg: '车辆严重震动',
warn: true
}]
}]
},
onLoad: function () {
},
getImgSrc(type){
console.log(type)
},
openDetail(e){
let a =this.data.alarmMsg.map(item=>{
if(item.id==e.target.dataset.num){
item.open=!item.open
}
return item
})
this.setData({
alarmMsg:a
})
a=null;
},
onShow: function () {
// console.log('welcome show')
// let ab=new jsbuffer().from('2152e2ac','hex')
// ab.set(0,36)
// console.log(ab)
// let ba=new jsbuffer().read(ab.buffer)
// console.log(ba)
// console.log(ab.get(2))
// console.log(ab.get(1, 'HEX'))
}
})
\ No newline at end of file
<scroll-view class='con'>
<block wx:for='{{alarmMsg}}'>
<view class='date'>
<view class='date-total'>
<view class='total-side'>
<image src='{{imgDotBig}}'></image>
</view>
<view class='total-main'>
<view>
<text>{{item.date.day}}</text>
<text>{{item.date.month}}</text>
</view>
<view class='total-item'>
<view>
<text>{{item.mileage}}</text>
<text>里程</text>
</view>
<view>
<text>{{item.alarmNum}}</text>
<text>警告</text>
</view>
<view>
<text>{{item.travelTimes}}</text>
<text>行驶次数</text>
</view>
</view>
<view class='total-arrow'>
<image src='{{item.open?imgArrowUp:imgArrowDown}}' bindtap='openDetail' data-num='{{item.id}}'></image>
</view>
</view>
</view>
<view wx:if='{{item.open}}'>
<block wx:for='{{item.detail}}'>
<view class='date-detail'>
<view class='detail-side'>
<text>{{item.time}}</text>
<image src='{{imgDotSmall}}' data-type='item.type'></image>
</view>
<view class='detail-main'>
<view class='alarm {{ item.warn?alarmClass:""}}'>
<image src='{{item.type=="battery"?imgAlarmBattery:imgAlarmMove}}'></image>
<text>{{ item.msg}}</text>
</view>
<!-- <view class='detail-arrow'>
<image src='{{imgArrowUp}}'></image>
</view> -->
</view>
</view>
</block>
</view>
</view>
</block>
</scroll-view>
\ No newline at end of file
/**index.wxss**/
page{
height: 100%;
}
.con{
height: 100%;
background-color: #efeff0;
}
.date-total{
box-sizing: border-box;
height:112rpx;
display: flex;
}
.total-side {
flex-basis: 120rpx;
flex-grow: 0;
display: flex;
align-items: flex-end;
justify-content: flex-end;
padding-right: 10rpx;
}
.total-main{
background-color: #fff;
margin-bottom: 6rpx;
display: flex;
flex-grow: 1;
padding: 10rpx 20rpx;
justify-content: space-between;
}
.total-main>view:first-child{
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
border-right: 4rpx solid #000;
}
.total-main>view:first-child text:first-child{
font-size: 42rpx;
padding-right: 14rpx;
}
.total-main>view:first-child text:nth-of-type(2){
padding-right: 22rpx;
}
.total-item{
display: flex;
align-items: center;
justify-content: space-around;
flex-grow: 1;
}
.total-item>view{
display: flex;
flex-direction: column;
align-items: center;
}
.total-arrow,.detail-arrow{
display: flex;
align-items: center;
justify-content: center;
}
.total-arrow image,.detail-arrow image{
width: 36rpx;
height: 18rpx;
}
.total-side image{
width: 24rpx;
height: 72rpx;
}
.date-detail{
box-sizing: border-box;
height: 92rpx;
display: flex;
}
.detail-side{
flex-basis: 120rpx;
flex-grow: 0;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 14.7rpx;
}
.detail-side image{
width: 13rpx;
height: 92rpx;
}
.detail-main{
background-color: #fff;
margin: 14rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.alarm image{
width: 38rpx;
height: 38rpx;
}
.detail-main{
padding: 0 20rpx 0 10rpx ;
flex-grow:1;
}
.alarm{
display: flex;
align-items: center;
font-size: 32rpx;
}
.alarm image{
padding-right: 24rpx;
}
.alarm-warn{
color: #e76955;
}
{
}
\ No newline at end of file
<!--pages/user_index/user_index.wxml-->
<view class='con' wx:if='{{baseMsg}}'>
<view class='tab-header'>
<view class='person' catchtap='toMy'>
<image src='{{imgPerson}}'></image>
</view>
<view class='main' catchtap='tabCarMenu'>
<view class='item {{tab===""? "active":""}}'>车辆位置</view>
<view class='item {{tab==="tab"? "active":""}}' id='tab'>车辆详情</view>
</view>
<view class='person'></view>
</view>
<view class='body-box {{tab}}'>
<view class='tab-map'>
<map id='carMap' scale='13' markers='{{ui.locMap.markers}}' show-location bindmarkertap='markersTap' longitude='{{ui.locMap.longitude}}' latitude='{{ui.locMap.latitude}}'>
<cover-view class='map-alarm' catchtap='toMsgPage' hidden='{{ui.message}}'>
<cover-view>您有消息需要关注</cover-view>
<cover-image src='{{imgMore}}'></cover-image>
</cover-view>
<cover-view class='map-fee' catchtap='toMsgPage' wx:if='{{person}}'>
<cover-view>预估费用(仅供参考,以实际结算为准):{{ui.fee}}元</cover-view>
</cover-view>
<cover-view class='map-controltap'>
<cover-image src='{{imgFind}}' catchtap='netFindCar'></cover-image>
<cover-image src='{{imgToloc}}' catchtap='showMyLoc'></cover-image>
</cover-view>
</map>
<view class='map-des'>
<view class='loc'>{{ui.deviceAdress}}</view>
<view class='loc-des'>定位时间:{{ui.last_communication_time}}</view>
<view class='status'>
<view class='status-item'>
<image class='km' src='{{imgKm}}'></image>
<view>里程:{{ui.estimatedMileage}}</view>
</view>
<view class='status-item'>
<image class='battery' src='{{imgSpeed}}'></image>
<view>速度:{{ui.speed}}</view>
</view>
<view class='status-item'>
<image class='battery' src='{{imgBattery}}'></image>
<view>电量:{{ui.dumpEnergy}}</view>
</view>
</view>
<view class='btn-action'>
<view class='lock' bindtap='returnCar' wx:if='{{person==1}}'>
<text>还车</text>
</view>
<view class='lock' bindtap='apiActionDevice'>
<image src='{{imgLock}}'></image>
<text>{{ui.lockState?'我要锁车':'开锁用车'}}</text>
</view>
</view>
</view>
</view>
<scroll-view class='tab-detail' scroll-y>
<view class='device-msg item'>
<view>
<text>车型名称 :</text>
<text class='vname' id='{{ui.vehicleTypeName}}' catchtap='seeQrCode'>{{ui.vehicleTypeName}}(二维码)</text>
</view>
<view>
<text>车架号 :</text>
<text class='vname' id='{{ui.froNo}}' catchtap='seeQrCode'>{{ui.froNo}}(二维码)</text>
</view>
<view>
<text>中控号 :</text>
<text class='vname' id='{{ui.vcuNo}}' catchtap='seeQrCode'>{{ui.vcuNo}}(二维码)</text>
</view>
<view>
<text>车牌号 :</text>
<text class='vname' id='{{ui.licensePlate}}' catchtap='seeQrCode'>{{ui.licensePlate}}(二维码)</text>
</view>
<view>
<text>起租时间 :</text>
<text class='vname'>{{ui.rentStartTime}}</text>
</view>
</view>
<view class='item'>
<image class='icon' src='{{imgMedical}}'></image>
<view class='des'>
<view class='title'>
<text>体检情况</text>
<text class='medical-btn' catchtap='reMedical'>立即体检</text>
</view>
<view class='medical'>
<view wx:if="{{!hasMedical}}">
<progress class='progress' onchange='progressChange' percent="{{medicalNum}}" active show-info activeColor='#d7193c' />
</view>
<view wx:else>
<view>动力系统:</view>
<view>供电系统:</view>
<view>显示系统:</view>
<view>中控系统:</view>
<view>总分:</view>
</view>
</view>
<view class='notify' wx:if="{{hasMedical&&medicalScore<100}}">体检结果不佳,
<text catchtap='changeBar'> 我要保修。</text>
</view>
</view>
</view>
<view class='item' wx:for="{{details}}" wx:key='{{item.title}}'>
<image class='icon' src='{{item.icon}}'></image>
<view class='des'>
<view class='title'>{{item.title}}</view>
<view class='low-des'>
<view>{{item.des1}}</view>
<view>{{item.des2}}</view>
<view>{{item.des3}}</view>
</view>
<view class='notify'>{{item.tip}}</view>
</view>
</view>
</scroll-view>
</view>
</view>
<view wx:else class='con'>
<view class='msg-err'>
<text class='des'>网络问题,获取数据失败。</text>
<text class='bind' catchtap='apiGetCarMsg'>点击重新获取</text>
<text class='bind' catchtap='reLogin'>或者重新登录</text>
</view>
</view>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment