'维修店'
99
components/cell-list/cell-list.vue
Normal file
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<view>
|
||||
<u-popup :show="show" bgColor="transparent" @close="close()" :safeAreaInsetBottom="false">
|
||||
<view class="title f-30 fw-b c222">
|
||||
{{title}}
|
||||
<image src="@/static/images/icon/x_1.png" mode="" @click="close"></image>
|
||||
</view>
|
||||
<view class="popup-box">
|
||||
<view class="popup-item flex align-center justify-between" @click="checkItem(item)" v-for="(item,index) in list" :key="index">
|
||||
{{item.text}}
|
||||
<image v-show="detail.type == item.type" class="icon-image" src="@/static/images/icon/true.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="btn-box bg-white">
|
||||
<u-button class="btn" shape="circle" color="#13AFA8" @click="confirm">确定</u-button>
|
||||
<view style="height: 68rpx;" />
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"cell-list",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
detail: {}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
checkItem(item){
|
||||
this.detail = item
|
||||
this.$emit('checkItem', item)
|
||||
},
|
||||
close() {
|
||||
this.show = false
|
||||
},
|
||||
confirm() {
|
||||
this.$emit('confirm', this.item)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.title {
|
||||
position: relative;
|
||||
width: 750rpx;
|
||||
height: 128rpx;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
background-color: #F5F5F5;
|
||||
text-align: center;
|
||||
line-height: 128rpx;
|
||||
image {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 24rpx;
|
||||
width: 26rpx;
|
||||
height: 26rpx;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
.popup-box {
|
||||
padding: 0 32rpx;
|
||||
width: 750rpx;
|
||||
max-height: 452rpx;
|
||||
background-color: #FFF;
|
||||
overflow-y: auto;
|
||||
.popup-item {
|
||||
width: 686rpx;
|
||||
border-bottom: 1rpx solid #F5F5F5;
|
||||
line-height: 112rpx;
|
||||
.icon-image {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-box {
|
||||
padding-top: 18rpx;
|
||||
.btn {
|
||||
width: 702rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -48,6 +48,10 @@
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
round: {
|
||||
type: [Number, String],
|
||||
default: 8
|
||||
},
|
||||
/** 上传图片背景 */
|
||||
uploadIcon: {
|
||||
type: String,
|
||||
@@ -81,13 +85,13 @@
|
||||
if(this.imageHeight) {
|
||||
style.height = this.imageHeight + 'rpx'
|
||||
} else style.height = this.imageWidth + 'rpx'
|
||||
style.borderRadius = this.round + 'rpx'
|
||||
return style
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value: {
|
||||
handler(nV, oV) {
|
||||
console.log(this.value)
|
||||
if(nV){
|
||||
this.PhotoSharinglist = this.value.split(',')
|
||||
}
|
||||
@@ -143,10 +147,11 @@
|
||||
filePath: url,
|
||||
name: 'file',
|
||||
header: {
|
||||
'Authorization': token ? 'Bearer' + ' ' + token : ''
|
||||
'Authori-zation': token ? token : ''
|
||||
},
|
||||
success: (res) => {
|
||||
uni.hideLoading();
|
||||
console.log(res);
|
||||
let url = JSON.parse(res.data).data.url;
|
||||
let compressUrl=JSON.parse(res.data).data.urlSmall;
|
||||
this.PhotoSharinglist.push(url);
|
||||
@@ -182,11 +187,9 @@
|
||||
font-size: 24rpx;
|
||||
color: #979797;
|
||||
background: #FEFEFE;
|
||||
border-radius: 20rpx;
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.clear {
|
||||
position: absolute;
|
||||
|
||||
131
js_sdk/AliOSS/base64.js
Normal file
@@ -0,0 +1,131 @@
|
||||
export const Base64 = {
|
||||
|
||||
// private property
|
||||
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
|
||||
|
||||
// public method for encoding
|
||||
encode: function(input) {
|
||||
var output = "";
|
||||
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
|
||||
var i = 0;
|
||||
|
||||
input = Base64._utf8_encode(input);
|
||||
|
||||
while (i < input.length) {
|
||||
|
||||
chr1 = input.charCodeAt(i++);
|
||||
chr2 = input.charCodeAt(i++);
|
||||
chr3 = input.charCodeAt(i++);
|
||||
|
||||
enc1 = chr1 >> 2;
|
||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||
enc4 = chr3 & 63;
|
||||
|
||||
if (isNaN(chr2)) {
|
||||
enc3 = enc4 = 64;
|
||||
} else if (isNaN(chr3)) {
|
||||
enc4 = 64;
|
||||
}
|
||||
|
||||
output = output +
|
||||
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
|
||||
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
// public method for decoding
|
||||
decode: function(input) {
|
||||
var output = "";
|
||||
var chr1, chr2, chr3;
|
||||
var enc1, enc2, enc3, enc4;
|
||||
var i = 0;
|
||||
|
||||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
||||
|
||||
while (i < input.length) {
|
||||
|
||||
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
||||
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
||||
|
||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||
|
||||
output = output + String.fromCharCode(chr1);
|
||||
|
||||
if (enc3 != 64) {
|
||||
output = output + String.fromCharCode(chr2);
|
||||
}
|
||||
if (enc4 != 64) {
|
||||
output = output + String.fromCharCode(chr3);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
output = Base64._utf8_decode(output);
|
||||
|
||||
return output;
|
||||
|
||||
},
|
||||
|
||||
// private method for UTF-8 encoding
|
||||
_utf8_encode: function(string) {
|
||||
string = string.replace(/\r\n/g, "\n");
|
||||
var utftext = "";
|
||||
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
|
||||
var c = string.charCodeAt(n);
|
||||
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
} else if ((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
} else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return utftext;
|
||||
},
|
||||
|
||||
// private method for UTF-8 decoding
|
||||
_utf8_decode: function(utftext) {
|
||||
var string = "";
|
||||
var i = 0;
|
||||
var c = c1 = c2 = 0;
|
||||
|
||||
while (i < utftext.length) {
|
||||
|
||||
c = utftext.charCodeAt(i);
|
||||
|
||||
if (c < 128) {
|
||||
string += String.fromCharCode(c);
|
||||
i++;
|
||||
} else if ((c > 191) && (c < 224)) {
|
||||
c2 = utftext.charCodeAt(i + 1);
|
||||
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
||||
i += 2;
|
||||
} else {
|
||||
c2 = utftext.charCodeAt(i + 1);
|
||||
c3 = utftext.charCodeAt(i + 2);
|
||||
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
||||
i += 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
}
|
||||
166
js_sdk/AliOSS/crypto.js
Normal file
@@ -0,0 +1,166 @@
|
||||
const base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
// Crypto utilities
|
||||
export const util = {
|
||||
|
||||
// Bit-wise rotate left
|
||||
rotl: function (n, b) {
|
||||
return (n << b) | (n >>> (32 - b));
|
||||
},
|
||||
|
||||
// Bit-wise rotate right
|
||||
rotr: function (n, b) {
|
||||
return (n << (32 - b)) | (n >>> b);
|
||||
},
|
||||
|
||||
// Swap big-endian to little-endian and vice versa
|
||||
endian: function (n) {
|
||||
|
||||
// If number given, swap endian
|
||||
if (n.constructor == Number) {
|
||||
return util.rotl(n, 8) & 0x00FF00FF |
|
||||
util.rotl(n, 24) & 0xFF00FF00;
|
||||
}
|
||||
|
||||
// Else, assume array and swap all items
|
||||
for (var i = 0; i < n.length; i++)
|
||||
n[i] = util.endian(n[i]);
|
||||
return n;
|
||||
|
||||
},
|
||||
|
||||
// Generate an array of any length of random bytes
|
||||
randomBytes: function (n) {
|
||||
for (var bytes = []; n > 0; n--)
|
||||
bytes.push(Math.floor(Math.random() * 256));
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a string to a byte array
|
||||
stringToBytes: function (str) {
|
||||
var bytes = [];
|
||||
for (var i = 0; i < str.length; i++)
|
||||
bytes.push(str.charCodeAt(i));
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a string
|
||||
bytesToString: function (bytes) {
|
||||
var str = [];
|
||||
for (var i = 0; i < bytes.length; i++)
|
||||
str.push(String.fromCharCode(bytes[i]));
|
||||
return str.join("");
|
||||
},
|
||||
|
||||
// Convert a string to big-endian 32-bit words
|
||||
stringToWords: function (str) {
|
||||
var words = [];
|
||||
for (var c = 0, b = 0; c < str.length; c++, b += 8)
|
||||
words[b >>> 5] |= str.charCodeAt(c) << (24 - b % 32);
|
||||
return words;
|
||||
},
|
||||
|
||||
// Convert a byte array to big-endian 32-bits words
|
||||
bytesToWords: function (bytes) {
|
||||
var words = [];
|
||||
for (var i = 0, b = 0; i < bytes.length; i++, b += 8)
|
||||
words[b >>> 5] |= bytes[i] << (24 - b % 32);
|
||||
return words;
|
||||
},
|
||||
|
||||
// Convert big-endian 32-bit words to a byte array
|
||||
wordsToBytes: function (words) {
|
||||
var bytes = [];
|
||||
for (var b = 0; b < words.length * 32; b += 8)
|
||||
bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a hex string
|
||||
bytesToHex: function (bytes) {
|
||||
var hex = [];
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
hex.push((bytes[i] >>> 4).toString(16));
|
||||
hex.push((bytes[i] & 0xF).toString(16));
|
||||
}
|
||||
return hex.join("");
|
||||
},
|
||||
|
||||
// Convert a hex string to a byte array
|
||||
hexToBytes: function (hex) {
|
||||
var bytes = [];
|
||||
for (var c = 0; c < hex.length; c += 2)
|
||||
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||
return bytes;
|
||||
},
|
||||
|
||||
// Convert a byte array to a base-64 string
|
||||
bytesToBase64: function (bytes) {
|
||||
|
||||
// Use browser-native function if it exists
|
||||
if (typeof btoa == "function") return btoa(util.bytesToString(bytes));
|
||||
|
||||
var base64 = [],
|
||||
overflow;
|
||||
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
switch (i % 3) {
|
||||
case 0:
|
||||
base64.push(base64map.charAt(bytes[i] >>> 2));
|
||||
overflow = (bytes[i] & 0x3) << 4;
|
||||
break;
|
||||
case 1:
|
||||
base64.push(base64map.charAt(overflow | (bytes[i] >>> 4)));
|
||||
overflow = (bytes[i] & 0xF) << 2;
|
||||
break;
|
||||
case 2:
|
||||
base64.push(base64map.charAt(overflow | (bytes[i] >>> 6)));
|
||||
base64.push(base64map.charAt(bytes[i] & 0x3F));
|
||||
overflow = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Encode overflow bits, if there are any
|
||||
if (overflow != undefined && overflow != -1)
|
||||
base64.push(base64map.charAt(overflow));
|
||||
|
||||
// Add padding
|
||||
while (base64.length % 4 != 0) base64.push("=");
|
||||
|
||||
return base64.join("");
|
||||
|
||||
},
|
||||
|
||||
// Convert a base-64 string to a byte array
|
||||
base64ToBytes: function (base64) {
|
||||
|
||||
// Use browser-native function if it exists
|
||||
if (typeof atob == "function") return util.stringToBytes(atob(base64));
|
||||
|
||||
// Remove non-base-64 characters
|
||||
base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
|
||||
|
||||
var bytes = [];
|
||||
|
||||
for (var i = 0; i < base64.length; i++) {
|
||||
switch (i % 4) {
|
||||
case 1:
|
||||
bytes.push((base64map.indexOf(base64.charAt(i - 1)) << 2) |
|
||||
(base64map.indexOf(base64.charAt(i)) >>> 4));
|
||||
break;
|
||||
case 2:
|
||||
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0xF) << 4) |
|
||||
(base64map.indexOf(base64.charAt(i)) >>> 2));
|
||||
break;
|
||||
case 3:
|
||||
bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & 0x3) << 6) |
|
||||
(base64map.indexOf(base64.charAt(i))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
25
js_sdk/AliOSS/hmac.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { util } from './crypto.js'
|
||||
|
||||
export function HMAC(hasher, message, key, options) {
|
||||
const _blocksize = 16
|
||||
// Allow arbitrary length keys
|
||||
key = key.length > _blocksize * 4 ?
|
||||
hasher(key, { asBytes: true }) :
|
||||
util.stringToBytes(key);
|
||||
|
||||
// XOR keys with pad constants
|
||||
var okey = key,
|
||||
ikey = key.slice(0);
|
||||
for (var i = 0; i < _blocksize * 4; i++) {
|
||||
okey[i] ^= 0x5C;
|
||||
ikey[i] ^= 0x36;
|
||||
}
|
||||
|
||||
var hmacbytes = hasher(util.bytesToString(okey) +
|
||||
hasher(util.bytesToString(ikey) + message, { asString: true }),
|
||||
{ asBytes: true });
|
||||
return options && options.asBytes ? hmacbytes :
|
||||
options && options.asString ? util.bytesToString(hmacbytes) :
|
||||
util.bytesToHex(hmacbytes);
|
||||
|
||||
}
|
||||
80
js_sdk/AliOSS/oss.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Base64 } from './base64.js'
|
||||
import { util } from './crypto.js'
|
||||
import { HMAC } from './hmac.js'
|
||||
import { SHA1 } from './sha1.js'
|
||||
|
||||
// 下面这3个信息必填
|
||||
const url = 'https://jimte.oss-cn-hangzhou.aliyuncs.com/'
|
||||
const OSSAccessKeyId = 'LTAI5tFZzfAMHw3WJNQtrhBZ'
|
||||
const OssAccesskeySercet= 'rqZUht8RhrAfxDltWeGs1Yzpqzmu8W';
|
||||
let date = new Date();
|
||||
date.setHours(date.getHours() + 87600);
|
||||
let srcT = date.toISOString();
|
||||
|
||||
const policyText = {
|
||||
"expiration": srcT, // 设置Policy的有效期,格式为UTC时间。如果Policy失效,将无法上传文件。
|
||||
"conditions": [
|
||||
["content-length-range", 0, 1048576000] // 限制上传文件的大小,单位为字节,此处限制文件大小为1 GB。如果上传的文件大小超过此限制,文件将无法上传到OSS。如果未设置该限制,则默认文件大小最大为5 GB。
|
||||
]
|
||||
}
|
||||
const policy = Base64.encode(JSON.stringify(policyText))
|
||||
const bytes = HMAC(SHA1, policy, OssAccesskeySercet, { asBytes: true })
|
||||
const signature = util.bytesToBase64(bytes)
|
||||
|
||||
// 生成文件名随机字符串
|
||||
function random_string(len) {
|
||||
const strLeng = len || 32;
|
||||
const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
|
||||
const maxPos = chars.length;
|
||||
let pwd = '';
|
||||
for (let i = 0; i < strLeng; i++) {
|
||||
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
|
||||
}
|
||||
return pwd;
|
||||
}
|
||||
|
||||
// 获取文件后缀
|
||||
function get_suffix(filename) {
|
||||
const pos = filename.lastIndexOf('.')
|
||||
let suffix = ''
|
||||
if (pos != -1) {
|
||||
suffix = filename.substring(pos)
|
||||
}
|
||||
return suffix;
|
||||
}
|
||||
// dir格式:'img/'
|
||||
export const ossUpload = (filePath, name, dir,progress,successCallback,errorCallback) => {
|
||||
const key = dir+uni.$u.timeFormat(new Date(), 'yyyy/mm/dd')+'/' + random_string(10) + get_suffix(name);
|
||||
const uploadFile = uni.uploadFile({
|
||||
url,
|
||||
filePath,
|
||||
name: 'file',
|
||||
formData: {
|
||||
name,
|
||||
key,
|
||||
policy,
|
||||
OSSAccessKeyId,
|
||||
success_action_status: '200',
|
||||
signature
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.statusCode == 200) {
|
||||
if (typeof(successCallback) === 'function'){
|
||||
successCallback({success: true, data: url+key})
|
||||
}
|
||||
} else {
|
||||
if (typeof(errorCallback) === 'function'){
|
||||
errorCallback({success: false, data: res})
|
||||
}
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
if (typeof(errorCallback) === 'function'){
|
||||
errorCallback({success: false, data: '上传失败'})
|
||||
}
|
||||
}
|
||||
});
|
||||
uploadFile.onProgressUpdate(res=>{
|
||||
progress(res);
|
||||
});
|
||||
}
|
||||
64
js_sdk/AliOSS/sha1.js
Normal file
@@ -0,0 +1,64 @@
|
||||
import { util } from './crypto.js'
|
||||
|
||||
// The core
|
||||
function _sha1(message) {
|
||||
|
||||
var m = util.stringToWords(message),
|
||||
l = message.length * 8,
|
||||
w = [],
|
||||
H0 = 1732584193,
|
||||
H1 = -271733879,
|
||||
H2 = -1732584194,
|
||||
H3 = 271733878,
|
||||
H4 = -1009589776;
|
||||
|
||||
// Padding
|
||||
m[l >> 5] |= 0x80 << (24 - l % 32);
|
||||
m[((l + 64 >>> 9) << 4) + 15] = l;
|
||||
|
||||
for (var i = 0; i < m.length; i += 16) {
|
||||
|
||||
var a = H0,
|
||||
b = H1,
|
||||
c = H2,
|
||||
d = H3,
|
||||
e = H4;
|
||||
|
||||
for (var j = 0; j < 80; j++) {
|
||||
|
||||
if (j < 16) w[j] = m[i + j];
|
||||
else {
|
||||
var n = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
|
||||
w[j] = (n << 1) | (n >>> 31);
|
||||
}
|
||||
|
||||
var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + (
|
||||
j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 :
|
||||
j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 :
|
||||
j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 :
|
||||
(H1 ^ H2 ^ H3) - 899497514);
|
||||
|
||||
H4 = H3;
|
||||
H3 = H2;
|
||||
H2 = (H1 << 30) | (H1 >>> 2);
|
||||
H1 = H0;
|
||||
H0 = t;
|
||||
|
||||
}
|
||||
|
||||
H0 += a;
|
||||
H1 += b;
|
||||
H2 += c;
|
||||
H3 += d;
|
||||
H4 += e;
|
||||
}
|
||||
return [H0, H1, H2, H3, H4];
|
||||
};
|
||||
|
||||
// Public API
|
||||
export function SHA1(message, options) {
|
||||
var digestbytes = util.wordsToBytes(_sha1(message));
|
||||
return options && options.asBytes ? digestbytes :
|
||||
options && options.asString ? util.bytesToString(digestbytes) :
|
||||
util.bytesToHex(digestbytes);
|
||||
};
|
||||
108
js_sdk/uni-read-pages/README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# uni-read-pages
|
||||
|
||||
   
|
||||
|
||||
通过 [vue.config.js](https://cli.vuejs.org/zh/config/) 配合此库,可以随心所欲的读取 `pages.json` 下的所有配置
|
||||
|
||||
## 安装
|
||||
|
||||
您可以使用 `Yarn` 或 `npm` 安装该软件包(选择一个):
|
||||
|
||||
##### Yarn
|
||||
|
||||
```sh
|
||||
yarn add uni-read-pages
|
||||
```
|
||||
##### npm
|
||||
|
||||
```sh
|
||||
npm install uni-read-pages
|
||||
```
|
||||
## 开始
|
||||
配置 `vue.config.js` 通过 `webpack` 注入全局变量 [查看文档](https://www.webpackjs.com/plugins/define-plugin/)
|
||||
|
||||
#### 配置 `vue.config.js`
|
||||
```js
|
||||
//vue.config.js
|
||||
const TransformPages = require('uni-read-pages')
|
||||
const tfPages = new TransformPages()
|
||||
module.exports = {
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
new tfPages.webpack.DefinePlugin({
|
||||
ROUTES: JSON.stringify(tfPages.routes)
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
借助`webpack.DefinePlugin` 轻松注入全局变量。`ROUTES` 及可全局使用
|
||||
|
||||
#### 使用
|
||||
```js
|
||||
// xxx.vue
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'Hello'
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
console.log(ROUTES)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
```
|
||||
## API
|
||||
#### options
|
||||
```js
|
||||
//默认值
|
||||
const CONFIG={
|
||||
cli:false, //当前是否为脚手架初始化的项目
|
||||
includes:['path','aliasPath','name'] //需要获取包涵的字段
|
||||
}
|
||||
```
|
||||
|
||||
#### Instance method
|
||||
|
||||
* **getPagesRoutes**
|
||||
* 通过读取 `pages.json` 文件 生成直接可用的routes
|
||||
|
||||
* **parsePages(pageCallback, subPageCallback)**
|
||||
* 单条page对象解析
|
||||
|
||||
* **resolvePath(dir)**
|
||||
* 解析绝对路径
|
||||
|
||||
#### Instance attr
|
||||
|
||||
* **CONFIG**
|
||||
* 当前配置项
|
||||
|
||||
* **webpack**
|
||||
* 当前工程下需要用到 `webpack`
|
||||
|
||||
* **uniPagesJSON**
|
||||
* 当前 `uni-app` 内置对象,可以通过此属性调用一些内置方法
|
||||
|
||||
* **routes**
|
||||
* 通过 **includes** 解析后得到的路由表 **可直接使用**
|
||||
|
||||
#### getter
|
||||
|
||||
* **pagesJson**
|
||||
* 获取所有 `pages.json` 下的内容 返回 `json`
|
||||
|
||||
|
||||
#### uniPagesJSON method
|
||||
|
||||
* getMainEntry()
|
||||
* getNVueMainEntry()
|
||||
* parsePages (pagesJson, pageCallback, subPageCallback)
|
||||
* parseEntry (pagesJson)
|
||||
* getPagesJson()
|
||||
* parsePagesJson (content, loader)
|
||||
|
||||
#### uniPagesJSON attr
|
||||
* pagesJsonJsFileName //默认值 pages.js
|
||||
83
js_sdk/uni-read-pages/index.js
Normal file
@@ -0,0 +1,83 @@
|
||||
const path = require('path')
|
||||
const CONFIG = {
|
||||
includes: ['path', 'aliasPath', 'name']
|
||||
}
|
||||
const rootPath = path.resolve(process.cwd(), 'node_modules');
|
||||
|
||||
/** 解析绝对路径
|
||||
* @param {Object} dir
|
||||
*/
|
||||
function resolvePath(dir) {
|
||||
return path.resolve(rootPath, dir);
|
||||
}
|
||||
|
||||
class TransformPages {
|
||||
constructor(config) {
|
||||
config = {
|
||||
...CONFIG,
|
||||
...config
|
||||
};
|
||||
this.CONFIG = config;
|
||||
this.webpack = require(resolvePath('webpack'));
|
||||
this.uniPagesJSON = require(resolvePath('@dcloudio/uni-cli-shared/lib/pages.js'));
|
||||
this.routes = this.getPagesRoutes().concat(this.getNotMpRoutes());
|
||||
}
|
||||
/**
|
||||
* 获取所有pages.json下的内容 返回json
|
||||
*/
|
||||
get pagesJson() {
|
||||
return this.uniPagesJSON.getPagesJson();
|
||||
}
|
||||
/**
|
||||
* 通过读取pages.json文件 生成直接可用的routes
|
||||
*/
|
||||
getPagesRoutes(pages = this.pagesJson.pages, rootPath = null) {
|
||||
const routes = [];
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
const item = pages[i];
|
||||
const route = {};
|
||||
for (let j = 0; j < this.CONFIG.includes.length; j++) {
|
||||
const key = this.CONFIG.includes[j];
|
||||
let value = item[key];
|
||||
if (key === 'path') {
|
||||
value = rootPath ? `/${rootPath}/${value}` : `/${value}`
|
||||
}
|
||||
if (key === 'aliasPath' && i == 0 && rootPath == null) {
|
||||
route[key] = route[key] || '/'
|
||||
} else if (value !== undefined) {
|
||||
route[key] = value;
|
||||
}
|
||||
}
|
||||
routes.push(route);
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
/**
|
||||
* 解析小程序分包路径
|
||||
*/
|
||||
getNotMpRoutes() {
|
||||
const {
|
||||
subPackages
|
||||
} = this.pagesJson;
|
||||
let routes = [];
|
||||
if (subPackages == null || subPackages.length == 0) {
|
||||
return [];
|
||||
}
|
||||
for (let i = 0; i < subPackages.length; i++) {
|
||||
const subPages = subPackages[i].pages;
|
||||
const root = subPackages[i].root;
|
||||
const subRoutes = this.getPagesRoutes(subPages, root);
|
||||
routes = routes.concat(subRoutes)
|
||||
}
|
||||
return routes
|
||||
}
|
||||
/**
|
||||
* 单条page对象解析
|
||||
* @param {Object} pageCallback
|
||||
* @param {Object} subPageCallback
|
||||
*/
|
||||
parsePages(pageCallback, subPageCallback) {
|
||||
this.uniPagesJSON.parsePages(this.pagesJson, pageCallback, subPageCallback)
|
||||
}
|
||||
}
|
||||
module.exports = TransformPages
|
||||
25
js_sdk/uni-read-pages/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "uni-read-pages",
|
||||
"version": "1.0.5",
|
||||
"description": "read `pages.json` file to generate the routes table",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"example": "examples"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node -e \"console.log('\\x1b[91m','\\n\\n uni-simple-router 垫脚片,欢迎下载!\\n \\n 开源不易,需要鼓励。去给 uni-read-pages 项目 点个 star 吧 \\n\\n')\"",
|
||||
"dev": "webpack --watch --progress --config webpack/webpack.dev.js",
|
||||
"build": "webpack --progress --config webpack/webpack.prod.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/SilurianYang/uni-read-pages.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/SilurianYang/uni-read-pages/issues"
|
||||
},
|
||||
"homepage": "https://github.com/SilurianYang/uni-read-pages#readme"
|
||||
}
|
||||
85
js_sdk/uni-simple-router/link.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<view @click="gotoPage()"><slot></slot></view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const navType = {
|
||||
push: 'push',
|
||||
replace: 'replace',
|
||||
replaceAll: 'replaceAll',
|
||||
pushTab: 'pushTab',
|
||||
back:'back'
|
||||
};
|
||||
export default {
|
||||
props: {
|
||||
to: {
|
||||
type: [String, Object],
|
||||
required: true
|
||||
},
|
||||
stopNavto: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
navType: {
|
||||
type: String,
|
||||
default: 'push',
|
||||
},
|
||||
level: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
append: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
formatNav(text) {
|
||||
if (text != null && text.constructor === String) {
|
||||
const keyArray = [];
|
||||
text = text.replace(/((\w+)|('\s*(\w+)\s*')|("\s*(\w+)\s*"))\s*(?=:)/g, function (val) {
|
||||
const key = `"${val.trim().replace(/"|'/g, '')}"`;
|
||||
keyArray.push(key);
|
||||
return key
|
||||
});
|
||||
const removeReg=/('|")/g;
|
||||
for (let i = 0; i < keyArray.length; i++) {
|
||||
const key = keyArray[i];
|
||||
text=text.replace(new RegExp(`${key}\\s*:\\s*('[^']+')`, 'g'),(...args)=>{
|
||||
const $1=args[1];
|
||||
return `${key}:"${$1.replace(removeReg,'')}"`
|
||||
})
|
||||
}
|
||||
try {
|
||||
text=JSON.parse(text);
|
||||
} catch (error) {}
|
||||
}
|
||||
if (this.append) {
|
||||
let pathArr = this.$Route.path.split('/');
|
||||
pathArr.splice(pathArr.length - this.level, this.level);
|
||||
pathArr = pathArr.join('/');
|
||||
if (text.constructor === Object) {
|
||||
if (text.path) {
|
||||
text.path = pathArr + text.path;
|
||||
}
|
||||
} else {
|
||||
text = pathArr + text;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
},
|
||||
gotoPage() {
|
||||
if (this.stopNavto) {
|
||||
return true;
|
||||
}
|
||||
const type = navType[this.navType];
|
||||
if (type == null) {
|
||||
return console.error(` "navType" unknown type \n\n value:${Object.values(navType).join('、')}`);
|
||||
}
|
||||
const navInfo = this.formatNav(this.to);
|
||||
|
||||
this.$Router[type](navInfo);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
17
js_sdk/uni-simple-router/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"id": "hhyang-uni-simple-router",
|
||||
"name": " 路由、拦截、最优雅解决方案 uni-simple-router",
|
||||
"version": "2.0.8-beta.4",
|
||||
"description": "一个完全相似Vue-router的路由插件",
|
||||
"keywords": [
|
||||
"路由守卫",
|
||||
"路由拦截",
|
||||
"页面路由"
|
||||
],
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"JS SDK",
|
||||
"通用 SDK"
|
||||
]
|
||||
}
|
||||
}
|
||||
397
js_sdk/uni-simple-router/uni-simple-router.d.ts
vendored
Normal file
@@ -0,0 +1,397 @@
|
||||
|
||||
export declare interface AppConfig {
|
||||
registerLoadingPage?: boolean;
|
||||
loadingPageStyle?: () => object;
|
||||
loadingPageHook?: (view: any) => void;
|
||||
launchedHook?: () => void;
|
||||
animation?: startAnimationRule;
|
||||
}
|
||||
|
||||
export declare interface appletConfig {
|
||||
animationDuration?: number;
|
||||
}
|
||||
|
||||
export declare function assertDeepObject(object: objectAny): boolean;
|
||||
|
||||
export declare function assertNewOptions<T extends InstantiateConfig>(options: T): T | never;
|
||||
|
||||
export declare function assertParentChild(parentPath: string, vueVim: any): boolean;
|
||||
|
||||
export declare type backTypeRule = 'backbutton' | 'navigateBack';
|
||||
|
||||
export declare function baseClone<T extends {
|
||||
[key: string]: any;
|
||||
}, K extends keyof T>(source: T, target: Array<any> | objectAny): Array<any> | objectAny | null;
|
||||
|
||||
export declare function copyData<T>(object: T): T;
|
||||
|
||||
export declare function createRouter(params: InstantiateConfig): Router;
|
||||
|
||||
export declare interface debuggerArrayConfig {
|
||||
error?: boolean;
|
||||
warn?: boolean;
|
||||
log?: boolean;
|
||||
}
|
||||
|
||||
export declare type debuggerConfig = boolean | debuggerArrayConfig;
|
||||
|
||||
export declare function deepClone<T>(source: T): T;
|
||||
|
||||
export declare function deepDecodeQuery(query: objectAny): objectAny;
|
||||
|
||||
export declare function def(defObject: objectAny, key: string, getValue: Function): void;
|
||||
|
||||
export declare interface endAnimationRule {
|
||||
animationType?: endAnimationType;
|
||||
animationDuration?: number;
|
||||
}
|
||||
|
||||
export declare type endAnimationType = 'slide-out-right' | 'slide-out-left' | 'slide-out-top' | 'slide-out-bottom' | 'pop-out' | 'fade-out' | 'zoom-in' | 'zoom-fade-in' | 'none';
|
||||
|
||||
export declare function forMatNextToFrom<T extends totalNextRoute>(router: Router, to: T, from: T): {
|
||||
matTo: T;
|
||||
matFrom: T;
|
||||
};
|
||||
|
||||
export declare function getDataType<T>(data: T): string;
|
||||
|
||||
export declare function getRoutePath(route: RoutesRule, router: Router): {
|
||||
finallyPath: string | string[];
|
||||
aliasPath: string;
|
||||
path: string;
|
||||
alias: string | string[] | undefined;
|
||||
};
|
||||
|
||||
export declare function getUniCachePage<T extends objectAny>(pageIndex?: number): T | [];
|
||||
|
||||
export declare function getWildcardRule(router: Router, msg?: navErrorRule): RoutesRule | never;
|
||||
|
||||
export declare type guardHookRule = (to: totalNextRoute, from: totalNextRoute, next: (rule?: navtoRule | false) => void) => void;
|
||||
|
||||
export declare interface H5Config {
|
||||
paramsToQuery?: boolean;
|
||||
vueRouterDev?: boolean;
|
||||
vueNext?: boolean;
|
||||
mode?: string;
|
||||
base?: string;
|
||||
linkActiveClass?: string;
|
||||
linkExactActiveClass?: string;
|
||||
scrollBehavior?: Function;
|
||||
fallback?: boolean;
|
||||
}
|
||||
|
||||
export declare interface h5NextRule {
|
||||
fullPath?: string | undefined;
|
||||
hash?: string | undefined;
|
||||
matched?: Array<object>;
|
||||
meta?: object;
|
||||
name?: undefined | string;
|
||||
type?: undefined | string;
|
||||
}
|
||||
|
||||
export declare type hookListRule = Array<(router: Router, to: totalNextRoute, from: totalNextRoute, toRoute: RoutesRule, next: Function) => void>;
|
||||
|
||||
export declare interface hookObjectRule {
|
||||
options: Array<any>;
|
||||
hook: Function;
|
||||
}
|
||||
|
||||
declare type hookRule = (args: Array<any>, next: (args: Array<any>) => void, router: Router) => void;
|
||||
|
||||
export declare enum hookToggle {
|
||||
'beforeHooks' = "beforeEach",
|
||||
'afterHooks' = "afterEach",
|
||||
'enterHooks' = "beforeEnter"
|
||||
}
|
||||
|
||||
export declare interface InstantiateConfig {
|
||||
[key: string]: any;
|
||||
keepUniOriginNav?: boolean;
|
||||
platform: platformRule;
|
||||
h5?: H5Config;
|
||||
APP?: AppConfig;
|
||||
applet?: appletConfig;
|
||||
beforeProxyHooks?: proxyHooksConfig;
|
||||
debugger?: debuggerConfig;
|
||||
routerBeforeEach?: (to: navtoRule, from: navtoRule, next: (rule?: navtoRule | false) => void) => void;
|
||||
routerAfterEach?: (to: navtoRule, from: navtoRule, next?: Function) => void;
|
||||
routerErrorEach?: (error: navErrorRule, router: Router) => void;
|
||||
resolveQuery?: (jsonQuery: objectAny) => objectAny;
|
||||
parseQuery?: (jsonQuery: objectAny) => objectAny;
|
||||
detectBeforeLock?: (router: Router, to: string | number | totalNextRoute | navRoute, navType: NAVTYPE) => void;
|
||||
routes: RoutesRule[];
|
||||
}
|
||||
|
||||
export declare interface LifeCycleConfig {
|
||||
beforeHooks: hookListRule;
|
||||
afterHooks: hookListRule;
|
||||
routerBeforeHooks: hookListRule;
|
||||
routerAfterHooks: hookListRule;
|
||||
routerErrorHooks: Array<(error: navErrorRule, router: Router) => void>;
|
||||
}
|
||||
|
||||
export declare function lockDetectWarn(router: Router, to: string | number | totalNextRoute | navRoute, navType: NAVTYPE, next: Function, uniActualData?: uniBackApiRule | uniBackRule | undefined, passiveType?: 'beforeHooks' | 'afterHooks'): void;
|
||||
|
||||
export declare function mergeConfig<T extends InstantiateConfig>(baseConfig: T, userConfig: T): T;
|
||||
|
||||
export declare interface navErrorRule {
|
||||
type: navRuleStatus;
|
||||
msg: string;
|
||||
to?: totalNextRoute;
|
||||
from?: totalNextRoute;
|
||||
nextTo?: any;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export declare type navMethodRule = Promise<void | undefined | navRuleStatus>;
|
||||
|
||||
export declare interface navRoute extends h5NextRule, navtoRule {
|
||||
}
|
||||
|
||||
export declare type navRuleStatus = 0 | 1 | 2 | 3;
|
||||
|
||||
export declare interface navtoRule {
|
||||
NAVTYPE?: NAVTYPE;
|
||||
path?: string;
|
||||
name?: string | undefined;
|
||||
query?: objectAny;
|
||||
params?: objectAny;
|
||||
animationType?: startAnimationType | endAnimationType;
|
||||
animationDuration?: number;
|
||||
events?: objectAny;
|
||||
success?: Function;
|
||||
fail?: Function;
|
||||
complete?: Function;
|
||||
}
|
||||
|
||||
export declare type NAVTYPE = 'push' | 'replace' | 'replaceAll' | 'pushTab' | 'back';
|
||||
|
||||
export declare enum navtypeToggle {
|
||||
'push' = "navigateTo",
|
||||
'replace' = "redirectTo",
|
||||
'replaceAll' = "reLaunch",
|
||||
'pushTab' = "switchTab",
|
||||
'back' = "navigateBack"
|
||||
}
|
||||
|
||||
export declare function notDeepClearNull<T>(object: T): T;
|
||||
|
||||
export declare function notRouteTo404(router: Router, toRoute: RoutesRule | {
|
||||
redirect: any;
|
||||
path: string;
|
||||
}, parseToRule: totalNextRoute, navType: NAVTYPE): RoutesRule | totalNextRoute | never;
|
||||
|
||||
export declare type objectAny = {
|
||||
[propName: string]: any;
|
||||
};
|
||||
|
||||
export declare interface originMixins extends uniNavApiRule {
|
||||
BACKTYPE: '' | backTypeRule;
|
||||
}
|
||||
|
||||
export declare type pageTypeRule = 'app' | 'page' | 'component';
|
||||
|
||||
export declare function paramsToQuery(router: Router, toRule: totalNextRoute | string): totalNextRoute | string;
|
||||
|
||||
export declare type platformRule = 'h5' | 'app-plus' | 'app-lets' | 'mp-weixin' | 'mp-baidu' | 'mp-alipay' | 'mp-toutiao' | 'mp-qq' | 'mp-360';
|
||||
|
||||
export declare type PromiseResolve = (value?: void | PromiseLike<void> | undefined) => void;
|
||||
|
||||
export declare type proxyDepsRule = {
|
||||
resetIndex: Array<number>;
|
||||
hooks: {
|
||||
[key: number]: {
|
||||
proxyHook: () => void;
|
||||
callHook: (enterPath: string) => void;
|
||||
resetHook: () => void;
|
||||
};
|
||||
};
|
||||
options: {
|
||||
[key: number]: Array<any>;
|
||||
};
|
||||
};
|
||||
|
||||
export declare type proxyHookName = 'beforeHooks' | 'afterHooks';
|
||||
|
||||
export declare interface proxyHooksConfig {
|
||||
onLaunch?: hookRule;
|
||||
onShow?: hookRule;
|
||||
onHide?: hookRule;
|
||||
onError?: hookRule;
|
||||
onInit?: hookRule;
|
||||
onLoad?: hookRule;
|
||||
onReady?: hookRule;
|
||||
onUnload?: hookRule;
|
||||
onResize?: hookRule;
|
||||
destroyed?: hookRule;
|
||||
created?: hookRule;
|
||||
beforeCreate?: hookRule;
|
||||
beforeMount?: hookRule;
|
||||
mounted?: hookRule;
|
||||
beforeDestroy?: hookRule;
|
||||
}
|
||||
|
||||
export declare type reloadNavRule = totalNextRoute | false | undefined | string;
|
||||
|
||||
export declare function removeSimpleValue(array: Array<string | number>, value: string): Boolean;
|
||||
|
||||
export declare type reNavMethodRule = 'navigateTo' | 'redirectTo' | 'reLaunch' | 'switchTab';
|
||||
|
||||
export declare type reNotNavMethodRule = 'navigateBack';
|
||||
|
||||
export declare function resolveAbsolutePath(path: string, router: Router): string | never;
|
||||
|
||||
export declare enum rewriteMethodToggle {
|
||||
'navigateTo' = "push",
|
||||
'navigate' = "push",
|
||||
'redirectTo' = "replace",
|
||||
'reLaunch' = "replaceAll",
|
||||
'switchTab' = "pushTab",
|
||||
'navigateBack' = "back"
|
||||
}
|
||||
|
||||
export declare interface Router {
|
||||
readonly lifeCycle: LifeCycleConfig;
|
||||
readonly options: InstantiateConfig;
|
||||
$lockStatus: boolean;
|
||||
$route: object | null;
|
||||
enterPath: string;
|
||||
runId: number;
|
||||
Vue: any;
|
||||
appMain: {
|
||||
NAVTYPE: reNavMethodRule | reNotNavMethodRule;
|
||||
path: string;
|
||||
} | {};
|
||||
proxyHookDeps: proxyDepsRule;
|
||||
routesMap: routesMapRule | {};
|
||||
mount: Array<{
|
||||
app: any;
|
||||
el: string;
|
||||
}>;
|
||||
install(Vue: any): void;
|
||||
push(to: totalNextRoute | navRoute | string, from?: totalNextRoute): void;
|
||||
replace(to: totalNextRoute | navRoute | string, from?: totalNextRoute): void;
|
||||
replaceAll(to: totalNextRoute | navRoute | string, from?: totalNextRoute): void;
|
||||
pushTab(to: totalNextRoute | navRoute | string, from?: totalNextRoute): void;
|
||||
back(level: number | undefined, origin?: uniBackRule | uniBackApiRule): void;
|
||||
forceGuardEach(navType: NAVTYPE | undefined, forceNav: boolean): void;
|
||||
beforeEach(userGuard: guardHookRule): void;
|
||||
afterEach(userGuard: (to: totalNextRoute, from: totalNextRoute) => void): void;
|
||||
}
|
||||
|
||||
export declare function RouterMount(Vim: any, router: Router, el?: string | undefined): void | never;
|
||||
|
||||
export declare interface routeRule {
|
||||
name: string | undefined;
|
||||
meta: objectAny;
|
||||
path: string;
|
||||
query: objectAny;
|
||||
params: objectAny;
|
||||
fullPath: string;
|
||||
NAVTYPE: NAVTYPE | '';
|
||||
BACKTYPE?: backTypeRule | '';
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export declare function routesForMapRoute(router: Router, path: string, mapArrayKey: Array<routesMapKeysRule>, deepFind?: boolean | undefined): RoutesRule | never;
|
||||
|
||||
export declare type routesMapKeysRule = 'finallyPathList' | 'finallyPathMap' | 'aliasPathMap' | 'pathMap' | 'nameMap' | 'vueRouteMap';
|
||||
|
||||
export declare interface routesMapRule {
|
||||
[key: string]: any;
|
||||
finallyPathList: Array<string>;
|
||||
finallyPathMap: RoutesRule;
|
||||
aliasPathMap: RoutesRule;
|
||||
pathMap: RoutesRule;
|
||||
nameMap: RoutesRule;
|
||||
vueRouteMap: objectAny;
|
||||
}
|
||||
|
||||
export declare interface RoutesRule {
|
||||
path: string;
|
||||
component?: object;
|
||||
name?: string;
|
||||
components?: object;
|
||||
redirect?: string | Function;
|
||||
props?: boolean | object | Function;
|
||||
aliasPath?: string;
|
||||
alias?: string | Array<string>;
|
||||
children?: Array<RoutesRule>;
|
||||
beforeEnter?: guardHookRule;
|
||||
meta?: any;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export declare function runtimeQuit(title?: string | undefined): void;
|
||||
|
||||
export declare interface startAnimationRule {
|
||||
animationType?: startAnimationType;
|
||||
animationDuration?: number;
|
||||
}
|
||||
|
||||
export declare type startAnimationType = 'slide-in-right' | 'slide-in-left' | 'slide-in-top' | 'slide-in-bottom' | 'pop-in' | 'fade-in' | 'zoom-out' | 'zoom-fade-out' | 'none';
|
||||
|
||||
export declare function timeOut(time: number): Promise<void>;
|
||||
|
||||
export declare interface totalNextRoute extends h5NextRule, navtoRule {
|
||||
path: string;
|
||||
delta?: number;
|
||||
[propName: string]: any;
|
||||
}
|
||||
|
||||
export declare interface uniBackApiRule {
|
||||
delta?: number;
|
||||
animationDuration?: number;
|
||||
animationType?: endAnimationType;
|
||||
}
|
||||
|
||||
export declare interface uniBackRule {
|
||||
from: backTypeRule;
|
||||
}
|
||||
|
||||
export declare interface uniNavApiRule {
|
||||
url: string;
|
||||
openType?: 'appLaunch';
|
||||
query?: objectAny;
|
||||
path?: string;
|
||||
delta?: number;
|
||||
detail?: {
|
||||
[propName: string]: any;
|
||||
};
|
||||
animationType?: startAnimationType;
|
||||
animationDuration?: number;
|
||||
events?: {
|
||||
[propName: string]: any;
|
||||
};
|
||||
success?: Function;
|
||||
fail?: Function;
|
||||
complete?: Function;
|
||||
animation?: {
|
||||
animationType?: startAnimationType;
|
||||
animationDuration?: number;
|
||||
};
|
||||
}
|
||||
|
||||
export declare function urlToJson(url: string): {
|
||||
path: string;
|
||||
query: objectAny;
|
||||
};
|
||||
|
||||
export declare function voidFun(...args: any): void;
|
||||
|
||||
export declare type vueHookNameRule = 'onLaunch' | 'onShow' | 'onHide' | 'onError' | 'onInit' | 'onLoad' | 'onReady' | 'onUnload' | 'onResize' | 'created' | 'beforeMount' | 'mounted' | 'beforeDestroy' | 'destroyed';
|
||||
|
||||
export declare type vueOptionRule = {
|
||||
[propName in vueHookNameRule]: Array<Function> | undefined;
|
||||
};
|
||||
|
||||
export { }
|
||||
|
||||
// @ts-ignore
|
||||
declare module 'vue/types/vue' {
|
||||
interface Vue {
|
||||
$Router: Router;
|
||||
$Route: routeRule;
|
||||
}
|
||||
}
|
||||
|
||||
1
js_sdk/uni-simple-router/uni-simple-router.js
Normal file
35
pages.json
@@ -72,7 +72,32 @@
|
||||
"navigationBarTitleText" : "维修开单",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
},
|
||||
}, {
|
||||
"path" : "pages/repair/repair/reservation/createNewOrder",
|
||||
"style": {
|
||||
"navigationBarTitleText" : "接单信息",
|
||||
"enablePullDownRefresh" : false,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
}, {
|
||||
"path" : "pages/repair/repair/reservation/createProject",
|
||||
"style": {
|
||||
"navigationBarTitleText" : "添加维修项目",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
}, {
|
||||
"path" : "pages/repair/repair/reservation/auxiliary/material",
|
||||
"style": {
|
||||
"navigationBarTitleText" : "",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
}, {
|
||||
"path" : "pages/repair/repair/reservation/auxiliary/package",
|
||||
"style": {
|
||||
"navigationBarTitleText" : "选择套餐",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -190,14 +215,6 @@
|
||||
"navigationBarTitleText": "签到",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path" : "pages/repair/repair/reservation/createOrder",
|
||||
"style" :
|
||||
{
|
||||
"navigationBarTitleText" : "维修开单",
|
||||
"enablePullDownRefresh" : false
|
||||
}
|
||||
}
|
||||
],
|
||||
"tabBar": {
|
||||
|
||||
122
pages/repair/repair/reservation/auxiliary/material.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- 添加材料页面 -->
|
||||
<template>
|
||||
<view>
|
||||
<view class="bg-white">
|
||||
<u-tabs :list="tabsList" lineWidth="29" lineColor="#111111" :fixed="false" :scrollable="false"></u-tabs>
|
||||
</view>
|
||||
<z-paging use-page-scroll>
|
||||
<view class="product-item bg-white flex align-center">
|
||||
<view class="left">
|
||||
<image src="@/static/htz-image-upload/play.png" mode=""></image>
|
||||
</view>
|
||||
<view class="right flex-column justify-between">
|
||||
<view class="item f-32 c111">
|
||||
配件名称
|
||||
</view>
|
||||
<view class="item f-26 c666">
|
||||
品牌
|
||||
</view>
|
||||
<view class="item f-26 c222">
|
||||
规格
|
||||
</view>
|
||||
<view class="flex align-center justify-between">
|
||||
<view class="f-38 red fw-b">
|
||||
¥198.00
|
||||
</view>
|
||||
<view class="price-num" v-if="value">
|
||||
<u-number-box v-model="value" @change="valChange">
|
||||
<view slot="minus" class="minus bg-white">
|
||||
<u-icon name="minus-circle" size="20" color="#13AFA8" ></u-icon>
|
||||
</view>
|
||||
<text slot="input" class="input">{{value}}</text>
|
||||
<view slot="plus" class="plus bg-white">
|
||||
<u-icon name="plus-circle-fill" color="#13AFA8" size="20"></u-icon>
|
||||
</view>
|
||||
</u-number-box>
|
||||
</view>
|
||||
<u-icon v-else name="plus-circle-fill" color="#13AFA8" size="20"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</z-paging>
|
||||
<view class="bot-box fixed-bottom bg-white">
|
||||
<view class="flex align-center justify-between">
|
||||
<view class="f-28">
|
||||
共2件
|
||||
</view>
|
||||
<u-button class="btn" color="#13AFA8" shape="circel">提交</u-button>
|
||||
</view>
|
||||
<view style="height: 64rpx;" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: 0,
|
||||
tabsList: [{
|
||||
name: '自供'
|
||||
},{
|
||||
name: '外采'
|
||||
}]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
valChange(e) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.product-item {
|
||||
margin: 24rpx;
|
||||
padding: 32rpx 24rpx;
|
||||
.right {
|
||||
margin-left: 16rpx;
|
||||
width: 500rpx;
|
||||
height: 192rpx;
|
||||
.item {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
.price-num {
|
||||
transform: translateX(40rpx);
|
||||
}
|
||||
.minus {
|
||||
border-radius: 50%;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
.plus {
|
||||
border-radius: 50%;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
.input {
|
||||
width: 142rpx;
|
||||
text-align: center;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 35rpx;
|
||||
}
|
||||
image {
|
||||
width: 192rpx;
|
||||
height: 192rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
}
|
||||
.bot-box {
|
||||
padding: 18rpx 24rpx 0 24rpx;
|
||||
width: 750rpx;
|
||||
.btn {
|
||||
margin: 0;
|
||||
width: 480rpx;
|
||||
height: 96rpx;
|
||||
border-radius: 48rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
100
pages/repair/repair/reservation/auxiliary/package.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<!-- 套餐页面 -->
|
||||
<template>
|
||||
<view>
|
||||
<z-paging>
|
||||
<view class="item-box bg-white" v-for="(item,index) in 10" :key="index" @click="checkItem(item, index)">
|
||||
<view class="item-box-title flex align-center justify-between">
|
||||
<text>B级保养</text>
|
||||
<image v-show="index==indexs" src="@/static/images/icon/true.png" mode=""></image>
|
||||
</view>
|
||||
<view class=" f-28 c111" v-for="(t,i) in 3" :key="i" :class="[indexs !== index ? 'no_item' : 'item']">
|
||||
<view class="item-title c666">
|
||||
<text>更换齿轮油</text>
|
||||
</view>
|
||||
<view class="item-title flex align-center justify-between">
|
||||
<text>美孚(合成齿轮油)SHC600系列</text>
|
||||
<text>¥100.00</text>
|
||||
</view>
|
||||
<view class="item-title flex align-center justify-between">
|
||||
<text>工时:0.3</text>
|
||||
<text>¥20.00</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 200rpx;" />
|
||||
</z-paging>
|
||||
<view class="btn-box fixed-bottom">
|
||||
<u-button class="btn" color="#13AFA8" shape="circle">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
indexs: 0
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
checkItem(item, index) {
|
||||
this.indexs = index
|
||||
},
|
||||
open(e) {
|
||||
// console.log('open', e)
|
||||
},
|
||||
close(e) {
|
||||
// console.log('close', e)
|
||||
},
|
||||
change(e) {
|
||||
// console.log('change', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.item-box {
|
||||
margin: 24rpx;
|
||||
padding: 32rpx;
|
||||
width: 702rpx;
|
||||
border-radius: 8rpx;
|
||||
.item-box-title {
|
||||
font-size: 32rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #111111;
|
||||
line-height: 44rpx;
|
||||
image {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
.item {
|
||||
margin-top: 24rpx;
|
||||
padding-top: 16rpx;
|
||||
border-top: 1rpx solid #f5f5f5;
|
||||
line-height: 40rpx;
|
||||
.item-title {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
}
|
||||
.no_item {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
transition: height 1s;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
background-color: #f5f5f5;
|
||||
.btn {
|
||||
width: 702rpx;
|
||||
margin: 42rpx 24rpx 68rpx 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
266
pages/repair/repair/reservation/createNewOrder.vue
Normal file
@@ -0,0 +1,266 @@
|
||||
<template>
|
||||
<view>
|
||||
<view class="navbar">
|
||||
<view :style="`height: ${$u.sys().statusBarHeight}px;`" />
|
||||
<view class="navbar-content rel">
|
||||
<view class="back-icon abs flex-center" @click="$tab.navigateBack">
|
||||
<image src="@/static/images/icon/arrow-left.png" mode=""></image>
|
||||
</view>
|
||||
<view class="f-36 fw-b black">
|
||||
接单信息
|
||||
</view>
|
||||
<view class="navbar-btn abs">
|
||||
<u-button
|
||||
:customStyle="{width: '136rpx', height: '48rpx',fontSize: '28rpx',padding: 0}"
|
||||
color="#13AFA8"
|
||||
@click="submitOrder">
|
||||
<text style="line-height: 1">提交工单</text>
|
||||
</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="">
|
||||
<u-form>
|
||||
<view class="form-box bg-white">
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
公里数
|
||||
<u-input border="none" input-align="right" placeholder="请输入公里数"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
故障现象
|
||||
<image @click="addFault" class="push_circle_black" src="@/static/images/icon/plus_circle_black.png" mode=""></image>
|
||||
</view>
|
||||
<view class="fault-item">
|
||||
<u-input border="none" v-model="faultValue" placeholder="请填写故障现象"></u-input>
|
||||
</view>
|
||||
<view class="fault-item flex align-center justify-between" v-for="(item, index) in qList" :key="index">
|
||||
{{item.content}}
|
||||
<image src="@/static/images/icon/x_2.png" mode="" @click="delFaultItem(index)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
车头图片
|
||||
<image-upload v-model="form.maintenance.headerImage" imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_box.png" />
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
车架号照片
|
||||
<image-upload v-model="form.maintenance.vinImage" imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_box.png" />
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
仪表盘照片
|
||||
<image-upload v-model="form.maintenance.dashboardImage" imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_box.png" />
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
行驶证及驾驶证
|
||||
<view class="flex">
|
||||
<image-upload v-model="form.maintenance.drivingLicenseImage" imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_x.png" />
|
||||
<image-upload v-model="form.maintenance.driveLicenseImage" imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_j.png" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom>
|
||||
<view class="form-item">
|
||||
<view class="flex align-center justify-between">
|
||||
故障照片/视频
|
||||
<image-upload imageWidth="112" round="8" clearIcon="../../../../static/images/icon/reduce.png" uploadIcon="../../../../static/images/icon/plus_box.png" />
|
||||
</view>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="btn-center-box bg-white flex justify-center align-center c111 f-28" @click="$tab.navigateTo('./createProject')">
|
||||
<image class="plus-icon" src="@/static/images/icon/plus_circle_black.png" mode=""></image>
|
||||
添加维修项目
|
||||
</view>
|
||||
<view class="form-box">
|
||||
<u-form-item>
|
||||
<view class="form-item">
|
||||
<text>维修项目1</text>
|
||||
<text>
|
||||
B保
|
||||
<image class="edit-icon" src="@/static/images/icon/edit.png" mode=""></image>
|
||||
</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="form-box bg-white">
|
||||
<u-form-item>
|
||||
<view class="form-item">
|
||||
<text>合计金额</text>
|
||||
<text>¥640.00</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
<u-form-item>
|
||||
<view class="form-item">
|
||||
<text>大写金额</text>
|
||||
<text>陆佰肆拾元整</text>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<view class="form-box bg-white">
|
||||
<u-form-item>
|
||||
<view class="form-item">
|
||||
<u-input type="textarea" placeholder="整备备注 (选填)"></u-input>
|
||||
</view>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</u-form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import imageUpload from '@/components/image-upload/image-upload';
|
||||
import { createAndBill } from '@/api/repair/repair'
|
||||
export default {
|
||||
components: { imageUpload },
|
||||
data() {
|
||||
return {
|
||||
qList: [],
|
||||
faultValue: '',
|
||||
form: {
|
||||
carNo: '', // 车牌号
|
||||
faultList: [], // 故障描述列表
|
||||
maintenance: { // 维修接待开单接单信息请求对象
|
||||
dashboardImage: '', // 仪表盘照片
|
||||
driveLicenseImage: '', // 驾驶证照片
|
||||
drivingLicenseImage: '', // 行驶证照片
|
||||
faultImage: '', // 故障照片
|
||||
faultVideo: '', // 故障视频
|
||||
headerImage: '', // 车头照片
|
||||
kilometer: 0, // 公里数
|
||||
vinImage: '' // 车架号照片
|
||||
},
|
||||
name: '', // 司机名称
|
||||
phone: '', // 联系方式
|
||||
repairType: 1, // 维修类型 1=常规保养2=故障维修3=事故维修4=退车
|
||||
projectList: [{ // 维修项目
|
||||
accessoryList: [{ // 工单项目材料表请求对象
|
||||
isPackage: 0, // 0=自定义,1=套餐快速
|
||||
name: '', // 维修项目名称
|
||||
packageId: '', // 套餐id
|
||||
price: '', // 材料价格
|
||||
type: '', // 1=金额计价,2=工时计价
|
||||
workingHour: 0, // 工时(小时)
|
||||
workingPrice: 0, // 工时价格
|
||||
}]
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
//
|
||||
addFault() {
|
||||
if(this.faultValue) {
|
||||
this.qList.push({content: this.faultValue})
|
||||
this.faultValue = ''
|
||||
}
|
||||
},
|
||||
delFaultItem(index) {
|
||||
this.qList.splice(index, 1)
|
||||
},
|
||||
submitOrder() {
|
||||
console.log('提交');
|
||||
this.form.faultList = this.qList
|
||||
console.log('form表单', this.form);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
.navbar {
|
||||
width: 750rpx;
|
||||
background-color: #fff;
|
||||
.navbar-content {
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
text-align: center;
|
||||
.back-icon {
|
||||
top: 50%;
|
||||
left: 24rpx;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
transform: translateY(-50%);
|
||||
image {
|
||||
width: 18rpx;
|
||||
height: 34rpx;
|
||||
}
|
||||
}
|
||||
.navbar-btn {
|
||||
right: 24rpx;
|
||||
top: 50%;
|
||||
width: 144rpx;
|
||||
height: 56rpx;
|
||||
transform: translateY(-50%);
|
||||
image {
|
||||
margin-right: 8rpx;
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn-center-box {
|
||||
margin: 0 auto;
|
||||
width: 702rpx;
|
||||
border-radius: 8rpx;
|
||||
line-height: 108rpx;
|
||||
.plus-icon {
|
||||
margin-right: 16rpx;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
}
|
||||
.form-box {
|
||||
margin: 24rpx;
|
||||
padding: 0 32rpx 40rpx 32rpx;
|
||||
border-radius: 8rpx;
|
||||
.form-item {
|
||||
width: 100%;
|
||||
.push_circle_black {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
.fault-item {
|
||||
padding: 16rpx 0;
|
||||
width: 632rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
line-height: 40rpx;
|
||||
image {
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
}
|
||||
}
|
||||
.edit-icon {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- 未处理维修开单 / 预约维修开单-->
|
||||
<template>
|
||||
<view>
|
||||
<u-form label-width="80">
|
||||
@@ -9,20 +10,20 @@
|
||||
</u-form-item>
|
||||
<view class="bg-white pb-3 primary-radius">
|
||||
<u-form-item border-bottom label="所属公司" class="forms-item">
|
||||
<u-input border="none" placeholder="浙江有限公司" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="data.company" placeholder="浙江有限公司" input-align="right"></u-input>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom label="维修类型" class="forms-item">
|
||||
<u-input border="none" placeholder="请选择维修类型" input-align="right">
|
||||
<template slot="sufix">
|
||||
<u-input disabled disabledColor="#fff" @click="openType" border="none" v-model="form.repairType" placeholder="请选择维修类型" input-align="right">
|
||||
<template slot="suffix">
|
||||
<image style="width: 8rpx;height: 16rpx;" src="@/static/images/icon/arrow-right.png" mode=""></image>
|
||||
</template>
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom label="司机名称" class="forms-item">
|
||||
<u-input border="none" placeholder="请输入送修人姓名" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="form.name" placeholder="请输入送修人姓名" input-align="right"></u-input>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom label="联系方式" class="forms-item">
|
||||
<u-input border="none" placeholder="请输入联系方式" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="form.phone" placeholder="请输入联系方式" input-align="right"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
<u-form-item>
|
||||
@@ -30,39 +31,84 @@
|
||||
</u-form-item>
|
||||
<view class="bg-white pb-3 primary-radius">
|
||||
<u-form-item border-bottom label="车架号" class="forms-item">
|
||||
<u-input border="none" placeholder="请输入车架号" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="data.vinId" placeholder="请输入车架号" input-align="right"></u-input>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom label="车辆品牌" class="forms-item">
|
||||
<u-input border="none" placeholder="请选择车辆品牌" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="data.brandName" placeholder="请选择车辆品牌" input-align="right">
|
||||
<image class="right-icon" src="@/static/images/icon/arrow-right.png" slot="suffix" mode=""></image>
|
||||
</u-input>
|
||||
</u-form-item>
|
||||
<u-form-item border-bottom label="车辆型号" class="forms-item">
|
||||
<u-input border="none" placeholder="请输入车辆型号" input-align="right"></u-input>
|
||||
<u-input border="none" v-model="data.modelName" placeholder="请输入车辆型号" input-align="right"></u-input>
|
||||
</u-form-item>
|
||||
</view>
|
||||
</u-form>
|
||||
<u-keyboard ref="uKeyboard" mode="car" @change="carNoChange" safeAreaInsetBottom :show="carShow" autoChange></u-keyboard>
|
||||
<view class="btn-bottom">
|
||||
<u-button color="#13AFA8" @click="toNewCreate">创建工单</u-button>
|
||||
<view class="" style="height: 60rpx;"/>
|
||||
</view>
|
||||
<cell-list ref="cellList" title="维修类型" :list="typelist"></cell-list>
|
||||
<u-keyboard ref="uKeyboard" mode="car" @cancel="cancel" @confirm="carConfirm" @change="carNoChange" safeAreaInsetBottom :show="carShow" autoChange></u-keyboard>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getCarInfo} from '@/api/repair/repair'
|
||||
import { getCarInfo } from '@/api/repair/repair';
|
||||
import cellList from '@/components/cell-list/cell-list';
|
||||
import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
components: {cellList},
|
||||
computed: { ...mapGetters(['btnState'])},
|
||||
data() {
|
||||
return {
|
||||
carShow: false,
|
||||
|
||||
typeShoe: false,
|
||||
form: {
|
||||
carNo: '', // 车牌号
|
||||
name: '', // 司机名称
|
||||
repairType: '', // 维修类型
|
||||
phone: '', // 联系方式
|
||||
}
|
||||
},
|
||||
data: {},
|
||||
typelist: [{
|
||||
text: '常规保养',
|
||||
type: 1
|
||||
},{
|
||||
text: '故障维修',
|
||||
type: 2
|
||||
},{
|
||||
text: '事故维修',
|
||||
type: 3
|
||||
},{
|
||||
text: '退车',
|
||||
type: 4
|
||||
}]
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
console.log(this.btnState);
|
||||
},
|
||||
methods: {
|
||||
toNewCreate() {
|
||||
this.$tab.navigateTo('/pages/repair/repair/reservation/createNewOrder')
|
||||
},
|
||||
openType() {
|
||||
this.$refs.cellList.show = true
|
||||
},
|
||||
cancel() {
|
||||
this.carShow = false
|
||||
},
|
||||
// 点击确认
|
||||
carConfirm() {
|
||||
console.log(this.form.carNo);
|
||||
getCarInfo({carNo: this.form.carNo}).then(res => {
|
||||
console.log(res);
|
||||
this.data = res.data
|
||||
}).finally(() => {
|
||||
this.carShow = false
|
||||
})
|
||||
},
|
||||
//
|
||||
carNoChange(e) {
|
||||
let a = this.checkType(e);
|
||||
if(a == 1) {
|
||||
@@ -119,6 +165,10 @@ page {
|
||||
padding: 12rpx 32rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 8rpx;
|
||||
.right-icon {
|
||||
width: 8rpx;
|
||||
height: 16rpx;
|
||||
}
|
||||
}
|
||||
.forms-title {
|
||||
font-size: 32rpx;
|
||||
@@ -126,4 +176,12 @@ page {
|
||||
color: #222222;
|
||||
line-height: 92rpx;
|
||||
}
|
||||
|
||||
.btn-bottom {
|
||||
margin-top: 188rpx;
|
||||
padding: 0 24rpx;
|
||||
.btn {
|
||||
height: 96rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
232
pages/repair/repair/reservation/createProject.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<template>
|
||||
<view class="">
|
||||
<view class="page-box bg-white">
|
||||
<view class="nav-select flex align-center justify-between">
|
||||
<view class="left">
|
||||
维修项目
|
||||
</view>
|
||||
<view class="content flex align-center justify-start">
|
||||
<view class="center flex align-center" @click="orderType = true">
|
||||
<image v-show="orderType" src="@/static/images/icon/true_1.png" mode=""></image>
|
||||
<image v-show="!orderType" src="@/static/images/icon/false_1.png" mode=""></image>
|
||||
快速开单
|
||||
</view>
|
||||
<view class="right flex align-center" @click="orderType = false">
|
||||
<image v-show="!orderType" src="@/static/images/icon/true_1.png" mode=""></image>
|
||||
<image v-show="orderType" src="@/static/images/icon/false_1.png" mode=""></image>
|
||||
自定义开单
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="nav-select flex align-center justify-between mt-4" v-show="!orderType">
|
||||
<view class="left">
|
||||
选择计价方式
|
||||
</view>
|
||||
<view class="content flex align-center justify-start">
|
||||
<view class="center flex align-center" @click="pricing = false">
|
||||
<image v-show="!pricing" src="@/static/images/icon/true_1.png" mode=""></image>
|
||||
<image v-show="pricing" src="@/static/images/icon/false_1.png" mode=""></image>
|
||||
金额计价
|
||||
</view>
|
||||
<view class="right flex align-center" @click="pricing = true">
|
||||
<image v-show="pricing" src="@/static/images/icon/true_1.png" mode=""></image>
|
||||
<image v-show="!pricing" src="@/static/images/icon/false_1.png" mode=""></image>
|
||||
工时计价
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="" v-show="orderType">
|
||||
<view class="select-item flex align-center justify-between">
|
||||
<view class="select-item-t">
|
||||
添加类型
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
请选择维修类型
|
||||
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between">
|
||||
<view class="select-item-t ">
|
||||
添加项目
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end" @click="$tab.navigateTo('./auxiliary/package')">
|
||||
请选择维修项目
|
||||
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="detail-list">
|
||||
<view class="detail-item flex-column justify-between">
|
||||
<view class="flex align-center justify-between">
|
||||
<text class="c666">更换空调滤芯</text>
|
||||
<image src="@/static/images/icon/edit.png" mode=""></image>
|
||||
</view>
|
||||
<view class="flex align-center justify-between c111">
|
||||
<text>空调滤芯*1</text>
|
||||
<text>¥100.00</text>
|
||||
</view>
|
||||
<view class="flex align-center justify-between">
|
||||
<text>工时:0.3</text>
|
||||
<text>¥20.00</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="" v-show="!orderType">
|
||||
<view class="select-item flex align-center justify-between">
|
||||
<view class="select-item-t">
|
||||
维修项目
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入维修项目"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between" v-show="pricing" @click="$tab.navigateTo('./auxiliary/material')">
|
||||
<view class="select-item-t ">
|
||||
添加材料
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
请选择维修材料
|
||||
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between" v-show="pricing">
|
||||
<view class="select-item-t">
|
||||
材料数量
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入数量"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between">
|
||||
<view class="select-item-t">
|
||||
材料价格
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入价格"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between" v-show="pricing">
|
||||
<view class="select-item-t ">
|
||||
添加工时
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
请选择维修工时
|
||||
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between" v-show="pricing">
|
||||
<view class="select-item-t">
|
||||
工时单价
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入单价"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between" v-show="pricing">
|
||||
<view class="select-item-t">
|
||||
工时数量
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入数量"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
<view class="select-item flex align-center justify-between">
|
||||
<view class="select-item-t">
|
||||
工时价格
|
||||
</view>
|
||||
<view class="select-item-b flex align-center justify-end">
|
||||
<u-input border="none" input-align="right" placeholder="请输入价格"></u-input>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-button class="btn" color="#13AFA8" shape="circle">{{!orderType && !pricing ? '确认' : '提交'}}</u-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderType: true,
|
||||
pricing: true
|
||||
};
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #f5f5f5;
|
||||
padding: 24rpx;
|
||||
}
|
||||
.page-box {
|
||||
padding: 40rpx 32rpx;
|
||||
border-radius: 8rpx;
|
||||
.nav-select {
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
color: #111111;
|
||||
line-height: 40rpx;
|
||||
|
||||
.left {
|
||||
width: 200rpx;
|
||||
}
|
||||
.content {
|
||||
width: 460rpx;
|
||||
.right {
|
||||
margin-left: 100rpx;
|
||||
}
|
||||
}
|
||||
image {
|
||||
margin-right: 8rpx;
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
}
|
||||
}
|
||||
.select-item {
|
||||
padding: 48rpx 0 16rpx 0;
|
||||
border-bottom: 1rpx solid #f5f5f5;
|
||||
.select-item-t {
|
||||
width: 160rpx;
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
color: #444444;
|
||||
line-height: 33rpx;
|
||||
}
|
||||
.select-item-b {
|
||||
width: 100%;
|
||||
}
|
||||
image {
|
||||
margin-left: 8rpx;
|
||||
width: 10rpx;
|
||||
height: 20rpx;
|
||||
}
|
||||
}
|
||||
.detail-list {
|
||||
.detail-item {
|
||||
margin-top: 48rpx;
|
||||
padding: 24rpx;
|
||||
width: 638rpx;
|
||||
height: 200rpx;
|
||||
background: #FFFFFF;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid rgba(0,0,0,0.1);
|
||||
font-size: 28rpx;
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
line-height: 40rpx;
|
||||
image {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.btn {
|
||||
margin: 42rpx 0 68rpx 0;
|
||||
}
|
||||
</style>
|
||||
@@ -23,7 +23,7 @@
|
||||
<u-button
|
||||
:customStyle="{width: '144rpx', height: '56rpx',fontSize: '24rpx',margin: 0}"
|
||||
color="#333333"
|
||||
@click="$tab.navigateTo('/pages/repair/repair/reservation/createOrder')">
|
||||
@click="toCreateOrder">
|
||||
<image src="@/static/images/icon/plus-circle.png" mode=""></image>
|
||||
<text style="line-height: 1">新建</text>
|
||||
</u-button>
|
||||
@@ -134,6 +134,11 @@
|
||||
this.current = e.index
|
||||
this.$refs.paging.reload()
|
||||
},
|
||||
toCreateOrder() {
|
||||
// 维修接待-创建工单
|
||||
if(this.btnState == 'orderType') this.$tab.navigateTo('/pages/repair/repair/reservation/createOrder')
|
||||
|
||||
},
|
||||
// 点击到店
|
||||
toStore(e) {
|
||||
console.log(e);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
this.init()
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
|
||||
BIN
static/images/icon/edit.png
Normal file
|
After Width: | Height: | Size: 647 B |
BIN
static/images/icon/false_1.png
Normal file
|
After Width: | Height: | Size: 759 B |
BIN
static/images/icon/plus_box.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/images/icon/plus_circle_black.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
static/images/icon/plus_j.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
static/images/icon/plus_x.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
static/images/icon/reduce.png
Normal file
|
After Width: | Height: | Size: 663 B |
BIN
static/images/icon/true.png
Normal file
|
After Width: | Height: | Size: 757 B |
BIN
static/images/icon/true_1.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
static/images/icon/true_2.png
Normal file
|
After Width: | Height: | Size: 757 B |
BIN
static/images/icon/x_1.png
Normal file
|
After Width: | Height: | Size: 322 B |
BIN
static/images/icon/x_2.png
Normal file
|
After Width: | Height: | Size: 421 B |
@@ -25,6 +25,12 @@ image {
|
||||
.f-32 {
|
||||
font-size: 32rpx;
|
||||
}
|
||||
.f-34 {
|
||||
font-size: 34rpx;
|
||||
}
|
||||
.f-36 {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
.f-38 {
|
||||
font-size: 38rpx;
|
||||
}
|
||||
@@ -74,12 +80,18 @@ image {
|
||||
.c333 {
|
||||
color: #333333;
|
||||
}
|
||||
.c666 {
|
||||
color: #666666;
|
||||
}
|
||||
.c444 {
|
||||
color: #444444;
|
||||
}
|
||||
.c999 {
|
||||
color: #999999;
|
||||
}
|
||||
.red {
|
||||
color: #F20808;
|
||||
}
|
||||
.c-primary {
|
||||
color: #13AFA8;
|
||||
}
|
||||
@@ -173,6 +185,9 @@ image {
|
||||
.mt-3 {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
.mt-4 {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
.mt-8 {
|
||||
margin-top: 80rpx;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ const request = config => {
|
||||
url = url.slice(0, -1)
|
||||
config.url = url
|
||||
}
|
||||
console.log(config.params);
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
method: config.method || 'get',
|
||||
@@ -38,7 +37,7 @@ const request = config => {
|
||||
}
|
||||
const code = res.data.code || 200
|
||||
const msg = errorCode[code] || res.data.msg || errorCode['default']
|
||||
if (code === 401) {
|
||||
if (code === 401 || code === 402) {
|
||||
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
|
||||
if (res.confirm) {
|
||||
// store.dispatch('LogOut').then(res => {
|
||||
|
||||