列表页

This commit is contained in:
xiaoshan
2023-12-08 19:16:01 +08:00
parent 16a5e19093
commit 7989cc9ec8
87 changed files with 2305 additions and 1905 deletions

25
App.vue
View File

@@ -7,25 +7,26 @@
onLaunch: function() {
this.initApp()
},
onShow() {
uni.hideTabBar()
},
methods: {
// 初始化应用
initApp() {
// 初始化应用配置
this.initConfig()
// 检查用户登录状态
//#ifdef H5
this.checkLogin()
//#endif
this.$store.dispatch('websocketInit')
this.getSys()
},
getSys() {
uni.getSystemInfo({
success: res => {
this.globalData.sys = res
}
})
},
initConfig() {
this.globalData.config = config
},
checkLogin() {
if (!getToken()) {
this.$tab.reLaunch('/pages/login/login')
}
}
}
}
</script>
@@ -34,7 +35,11 @@
@import "@/uni_modules/uview-ui/index.scss";
@import '@/static/scss/index.scss';
@import '@/static/scss/currency.css';
@import '@/static/font/common.css';
page {
background-color: #fff;
}
body {
font-family: Source Han Sans CN, Source Han Sans CN;
}
</style>

24
api/login/index.js Normal file
View File

@@ -0,0 +1,24 @@
import request from '@/utils/request'
/**
* 获取手机验证码
*/
export function getSendCode(data) {
return request({
'url': '/api/front/login/send/code',
method: 'post',
timeout: 20000,
data
})
}
/**
* 维修端验证码登录
*/
export function repairLogin(data) {
return request({
'url': '/api/front/repair/login/mobile/captcha',
'method': 'post',
'data': data
})
}

View File

