This commit is contained in:
MeSHard
2025-11-14 17:23:25 +08:00
commit 0dbbf978d3
507 changed files with 43048 additions and 0 deletions

436
pages/my/index.vue Normal file
View File

@@ -0,0 +1,436 @@
<template>
<view class="container">
<view class="top-bg"></view>
<view class="user-info ">
<view class="avatar">
<u--image :showLoading="true" :src="userInfo.head" width="100px" height="100px" shape="circle"
v-if="userInfo.head"></u--image>
<u-icon name="account-fill" color="#ffffff" size="80" v-else></u-icon>
</view>
<view class="user-details">
<!-- <u-tag text="黄码" type="warning" class="tag" v-if="color==1"></u-tag>
<u-tag text="绿码" type="success" class="tag" v-else-if="color == 2">></u-tag>
<u-tag text="红码" type="error" class="tag" v-else></u-tag> -->
<view class="user-name">{{userInfo.account}}</view>
<view class="user-contact">
<u-icon name="phone-fill" color="#1a6dcc" size="18"></u-icon>
<span>{{userInfo.phone}}</span>
</view>
<!-- <view class="user-contact">
<u-icon name="email-fill" color="#1a6dcc" size="18"></u-icon>
<span>{{userInfo.email}}</span>
</view> -->
<u-button text="修改资料" class="updateInfoBtn" type="primary" size="small" shape="circle"
@click="toDriverInfo(1)"></u-button>
</view>
</view>
<view class="stats-cards animated">
<view class="stat-card">
<view class="stat-value">{{userInfo.mouth}}</view>
<view class="stat-label">本月运单</view>
</view>
<view class="stat-card">
<view class="stat-value">{{userInfo.lv}}</view>
<view class="stat-label">完成率</view>
</view>
<view class="stat-card">
<view class="stat-value">{{userInfo.onPassage}}</view>
<view class="stat-label">在途中</view>
</view>
</view>
<view class="menu-section">
<view class="section-title">
<view class="title_left">
<u-icon name="list-dot" color="#1a6dcc" size="20" :bold="true"></u-icon>
<span>功能模块</span>
</view>
<view>
</view>
</view>
<view class="menu-grid">
<view class="menu-item" @click="toNav('order/park')">
<view class="menu-icon">
<u-icon name="file-text" color="#1a6dcc" size="28"></u-icon>
</view>
<view class="menu-label">园区入园上报</view>
</view>
<view class="menu-item" @click="toNav('order/waybill')">
<view class="menu-icon">
<u-icon name="order" color="#1a6dcc" size="28"></u-icon>
</view>
<view class="menu-label">电子运单上报</view>
</view>
<view class="menu-item" @click="toNav('order/alarm')">
<view class="menu-icon">
<u-icon name="info-circle" color="#1a6dcc" size="28"></u-icon>
</view>
<view class="menu-label">车辆事故上报</view>
</view>
<view class="menu-item" @click="toMap">
<view class="menu-icon">
<u-icon name="map" color="#1a6dcc" size="28"></u-icon>
</view>
<view class="menu-label">路径导航</view>
</view>
</view>
<view class="section-title">
<view class="title_left">
<u-icon name="setting" color="#1a6dcc" size="20" :bold="true"></u-icon>
<span>账户设置</span>
</view>
<view>
</view>
</view>
<view class="menu-grid">
<view class="menu-item" @click="toDriverInfo(2)">
<view class="menu-icon">
<u-icon name="home" size="28" color="#1a6dcc"></u-icon>
</view>
<view class="menu-label">个人信息</view>
</view>
<view class="menu-item" @click="toNav('car/car')">
<view class="menu-icon">
<u-icon name="grid" size="28" color="#1a6dcc"></u-icon>
</view>
<view class="menu-label">车辆信息</view>
</view>
<view class="menu-item" @click="toNav('index/message')">
<view class="menu-icon">
<u-icon name="bell" size="28" color="#1a6dcc"></u-icon>
</view>
<view class="menu-label">报警信息接收</view>
</view>
<view class="menu-item" @click="toNav('index/notice')">
<view class="menu-icon">
<u-icon name="question-circle" size="28" color="#1a6dcc"></u-icon>
</view>
<view class="menu-label">帮助中心</view>
</view>
</view>
<view style="margin-bottom: 20px;">
<u-button type="primary" class="btn" text="退出登录" size="small" shape="circle" @click="logout"></u-button>
</view>
</view>
</view>
</template>
<script>
import config from '../../common/config';
import {
get,
post
} from '@/common/request.js'
export default {
data() {
return {
src: "./static/1752220647221.jpg",
userInfo: {
name: '张三',
mobile: '158****888',
email: '1'
},
color: 2
};
},
onShow() {
if (!config.driverInfo) {
this.getDriverInfo()
}
},
methods: {
onPullDownRefresh() {
setTimeout(() => {
this.getDriverInfo()
uni.stopPullDownRefresh();
}, 500);
},
toNav2(nav, num) {
uni.switchTab({
url: '/pages/' + nav + '?type=' + num,
});
},
toNav(nav) {
uni.navigateTo({
url: '/pages/' + nav,
});
},
logout() {
uni.showLoading({
title: '退出中'
})
uni.removeStorageSync('token');
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '退出成功',
icon: "none"
})
setTimeout(() => {
uni.navigateTo({
url: '/pages/my/login'
})
}, 1500)
}, 1500)
},
toMap() {
uni.showToast({
title: '暂未开放',
icon: 'none'
})
},
async getDriverInfo() {
await post('/myapi/api/yq_driver/getDriverInfo').then(res => {
this.userInfo = res.data
config.driverInfo = res.data
})
},
toDriverInfo(type) {
uni.navigateTo({
url: '/pages/my/update?type=' + type
})
}
}
};
</script>
<style scoped lang="less">
.container {
.top-bg {
height: 120px;
background: linear-gradient(135deg, #1a6dcc, #0d4a9e);
position: relative;
overflow: hidden;
&::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 70%);
transform: rotate(30deg);
}
}
.user-info {
position: relative;
margin-top: -80px;
padding: 25px 20px;
display: flex;
align-items: center;
background: white;
border-radius: 20px;
margin: -80px 20px 0;
box-shadow: 0 10px 30px rgba(0, 61, 165, 0.15);
z-index: 10;
transition: all 0.3s ease;
// background: url('@/static/user-bg.jpg');
// background-size: cover;
.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
overflow: hidden;
border: 4px solid white;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
background: linear-gradient(45deg, #4a90e2, #1a6dcc);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 40px;
margin-right: 20px;
.u-avatar__image--circle {
width: 100%;
height: 100%
}
}
.user-details {
flex: 1;
.tag {
width: 50px;
position: absolute;
right: 0px;
top: 0px;
}
.user-name {
font-size: 22px;
font-weight: 700;
color: #1a3a6d;
margin-bottom: 5px;
}
.user-contact {
display: flex;
align-items: center;
margin-bottom: 10px;
color: #666;
font-size: 15px;
.u-icon {
margin-right: 8px;
}
}
.updateInfoBtn {
background: linear-gradient(to right, #1a6dcca1, #0d4a9ecf);
color: white;
border: none;
padding: 8px 20px;
border-radius: 50px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
font-size: 15px;
box-shadow: 0 4px 15px rgba(26, 109, 204, 0.3);
width: 120px;
}
}
}
.stats-cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
padding: 25px 20px 15px;
.stat-card {
background: white;
border-radius: 15px;
padding: 15px 10px;
text-align: center;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
border: 1px solid #eef2f7;
.stat-value {
font-size: 24px;
font-weight: 700;
color: #1a6dcc;
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
color: #777;
}
}
}
.menu-section {
padding: 0 20px;
margin-top: 10px;
.section-title {
font-size: 18px;
font-weight: 700;
color: #1a3a6d;
padding: 15px 0;
display: flex;
align-items: center;
justify-content: space-between;
.title_left {
display: flex;
}
.u-icon {
margin-right: 8px;
}
.btn {}
}
.menu-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
margin-bottom: 25px;
.menu-item {
background: white;
border-radius: 15px;
padding: 15px 10px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
border: 1px solid #eef2f7;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.03);
display: flex;
flex-direction: column;
align-items: center;
.menu-label {
font-size: 14px;
color: #444;
font-weight: 500;
width: 100%;
}
.menu-icon {
font-size: 24px;
color: #1a6dcc;
margin-bottom: 12px;
width: 35px;
height: 35px;
line-height: 35px;
background: rgba(26, 109, 204, 0.1);
border-radius: 50%;
margin: 0 auto 12px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.content {
background-color: #f4f4f4;
height: calc(100vh - 100px);
}
</style>

124
pages/my/login.vue Normal file
View File

@@ -0,0 +1,124 @@
<template>
<view class="container">
<view style="width: 100%;">
<image style="width: 100%; height: 200px; background-color: #eeeeee;"
src="@/static/2021111015193250849.jpg"></image>
</view>
<view class="title">
<h1>危化品车辆运单平台</h1>
</view>
<view class="login">
<u--form class="form" labelPosition="left" :model="userInfo" ref="uForm">
<u-form-item label="账号:" prop="userInfo.account" borderBottom ref="item1">
<u--input v-model="userInfo.account" border="none" maxlength="20"
placeholder="请输入账号"></u--input>
</u-form-item>
<u-form-item label="密码:" prop="userInfo.password" borderBottom>
<u--input v-model="userInfo.password" border="none" type="password" maxlength="20"
placeholder="请输入密码"></u--input>
</u-form-item>
</u--form>
</view>
<view class="register">
<u--text type="primary" text="没有账号,前往注册?" @click="register"></u--text>
</view>
<u-button type="primary" class="btn" text="登录" shape="circle" @click="login"></u-button>
</view>
</template>
<script>
import {
get,
post
} from '@/common/request.js'
export default {
data() {
return {
userInfo: {
account: '',
password: '',
},
};
},
onLoad() {
if (uni.getStorageSync('token')) {
this.login()
}
},
methods: {
register() {
uni.navigateTo({
url: '/pages/my/register'
})
},
login() {
uni.showLoading({
title: '登录中'
})
post('/myapi/api/yq_driver/login', {
...this.userInfo
}).then(res => {
setTimeout(() => {
uni.setStorageSync('token', res.data.token)
uni.hideLoading()
uni.showToast({
title: '登录成功!',
icon: "none"
})
setTimeout(() => {
uni.switchTab({
url: '/pages/my/index'
})
}, 500)
}, 500)
})
}
},
};
</script>
<style scoped lang="less">
.container {
display: flex;
flex-direction: column;
align-items: center;
height: calc(100vh - 50px);
.title {
position: fixed;
top: 110px;
color: #fff;
}
.login {
// border: 1px solid #f4f4f4;
// border-radius: 15px;
padding: 20px 0;
width: 80%;
.form {
height: 100px;
}
}
.register {
width: 80%;
padding-bottom: 10px;
}
.btn {
width: 80%;
font-size: 24px;
}
}
</style>

204
pages/my/register.vue Normal file
View File

@@ -0,0 +1,204 @@
<template>
<view class="container">
<u--form labelPosition="top" :model="userInfo" :rules="rules" ref="uForm" labelWidth="120">
<u-form-item label="真实姓名" prop="userInfo.account" borderBottom ref="item1" required>
<u--input v-model="userInfo.account" border="none" maxlength="5" placeholder="请输入真实姓名"></u--input>
</u-form-item>
<!-- <u-form-item label="性别" prop="userInfo.sex" borderBottom @click="showSex = true;" ref="item1">
<u--input v-model="userInfo.sex" disabled disabledColor="#ffffff" placeholder="请选择性别"
border="none"></u--input>
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item> -->
<u-form-item label="手机号码" prop="userInfo.phone" borderBottom ref="item1" required>
<u--input v-model="userInfo.phone" border="none" maxlength="11" placeholder="请输入手机号码"></u--input>
</u-form-item>
<!-- <u-form-item label="电子邮箱" prop="userInfo.email" borderBottom ref="item1">
<u--input v-model="userInfo.email" border="none" maxlength="20" placeholder="请输入电子邮箱"></u--input>
</u-form-item> -->
<!-- <u-form-item label="用户类型" prop="userInfo.type" borderBottom @click="showType = true;" ref="item1">
<u--input v-model="userInfo.type" disabled disabledColor="#ffffff" placeholder="请选择类型"
border="none"></u--input>
<u-icon slot="right" name="arrow-right"></u-icon>
</u-form-item>
<u-form-item label="企业名称" prop="userInfo.enterprise" borderBottom ref="item1" v-if="userInfo.type == '企业'">
<u--input v-model="userInfo.enterprise" border="none" maxlength="20" placeholder="请输入企业名称"></u--input>
</u-form-item>
<u-form-item label="职位" prop="userInfo.position" borderBottom ref="item1">
<u--input v-model="userInfo.position" border="none" maxlength="10" placeholder="请输入职位名称"></u--input>
</u-form-item>
<u-form-item label="常用发货地址" prop="userInfo.shipping_address" borderBottom ref="item1">
<u--input v-model="userInfo.shipping_address" border="none" maxlength="100"
placeholder="请输入常用发货地址"></u--input>
</u-form-item>
<u-form-item label="常用收货地址" prop="userInfo.receiving_address" borderBottom ref="item1">
<u--input v-model="userInfo.receiving_address" border="none" maxlength="100"
placeholder="请输入常用收货地址"></u--input>
</u-form-item> -->
</u--form>
<u-action-sheet :show="showSex" :actions="actions" title="请选择性别" description="" @close="showSex = false"
@select="sexSelect">
</u-action-sheet>
<u-action-sheet :show="showType" :actions="typeActions" title="请选择类型" description="" @close="showType = false"
@select="typeSelect">
</u-action-sheet>
<view class="agreement">
<view class="content">
<u-checkbox-group v-model="agreement1" placement="row">
<u-checkbox label=""></u-checkbox>
请阅读和勾选
<u--text type="primary" text="用户协议" @click="agreement(1)"></u--text>
<u--text type="primary" text="隐私政策" @click="agreement(2)"></u--text>
协议
</u-checkbox-group>
</view>
</view>
<u-button type="primary" class="btn" text="注册" shape="circle" @click="register"></u-button>
</view>
</template>
<script>
import {
get,
post
} from '@/common/request.js'
import {
config
} from '@/common/config.js'
export default {
data() {
return {
showSex: false,
showType: false,
userInfo: {
account: '',
sex: '男',
phone: '',
email: '',
type: '个人',
enterprise: '',
position: '',
shipping_address: '',
receiving_address: '',
},
actions: [{
name: '男',
},
{
name: '女',
},
],
typeActions: [{
name: '个人',
},
{
name: '企业',
},
],
rules: {
},
agreement1: [],
}
},
methods: {
sexSelect(e) {
this.userInfo.sex = e.name
this.$refs.uForm.validateField('userInfo.sex')
},
typeSelect(e) {
this.userInfo.type = e.name
this.$refs.uForm.validateField('userInfo.type')
},
agreement(id) {
uni.navigateTo({
url: '/pages/index/details?id=' + id
})
},
async register() {
console.log()
if (this.agreement1.length !== 1) {
uni.showToast({
title: '请阅读并勾选相关协议!',
icon: "none"
})
return false
}
uni.showLoading({
title: '注册中'
})
post('/myapi/api/yq_driver/register', {
...this.userInfo
}).then(res => {
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '恭喜你,注册成功!',
icon: "none"
})
uni.setStorageSync('token', res.data.token)
setTimeout(() => {
uni.showToast({
title: '正在登录',
icon: "none"
})
setTimeout(() => {
uni.switchTab({
url: '/pages/my/index'
})
}, 500)
}, 1500)
}, 1500)
})
}
}
}
</script>
<style scoped lang="less">
.container {
padding: 10px 20px;
.btn {
margin-top: 10px;
font-size: 24px;
}
.agreement {
display: flex;
flex-direction: column;
margin: 10px 0 20px;
.content {
display: flex;
margin-top: 10px;
}
}
}
/deep/ .u-checkbox__icon-wrap--square {
border-radius: 15px !important;
}
</style>