@@ -1,63 +1,40 @@
import request from '@/utils/request'
// 密码登录
export function login(data) {
return request({
'url': '/ums/login/login/password',
'method': 'post',
'data': data
})
}
// 验证码登录
export function phoneLogin(data) {
return request({
'url': '/ums/login/login/phone',
'method': 'post',
'data': data
})
}
// 微信小程序
export function weixinPhoneLogin(data) {
return request({
'url': '/ums/login/login/phone/xcx/phone',
'method': 'post',
'data': data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
'url': '/ums/user/info',
'method': 'get'
})
}
// 退出方法
export function logout() {
return request({
'url': '/logout',
'method': 'post'
})
}
// 获取验证码
export function getCodeImg() {
return request({
'url': '/captchaImage',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}
// 获取手机验证码
export function getSendCode(data) {
return request({
'url': '/ums/login/sms/sendCode',
method: 'post',
timeout: 20000,
data
})
import request from '@/utils/request'
// 密码登录
export function login(data) {
return request({
'url': '/ums/login/login/password',
'method': 'post',
'data': data
})
}
// 微信小程序
export function weixinPhoneLogin(data) {
return request({
'url': '/ums/login/login/phone/xcx/phone',
'method': 'post',
'data': data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
'url': '/ums/user/info',
'method': 'get'
})
}
// 退出方法
export function logout() {
return request({
'url': '/logout',
'method': 'post'
})
}

78
api/repair/repair.js Normal file
View File

@@ -0,0 +1,78 @@
import request from '@/utils/request'
/**
* 获取维修店首页信息
*/
export function getRepairIndexInfo() {
return request({
'url': '/api/front/merchant/index',
'method': 'get'
})
}
/**
* 获取工单预约列表
*/
export function reservationList(params) {
return request({
url: '/api/front/repair/reservation/management/check/list',
method: 'get',
params
})
}
/**
* 获取事故接待列表
*/
export function accidentList(params) {
return request({
url: '/api/front/repair/accident/order/list',
method: 'get',
params
})
}
/**
* 获取维修接待列表
*/
export function maintenanceList(params) {
return request({
url: '/api/front/repair/maintenance/order/list',
method: 'get',
params
})
}
/**
* 维修接待-创建并开单
*/
export function createAndBill(data) {
return request({
url: '/api/front/repair/maintenance/createAndBill',
method: 'post',
data
})
}
/**
* 获取退车接待列表
*/
export function returnList(params) {
return request({
url: '/api/front/repair/return/order/list',
method: 'get',
params
})
}
/**
* 跟具车牌号查询车辆详情
*/
export function getCarInfo(params) {
return request({
url: '/api/front/car/user/center/getInfo',
method: 'get',
params
})
}

View File

@@ -1,6 +1,24 @@
import upload from '@/utils/upload'
import request from '@/utils/request'
// 查询用户个人信息
export function getUserInfo() {
return request({
url: '/api/front/user/info',
method: 'get'
})
}
// 用户密码重置
export function updateUserPwd(data) {
return request({

View File

@@ -0,0 +1,82 @@
<template>
<view>
<view class="item bg-white c444 f-28">
<view class="item-title flex align-center justify-between">
<text class="f-38 black">浙A·15JD6</text>
<text class="c-danger f-24">待确认</text>
</view>
<view class="flex align-center justify-between">
<text>维修类型</text>
<text>维修保养</text>
</view>
<view class="flex align-center justify-between">
<text>车辆型号</text>
<text>UE5系列</text>
</view>
<view class="flex align-center justify-between">
<text>预约时间</text>
<text>2023-11-07 14:00-14:30</text>
</view>
<view class="btns flex justify-end">
<u-button :customStyle="{width: '160rpx',height: '56rpx', margin: 0, fontSize:'24rpx'}" shape="circle" @click="reject">驳回</u-button>
<u-button :customStyle="{width: '160rpx',height: '56rpx', margin: 0, fontSize:'24rpx'}" shape="circle" @click="toStore">到店</u-button>
<u-button :customStyle="{width: '160rpx',height: '56rpx', margin: '0 0 0 16rpx', fontSize:'24rpx'}" color="#13AFA8" shape="circle" @click="argee">同意</u-button>
</view>
</view>
</view>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
name:"billing-item",
props: {
item: {
type: Object,
default() {
return {}
}
}
},
components: {
...mapGetters(['btnStatw'])
},
data() {
return {
show: false,
};
},
methods: {
argee() {
this.$emit('argee', this.item)
},
reject() {
this.$emit('reject', this.item)
},
toStore() {
console.log('点击');
this.$emit('toStore', this.item)
}
}
}
</script>
<style lang="scss">
.item {
margin-bottom: 24rpx;
padding: 16rpx 24rpx;
width: 750rpx;
line-height: 40rpx;
.item-title {
line-height: 54rpx;
}
.btns {
margin-top: 24rpx;
padding-top: 24rpx;
border-top: 1rpx solid #EDEDED;
}
& view {
margin-bottom: 8rpx;
}
}
</style>

View File

@@ -0,0 +1,51 @@
<template>
<view class="page">
<image :src="image" mode="widthFix"></image>
<view class="nodata-content">
{{text}}
</view>
</view>
</template>
<script>
export default {
name:"empty-view",
props: {
image: {
type: String,
default: '/static/images/icon/nodata_search.png'
},
text: {
type: String,
default: '没有搜索出相关结果~'
}
},
data() {
return {
};
}
}
</script>
<style lang="scss">
.page {
width: 100%;
display: flex;
flex-flow: column;
align-items: center;
}
image {
margin-top: -400rpx;
width: 500rpx;
}
.nodata-content {
margin-top: 40rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #444444;
line-height: 40rpx;
}
</style>

View File

@@ -0,0 +1,106 @@
<template>
<view>
<u-popup :show="show" :mode="mode" :round="round">
<view class="popup-box">
<view class="title">
{{tipContent.title}}
</view>
<view class="content">
{{tipContent.content}}
</view>
<view class="btns" v-if="tipContent.cancelText">
<u-button :color="btnStyle.cancelBg" :customStyle="{ color:btnStyle.cancelColor, lineHeight: '88rpx' }" shape="circle" @click="cancel">{{tipContent.cancelText}}</u-button>
<u-button :color="btnStyle.confirmBg" :customStyle="{marginLeft: '24rpx', color:btnStyle.confirmColor, lineHeight: '88rpx' }" shape="circle" @click="confirm">{{tipContent.confirmText}}</u-button>
</view>
<view class="btn" v-else>
<u-button :color="btnStyle.confirmBg" :customStyle="{ color:btnStyle.confirmColor, lineHeight: '88rpx' }" shape="circle" @click="confirm">{{tipContent.confirmText}}</u-button>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
name:"prompt-box",
props: {
round: {
type: String,
default: '8'
},
mode: {
type: String,
default: 'center'
},
btnStyle: {
type: Object,
default(){
return {
confirmColor: '#ffffff',
cancelColor: '#222222',
confirmBg: '#333333',
cancelBg: '#ededed',
}
}
}
},
data() {
return {
show: false,
tipContent: {
title: '提示',
content: '未查询到您的账号信息,请核实后再登陆',
confirmText: '确认',
cancelText: '',
},
};
},
methods: {
confirm() {
this.show = false
this.$emit('confirm')
},
cancel(){
this.show = false
this.$emit('cancel')
}
}
}
</script>
<style lang="scss" scoped>
.popup-box {
display: flex;
flex-flow: column;
align-items: center;
width: 598rpx;
padding: 60rpx 32rpx;
}
.title {
font-size: 34rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 48rpx;
text-align: center;
}
.content {
margin-top: 22rpx;
width: 500rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #222222;
line-height: 40rpx;
}
.btns {
display: flex;
justify-content: space-between;
margin-top: 60rpx;
width: 100%;
}
.btn {
width: 100%;
margin-top: 60rpx;
}
</style>

View File

@@ -0,0 +1,64 @@
<template>
<view class="tabBar_css">
<u-tabbar
:value="current"
:fixed="true"
:placeholder="true"
:safeAreaInsetBottom="true"
>
<u-tabbar-item
v-for="(item,index) in repairTabList"
:text="item.text"
:name="item.path"
:key="index"
@click="click_page(item)">
<image
class="u-page__item__slot-icon"
style="width: 48rpx;"
slot="active-icon"
mode="widthFix"
:src="item.activeIconPath"
></image>
<image
style="width: 48rpx;"
class="u-page__item__slot-icon"
slot="inactive-icon"
mode="widthFix"
:src="item.iconPath"
></image>
</u-tabbar-item>
</u-tabbar>
</view>
</template>
<script>
import { repairTabList } from '@/data/tabbar'
export default {
name:"tabbar-repair",
props: {
current: {
type: String,
default: '/pages/repair/tabbar/repair'
}
},
data() {
return {
repairTabList,
};
},
mounted() {
uni.hideTabBar();
},
methods: {
click_page(item) {
uni.switchTab({
url: item.path
})
}
}
}
</script>
<style lang="scss">
</style>

View File

@@ -1,8 +1,8 @@
// 应用全局配置
module.exports = {
baseUrl: 'http://121.199.24.205:9107/lxk',
baseUrl: 'https://mall.lianxianke.cn/car_app_api',
// baseUrl: 'http://10.0.21.127:8080/lxk',
fileUploadUrl: 'http://121.199.24.205:9107/lxk/uploadImage',
fileUploadUrl: 'https://mall.lianxianke.cn/car_app_api/uploadImage',
WebSocketUrl: 'ws://121.199.24.205:9107/lxk/websocket',
WebSocketOpen: false,
aliyunOssUrl: "https://jimte.oss-cn-hangzhou.aliyuncs.com",

23
data/tabbar.js Normal file
View File

@@ -0,0 +1,23 @@
export const repairTabList = [
{
text: '维修',
iconPath: '../../../static/images/repair/tabbar/repair.png',
activeIconPath: '../../../static/images/repair/tabbar/repair_active.png',
path: '/pages/repair/tabbar/repair'
}, {
text: '配件',
iconPath: '../../../static/images/repair/tabbar/accessory.png',
activeIconPath: '../../../static/images/repair/tabbar/accessory_active.png',
path: '/pages/repair/tabbar/accessory'
}, {
text: '采购',
iconPath: '../../../static/images/repair/tabbar/procure.png',
activeIconPath: '../../../static/images/repair/tabbar/procure_active.png',
path: '/pages/repair/tabbar/procure'
}, {
text: '我的',
iconPath: '../../../static/images/repair/tabbar/mine.png',
activeIconPath: '../../../static/images/repair/tabbar/mine_active.png',
path: '/pages/repair/tabbar/mine'
}
]

73
data/tabsData.js Normal file
View File

@@ -0,0 +1,73 @@
export const tabsList1 = [{
name: '全部',
value: 'all'
}, {
name: '未确认',
value: 'ucheck'
}, {
name: '未到店',
value: 'noArrive'
}, {
name: '已驳回',
value: 'reject'
}]
export const tabsList2 = [{
name: '接车',
value: 'unpickup'
}, {
name: '定损',
value: 'damage'
}, {
name: '开单',
value: 'unbill'
}, {
name: '维修',
value: 'repairing'
}, {
name: '交车',
value: 'undelivery'
}, {
name: '结算',
value: 'unsettlement'
}, {
name: '完成',
value: 'finish'
}]
export const tabsList3 = [{
name: '未处理',
value: 'untreated'
}, {
name: '待审核',
value: 'billAudit'
}, {
name: '维修中',
value: 'repair'
}, {
name: '已拒绝',
value: 'refuse'
}, {
name: '已完成',
value: 'finish'
}]
export const tabsList4 = [{
name: '接车',
value: 'unpickup'
}, {
name: '确认',
value: 'unbill'
}, {
name: '审核',
value: 'billAudit'
}, {
name: '维修',
value: 'repairing'
}, {
name: '交车',
value: 'undelivery'
}, {
name: '完成',
value: 'finish'
}, {
name: '拒绝',
value: 'refuse'
}]

View File

@@ -1,33 +1,91 @@
{
"pages": [{
"path": "pages/repair/tabbar/repair",
"style": {
"navigationBarTitleText" : "首页",
"navigationStyle": "custom"
}
}, {
"path": "pages/login/driver-login",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom"
}
}, {
"path": "pages/login/server-login",
"style": {
"navigationBarTitleText": "登录",
"navigationStyle": "custom"
}
}, {
"path": "pages/repair/tabbar/accessory",
"style": {
"navigationBarTitleText" : "",
"enablePullDownRefresh" : false
}
}, {
"path": "pages/repair/tabbar/procure",
"style": {
"navigationBarTitleText" : "",
"enablePullDownRefresh" : false
}
}, {
"path": "pages/repair/tabbar/mine",
"style": {
"navigationBarTitleText" : "",
"enablePullDownRefresh" : false
}
}, {
"path": "pages/repair/repair/search",
"style": {
"navigationBarTitleText" : "搜索",
"enablePullDownRefresh" : false,
"navigationBarBackgroundColor": "#f5f5f5"
}
}, {
"path": "pages/repair/repair/message/index",
"style": {
"navigationBarTitleText" : "消息",
"navigationStyle": "custom"
}
}, {
"path": "pages/repair/repair/message/message-list",
"style": {
"navigationBarTitleText" : "系统消息",
"enablePullDownRefresh" : false
}
}, {
"path": "pages/repair/repair/reservation/list",
"style": {
"navigationBarTitleText" : "",
"navigationStyle": "custom"
}
}, {
"path": "pages/repair/repair/reservation/detail",
"style": {
"navigationBarTitleText" : "",
"enablePullDownRefresh" : false
}
}, {
"path": "pages/repair/repair/reservation/createOrder",
"style": {
"navigationBarTitleText" : "维修开单",
"enablePullDownRefresh" : false
}
},
{
"path": "pages/index",
"style": {
"navigationBarTitleText": "若依移动端框架",
"navigationStyle": "custom"
}
}, {
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "登录"
}
}, {
"path": "pages/login/login-code",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/login/login-password",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/login/reset-password",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/work/index",
"style": {
@@ -132,26 +190,12 @@
"navigationBarTitleText": "签到",
"enablePullDownRefresh": false
}
}, {
"path": "pages/live/plug-flow",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}, {
"path": "pages/live/pull-flow",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path" : "pages/mine/faceRecognition/faceRecognition",
"path" : "pages/repair/repair/reservation/createOrder",
"style" :
{
"navigationBarTitleText" : "",
"navigationBarTitleText" : "维修开单",
"enablePullDownRefresh" : false
}
}
@@ -159,28 +203,16 @@
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home_.png",
"text": "首页"
}, {
"pagePath": "pages/work/index",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "工作台"
}, {
"pagePath": "pages/mine/index",
"iconPath": "static/images/tabbar/mine.png",
"selectedIconPath": "static/images/tabbar/mine_.png",
"text": "我的"
}]
"list": [
{"pagePath": "pages/repair/tabbar/repair"},
{"pagePath": "pages/repair/tabbar/accessory"},
{"pagePath": "pages/repair/tabbar/procure"},
{"pagePath": "pages/repair/tabbar/mine"}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarTitleText": "星桔",
"navigationBarBackgroundColor": "#FFFFFF"
}
}

View File

@@ -1,9 +1,10 @@
<template>
<view>
<uni-card class="view-title" :title="title">
<view class="page">
<!-- <uni-card class="view-title" :title="title">
<rich-text v-if="type" class="uni-body view-content" :nodes="content" />
<text v-else class="uni-body view-content">{{ content }}</text>
</uni-card>
</uni-card> -->
<u-parse :content="content"></u-parse>
</view>
</template>
@@ -56,7 +57,10 @@
page {
background-color: #ffffff;
}
.page {
padding: 48rpx 40rpx;
border-top: 1rpx solid #ededed;
}
.view-title {
font-weight: bold;
}

View File

@@ -1,13 +1,8 @@
<template>
<view class="content">
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title">Hello RuoYi</text>
</view>
<button @click="$tab.navigateTo('/pages/live/plug-flow')">推流</button>
<button @click="$tab.navigateTo('/pages/live/pull-flow')">拉流</button>
<button @click="$tab.navigateTo('/pages/mine/faceRecognition/faceRecognition')">人脸识别</button>
<button @click="$tab.navigateTo('/pages/componentsTest')">跳转组件测试页</button>
<view class="">
</view>
</view>
</template>
@@ -18,29 +13,5 @@
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>

View File

@@ -1,494 +0,0 @@
<template>
<div class="page-box" :style="`height: ${livePusherStyle}px;`">
<live-pusher
id='livePusher'
ref="livePusher"
class="livePusher"
:url="`rtmp://121.199.24.205:9116/live/livestream2?secret=0a0b8d0d7dc84232ad8c5d24f3000b00&token=${userToken}`"
:whiteness="whiteness"
:beauty="beauty"
:orientation="orientation"
:aspect="aspect"
:mode="showMode"
:style="`height: ${livePusherStyle}px;`"
:muted="muted"
:enable-camera="true"
:auto-focus="true"
@statechange="statechange"
@netstatus="netstatus"
@error="error"
/>
<div class="camera-box-left" @click="back">
<u-icon name="close" size="22" color="#fff" />
</div>
<div class="camera-box" @click="openEdit">
<text v-if="edit" class="camera-box-text">···</text>
<u-icon v-else name="arrow-right" color="#fff"></u-icon>
</div>
<div class="camera-box-1" @click="close" v-if="liveState" :style="{width: boxWidth}">
<text class="camera-box-text">直播结束</text>
</div>
<div class="camera-box-1" @click="start" v-else :style="{width: boxWidth}">
<text class="camera-box-text">开始直播</text>
</div>
<div class="camera-box-2" @click="switchCamera" :style="{width: boxWidth}">
<text class="camera-box-text">切换镜头</text>
</div>
<div class="camera-box-3" @click="pause" :style="{width: boxWidth}">
<text class="camera-box-text">暂停直播</text>
</div>
<div class="camera-box-4" @click="openShowMode('mode')" :style="{width: boxWidth}">
<text class="camera-box-text">清晰</text>
<text class="camera-box-text">{{showMode}}</text>
<div class="mode-list-1" :style="{width: showModeWidth}">
<text @click="checkMode(item)" :style="{color: showMode == item ? '#00aaff' : '#fff'}" class="camera-box-text" v-for="(item, index) in showModeList" :key="index">
{{item}}
</text>
</div>
</div>
<div class="camera-box-5" @click="openShowMode('aspect')" :style="{width: boxWidth}">
<text class="camera-box-text">宽高</text>
<text class="camera-box-text">{{aspect}}</text>
<div class="mode-list-2" :style="{width: showAspectWidth}">
<text @click="checkMode(item)" :style="{color: aspect == item ? '#00aaff' : '#fff'}" class="camera-box-text" v-for="(item, index) in aspectList" :key="index">
{{item}}
</text>
</div>
</div>
<div class="camera-box-6" @click="isMute" :style="{width: boxWidth}">
<text class="camera-box-text">{{muted ? '静音' : '不静音'}}</text>
</div>
<div class="camera-box-7" @click="openShowMode('orientation')" :style="{width: boxWidth}">
<text class="camera-box-text">方向</text>
<text class="camera-box-text">{{orientationList.filter(i => i.id == orientation)[0].name}}</text>
<div class="mode-list-3" :style="{width: showOrientationWidth}">
<text @click="checkMode(item)" :style="{color: orientation == item.id ? '#00aaff' : '#fff'}" class="camera-box-text" v-for="(item, index) in orientationList" :key="index">
{{item.name}}
</text>
</div>
</div>
<div class="camera-box-8" @click="openShowMode('beaut')" :style="{width: boxWidth}">
<text class="camera-box-text">美颜</text>
<view class="mode-list-4" :style="{width: beautWidth}">
<u-slider
style="width: 500rpx;margin-top: 28rpx;margin-left: 35rpx;"
v-model="beauty"
min="0"
:max="maxType"></u-slider>
</view>
</div>
<div class="camera-box-9" @click="openShowMode('whiteness')" :style="{width: boxWidth}">
<text class="camera-box-text">美白</text>
<div class="mode-list-5" :style="{width: whitenessWidth}">
<u-slider
style="width: 500rpx;margin-top: 28rpx;margin-left: 35rpx;"
v-model="whiteness"
min="0"
:max="maxType"></u-slider>
</div>
</div>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
export default {
data() {
return {
aspect: '16:9',
showMode:'SD',
beauty: 0,
whiteness: 0,
step: 1,
maxType: 10,
orientation: 'vertical',
muted: true,
type: '',
userToken: getToken(),
context: null,
livePusherStyle: 0,
showModeWidth: 0,
showAspectWidth: 0,
showOrientationWidth: 0,
beautWidth: 0,
whitenessWidth: 0,
boxWidth: 0,
liveState: false,
playState: true,
edit: true,
showModeList: [ 'SD', 'HD', 'FHD' ],
aspectList: ['3:2', '9:16', '16:9'],
orientationList: [
{id: 'vertical', name: '竖屏'},
{id: 'horizontal', name: '横屏'}
]
};
},
onReady() {
// 注意需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext("livePusher", this);
uni.getSystemInfo({
success: (res) => {
console.log(res);
this.livePusherStyle = res.screenHeight
}
})
},
mounted() {
// this.startPreview()
},
methods: {
startPreview: function() {
this.context.startPreview({
success: (a) => {
console.log("livePusher.startPreview:" + JSON.stringify(a));
}
});
},
back() {
uni.navigateBack()
},
openEdit() {
this.edit = !this.edit
if(this.edit) {
let timer = setTimeout(() => {
this.boxWidth = 0
clearTimeout(timer)
}, 500)
this.resetWidth()
}
else this.boxWidth = '100rpx'
},
// 静音
isMute() {
this.muted = !this.muted
},
// 选中弹出窗内容
checkMode(item) {
if(this.type == 'mode') this.showMode = item
else if( this.type == 'aspect') this.aspect = item
else if( this.type = 'orientation') {
this.orientation = item.id
let mode = this.showMode
let timer = null
this.showMode = ''
timer = setTimeout(() => {
this.showMode = mode
clearTimeout(timer)
})
}
},
// 打开功能选项弹出
openShowMode(item){
this.type = item
if(item == 'mode') {
// 设置清晰度
if(this.showModeWidth) {
this.showModeWidth = 0
} else {
this.resetWidth()
this.showModeWidth = '300rpx'
}
} else if (item == 'aspect') {
// 设置比例
if(this.showAspectWidth) {
this.showAspectWidth = 0
} else {
this.resetWidth()
this.showAspectWidth = '300rpx'
}
} else if (item == 'orientation') {
// 设置视频方向
if(this.showOrientationWidth) {
this.showOrientationWidth = 0
} else {
this.resetWidth()
this.showOrientationWidth = '200rpx'
}
} else if (item == 'beaut') {
// 设置美颜
if(this.beautWidth) {
this.beautWidth = 0
} else {
this.resetWidth()
this.beautWidth = '560rpx'
}
} else if (item == 'whiteness') {
// 设置美白
if(this.whitenessWidth) {
this.whitenessWidth = 0
} else {
this.resetWidth()
this.whitenessWidth = '560rpx'
}
}
},
// 重置弹窗宽度
resetWidth() {
this.showAspectWidth = 0
this.showModeWidth = 0
this.showOrientationWidth = 0
this.beautWidth = 0
this.whitenessWidth = 0
},
statechange(e) {
// console.log("statechange:" + JSON.stringify(e));
},
netstatus(e) {
// console.log("netstatus:" + JSON.stringify(e));
},
error(e) {
console.log("error:" + JSON.stringify(e));
},
// 开始直播
start: function() {
this.context.start({
success: (a) => {
console.log("livePusher.start:" + JSON.stringify(a));
this.liveState = true
}
});
},
close: function() {
console.log(this.context);
this.context.stop({
success: (a) => {
console.log("livePusher.close:" + JSON.stringify(a));
this.liveState = false
}
});
},
switchCamera: function() {
this.context.switchCamera({
success: (a) => {
console.log("livePusher.switchCamera:" + JSON.stringify(a));
}
});
},
pause: function() {
this.context.pause({
success: (a) => {
this.playState = false
console.log("livePusher.pause:" + JSON.stringify(a));
}
});
},
}
}
</script>
<style lang="scss">
.livePusher {
width: 750rpx;
}
.page-box {
width: 750rpx;
background-color: #000;
}
.camera-box-left {
position: fixed;
top: 60rpx;
left: 0rpx;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
}
.camera-box {
position: fixed;
top: 60rpx;
right: 0rpx;
align-items: center;
justify-content: center;
width: 60rpx;
height: 60rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
}
.camera-box-1 {
position: fixed;
top: 60rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-2 {
position: fixed;
top: 160rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-3 {
position: fixed;
top: 260rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-4 {
position: fixed;
top: 360rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-5 {
position: fixed;
top: 460rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-6 {
position: fixed;
top: 560rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-7 {
position: fixed;
top: 660rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-8 {
position: fixed;
top: 760rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.camera-box-9 {
position: fixed;
top: 860rpx;
right: 60rpx;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
border: 1rpx;
border-style: solid;
border-color: #fff;
transition: width .5s;
}
.mode-list-1 {
position: fixed;
top: 360rpx;
right: 160rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100rpx;
border-radius: 15rpx 0 0 15rpx;
background-color: rgba(255, 255, 255, .2);
transition: width .5s;
}
.mode-list-2 {
position: fixed;
top: 460rpx;
right: 160rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100rpx;
border-radius: 15rpx 0 0 15rpx;
background-color: rgba(255, 255, 255, .2);
transition: width .5s;
}
.mode-list-3 {
position: fixed;
top: 660rpx;
right: 160rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 100rpx;
border-radius: 15rpx 0 0 15rpx;
background-color: rgba(255, 255, 255, .2);
transition: width .5s;
}
.mode-list-4 {
position: fixed;
top: 760rpx;
right: 160rpx;
height: 100rpx;
border-radius: 15rpx 0 0 15rpx;
background-color: rgba(255, 255, 255, .2);
transition: width .5s;
}
.mode-list-5 {
position: fixed;
top: 860rpx;
right: 160rpx;
height: 100rpx;
border-radius: 15rpx 0 0 15rpx;
background-color: rgba(255, 255, 255, .2);
transition: width .5s;
}
.camera-box-text {
width: 100rpx;
color: #fff;
text-align: center;
}
.top-1 {
top: 100rpx;
}
.top-2 {
top: 200rpx;
}
.top-3 {
top: 300rpx;
}
</style>

View File

@@ -1,37 +0,0 @@
<template>
<view>
<video
id="myVideo"
class="myVideo"
:autoplay="true"
:style="`height: ${livePusherStyle}px;`"
:src="`rtmp://192.168.1.16:1935/live/livestream2?&token=${userToken}`"
:is-live="true"></video>
</view>
</template>
<script>
import { getToken } from '../../utils/auth';
export default {
data() {
return {
userToken: getToken(),
livePusherStyle: 0
};
},
onLoad() {
uni.getSystemInfo({
success: (res) => {
console.log(res);
this.livePusherStyle = res.screenHeight
}
})
}
}
</script>
<style lang="scss">
.myVideo {
width: 750rpx;
}
</style>

View File

@@ -1,110 +0,0 @@
<template>
<view style="width: 500rpx;">
<live-pusher id='livePusher' ref="livePusher" class="livePusher" url="" mode="SD" :muted="true"
:enable-camera="true" :auto-focus="true" :beauty="1" whiteness="2" aspect="9:16"
@statechange="statechange" @netstatus="netstatus" @error="error"></live-pusher>
<button class="btn" @click="start">开始推流</button>
<button class="btn" @click="pause">暂停推流</button>
<button class="btn" @click="resume">resume</button>
<button class="btn" @click="stop">停止推流</button>
<button class="btn" @click="snapshot">快照</button>
<button class="btn" @click="startPreview">开启摄像头预览</button>
<button class="btn" @click="stopPreview">关闭摄像头预览</button>
<button class="btn" @click="switchCamera">切换摄像头</button>
</view>
</template>
<script>
export default {
onReady() {
// 注意需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext("livePusher", this);
},
methods: {
statechange(e) {
console.log("statechange:" + JSON.stringify(e));
},
netstatus(e) {
console.log("netstatus:" + JSON.stringify(e));
},
error(e) {
console.log("error:" + JSON.stringify(e));
},
start() {
this.context.start({
success: (a) => {
console.log("livePusher.start:" + JSON.stringify(a));
}
});
},
close() {
this.context.close({
success: (a) => {
console.log("livePusher.close:" + JSON.stringify(a));
}
});
},
snapshot() {
console.log("快照111")
this.context.snapshot({
success: (e) => {
console.log("快照11111", e.message)
console.log(JSON.stringify(e));
},
error: (e) => {
console.log("快照error", e.message)
}
});
},
resume() {
this.context.resume({
success: (a) => {
console.log("livePusher.resume:" + JSON.stringify(a));
}
});
},
pause() {
this.context.pause({
success: (a) => {
console.log("livePusher.pause:" + JSON.stringify(a));
}
});
},
stop() {
this.context.stop({
success: (a) => {
console.log(JSON.stringify(a));
}
});
},
switchCamera() {
this.context.switchCamera({
success: (a) => {
console.log("livePusher.switchCamera:" + JSON.stringify(a));
}
});
},
startPreview() {
this.context.startPreview({
success: (a) => {
console.log("livePusher.startPreview:" + JSON.stringify(a));
}
});
},
stopPreview() {
this.context.stopPreview({
success: (a) => {
console.log("livePusher.stopPreview:" + JSON.stringify(a));
}
});
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,190 @@
<!-- 司机登录页 -->
<template>
<view class="page">
<view class="login-now f-56 fw-5 c333">
立即登录
</view>
<view class="login-r f-32 fw-4 color-c">
登录以实现您的需求
</view>
<view class="">
<u-form class="form-box" :model="form" :rules="rules" ref="uForm">
<u-form-item border-bottom prop="phone">
<u-input type="number" maxlength="11" placeholder="请输入手机号码" placeholder-class="placeholder-class" border="none" v-model="form.phone" />
</u-form-item>
<u-form-item border-bottom class="mt-44" prop="captcha">
<u-input type="number" maxlength="6" placeholder="请输入验证码" placeholder-class="placeholder-class" border="none" v-model="form.captcha" >
<text class="f-30 c111" v-show="!codeStatus" slot="suffix">{{resendCodeTime}}秒重新获取</text>
<text class="f-30 c111" v-show="codeStatus" slot="suffix" @click="getCode">获取验证码</text>
</u-input>
</u-form-item>
</u-form>
</view>
<view class="agreement-box flex align-center">
<view class="frame flex justify-center align-center bg-primary" :style="agree ? 'background: #13AFA8;' : 'border: 2rpx solid #999999'">
<u-icon v-show="agree" name="checkmark" size="8" color="#fff"></u-icon>
</view>
<view class="f-26 c444" @click="agree = !agree">
我已阅读并同意<text class="c-primary">{{' 用户协议 '}}</text><text class="c-primary">{{' 隐私政策 '}}</text>
</view>
</view>
<u-button class="login-btn mt-8" color="#13AFA8" shape="circle" @click="loginSumbit">登录</u-button>
<view class="order-login fixed f-28 c-primary fw-5 text-center">
<text class="serve-login" @click="gotoRepair">服务商登录</text>
<u-safe-bottom></u-safe-bottom>
</view>
<prompt-box :show="tipShow" @confirm="confirm"></prompt-box>
</view>
</template>
<script>
import { getSendCode, phoneLogin } from '@/api/login';
import promptBox from '@/components/prompt-box/prompt-box'
export default {
components: { promptBox },
data() {
return {
agree: false,
tipShow: false,
codeStatus: true,
resendCodeTime: 60,
timer: null,
form: {
phone: '',
captcha: ''
},
rules: {
phone: [
{
required: true,
message: '请输入手机号',
trigger: ['change','blur'],
},
{
validator: (rule, value, callback) => {
return uni.$u.test.mobile(value);
},
message: '手机号码不正确',
trigger: ['blur'],
}
],
captcha: {
type: 'string',
required: true,
len: 6,
message: '请填写6位验证码',
trigger: ['blur']
},
}
}
},
methods: {
confirm() {
console.log('知道了');
this.tipShow = false
},
// 切换登录商
gotoRepair() {
uni.reLaunch({
url: '/pages/login/server-login'
})
},
// 获取验证码
getCode() {
if(this.form.phone) {
if(this.codeStatus) {
this.codeStatus = false
this.timer = setInterval(() => {
this.resendCodeTime--
if(this.resendCodeTime == 0) {
this.codeStatus = true
clearInterval(this.timer)
}
}, 1000)
getSendCode(this.form).then(res => {
console.log(res);
}).catch(err => {
console.log('请求失败', err);
})
}
} else {
uni.$u.toast('请先输入手机号')
}
},
// 登录
loginSumbit() {
uni.$u.toast('司机模块开发中')
return
if(this.agree) {
this.$refs.uForm.validate().then(res => {
}).catch(err => {
uni.$u.toast('信息填入错误')
})
} else {
uni.$u.toast("请先阅读用并同意勾选户协议和隐私协议")
}
}
},
onReady() {
uni.hideTabBar();
this.$refs.uForm.setRules(this.rules)
}
}
</script>
<style lang="scss">
page {
padding: 290rpx 60rpx;
}
.login-now {
line-height: 84rpx;
}
.login-r {
margin-top: 8rpx;
line-height: 48rpx;
}
.form-box {
margin-top: 42rpx;
width: 100%;
}
.agreement-box {
margin-top: 32rpx;
line-height: 36rpx;
.frame {
margin-right: 14rpx;
width: 24rpx;
height: 24rpx;
border-radius: 50%;
}
}
.login-btn {
width: 630rpx;
height: 96rpx;
border-radius: 50rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #FFFFFF;
}
.order-login {
bottom: 24rpx;
left: 50%;
transform: translateX(-50%);
.serve-login {
border-bottom: 1rpx solid #13AFA8;
}
}
.color-c {
color: #CDCDCD;
}
.mt-44 {
margin-top: 44rpx;
}
.placeholder-class {
font-size: 30rpx;
font-family: PingFang SC, PingFang SC;
color: #A4A7A6;
}
</style>

View File

@@ -1,124 +0,0 @@
<template>
<view class="page">
<view class="code-title text-center f-38">
请输入验证码
</view>
<view class="text-center f-26 aaa">
已发送至手机 {{ phoneNumber }} <text v-if="time<=60"> <text class="black ml-1">重新发送</text>{{ time }}</text>
</view>
<view class="code flex-center">
<u-code-input v-model="code" mode="line" :maxlength="6" hairline></u-code-input>
</view>
<u-button @click="codeLogin" class="btn mb-3" type="primary" shape="circle">完成</u-button>
<view v-if="this.time==61" class="text-center" @click="reSendCode">
重发短信验证码
</view>
</view>
</template>
<script>
import { getSendCode } from '@/api/login'
export default {
data() {
return {
phoneNumber: '',
time: 61,
code: '',
sendStatus: true,
timer: null,
type: false
};
},
onLoad(options) {
console.log(options);
if(options.type) {
this.type = options.type
} else {
this.type = false
}
this.phoneNumber = options.phoneNumber
this.getCode(this.phoneNumber)
},
methods: {
// 重发验证码
reSendCode() {
this.getCode(this.phoneNumber)
},
// 验证码登录
async codeLogin() {
if(this.code.length < 6) {
this.$toast('请输入完整的验证码')
} else {
if(this.type) {
if(this.type == 'false') {
this.$tab.navigateTo(`/pages/mine/pwd/index?phone=${this.phoneNumber}&code=${this.code}&type=${this.type}`)
} else if (this.type == 'resetPhone') {
this.$tab.navigateTo(`/pages/mine/setting/new-phone`)
}
} else {
console.log(this.type);
this.$store.dispatch('PhoneLogin', {
phoneNumber: this.phoneNumber,
code: this.code
}).then(() => {
console.log('登录成功');
this.$modal.closeLoading()
this.loginSuccess()
}).catch(() => {
this.$toast("登录失败")
uni.navigateBack()
})
}
}
},
// 登录成功后,处理函数
loginSuccess(result) {
console.log('登录成功');
// 设置用户信息
this.$store.dispatch('GetInfo').then(res => {
this.$tab.reLaunch('/pages/index')
}).catch(err => {
console.log('登录失败');
})
},
// 获取验证码
getCode(phone) {
if(this.time == 61 && this.sendStatus) {
this.sendStatus = false
getSendCode({phone}).then(res => {
this.$toast('验证码发送成功')
}).finally(res => {
this.timer = setInterval(() => {
this.time--
if(this.time == 0) {
this.sendStatus = true
this.time = 61
clearInterval(this.timer)
}
}, 1000)
})
} else {
this.$toast('请不要重复操作')
}
}
}
}
</script>
<style lang="scss">
page {
background-color: #fff;
}
.page {
padding: 36rpx 80rpx;
.code-title {
margin-bottom: 28rpx;
}
.code {
margin-top: 96rpx;
}
.btn {
margin-top: 120rpx;
}
}
</style>

View File

@@ -1,154 +0,0 @@
<template>
<view>
<view class="title text-center">
账号密码登录
</view>
<view class="form-box flex-center">
<u--form>
<u-form-item>
<view class="phone-enter flex align-center justify-between border-bottom border-eee pz-1 px-3">
<view class="code-box flex align-center">
{{ areaCode }}
<u-icon class="ml-2" name="arrow-down-fill" size="8" />
</view>
<view class="input-box ml-3">
<u--input
type="number"
maxlength="11"
v-model="form.username"
placeholder="请输入手机号码"
border="none" />
</view>
</view>
</u-form-item>
<u-form-item>
<view class="phone-enter flex align-center justify-between border-bottom border-eee pz-1 px-3">
<view class="code-box flex align-center mr-3">
密码
</view>
<view class="input-box ml-3 flex align-center">
<u--input v-show="pwStatus" type="password" v-model="form.password" placeholder="请输入密码" border="none" />
<u--input v-show="!pwStatus" v-model="form.password" placeholder="请输入密码" border="none" />
<image v-if="!form.password" src="@/static/images/icon/show_none.png" mode="widthFix"></image>
<image @click="checkPSType" v-if="form.password&&pwStatus" src="@/static/images/icon/show.png" mode="widthFix"></image>
<image @click="checkPSType" v-if="form.password&&!pwStatus" src="@/static/images/icon/disshow.png" mode="widthFix"></image>
</view>
</view>
</u-form-item>
<view class="forgot" @click="goToReset">
忘记密码?
</view>
</u--form>
</view>
<view class="btn-box">
<u-button
type="primary"
shape="circle"
:disabled="!this.form.username || !this.form.password"
:color="(!this.form.username || !this.form.password) && '#000' || ''"
@click="handleLogin">登录</u-button>
</view>
<view class="xieyi text-center ml-3 flex align-center">
<u-checkbox-group v-model="agreeStatus">
<u-checkbox name="同意"></u-checkbox>
</u-checkbox-group>
<text class="text-grey1">我同意并遵守</text>
<text @click="handleUserAgrement" class="text-blue">用户协议</text>
<text @click="handlePrivacy" class="text-blue">隐私协议</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
form: {
username: '',
password: '',
userType: 'app_user',
inviteCode: '',
registerDeviceType: ''
},
agreeStatus: [],
pwStatus: true,
phoneNumber: '',
areaCode: '+86',
};
},
methods: {
goToReset() {
this.$tab.navigateTo('/pages/login/reset-password?phone='+ this.form.username)
},
checkPSType() {
this.pwStatus = !this.pwStatus
},
// 登录方法
async handleLogin() {
if(!this.agreeStatus.length) {
this.$toast('请先阅读并勾选用户协议和隐私协议')
} else {
this.$modal.loading("登录中,请耐心等待...")
this.pwdLogin()
}
},
// 密码登录
async pwdLogin() {
this.$store.dispatch('Login', this.form).then(() => {
this.$modal.closeLoading()
this.loginSuccess()
}).catch(() => {
this.$toast('登录失败')
})
},
// 登录成功后,处理函数
loginSuccess(result) {
// 设置用户信息
this.$store.dispatch('GetInfo').then(res => {
this.$tab.reLaunch('/pages/index')
})
},
// 隐私协议
handlePrivacy() {
let site = this.globalConfig.appInfo.agreements[0]
this.$tab.navigateTo(`/pages/common/textview/index?title=隐私政策`)
},
// 用户协议
handleUserAgrement() {
let site = this.globalConfig.appInfo.agreements[1]
this.$tab.navigateTo(`/pages/common/textview/index?title=用户协议`)
},
}
}
</script>
<style lang="scss">
.title {
padding: 48rpx;
font-size: 48rpx;
}
.phone-enter {
width: 660rpx;
}
.code-box {
width: 120rpx;
}
.input-box {
width: 100%;
image {
width: 32rpx;
}
}
.forgot {
position: absolute;
right: 52rpx;
}
.btn-box {
margin-top: 100rpx;
padding: 0 50rpx;
}
.xieyi {
margin-top: 36rpx;
padding-left: 32rpx;
}
</style>

View File

@@ -1,201 +0,0 @@
<template>
<view class="normal-login-container">
<view class="logo-content align-center justify-center flex">
<image :src="globalConfig.appInfo.logo" mode="widthFix" />
<text class="title">连线客移动端登录</text>
</view>
<view class="login-form-content">
<view class="phone-enter flex align-center justify-between border-bottom border-eee pz-1">
<view class="flex align-center">
{{ areaCode }}
<u-icon class="ml-2" name="arrow-down-fill" size="8" />
</view>
<view class="input-box ml-3">
<u--input
type="number"
maxlength="11"
v-model="phoneNumber"
placeholder="请输入手机号码"
border="none" />
</view>
</view>
<u-button
class="mb-3"
type="primary"
shape="circle"
:disabled="phoneNumber.length!=11"
:color="phoneNumber.length != 11 ? '#000' : ''"
@click="sendCode">发送验证码</u-button>
<text @click="$tab.navigateTo('/pages/login/login-password')">使用密码登录</text>
</view>
<!-- #ifdef MP-WEIXIN -->
<view class="weixin">
<open-data class="user-avatar" type="userAvatarUrl"></open-data>
<open-data class="user-name" type="userNickName"></open-data>
<view class="login-notice"></view>
<view class="action-btn">
<button
class="login-btn cu-btn block bg-blue lg round"
open-type="getPhoneNumber"
@getphonenumber="phoneLogin">手机号一键登录</button>
</view>
</view>
<!-- #endif -->
<view class="xieyi text-center ml-3 flex align-center">
<u-checkbox-group v-model="agreeStatus">
<u-checkbox name="同意"></u-checkbox>
</u-checkbox-group>
<text class="text-grey1">我同意并遵守</text>
<!-- #ifdef MP-WEIXIN -->
<text class="text-grey1">登录即代表同意</text>
<!-- #endif -->
<text @click="handleUserAgrement" class="text-blue">用户协议</text>
<text @click="handlePrivacy" class="text-blue">隐私协议</text>
</view>
</view>
</template>
<script>
import { getCodeImg } from '@/api/login'
export default {
data() {
return {
areaCode: '+86',
phoneNumber: '',
agreeStatus: [],
globalConfig: getApp().globalData.config,
loginForm: {}
}
},
methods: {
async phoneLogin(e) {
console.log('获取微信手机号', e);
let phone = await uni.getSystemInfo()
this.loginForm.xcxPhoneCode = e.detail.code
this.loginForm.userType = 'wx_mini_user'
this.loginForm.registerDeviceType = phone[phone.length-1].deviceModel.includes('iPhone')? 'IOS': 'Android'
this.$store.dispatch('WeixinPhoneLogin', this.loginForm).then(res => {
console.log(res);
this.loginSuccess()
}).catch(err => {
console.log('失败', err);
})
},
sendCode() {
console.log(this.agreeStatus);
if(!this.agreeStatus.length) {
this.$toast('请先阅读并同意用户协议及隐私协议')
} else {
this.$tab.navigateTo(`/pages/login/login-code?phoneNumber=${this.phoneNumber}`)
}
},
// 隐私协议
handlePrivacy() {
let site = this.globalConfig.appInfo.agreements[0]
this.$tab.navigateTo(`/pages/common/textview/index?title=隐私政策`)
},
// 用户协议
handleUserAgrement() {
let site = this.globalConfig.appInfo.agreements[1]
this.$tab.navigateTo(`/pages/common/textview/index?title=用户协议`)
}
}
}
</script>
<style lang="scss">
page {
background-color: #ffffff;
}
.normal-login-container {
width: 100%;
.logo-content {
width: 100%;
font-size: 21px;
text-align: center;
padding-top: 15%;
image {
width: 100rpx;
height: 100rpx;
border-radius: 4px;
}
.title {
margin-left: 10px;
}
}
.login-form-content {
text-align: center;
margin: 20px auto;
margin-top: 15%;
width: 80%;
.phone-enter {
margin-bottom: 80rpx;
.input-box {
width: 100%;
}
}
.input-item {
margin: 20px auto;
background-color: #f5f6f7;
height: 45px;
border-radius: 20px;
.icon {
font-size: 38rpx;
margin-left: 10px;
color: #999;
}
.input {
width: 100%;
font-size: 14px;
line-height: 20px;
text-align: left;
padding-left: 15px;
}
}
}
.xieyi {
margin-top: 50px;
padding-left: 60rpx;
color: #333;
}
}
.weixin {
display: flex;
align-items: center;
flex-flow: column;
}
.user-avatar {
margin: 0 auto;
display: block;
width: 176rpx;
height: 176rpx;
border-radius: 50%;
overflow: hidden;
margin-bottom: 40rpx;
}
.user-name {
font-size: 35rpx;
font-family: PingFang SC;
font-weight: bold;
color: #000;
margin-bottom: 30rpx;
}
.login-btn {
margin-top: 40px;
width: 680rpx;
height: 45px;
}
</style>

View File

@@ -1,110 +0,0 @@
<template>
<view>
<view v-if="userState=='false'" class="text-center f-48">
找回密码
</view>
<view class="login-form-content">
<view v-if="userState=='false'" class="phone-enter flex align-center justify-between border-bottom border-eee pz-1">
<view class="flex align-center">
{{ areaCode }}
<u-icon class="ml-2" name="arrow-down-fill" size="8" />
</view>
<view class="input-box ml-3">
<u--input type="number" maxlength="11" v-model="username" placeholder="请输入手机号码" border="none" />
</view>
</view>
<view class="" v-else>
<view class="new-title">
为了保证你的账号安全请验证身份验证成功后进行下一步操作
</view>
<view class="phone f-48">
{{ phonenumber }}
</view>
</view>
<u-button
class="mb-3"
type="primary"
shape="circle"
:disabled="!username || username.length!=11"
:color="(!username || username.length!=11) && '#000' || ''"
@click="getCode"
>发送验证码</u-button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phonenumber: '',
username: '',
areaCode: '+86',
userState: true
};
},
onLoad(options) {
console.log(this.$store.state.user);
if(this.$store.state.user.name) {
this.username = this.$store.state.user.name
this.phonenumber = this.$store.state.user.phonenumber
this.userState = options.type
uni.setNavigationBarTitle({
title: '安全验证'
})
}
},
methods: {
// 获取验证码
getCode(phone) {
console.log(this.userState);
this.$tab.navigateTo(`/pages/login/login-code?type=${this.userState}&phoneNumber=${this.username}`)
}
}
}
</script>
<style lang="scss">
.phone {
margin: 80rpx 0 120rpx ;
}
.new-title {
text-align: left;
}
.login-form-content {
text-align: center;
margin: 20px auto;
margin-top: 15%;
width: 80%;
.phone-enter {
margin-bottom: 80rpx;
.input-box {
width: 100%;
}
}
.input-item {
margin: 20px auto;
background-color: #f5f6f7;
height: 45px;
border-radius: 20px;
.icon {
font-size: 38rpx;
margin-left: 10px;
color: #999;
}
.input {
width: 100%;
font-size: 14px;
line-height: 20px;
text-align: left;
padding-left: 15px;
}
}
}
</style>

View File

@@ -0,0 +1,245 @@
<!-- 服务商登录页 -->
<template>
<view class="page">
<view class="login-now f-56 fw-5 c333">
立即登录
</view>
<view class="login-r f-32 fw-4 color-c">
登录以实现您的需求
</view>
<view class="">
<u-form class="form-box" :model="form" :rules="rules" ref="uForm">
<u-form-item border-bottom>
<u-input type="number" disabledColor="#ffffff" disabled maxlength="11" placeholder="服务商类型" placeholder-class="placeholder-class" border="none" v-model="identityName">
<view class="flex" slot="suffix" @click="identityShow = true">
<text class="f-30 c111">{{ identityName }}</text>
<u-icon name="arrow-right" color="#999999" size="12"></u-icon>
</view>
</u-input>
</u-form-item>
<u-form-item class="mt-44" border-bottom prop="phone">
<u-input type="number" maxlength="11" placeholder="请输入手机号码" placeholder-class="placeholder-class" border="none" v-model="form.phone"></u-input>
</u-form-item>
<u-form-item border-bottom class="mt-44" prop="captcha">
<u-input type="number" maxlength="6" placeholder="请输入验证码" placeholder-class="placeholder-class" border="none" v-model="form.captcha" >
<text class="f-30 c111" v-show="!codeStatus" slot="suffix">{{resendCodeTime}}秒重新获取</text>
<text class="f-30 c111" v-show="codeStatus" slot="suffix" @click="getCode">获取验证码</text>
</u-input>
</u-form-item>
</u-form>
</view>
<view class="agreement-box flex align-center" @click="agreement">
<view class="frame flex justify-center align-center" :style="agree ? 'background: #13AFA8;' : 'border: 2rpx solid #999999'">
<u-icon v-show="agree" name="checkmark" size="8" color="#fff"></u-icon>
</view>
<view class="f-26 c444">
我已阅读并同意<text class="c-primary">{{' 用户协议 '}}</text><text class="c-primary">{{' 隐私政策 '}}</text>
</view>
</view>
<u-button class="login-btn mt-8" color="#13AFA8" shape="circle" @click="loginSumbit">登录</u-button>
<view class="order-login fixed f-28 c-primary fw-5 text-center">
<text class="serve-login" @click="gotoServeLogin">司机端登录</text>
<u-safe-bottom></u-safe-bottom>
</view>
<u-picker
:show="identityShow"
:columns="identityList"
title="请选择"
keyName="text"
confirmColor="#13AFA8"
cancelColor="#999999"
@confirm="confirm"
@cancel="cancel"
/>
</view>
</template>
<script>
import { getSendCode } from '@/api/login';
export default {
data() {
return {
agree: false,
codeStatus: true,
identityShow: false,
resendCodeTime: 60,
timer: null,
identityName: '车商',
identityList: [[
{keyName: 'platform', text: '平台'},
{keyName: 'repair', text: '维修店'},
{keyName: 'carDealers', text: '车商'}
]],
form: {
phone: '',
captcha: '',
sid: 'carDealers'
},
rules: {
phone: [
{
required: true,
message: '请输入手机号',
trigger: ['change','blur'],
},
{
validator: (rule, value, callback) => {
return uni.$u.test.mobile(value);
},
message: '手机号码不正确',
trigger: ['blur'],
}
],
captcha: {
type: 'string',
required: true,
len: 6,
message: '请填写6位验证码',
trigger: ['blur']
},
}
}
},
methods: {
confirm(e) {
console.log(e.value[0].text);
this.identityName = e.value[0].text
this.form.sid = e.value[0].keyName
this.identityShow = false
},
cancel() {
this.identityShow = false
},
selectClick(e) {
console.log(e);
},
agreement() {
console.log(this.agree);
this.agree = !this.agree
console.log(this.agree);
},
// 切换登录
gotoServeLogin() {
uni.reLaunch({
url: '/pages/login/driver-login'
})
},
// 获取验证码
getCode() {
if(this.form.phone) {
if(this.codeStatus) {
this.codeStatus = false
this.timer = setInterval(() => {
this.resendCodeTime--
if(this.resendCodeTime == 0) {
this.codeStatus = true
clearInterval(this.timer)
}
}, 1000)
getSendCode(this.form).then(res => {
console.log(res);
}).catch(err => {
console.log('请求失败', err);
})
}
} else {
uni.$u.toast('请先输入手机号')
}
},
// 登录
loginSumbit() {
console.log('登录');
if(this.agree) {
uni.showLoading({
title: '登录中'
})
this.$refs.uForm.validate().then(res => {
if(this.form.sid == 'platform') {
uni.hideLoading()
uni.$u.toast('平台模块开发中')
} else if (this.form.sid == 'repair') {
this.$store.dispatch('RepairLogin', this.form).then(res => {
uni.hideLoading()
uni.$u.toast('登录成功')
uni.switchTab({
url: '/pages/repair/tabbar/repair'
})
})
} else if ( this.form.sid == 'carDealers') {
uni.hideLoading()
uni.$u.toast('车商模块开发中')
}
// phoneLogin(this.form).then(res => {
// console.log(res);
// }).catch(err => {
// console.log(err);
// })
}).catch(err => {
uni.$u.toast('信息填入错误')
})
} else {
uni.$u.toast('请先阅读用并同意勾选户协议和隐私协议')
}
}
},
onReady() {
this.$refs.uForm.setRules(this.rules)
}
}
</script>
<style lang="scss">
page {
padding: 290rpx 60rpx;
}
.login-now {
line-height: 84rpx;
}
.login-r {
margin-top: 8rpx;
line-height: 48rpx;
}
.form-box {
margin-top: 42rpx;
width: 100%;
}
.agreement-box {
margin-top: 32rpx;
line-height: 36rpx;
.frame {
margin-right: 14rpx;
width: 24rpx;
height: 24rpx;
border-radius: 50%;
}
}
.login-btn {
width: 630rpx;
height: 96rpx;
border-radius: 50rpx;
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 600;
color: #FFFFFF;
}
.order-login {
bottom: 24rpx;
left: 50%;
transform: translateX(-50%);
.serve-login {
border-bottom: 1rpx solid #13AFA8;
}
}
.color-c {
color: #CDCDCD;
}
.mt-44 {
margin-top: 44rpx;
}
.placeholder-class {
font-size: 30rpx;
font-family: PingFang SC, PingFang SC;
color: #A4A7A6;
}
</style>

View File

@@ -1,312 +0,0 @@
<template>
<view class="face_2">
<div class="custom" :style="{height: CustomBar+'px'}">
<view class="navcontent" :style="[{top:statusBar + 'px'}]">
<text style="color: #FFFFFF;font-size: 16px;line-height: 45px;" class="iconfont icon-xiangzuo"
@click="BackPage"></text>
<text style="color: #FFFFFF;font-size: 16px;line-height: 45px;text-align: center;">人脸识别</text>
</view>
</div>
<view class="camera">
<live-pusher
id='livePusher'
ref="livePusher"
class="livePusher"
url=""
mode="SD"
:muted="true"
:enable-camera="true"
:auto-focus="true"
:beauty="1"
whiteness="2"
aspect="9:16"
></live-pusher>
<view class="images">
<text v-if="showStatus==1" class="images-text">如果确认开始人脸识别,请点击下方按钮!</text>
<text v-if="showStatus==2" class="images-text-1">人脸信息不一致!</text>
<text v-if="showStatus==3" class="images-text-1">未采集到人脸!</text>
<!-- <cover-image src="../static/rentouxiang.png"></cover-image> -->
</view>
</view>
<button class="btn" v-if="showStatus==1" @click="faceRecognition()"><text style="color: #FFF;">点击进行人脸识别验证</text></button>
<!-- <button class="btn" v-else @click="faceRecognitionStop()"><text style="color: #FFF;">停止人脸识别验证</text></button> -->
<u-toast ref="uToast" />
</view>
</template>
<script>
// import { faceID, getAnswerTime, } from '@/util/request/api.js';
import { base64ToPath } from "@/node_modules/image-tools/index.js";
// import { baseUrl } from "@/util/request/config.js";
export default {
data() {
return {
showStatus: 1,
context: null,
// 定时器
Timer: null,
// 快照的图片路径
imagUrl: null,
id: "",
titles: "",
flag: false,
CustomBar: 0,
statusBar: 0
}
},
watch: {
'flag': function() {
if (this.flag) {
return uni.redirectTo({
url: "/pagesB/my-AnswerPage/my-AnswerPage?id=" + this.id + "&title=" + this.titles,
success() {
// face.close()
this.flag = false;
}
})
}
},
},
// onLoad(e) {
// console.log(e);
// },
onShow() {
let routes = getCurrentPages();
this.id = routes[routes.length - 1].options.id;
this.titles = routes[routes.length - 1].options.title;
},
onReady() {
// 获取导航栏高度
var that = this
uni.getSystemInfo({
success: function(e) {
// 计算导航栏高度
that.statusBar = e.statusBarHeight
// #ifndef MP
if (e.platform == 'android') {
that.CustomBar = e.statusBarHeight + 50
} else {
that.CustomBar = e.statusBarHeight + 45
}
console.log(that.statusBar)
// #endif
// #ifdef MP-WEIXIN
let custom = wx.getMenuButtonBoundingClientRect()
that.CustomBar = custom.bottom + custom.top - e.statusBarHeight
// #endif
// #ifdef MP-ALIPAY
that.CustomBar = e.statusBarHeight + e.titleBarHeight
// #endif
}
})
// 注意需要在onReady中 或 onLoad 延时
// this.context = uni.createLivePusherContext("livePusher", this);
// console.log(this.context);
// 开启摄像头
// this.startPreview();
},
onHide() {
clearInterval(this.Timer)
},
methods: {
BackPage() {
uni.navigateBack(1);
},
// 点击进行人脸识别
faceRecognition() {
this.context = uni.createLivePusherContext("livePusher", this);
// 开启摄像头
this.startPreview();
this.showStatus = 0;
let that = this;
clearInterval(this.Timer);
that.snapshot();
this.Timer = setInterval(() => {
// 调用快照方法
that.snapshot();
}, 2000)
},
faceRecognitionStop() {
this.content.stop()
clearInterval(this.Timer)
this.context = null
},
// 快照
snapshot() {
this.context.snapshot({
success: (e) => {
// 快照拿到的图片地址存在 this.imagUrl
this.imagUrl = e.message.tempImagePath;
this.getMinImage(this.imagUrl)
},
error: (e) => {
console.log("快照error", e.message)
}
});
},
// 开启摄像头
startPreview() {
this.context.startPreview({
success: (a) => {
console.log("livePusher.startPreview:" + JSON.stringify(a));
}
});
},
// 使用plus.zip.compressImage压缩图片并转换成base64
getMinImage(imgPath) {
let token = uni.getStorageSync('token');
let _this = this;
plus.zip.compressImage({
src: imgPath,
dst: imgPath,
overwrite: true,
quality: 40
},
zipRes => {
setTimeout(() => {
var reader = new plus.io.FileReader();
reader.onloadend = res => {
var e = res.target.result; //base64图片
// console.log(e);
base64ToPath(e).then(path => {
console.log(path);
let p = plus.io.convertLocalFileSystemURL(path);
let url = "";
e = 'file://' + p;
uni.uploadFile({
url: baseUrl + "/app/common/upload",
filePath: e,
name: 'file',
header: {
'Authorization': 'Bearer ' + token,
},
success: (res) => {
url = JSON.parse(res.data).data.url;
let result = faceID(url);
console.log(result, "++++++++++++++");
// let t;
result.then(val => {
// console.log(val);
// console.log(val.data.isMatch)
if (val.code == 200 && val.data.isMatch) {
_this.flag = true;
getAnswerTime(_this.id);
} else if (val.code == 200 && !val.data.isMatch) {
this.showStatus = 2
// _this.num++;
// return _this.$refs.uToast.show({
// message: '人脸信息不一致!',
// type: 'warning',
// duration: 1000,
// })
} else {
this.showStatus = 3
// _this.nums++;
// return _this.$refs.uToast.show({
// message: '未采集到人脸!',
// type: 'danger',
// duration: 1000,
// })
}
}).catch(error => {
console.error(error)
})
}
});
}).catch(error => {
console.error(error)
})
};
//一定要使用plus.io.convertLocalFileSystemURL将target地址转换为本地文件地址否则readAsDataURL会找不到文件
reader.readAsDataURL(plus.io.convertLocalFileSystemURL(zipRes.target));
}, 1000);
},
function(error) {
console.log('Compress error!', error);
}
);
}
}
}
</script>
<style scoped>
.custom {
background-color: #2C65F7;
}
.navcontent {
height: 45px;
color: #FFFFFF;
display: flex;
justify-content: space-around;
flex-direction: row;
position: relative;
}
.iconfont {
width: 26rpx;
height: 26rpx;
border-bottom: 2rpx solid #FFFFFF;
border-left: 2rpx solid #FFFFFF;
transform: rotate(45deg);
position: absolute;
top: 50%;
left: 36rpx;
margin-top: -65rpx;
}
.camera {
width: 750rpx;
height: 750rpx;
margin: 0rpx auto 20rpx;
position: relative;
}
.images {
width: 750rpx;
height: 750rpx;
position: absolute;
top: 0;
left: 0;
}
.images-text {
color: #FFFFFF;
text-align: center;
line-height: 750rpx;
}
.images-text-1 {
color: #FFFFFF;
text-align: center;
line-height: 80rpx;
}
image {
width: 100%;
height: 100%;
}
.livePusher {
width: 750rpx;
height: 750rpx;
}
.btn {
width: 600rpx;
height: 100rpx;
border-radius: 50rpx;
color: #FFFFFF;
background: #2B6FC9;
line-height: 100rpx;
text-align: center;
font-size: 36rpx;
margin: 0 75rpx;
}
</style>

View File

@@ -0,0 +1,106 @@
<!-- 消息页面 -->
<template>
<view>
<view class="navbar fixed-top">
<view :style="`height: ${$u.sys().statusBarHeight}px;`" />
<view class="navbar-title flex align-center justify-between text-center pt-2">
<view class="image flex-center" @click="back">
<image class="back" src="@/static/images/icon/arrow-left.png" mode=""></image>
</view>
<view class="title">
消息
</view>
<view class="image">
<image class="clear" src="@/static/images/icon/clear.png" mode=""></image>
</view>
</view>
</view>
<view :style="{ height: $u.addUnit($u.getPx('104rpx') + $u.sys().statusBarHeight,'px')}" />
<view class="message-item flex align-center justify-between bg-white" @click="link('./message-list')">
<view class="left flex align-center justify-start">
<image src="@/static/images/icon/sys_icon.png" mode=""></image>
<text class="f-32 black">系统消息</text>
</view>
<view class="right flex align-center justify-end">
<view class="bg-primary flex-center white f-22">
1
</view>
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
back() {
uni.navigateBack()
},
link(url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #F5F5F5;
}
.navbar {
padding-bottom: 16rpx;
width: 750rpx;
background-color: #fff;
border-bottom: 1rpx solid #EDEDED;
z-index: 1000;
.navbar-title {
padding: 0 34rpx;
height: 88rpx;
font-size: 36rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 36rpx;
.image {
width: 40rpx;
height: 40rpx;
.back {
width: 18rpx;
height: 34rpx;
}
}
}
}
.message-item {
padding: 0 32rpx 0 24rpx;
width: 750rpx;
height: 168rpx;
.left {
image {
margin-right: 36rpx;
width: 104rpx;
height: 104rpx;
}
}
.right {
view {
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
image {
margin-left: 16rpx;
width: 10rpx;
height: 20rpx;
}
}
}
</style>

View File

@@ -0,0 +1,98 @@
<!-- 系统消息页 -->
<template>
<view>
<scroll-view scroll-y>
<view class="list flex-column align-center">
<view class="item" v-for="(item,index) in messageList" :key="index">
<view class="time text-center f-24 c666">
{{item.time}}
</view>
<view class="content-box" :style="index%2 && 'background: #F1F1F1'">
<view class="title f-32 c111">
{{item.title}}
</view>
<view class="content">
<u-parse :content="item.content"></u-parse>
</view>
<view class="bottom-box flex align-center justify-between" @click="link(`/pages/common/textview/index?title=${item.title}&content=${item.content}`)">
<view class="f-28 c111">
点击查看全文
</view>
<image src="@/static/images/icon/arrow-right.png" mode=""></image>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
data() {
return {
messageList: [
{
time: '10-19 12:34',
title: '恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!',
content: `<h3>恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!</h3><img src="https://cdn.uviewui.com/uview/swiper/2.jpg" /><p>露从今夜白,月是故乡明</p>`
},{
time: '10-19 12:34',
title: '恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!',
content: `<h3>恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!</h3><img src="https://cdn.uviewui.com/uview/swiper/2.jpg" /><p>露从今夜白,月是故乡明</p>`
},{
time: '10-19 12:34',
title: '恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!',
content: `<h3>恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!</h3><img src="https://cdn.uviewui.com/uview/swiper/2.jpg" /><p>露从今夜白,月是故乡明</p>`
},{
time: '10-19 12:34',
title: '恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!',
content: `<h3>恭喜获得#带着宠物去旅行 #红包!现金实物超多惊喜,速拆!</h3><img src="https://cdn.uviewui.com/uview/swiper/2.jpg" /><p>露从今夜白,月是故乡明</p>`
}
]
}
},
methods: {
link(url) {
uni.navigateTo({
url
})
}
}
}
</script>
<style lang="scss">
page {
background: #F5F5F5;
}
.list {
.item {
.time {
line-height: 72rpx;
}
.content-box {
padding: 32rpx;
width: 702rpx;
background: #FFFFFF;
border-radius: 8rpx;
.title {
}
.content {
}
.bottom-box {
margin-top: 16rpx;
padding-top: 16rpx;
border-top: 1rpx solid #ededed;
line-height: 40rpx;
image {
width: 10rpx;
height: 20rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,129 @@
<template>
<view>
<u-form label-width="80">
<u-form-item label="车牌号码" class="forms-item">
<u-input v-model="form.carNo" @focus="carNumdfocus" maxlength="8" border="none" placeholder="请输入车牌号码" input-align="right"></u-input>
</u-form-item>
<u-form-item>
<text class="forms-title">送修信息</text>
</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-form-item>
<u-form-item border-bottom label="维修类型" class="forms-item">
<u-input border="none" placeholder="请选择维修类型" input-align="right">
<template slot="sufix">
<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-form-item>
<u-form-item border-bottom label="联系方式" class="forms-item">
<u-input border="none" placeholder="请输入联系方式" input-align="right"></u-input>
</u-form-item>
</view>
<u-form-item>
<text class="forms-title">车辆信息</text>
</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-form-item>
<u-form-item border-bottom label="车辆品牌" class="forms-item">
<u-input border="none" 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-form-item>
</view>
</u-form>
<u-keyboard ref="uKeyboard" mode="car" @change="carNoChange" safeAreaInsetBottom :show="carShow" autoChange></u-keyboard>
</view>
</template>
<script>
import {getCarInfo} from '@/api/repair/repair'
export default {
data() {
return {
carShow: false,
form: {
carNo: '', // 车牌号
name: '', // 司机名称
repairType: '', // 维修类型
phone: '', // 联系方式
}
};
},
onLoad() {
},
methods: {
carNoChange(e) {
let a = this.checkType(e);
if(a == 1) {
if(this.form.carNo) {
this.form.carNo = this.replaceStr(this.form.carNo, 0, e)
} else {
this.form.carNo = e
}
} else {
if(this.form.carNo.length == 2) {
this.form.carNo += ('·' + e)
} else {
this.form.carNo += e
}
}
},
// 根据下标替换字符串
replaceStr (str, index, char) {
const strAry = str.split('');
strAry[index] = char;
return strAry.join('');
},
checkType(str) {
if(/^[\u4e00-\u9fa5]+$/.test(str)) {
// 中文
return 1
} else if (/^[0-9]+$/.test(str)) {
// 数字
return 2
} else if (/^[a-zA-Z]+$/.test(str)){
// 字母
return 3
}
},
carNumdfocus() {
this.carShow = true
uni.hideKeyboard()
},
carInfo() {
getCarInfo({carNo: form.carNo}).then(res => {
console.log(res);
})
}
}
}
</script>
<style lang="scss">
page {
padding: 24rpx;
background-color: #f5f5f5;
}
.forms-item {
padding: 12rpx 32rpx;
background-color: #fff;
border-radius: 8rpx;
}
.forms-title {
font-size: 32rpx;
font-family: PingFang SC, PingFang SC;
color: #222222;
line-height: 92rpx;
}
</style>

View File

@@ -0,0 +1,20 @@
<!-- 预约单详情页 -->
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,187 @@
<!-- 预约管理主页 -->
<template>
<view class="page">
<view class="navbar">
<view :style="`height: ${$u.sys().statusBarHeight}px;`" />
<view class="navbar-content flex align-center justify-between">
<view class="back-icon flex-center" @click="$tab.navigateBack">
<image src="@/static/images/icon/arrow-left.png" mode=""></image>
</view>
<u-input
customStyle="height: 72rpx"
placeholder="输入车牌号/所属公司搜索"
shape="circle"
v-model="keyword"
confirmType="search"
placeholderStyle="fontSize: 28rpx;color:#999;font-weight: 500;"
@confirm="inputConfirm">
<template slot="prefix">
<u-image width="16" height="16" src="@/static/images/icon/search.png"></u-image>
</template>
</u-input>
<view class="navbar-btn" v-if="btnState!='commonOrderType'">
<u-button
:customStyle="{width: '144rpx', height: '56rpx',fontSize: '24rpx',margin: 0}"
color="#333333"
@click="$tab.navigateTo('/pages/repair/repair/reservation/createOrder')">
<image src="@/static/images/icon/plus-circle.png" mode=""></image>
<text style="line-height: 1">新建</text>
</u-button>
</view>
</view>
</view>
<view class="tabs-box bg-white">
<u-tabs v-if="btnState=='commonOrderType'" :activeStyle="{color: '#111111'}" :inactiveStyle="{color: '#666666' }" :current="current" lineWidth="30" lineColor="#222222" :list="tabsList1" @click="clickTab" :scrollable="false"></u-tabs>
<u-tabs v-if="btnState=='accientOrderType'" :activeStyle="{color: '#111111'}" :inactiveStyle="{color: '#666666' }" :current="current" lineWidth="30" lineColor="#222222" :list="tabsList2" @click="clickTab" :scrollable="false"></u-tabs>
<u-tabs v-if="btnState=='orderType'" :activeStyle="{color: '#111111'}" :inactiveStyle="{color: '#666666' }" :current="current" lineWidth="30" lineColor="#222222" :list="tabsList3" @click="clickTab" :scrollable="false"></u-tabs>
<u-tabs v-if="btnState=='backOrderType'" :activeStyle="{color: '#111111'}" :inactiveStyle="{color: '#666666' }" :current="current" lineWidth="30" lineColor="#222222" :list="tabsList4" @click="clickTab" :scrollable="false"></u-tabs>
</view>
<view class="">
<z-paging :auto="false" ref="paging" height="100%" :fixed ="false" v-model="dataList" @query="queryList" safe-area-inset-bottom :use-page-scroll="true">
<empty-view slot="empty" text="暂无更多"></empty-view>
<billing-item @toStore="toStore" v-for="(item,index) in dataList" :key="item.id"></billing-item>
</z-paging>
</view>
<prompt-box ref="prompt" />
<u-popup :show="opinionShow">
<view class="">
</view>
</u-popup>
</view>
</template>
<script>
import billindItem from '@/components/billing-item/billing-item'
import { reservationList, maintenanceList, accidentList, returnList } from '@/api/repair/repair'
import { tabsList1, tabsList2, tabsList3, tabsList4 } from '@/data/tabsData'
import { mapGetters } from 'vuex'
export default {
components: { billindItem },
data() {
return {
current: 0,
keyword: '',
opinionShow: false,
tabsList1,
tabsList2,
tabsList3,
tabsList4,
dataList: [],
query: {}
};
},
onLoad(option) {
console.log(option);
// 将传进来的字段名存储vuex用于全局判断
this.$store.dispatch('changeBtnState', option.modul)
// 将请求query的传进来的字段名赋值相应tabs下的默认参数
this.query[option.modul] = this[`tabsList${option.index}`][0].value
console.log(123, this.btnState);
},
mounted() {
// 这里调用是避免参数获取不及时
this.$refs.paging.reload()
},
computed: {
...mapGetters(['btnState'])
},
methods: {
// 获取列表
queryList(pageNo, pageSize) {
console.log(this.query);
if(this.btnState == 'commonOrderType') {
reservationList({ page: pageNo,limit: pageSize, keyword: this.keyword, ...this.query }).then(res => {
console.log(res);
this.$refs.paging.complete(res.data.list);
}).catch(res => {
console.log('失败', res);
this.$refs.paging.complete(false);
})
} else if(this.btnState == 'orderType') {
maintenanceList({ page: pageNo,limit: pageSize, keyword: this.keyword, ...this.query }).then(res => {
console.log(res);
this.$refs.paging.complete(res.data.list);
}).catch(res => {
this.$refs.paging.complete(false);
})
} else if(this.btnState == 'accientOrderType') {
accidentList({ page: pageNo,limit: pageSize, keyword: this.keyword, ...this.query }).then(res => {
console.log(res);
this.$refs.paging.complete(res.data.list);
}).catch(res => {
this.$refs.paging.complete(false);
})
} else if (this.btnState == 'backOrderType') {
returnList({ page: pageNo,limit: pageSize, keyword: this.keyword, ...this.query }).then(res => {
console.log(res);
this.$refs.paging.complete(res.data.list);
}).catch(res => {
this.$refs.paging.complete(false);
})
}
},
// 点击搜索
inputConfirm() {
console.log('搜索');
this.$refs.paging.reload()
},
// 点击tabs栏
clickTab(e) {
console.log(e);
this.query[this.btnState] = e.value
this.current = e.index
this.$refs.paging.reload()
},
// 点击到店
toStore(e) {
console.log(e);
this.$refs.prompt.tipContent={
title: '确认到店',
content: `是否确认车牌号为【${'浙A·15JD6'}】的用户已到店?`,
confirmText: '确认',
cancelText: '取消',
}
this.$refs.prompt.show = true
}
}
}
</script>
<style lang="scss">
page {
background-color: #f5f5f5;
}
.page {
.navbar {
width: 750rpx;
background-color: #fff;
.navbar-content {
padding: 8rpx 24rpx;
.back-icon {
margin-right: 24rpx;
width: 40rpx;
height: 40rpx;
image {
width: 18rpx;
height: 34rpx;
}
}
.navbar-btn {
margin-left: 24rpx;
width: 144rpx;
height: 56rpx;
image {
margin-right: 8rpx;
width: 24rpx;
height: 24rpx;
}
}
}
}
.tabs-box {
justify-content: center;
}
}
</style>

View File

@@ -0,0 +1,247 @@
<!-- 维修端-搜索页 -->
<template>
<view>
<view class="search-box flex-wrap align-center justify-between fixed-top">
<view class="search flex-wrap align-center">
<image src="@/static/images/icon/search_primary.png" mode=""></image>
<u-input v-model="keyword" placeholder="请输入车牌/公司/维修类型" border="none"></u-input>
</view>
<text class="search-text" @click="searchClick">搜索</text>
</view>
<view style="height: 68rpx;" />
<view v-show="false" class="history flex-wrap justify-between align-center">
<view class="history-title flex align-center justify-between">
历史记录
<image v-if="removeShow" class="text-image" @click="over" src="@/static/images/icon/over.png" mode=""></image>
<image v-else src="@/static/images/icon/del.png" @click="delHistoryList" mode=""></image>
</view>
<view class="history-box">
<view v-if="searchHistory.length" class="historyText">
<view class="historyItem"
v-for="(item,index) in searchHistory"
:key="index" @click="onclick(item)"
@longpress="longpress(item,index)"
@touchend="touchend">
{{item}}
<image class="removeImg" src="@/static/images/icon/x.png" v-if="removeShow" mode="" @click.stop="removeOne(index)"></image>
</view>
</view>
<view v-else class="text-center">
暂无搜索历史
</view>
</view>
</view>
<view class="search-list">
<z-paging ref="paging" height="100%" :fixed ="false" v-model="dataList" @query="queryList" safe-area-inset-bottom :use-page-scroll="true">
<empty-view slot="empty"></empty-view>
<billing-item @toStore="toStore" @argee="argee" v-for="(item,index) in 5"></billing-item>
</z-paging>
</view>
<prompt-box ref="prompt" @confirm="confirm" @cancel="cancel" />
</view>
</template>
<script>
import emptyView from '@/components/empty-view/empty-view';
import billingItem from '@/components/billing-item/billing-item'
import promptBox from '@/components/prompt-box/prompt-box'
export default {
components: { emptyView, billingItem, promptBox },
data() {
return {
keyword: '',
searchHistory: [],
dataList: [],
islongPress: false, //长按记录变量
removeShow: false,
};
},
onShow() {
this.searchHistory = uni.getStorageSync('history') || []
},
methods: {
// 获取搜索结果
queryList() {
// queryList(pageNo, pageSize) {
// queryList({ pageNo,pageSize }).then(res => {
// this.$refs.paging.complete(res.data.list);
// }).catch(res => {
// this.$refs.paging.complete(false);
// })
// }
},
// 点击同意
argee(e) {
console.log(e);
this.$refs.prompt.tipContent={
title: '预约单确认',
content: `是否同意该预约单?`,
confirmText: '同意',
cancelText: '取消',
}
this.$refs.prompt.show = true
},
// 点击到店
toStore(e) {
console.log(e);
this.$refs.prompt.tipContent={
title: '确认到店',
content: `是否确认车牌号为【${'浙A·15JD6'}】的用户已到店?`,
confirmText: '确认',
cancelText: '取消',
}
this.$refs.prompt.show = true
},
// 弹窗确认回调
confirm() {
console.log('确认按钮');
},
// 弹窗取消回调
cancel() {
console.log('取消按钮');
},
// 完成按钮
over() {
this.removeShow = false
},
//删除单个历史记录
removeOne(index){
this.searchHistory.splice(index, 1);
uni.setStorageSync('history', this.searchHistory)
this.$u.toast('删除成功')
},
//长按历史记录
longpress(item, index) {
console.log("长按")
this.islongPress = true;
this.removeShow = true;
},
touchend() {
//延时执行为了防止 onclick() 还未判断 islongPress 的值就被置为 fasle
setTimeout(() => {
this.islongPress = false
}, 200)
},
// 点击搜索控件
searchClick() {
if(this.keyword) {
let identical = -1
this.searchHistory.forEach( (i,index) => {
if(i == this.keyword) identical = index
})
if(identical != -1) {
this.searchHistory.splice(identical, 1)
this.searchHistory.unshift(this.keyword)
} else if(this.searchHistory.length < 10) {
this.searchHistory.unshift(this.keyword)
} else {
this.searchHistory.splice(9,1)
this.searchHistory.unshift(this.keyword)
}
uni.setStorageSync('history', this.searchHistory)
}
},
//清除历史记录
delHistoryList() {
this.searchHistory = []
uni.clearStorageSync('history')
this.$u.toast('删除成功')
},
}
}
</script>
<style lang="scss">
page {
background-color: #f5f5f5;
}
.search-box {
background-color: #f5f5f5;
padding: 0 32rpx;
padding-bottom: 24rpx;
width: 750rpx;
.search {
width: 606rpx;
height: 64rpx;
background: #FEFEFE;
border-radius: 34rpx;
image {
margin: 0 8rpx 0 20rpx;
width: 32rpx;
height: 32rpx;
}
}
.search-text {
font-size: 28rpx;
font-family: PingFang SC, PingFang SC;
font-weight: bold;
color: #222222;
}
}
.history {
margin: 48rpx 32rpx 0 32rpx;
.history-title {
width: 100%;
font-size: 36rpx;
font-family: PingFang SC, PingFang SC;
font-weight: bold;
color: #000000;
line-height: 50rpx;
image {
width: 40rpx;
height: 40rpx;
}
}
.history-box {
margin-top: 46rpx;
width: 100%;
.historyText {
display: flex;
flex-wrap: wrap;
.historyItem {
position: relative;
margin-right: 32rpx;
padding: 0 24rpx;
height: 58rpx;
background: #EEEEEE;
border-radius: 40rpx;
font-size: 24rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 58rpx;
.removeImg{
position: absolute;
top: -8rpx;
right: -12rpx;
width: 24rpx;
height: 24rpx;
}
}
}
}
}
.search-list {
margin-top: 24rpx;
width: 750rpx;
height: auto;
.item {
margin-bottom: 24rpx;
padding: 16rpx 24rpx;
width: 750rpx;
line-height: 40rpx;
.item-title {
line-height: 54rpx;
}
.btns {
margin-top: 24rpx;
padding-top: 24rpx;
border-top: 1rpx solid #EDEDED;
}
& view {
margin-bottom: 8rpx;
}
}
}
</style>

View File

@@ -0,0 +1,22 @@
<!-- 维修端-配件页 -->
<template>
<view>
<tabbar-repair current="/pages/repair/tabbar/accessory"></tabbar-repair>
</view>
</template>
<script>
import tabbarRepair from '@/components/tabbar-repair/tabbar-repair'
export default {
components: {tabbarRepair},
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,22 @@
<!-- 维修端-我的 -->
<template>
<view>
<tabbar-repair current="/pages/repair/tabbar/mine"></tabbar-repair>
</view>
</template>
<script>
import tabbarRepair from '@/components/tabbar-repair/tabbar-repair'
export default {
components: {tabbarRepair},
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,22 @@
<!-- 维修端采购页 -->
<template>
<view>
<tabbar-repair current="/pages/repair/tabbar/procure"></tabbar-repair>
</view>
</template>
<script>
import tabbarRepair from '@/components/tabbar-repair/tabbar-repair'
export default {
components: {tabbarRepair},
data() {
return {
};
}
}
</script>
<style lang="scss">
</style>

View File

@@ -0,0 +1,162 @@
<!-- 维修端-首页 -->
<template>
<view class="page">
<view class="navbar fixed-top">
<view :style="`height: ${$u.sys().statusBarHeight}px;`" />
<view class="navbar-title rel text-center pt-2">
{{ storeInfo.name || '加载中' }}
<view class="message-icon abs" @click.stop="$tab.navigateTo('/pages/repair/repair/message/index')">
<u-badge isDot :value="1" absolute :offset="[0, 0]"></u-badge>
</view>
</view>
<view class="search flex align-center" @click="$tab.navigateTo('/pages/repair/repair/search')">
<image src="@/static/images/icon/search.png" mode=""></image>
<text class="f-28 c999 fw-5">搜索车牌/公司/维修类型</text>
</view>
</view>
<view :style="{ height: $u.addUnit($u.getPx('180rpx') + $u.sys().statusBarHeight,'px')}" />
<view class="branner-box">
<u-swiper :list="brannerList" height="370rpx" @change="brannerChange" @click="brannerClick"></u-swiper>
</view>
<view class="pic-btn-box flex-wrap f-36 fw-b">
<!--四个参数是列表请求接口的字段名
这里用于判断跳转后的请求接口 commonOrderType|accientOrderType|orderType|backOrderType -->
<view class="btn-item_1" v-if="storeInfo.reservationSwitch" @click="$tab.navigateTo(`/pages/repair/repair/reservation/list?index=1&modul=commonOrderType`)">
预约管理
</view>
<view class="btn-item_2" v-if="storeInfo.accientSwitch" @click="$tab.navigateTo(`/pages/repair/repair/reservation/list?index=2&modul=accientOrderType`)">
事故接待
</view>
<view class="btn-item_3" v-if="storeInfo.repairSwitch" @click="$tab.navigateTo(`/pages/repair/repair/reservation/list?index=3&modul=orderType`)">
维保接待
</view>
<view class="btn-item_4" v-if="storeInfo.returnSwitch" @click="$tab.navigateTo(`/pages/repair/repair/reservation/list?index=4&modul=backOrderType`)">
退车街待
</view>
</view>
<tabbar-repair current="/pages/repair/tabbar/repair"></tabbar-repair>
</view>
</template>
<script>
import tabbarRepair from '@/components/tabbar-repair/tabbar-repair'
import { getRepairIndexInfo } from '@/api/repair/repair'
export default {
components: {tabbarRepair},
data() {
return {
storeInfo: {},
brannerList: []
};
},
onLoad() {
this.init()
},
onShow() {
},
methods: {
// 初始化
init() {
uni.showLoading({
title: '加载中...'
})
this.getIndexInfo()
},
// 获取首页信息
getIndexInfo() {
getRepairIndexInfo().then( res => {
console.log('首页信息', res);
this.storeInfo = res.data
this.brannerList = res.data.carouselList
}).catch( err => {
console.log('首页信息失败', err);
}).finally(() => {
uni.hideLoading()
})
},
// 轮播图变化
brannerChange(e) {
console.log('轮播图change', e);
},
// 点击轮播图
brannerClick(e) {
console.log('点击轮播图', e);
}
}
}
</script>
<style lang="scss">
.page {
.navbar {
padding-bottom: 16rpx;
width: 750rpx;
background-color: #fff;
z-index: 1000;
.navbar-title {
height: 88rpx;
font-size: 36rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #000000;
line-height: 36rpx;
.message-icon {
top: 16rpx;
right: 24rpx;
width: 48rpx;
height: 48rpx;
background-image: url('@/static/images/icon/message.png');
background-repeat: no-repeat;
background-size: cover;
}
}
.search {
margin: 0 auto;
padding-left: 32rpx;
width: 684rpx;
height: 76rpx;
background: #F5F5F5;
border-radius: 38rpx;
image {
margin-right: 8rpx;
width: 32rpx;
height: 32rpx;
}
}
}
.branner-box {
margin: 0 auto;
width: 686rpx;
height: 370rpx;
}
.pic-btn-box {
margin: 16rpx 32rpx;
justify-content: space-between;
.btn-item_1 {
margin-bottom: 32rpx;
background-image: url('@/static/images/repair/index/booking_management.png');
}
.btn-item_2 {
margin-bottom: 32rpx;
background-image: url('@/static/images/repair/index/troubleshooting.png');
}
.btn-item_3 {
margin-bottom: 32rpx;
background-image: url('@/static/images/repair/index/maintenance_reception.png');
}
.btn-item_4 {
margin-bottom: 32rpx;
background-image: url('@/static/images/repair/index/cart_reception.png');
}
view {
padding: 38rpx 0 0 26rpx;
width: 330rpx;
height: 330rpx;
background-repeat: no-repeat;
background-size: cover;
line-height: 50rpx;
color: #302E2B;
}
}
}
</style>

View File

@@ -1,119 +0,0 @@
<template>
<view>
<cover-view>
<pull-flow />
</cover-view>
<cover-view>
<plug-flow />
</cover-view>
<!-- <cover-view>
<video id="myVideo" style="" :autoplay="true" src="rtmp://192.168.1.16:1935/live/livestream" :is-live="true"></video>
</cover-view> -->
<!-- <cover-view>
<live-pusher id='livePusher' ref="livePusher" class="livePusher" url="rtmp://192.168.1.16:1935/live/livestream?secret=0a0b8d0d7dc84232ad8c5d24f3000b00"
mode="SD" :muted="true" :enable-camera="true" :auto-focus="true" :beauty="1" whiteness="2"
aspect="9:16" @statechange="statechange" @netstatus="netstatus" @error = "error"
></live-pusher>
<cover-view style="width: 100vw;height: 100rpx;background-color: aqua;position: fixed;top: 0;"></cover-view>
<cover-view class="start-btn">开始推流</cover-view>
</cover-view> -->
<!-- <button class="btn" @click="start">开始推流</button>
<button class="btn" @click="pause">暂停推流</button>
<button class="btn" @click="resume">resume</button>
<button class="btn" @click="stop">停止推流</button>
<button class="btn" @click="snapshot">快照</button>
<button class="btn" @click="startPreview">开启摄像头预览</button>
<button class="btn" @click="stopPreview">关闭摄像头预览</button>
<button class="btn" @click="switchCamera">切换摄像头</button> -->
</view>
</template>
<script>
export default {
data() {
return {
}
},
onReady() {
// 注意需要在onReady中 或 onLoad 延时
this.context = uni.createLivePusherContext("livePusher", this);
},
methods: {
statechange(e) {
console.log("statechange:" + JSON.stringify(e));
},
netstatus(e) {
console.log("netstatus:" + JSON.stringify(e));
},
error(e) {
console.log("error:" + JSON.stringify(e));
},
start: function() {
this.context.start({
success: (a) => {
console.log("livePusher.start:" + JSON.stringify(a));
}
});
},
close: function() {
this.context.close({
success: (a) => {
console.log("livePusher.close:" + JSON.stringify(a));
}
});
},
snapshot: function() {
this.context.snapshot({
success: (e) => {
console.log(JSON.stringify(e));
}
});
},
resume: function() {
this.context.resume({
success: (a) => {
console.log("livePusher.resume:" + JSON.stringify(a));
}
});
},
pause: function() {
this.context.pause({
success: (a) => {
console.log("livePusher.pause:" + JSON.stringify(a));
}
});
},
stop: function() {
this.context.stop({
success: (a) => {
console.log(JSON.stringify(a));
}
});
},
switchCamera: function() {
this.context.switchCamera({
success: (a) => {
console.log("livePusher.switchCamera:" + JSON.stringify(a));
}
});
},
startPreview: function() {
this.context.startPreview({
success: (a) => {
console.log("livePusher.startPreview:" + JSON.stringify(a));
}
});
},
stopPreview: function() {
this.context.stopPreview({
success: (a) => {
console.log("livePusher.stopPreview:" + JSON.stringify(a));
}
});
}
}
}
</script>

View File

@@ -1,20 +1,15 @@
import { getToken } from '@/utils/auth'
// 登录页面
const loginPage = "/pages/login/login"
const loginPage1 = "/pages/login/driver-login"
const loginPage2 = "/pages/login/server-login"
// 页面白名单
const whiteList = [
'/pages/index',
// '/pages/mine/index',
'/pages/login/login',
'/pages/login/login-code',
'/pages/login/login-password',
'/pages/login/reset-password',
'/pages/mine/pwd/index',
'/pages/common/webview/index',
'/pages/componentsTest',
'/pages/mine/faceRecognition/faceRecognition'
'/pages/login/driver-login',
'/pages/login/server-login',
'/pages/repair/tabbar/repair'
]
// 检查地址白名单
@@ -29,7 +24,7 @@ list.forEach(item => {
uni.addInterceptor(item, {
invoke(to) {
if (getToken()) {
if (to.url === loginPage) {
if (to.url === loginPage1 || to.url === loginPage2) {
uni.reLaunch({ url: "/" })
}
return true
@@ -38,7 +33,7 @@ list.forEach(item => {
return true
}
console.log("触发页面验证拦截", to.url)
uni.reLaunch({ url: loginPage })
uni.reLaunch({ url: loginPage1 })
return false
}
},

16
static/font/common.css Normal file
View File

@@ -0,0 +1,16 @@
/* 字体 */
/* 颜色 */
/* 内外边距 */
/* 布局 */
/* 定位 */

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

BIN
static/images/icon/del.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
static/images/icon/over.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
static/images/icon/x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

@@ -1,5 +1,18 @@
body {
box-sizing: border-box;
}
image {
width: 100%;
height: 100%;
}
/* 字体 */
.f-22 {
font-size: 22rpx;
}
.f-24 {
font-size: 24rpx;
}
.f-26 {
font-size: 26rpx;
}
@@ -18,10 +31,28 @@
.f-48 {
font-size: 48rpx
}
.f-56 {
font-size: 56rpx;
}
.fw-4 {
font-weight: 400;
}
.fw-5 {
font-weight: 500;
}
.fw-b {
font-weight: bold;
}
.f-down-line {
text-decoration: underline;
}
/* 颜色 */
.black {
color: #000;
}
.white {
color: #fff
}
.aaa {
color: #aaa;
}
@@ -37,10 +68,35 @@
.fff {
color: #fff;
}
.bg-fff {
.c111 {
color: #111111;
}
.c333 {
color: #333333;
}
.c444 {
color: #444444;
}
.c999 {
color: #999999;
}
.c-primary {
color: #13AFA8;
}
.c-danger {
color: #F20808;
}
.bg-primary {
background: #13AFA8;
}
.bg-white {
background-color: #fff;
}
/* 文字对齐 */
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
@@ -67,6 +123,15 @@
.pt-2 {
padding-top: 20rpx;
}
.pb-2 {
padding-bottom: 20rpx;
}
.pb-3 {
padding-bottom: 30rpx;
}
.pb-4 {
padding-bottom: 40rpx;
}
.pz-1 {
padding-top: 10rpx;
padding-bottom: 10rpx;
@@ -108,6 +173,9 @@
.mt-3 {
margin-top: 30rpx;
}
.mt-8 {
margin-top: 80rpx;
}
.ml-1 {
margin-left: 10rpx;
}
@@ -129,7 +197,14 @@
.mz-30 {
margin: 30rpx 0;
}
/* 圆角 */
.primary-radius {
border-radius: 8rpx;
}
/* 布局 */
.flex {
display: flex;
}
.flex-wrap {
display: flex;
flex-flow: wrap;
@@ -171,6 +246,21 @@
justify-content: center;
}
/* 定位 */
.rel {
position: relative;
}
.abs {
position: absolute;
}
.fixed {
position: fixed;
}
.fixed-top {
position: fixed;
top: 0;
left: 0;
z-index: 99999;
}
.fixed-bottom {
position: fixed;
bottom: 0;

View File

@@ -7,6 +7,7 @@ const getters = {
phonenumber: state => state.user.phonenumber,
birthDay: state => state.user.birthDay,
roles: state => state.user.roles,
permissions: state => state.user.permissions
permissions: state => state.user.permissions,
btnState: state => state.pageManager.btnState
}
export default getters

View File

@@ -1,7 +1,8 @@
import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/store/modules/user'
import websocket from '@/store/modules/websocket.js'
import pageManager from '@/store/modules/pageManager.js'
import websocket from '@/store/modules/websocket'
import getters from './getters'
Vue.use(Vuex)
@@ -9,7 +10,8 @@ Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user,
websocket
websocket,
pageManager
},
getters
})

View File

@@ -0,0 +1,21 @@
import config from '@/config'
const pageManager = {
state: {
btnState: ''
},
mutations: {
SET_BTNSTATE: (state, str) => {
state.btnState = str
}
},
actions: {
changeBtnState({ commit }, str) {
commit('SET_BTNSTATE', str)
}
}
}
export default pageManager

View File

@@ -1,7 +1,8 @@
import config from '@/config'
import storage from '@/utils/storage'
import constant from '@/utils/constant'
import { login, logout, getInfo, phoneLogin, weixinPhoneLogin } from '@/api/login'
import { repairLogin } from '@/api/login'
import { getUserInfo } from '@/api/system/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
const baseUrl = config.baseUrl
@@ -58,14 +59,13 @@ const user = {
},
actions: {
// 登录
Login({ commit }, userInfo) {
// 维修端登录
RepairLogin({ commit }, userInfo) {
return new Promise((resolve, reject) => {
console.log('userInfo', userInfo);
login(userInfo).then(res => {
console.log(res);
setToken(res.data.loginToken)
commit('SET_TOKEN', res.data.loginToken)
repairLogin(userInfo).then(res => {
console.log(res.data.token);
setToken(res.data.token)
commit('SET_TOKEN', res.data.token)
resolve()
}).catch(error => {
console.log(error);
@@ -73,54 +73,30 @@ const user = {
})
})
},
PhoneLogin({ commit }, userInfo) {
console.log(userInfo);
const phone = userInfo.phoneNumber
const smsCode = userInfo.code
return new Promise((resolve, reject) => {
phoneLogin({phone, smsCode}).then(res => {
setToken(res.data.loginToken)
commit('SET_TOKEN', res.data.loginToken)
resolve()
}).catch(error => {
reject(error)
})
})
},
WeixinPhoneLogin({ commit }, userInfo) {
return new Promise((resolve, reject) => {
weixinPhoneLogin(userInfo).then(res => {
setToken(res.data.loginToken)
commit('SET_TOKEN', res.data.loginToken)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.data
const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : user.avatar
const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
const nickname = (user == null || user.nickName == "" || user.nickName == null) ? "" : user.nickName
const phonenumber = (user == null || user.phonenumber == "" || user.phonenumber == null) ? "" : user.phonenumber
const sex = (user == null || user.sex == "" || user.sex == null) ? "" : user.sex
const birthDay = (user == null || user.birthDay == "" || user.birthDay == null) ? "" : user.birthDay
if (res.roles && res.roles.length > 0) {
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_NAME', username)
commit('SET_AVATAR', avatar)
commit('SET_NICK', nickname)
commit('SET_PHONE', phonenumber)
commit('SET_SEX', sex)
commit('SET_BIRTHDAY', birthDay)
getUserInfo().then(res => {
console.log('vuex, 用户信息', res);
// const user = res.data
// const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : user.avatar
// const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
// const nickname = (user == null || user.nickName == "" || user.nickName == null) ? "" : user.nickName
// const phonenumber = (user == null || user.phonenumber == "" || user.phonenumber == null) ? "" : user.phonenumber
// const sex = (user == null || user.sex == "" || user.sex == null) ? "" : user.sex
// const birthDay = (user == null || user.birthDay == "" || user.birthDay == null) ? "" : user.birthDay
// if (res.roles && res.roles.length > 0) {
// commit('SET_ROLES', res.roles)
// commit('SET_PERMISSIONS', res.permissions)
// } else {
// commit('SET_ROLES', ['ROLE_DEFAULT'])
// }
// commit('SET_NAME', username)
// commit('SET_AVATAR', avatar)
// commit('SET_NICK', nickname)
// commit('SET_PHONE', phonenumber)
// commit('SET_SEX', sex)
// commit('SET_BIRTHDAY', birthDay)
resolve(res)
}).catch(error => {
reject(error)

View File

@@ -27,7 +27,7 @@
<text
:class="[item.disabled && 'u-tabs__wrapper__nav__item__text--disabled']"
class="u-tabs__wrapper__nav__item__text"
:style="[textStyle(index)]"
:style="[textStyle(index), {fontSize: '28rpx'}]"
>{{ item[keyName] }}</text>
<u-badge
:show="!!(item.badge && (item.badge.show || item.badge.isDot || item.badge.value))"

View File

@@ -11,14 +11,16 @@ const request = config => {
const isToken = (config.headers || {}).isToken === false
config.header = config.header || {}
if (getToken() && !isToken) {
config.header['Authorization'] = 'Bearer ' + getToken()
config.header['Authori-zation'] = getToken()
}
console.log(getToken());
// get请求映射params参数
if (config.params) {
let url = config.url + '?' + tansParams(config.params)
url = url.slice(0, -1)
config.url = url
}
console.log(config.params);
return new Promise((resolve, reject) => {
uni.request({
method: config.method || 'get',
@@ -39,9 +41,9 @@ const request = config => {
if (code === 401) {
showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录?').then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(res => {
uni.reLaunch({ url: '/pages/login/login' })
})
// store.dispatch('LogOut').then(res => {
uni.reLaunch({ url: '/pages/login/driver-login' })
// })
}
})
reject('无效的会话,或者会话已过期,请重新登录。')