208
pages/my/update.vue Normal file
View File

@@ -0,0 +1,208 @@
<template>
<view class="container">
<u--form labelPosition="top" :model="form" :rules="rules" ref="uForm" labelWidth="120">
<u-form-item label="姓名" prop="form.account" borderBottom>
<u--input v-model="form.account" border="none" placeholder="请输入真实姓名"></u--input>
</u-form-item>
<u-form-item label="手机号" prop="form.phone" borderBottom>
<u--input v-model="form.phone" border="none" placeholder="请输入手机号"></u--input>
</u-form-item>
<u-form-item label="密码" prop="form.password" borderBottom>
<u--input v-model="form.password" border="none" placeholder="不修改密码不填此项"></u--input>
</u-form-item>
<u-form-item label="头像" prop="form.head" borderBottom>
<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
:maxCount="1"></u-upload>
</u-form-item>
<u-form-item label="身份证" prop="form.card_image" borderBottom>
<u-upload :fileList="fileList2" @afterRead="afterRead" @delete="deletePic" name="2" multiple
:maxCount="2"></u-upload>
</u-form-item>
<u-form-item label="驾驶证" prop="form.license_image" borderBottom>
<u-upload :fileList="fileList3" @afterRead="afterRead" @delete="deletePic" name="3" multiple
:maxCount="1"></u-upload>
</u-form-item>
<u-form-item label="牵引车车牌号" prop="form.tractor_no" borderBottom>
<u--input v-model="form.tractor_no" border="none" maxlength="11" placeholder="请输入牵引车车牌号"></u--input>
</u-form-item>
<u-form-item label="牵引车道运证" prop="form.tractor_image" borderBottom>
<u-upload :fileList="fileList4" @afterRead="afterRead" @delete="deletePic" name="4" multiple
:maxCount="1"></u-upload> </u-form-item>
<u-form-item label="牵引车行驶证" prop="form.traactor_license_image" borderBottom>
<u-upload :fileList="fileList5" @afterRead="afterRead" @delete="deletePic" name="5" multiple
:maxCount="1"></u-upload> </u-form-item>
</u--form>
<u-button type="primary" class="btn" v-if="show" text="提交信息" shape="circle" @click="add"></u-button>
</view>
</template>
<script>
import config from '../../common/config';
import {
get,
post
} from '@/common/request.js'
export default {
data() {
return {
form: {
tractor_no: "", //牵引车牌号
head: "", //头像
card_image: "", //身份证
tractor_image: "", //牵引车道运证
traactor_license_image: "", //牵引车行驶证
license_image: "", //驾驶证
account: "", //账号
password: "", //密码
nick_name: "", //昵称
phone: "" //电话
},
rules: {},
array: ['货车', '卡车', '厢式货车'],
index: null,
fileList1: [],
fileList2: [],
fileList3: [],
fileList4: [],
fileList5: [],
show: true
}
},
onLoad(options) {
if (options.type == 2) {
this.show = false
uni.setNavigationBarTitle({
title: '个人信息'
});
}
const driver_info = config.driverInfo
this.form = {
...driver_info
}
this.form.password = ''
this.fileList1 = this.imageArr(this.form.head)
this.fileList2 = this.form.card_image ? this.form.card_image.split(',') : []
this.fileList3 = this.form.license_image ? this.form.license_image.split(',') : []
this.fileList4 = this.form.tractor_image ? this.form.tractor_image.split(',') : []
this.fileList5 = this.form.traactor_license_image ? this.form.traactor_license_image.split(',') : []
},
methods: {
async add() {
this.form.head = this.imageStr(this.fileList1)
this.form.card_image = this.imageStr(this.fileList2)
this.form.license_image = this.imageStr(this.fileList3)
this.form.tractor_image = this.imageStr(this.fileList4)
this.form.traactor_license_image = this.imageStr(this.fileList5)
await post('/myapi/api/yq_driver/updateDriverInfo', {
...this.form
}).then((res) => {
if (res.code == 1) {
uni.showToast({
title: '修改成功',
icon: 'none'
})
config.driverInfo = res.data
setTimeout(() => {
uni.switchTab({
url: '/pages/my/index'
})
}, 800)
}
})
},
imageStr(arr) {
return arr
.filter(item => item.url)
.map(item => item.url)
.join(',')
},
imageArr(str) {
if (str) {
var arr = []
str.split(',').map(item => {
arr.push({
url: item
})
})
return arr
} else {
return []
}
},
bindPickerChange: function(e) {
this.index = e.detail.value
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1);
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = this[`fileList${event.name}`].length;
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: "uploading",
message: "上传中",
});
});
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url);
console.log('result', result)
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: "success",
message: "",
url: result,
})
);
fileListLen++;
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: "/myapi/api/yq_driver/upload",
filePath: url,
name: "file",
header: {
token: uni.getStorageSync('token'),
},
success: (res) => {
const data = JSON.parse(res.data);
resolve(data.data.fullurl);
},
});
});
},
},
}
</script>
<style scoped lang="less">
.container {
padding: 20px;
.tag_title {
width: 80px;
height: 30px;
display: flex;
align-items: center;
}
.btn {
margin-top: 20px;
}
}
</style>