style:样式重构

This commit is contained in:
2025-10-18 09:24:35 +08:00
parent 729eba5a3b
commit 179be8f8b0
30 changed files with 880 additions and 423 deletions
+40
View File
@@ -0,0 +1,40 @@
import request from '../http'
// 设备查询
export const getDeviceInfo = (deviceNo) => {
return request({
url: `/app/device/${deviceNo}`,
method: 'get',
})
}
// 立即租借
export const rentPowerBank = (deviceNo, phone) => {
return request({
url: `/app/device/rentPowerBank?deviceNo=${deviceNo}`,
method: 'post',
data: {
// deviceNo,
phone
}
})
}
// 确认支付并弹出风扇
export const confirmPaymentAndRent = (orderId) => {
console.log(`确认支付并弹出风扇, orderId: ${orderId}`)
return request({
url: `/app/device/confirmPaymentAndRent?orderId=${orderId}`,
method: 'GET'
})
}
// 强制打开空格子
export const forcefOpenEmptyGrid = (deviceNo) => {
console.log(`强制打开空格子, deviceNo: ${deviceNo}`)
return request({
url: `/app/device/forcef/${deviceNo}`,
method: 'post'
})
}
+61
View File
@@ -0,0 +1,61 @@
import request from '../http'
// ===================== 快递归还相关接口 =====================
// 1) 申请快递归还
export const applyExpressReturn = (data) => {
// data: { orderId: number, logisticsTrackingNumber?: string, remark?: string }
return request({
url: '/app/express-return/apply',
method: 'post',
data
})
}
// 2) 补填快递单号
export const fillExpressTrackingNumber = (data) => {
// data: { id: number, logisticsTrackingNumber: string }
return request({
url: '/app/express-return/fill-tracking-number',
method: 'post',
data
})
}
// 3) 查询快递归还记录列表
export const getExpressReturnList = (params) => {
// params: { orderId?: number, status?: number, logisticsTrackingNumber?: string, pageNum?: number, pageSize?: number }
return request({
url: '/app/express-return/list',
method: 'get',
data: params,
hideLoading: true
})
}
// 4) 根据订单ID查询快递归还记录
export const getExpressReturnByOrder = (orderId) => {
return request({
url: `/app/express-return/by-order/${orderId}`,
method: 'get',
hideLoading: true
})
}
// 5) 获取快递归还记录详情
export const getExpressReturnDetail = (id) => {
return request({
url: `/app/express-return/${id}`,
method: 'get',
hideLoading: true
})
}
// 6) 取消快递归还申请
export const cancelExpressReturn = (id) => {
return request({
url: `/app/express-return/cancel/${id}`,
method: 'post'
})
}
+12
View File
@@ -0,0 +1,12 @@
import request from '../http'
// 投诉反馈
export const addUserFeedback = (data) => {
console.log(data);
return request({
url: '/app/feedback/add',
method: 'post',
data,
})
}
+120
View File
@@ -0,0 +1,120 @@
import request from '../http'
// 获取所有全部订单
export const getOrderList = (data) => {
return request({
url: '/app/order/list',
method: 'get',
data,
hideLoading: true
})
}
// 查询是否有订单
export const queryHasOrder = (deviceNo) => {
return request({
url: `/app/order/list?deviceNo=${deviceNo}&orderStatus=in_used`,
method: 'get',
})
}
// 查询指定设备号下,特定状态的订单列表
export const checkOrdersByStatus = (deviceNo, statuses) => {
// statuses 是一个包含状态字符串的数组,例如 ['in_used', 'waiting_for_payment']
const statusQuery = statuses.join(','); // 后端需要支持逗号分隔的状态查询
return request({
url: `/app/order/list?deviceNo=${deviceNo}&orderStatus=${statusQuery}`,
method: 'get',
hideLoading: true, // 隐藏加载提示,避免干扰用户
ignoreEmptyError: true // 添加标记,表示即使返回空数据也不视为错误
})
}
// 创建订单
export const createOrder = (data) => {
return request({
url: '/app/order/add',
method: 'post',
data,
})
}
// 查询订单
export const queryById = (id) => {
console.log(`查询订单详情, orderId: ${id}`)
return request({
url: `/app/order/${id}`,
method: 'get',
hideLoading: true
})
}
// 取消订单
export const cancelOrder = (data) => {
return request({
url: `/device/order/clear/${data.orderId}`,
method: 'get',
data,
})
}
// 结束订单
export const overOrderById = (orderId) => {
console.log(`调用结束订单API, orderId: ${orderId}`)
return request({
url: `/app/order/close/${orderId}`,
method: 'get',
})
}
// 通过订单号获取订单信息
export const getOrderByOrderNo = (orderNo) => {
return request({
url: `/app/order/byOrderNo/${orderNo}`,
method: 'get',
hideLoading: true
})
}
// 通过订单号获取支付分订单信息
export const getOrderByOrderNoScore = (orderNo) => {
console.log('通过订单号获取支付分订单信息', orderNo);
return request({
url: `/app/wx-payment/score/create/${orderNo}`,
method: 'get',
hideLoading: true
})
}
// 通过订单号获取支付分订单状态
export const getOrderByOrderNoScorePayStatus = (orderNo) => {
console.log('通过订单号获取支付分订单状态', orderNo);
return request({
url: `/app/wx-payment/score/status/${orderNo}`,
method: 'get',
hideLoading: true
})
}
// 更新订单套餐信息
export const updateOrderPackage = (data) => {
console.log('更新订单套餐信息:', data)
return request({
url: '/app/device/updateOrderPackage',
method: 'post',
data
})
}
/*
* 弃用
*/
export const getPotionsDetail = (data) => {
console.log(data);
return request({
url: '/device/position/positionDetails',
method: 'get',
data
})
}
+20
View File
@@ -0,0 +1,20 @@
import request from '../http'
// 获取系统配置(预留接口)
// 期望后端返回形如:{ code: 200, data: { expressReturnCountdownSeconds: number } }
export const getSystemConfig = () => {
return request({
url: '/app/system/config',
method: 'get',
hideLoading: true
})
}
// 获取通知接口
export const getNoticeTextData = (data) => {
return request({
url: `/system/notice/title/${data.title}`,
method: 'get'
})
}
+117
View File
@@ -0,0 +1,117 @@
import request from '../http'
import { URL, appid } from '../url'
// 用户登录
export const login = (data) => {
return request({
url: '/app/user/login',
method: 'get',
data
})
}
// 用户退出登录
export const userLogout = (data) => {
return request({
url: '/auth/logout',
method: 'post',
data
})
}
// 获取用户信息
export const getMyIndexInfo = (data) => {
return request({
url: '/app/user/userInfo',
method: 'get',
data,
})
}
// 更新用户信息
export const updateUserInfo = (data) => {
return request({
url: '/app/user/updateUser',
method: 'post',
data
})
}
// 更新用户余额
export const updateUserBalance = (orderId) => {
return request({
url: `/app/user/updateBalance/${orderId}`,
method: 'post',
hideLoading: true
})
}
// 上传并更新用户头像(后端接口)
export const uploadUserAvatar = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: URL + '/app/user/uploadAvatar',
filePath,
name: 'file',
header: {
'appid': appid,
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
},
success: (res) => {
try {
const parsed = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
resolve(parsed)
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 文件上传到 OSS(若依后端)
export const uploadOssResource = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: URL + '/manager/upload',
filePath,
name: 'file',
header: {
'appid': appid,
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
},
success: (res) => {
try {
const parsed = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
const codeOk = (res.statusCode === 200 || res.statusCode === 201 || parsed?.code === 200)
const url = parsed?.url || parsed?.data?.url || parsed?.data?.fileUrl || parsed?.fileUrl || parsed?.path || parsed?.data
if (codeOk && url) {
resolve(url)
return
}
reject(parsed || res)
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 添加押金提现API
export const withdrawDeposit = (orderNo) => {
return request({
url: `/app/withdraw/add/${orderNo}`,
method: 'get',
hideLoading: true
})
}
+2 -2
View File
@@ -1,5 +1,5 @@
// export const URL = "https://my.gxfs123.com/api" //正式服务器 export const URL = "https://my.gxfs123.com/api" //正式服务器
export const URL = "https://fansdev.gxfs123.com/api" //测试服务器 // export const URL = "https://fansdev.gxfs123.com/api" //测试服务器
// export const URL = "http://192.168.5.37:8080" //本地调试 // export const URL = "http://192.168.5.37:8080" //本地调试
// export const URL = "http://127.0.0.1:8080" //本地调试 // export const URL = "http://127.0.0.1:8080" //本地调试
-354
View File
@@ -1,354 +0,0 @@
import request from './http'
import { URL, appid } from './url'
//用户登录
export const login = (data) => {
return request({
url: '/app/user/login',
method: 'get',
data
})
}
//用户退出登录
export const userLogout = (data)=>{
return request({
url:'/auth/logout',
method:'post',
data
})
}
//获取用户信息
export const getMyIndexInfo = (data) => {
return request({
url: '/app/user/userInfo',
method: 'get',
data,
})
}
// 添加押金提现API
export const withdrawDeposit = (orderNo) => {
return request({
url: `/app/withdraw/add/${orderNo}`,
method: 'get',
hideLoading: true
})
}
//获取所有全部订单
export const getOrderList = (data) => {
return request({
url: '/app/order/list',
method: 'get',
data,
hideLoading: true
})
}
//查询是否有订单
export const queryHasOrder = (deviceNo) => {
return request({
url: `/app/order/list?deviceNo=${deviceNo}&orderStatus=in_used`,
method: 'get',
})
}
// 查询指定设备号下,特定状态的订单列表
export const checkOrdersByStatus = (deviceNo, statuses) => {
// statuses 是一个包含状态字符串的数组,例如 ['in_used', 'waiting_for_payment']
const statusQuery = statuses.join(','); // 后端需要支持逗号分隔的状态查询
return request({
url: `/app/order/list?deviceNo=${deviceNo}&orderStatus=${statusQuery}`,
method: 'get',
hideLoading: true, // 隐藏加载提示,避免干扰用户
ignoreEmptyError: true // 添加标记,表示即使返回空数据也不视为错误
})
}
//设备查询
export const getDeviceInfo = (deviceNo) => {
return request({
url: `/app/device/${deviceNo}`,
method: 'get',
})
}
//创建订单
export const createOrder = (data) => {
return request({
url: '/app/order/add',
method: 'post',
data,
})
}
//查询订单
export const queryById = (id) => {
console.log(`查询订单详情, orderId: ${id}`)
return request({
url: `/app/order/${id}`,
method: 'get',
hideLoading: true
})
}
//取消订单
export const cancelOrder = (data) => {
return request({
url: `/device/order/clear/${data.orderId}`,
method: 'get',
data,
})
}
//结束订单
export const overOrderById = (orderId) => {
console.log(`调用结束订单API, orderId: ${orderId}`)
return request({
url: `/app/order/close/${orderId}`,
method: 'get',
})
}
//立即租借
export const rentPowerBank = (deviceNo, phone) => {
return request({
url: `/app/device/rentPowerBank?deviceNo=${deviceNo}`,
method: 'post',
data: {
// deviceNo,
phone
}
})
}
//确认支付并弹出风扇
export const confirmPaymentAndRent = (orderId) => {
console.log(`确认支付并弹出风扇, orderId: ${orderId}`)
return request({
url: `/app/device/confirmPaymentAndRent?orderId=${orderId}`,
method: 'GET'
})
}
//投诉反馈
export const addUserFeedback = (data) => {
console.log(data);
return request({
url: '/app/feedback/add',
method: 'post',
data,
})
}
//强制打开空格子
export const forcefOpenEmptyGrid = (deviceNo) => {
console.log(`强制打开空格子, deviceNo: ${deviceNo}`)
return request({
url: `/app/device/forcef/${deviceNo}`,
method: 'post'
})
}
// 通过订单号获取订单信息
export const getOrderByOrderNo = (orderNo) => {
return request({
url: `/app/order/byOrderNo/${orderNo}`,
method: 'get',
hideLoading: true
})
}
// 通过订单号获取支付分订单信息
export const getOrderByOrderNoScore = (orderNo) => {
console.log('通过订单号获取支付分订单信息', orderNo);
return request({
url: `/app/wx-payment/score/create/${orderNo}`,
method: 'get',
hideLoading: true
})
}
export const getOrderByOrderNoScorePayStatus = (orderNo) => {
console.log('通过订单号获取支付分订单状态', orderNo);
return request({
url: `/app/wx-payment/score/status/${orderNo}`,
method: 'get',
hideLoading: true
})
}
// 更新订单套餐信息
export const updateOrderPackage = (data) => {
console.log('更新订单套餐信息:', data)
return request({
url: '/app/device/updateOrderPackage',
method: 'post',
data
})
}
// 更新用户余额
export const updateUserBalance = (orderId) => {
return request({
url: `/app/user/updateBalance/${orderId}`,
method: 'post',
hideLoading: true
})
}
/*
*弃用
*/
export const getPotionsDetail = (data) => {
console.log(data);
return request({
url: '/device/position/positionDetails',
method: 'get',
data
})
}
// 文件上传到 OSS(若依后端)
export const uploadOssResource = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: URL + '/manager/upload',
filePath,
name: 'file',
header: {
'appid': appid,
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
},
success: (res) => {
try {
const parsed = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
const codeOk = (res.statusCode === 200 || res.statusCode === 201 || parsed?.code === 200)
const url = parsed?.url || parsed?.data?.url || parsed?.data?.fileUrl || parsed?.fileUrl || parsed?.path || parsed?.data
if (codeOk && url) {
resolve(url)
return
}
reject(parsed || res)
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 上传并更新用户头像(后端接口)
export const uploadUserAvatar = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: URL + '/app/user/uploadAvatar',
filePath,
name: 'file',
header: {
'appid': appid,
'Authorization': 'Bearer ' + uni.getStorageSync('token'),
'Clientid': uni.getStorageSync('client_id')
},
success: (res) => {
try {
const parsed = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
resolve(parsed)
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err)
}
})
})
}
// 获取系统配置(预留接口)
// 期望后端返回形如:{ code: 200, data: { expressReturnCountdownSeconds: number } }
export const getSystemConfig = () => {
return request({
url: '/app/system/config',
method: 'get',
hideLoading: true
})
}
// ===================== 快递归还相关接口 =====================
// 1) 申请快递归还
export const applyExpressReturn = (data) => {
// data: { orderId: number, logisticsTrackingNumber?: string, remark?: string }
return request({
url: '/app/express-return/apply',
method: 'post',
data
})
}
// 2) 补填快递单号
export const fillExpressTrackingNumber = (data) => {
// data: { id: number, logisticsTrackingNumber: string }
return request({
url: '/app/express-return/fill-tracking-number',
method: 'post',
data
})
}
// 3) 查询快递归还记录列表
export const getExpressReturnList = (params) => {
// params: { orderId?: number, status?: number, logisticsTrackingNumber?: string, pageNum?: number, pageSize?: number }
return request({
url: '/app/express-return/list',
method: 'get',
data: params,
hideLoading: true
})
}
// 4) 根据订单ID查询快递归还记录
export const getExpressReturnByOrder = (orderId) => {
return request({
url: `/app/express-return/by-order/${orderId}`,
method: 'get',
hideLoading: true
})
}
// 5) 获取快递归还记录详情
export const getExpressReturnDetail = (id) => {
return request({
url: `/app/express-return/${id}`,
method: 'get',
hideLoading: true
})
}
// 6) 取消快递归还申请
export const cancelExpressReturn = (id) => {
return request({
url: `/app/express-return/cancel/${id}`,
method: 'post'
})
}
//获取通知接口
export const getNoticeTextData = (data)=>{
return request({
url: `/system/notice/title/${data.title}`,
method: 'get'
})
}
+16 -8
View File
@@ -40,14 +40,22 @@
"navigationBarTextStyle": "black" "navigationBarTextStyle": "black"
} }
}, },
{ {
"path": "pages/my/index", "path": "pages/my/index",
"style": { "style": {
"navigationBarTitleText": "个人中心", "navigationBarTitleText": "个人中心",
"navigationBarBackgroundColor": "#D1FFE1", "navigationBarBackgroundColor": "#D1FFE1",
"navigationBarTextStyle": "black" "navigationBarTextStyle": "black"
} }
}, },
{
"path": "pages/userProfile/index",
"style": {
"navigationBarTitleText": "个人信息",
"navigationBarBackgroundColor": "#D1FFE1",
"navigationBarTextStyle": "black"
}
},
{ {
"path": "pages/setting/index", "path": "pages/setting/index",
"style": { "style": {
+2 -1
View File
@@ -40,7 +40,8 @@
<script> <script>
import { getUserInfo } from '../../util/index.js' import { getUserInfo } from '../../util/index.js'
import { withdrawDeposit,queryById } from '../../config/user.js' import { withdrawDeposit } from '../../config/api/user.js'
import { queryById } from '../../config/api/order.js'
export default { export default {
data() { data() {
+4 -2
View File
@@ -116,13 +116,15 @@
} from '@dcloudio/uni-app' } from '@dcloudio/uni-app'
import { import {
getDeviceInfo, getDeviceInfo,
rentPowerBank, rentPowerBank
} from '@/config/api/device.js'
import {
getOrderByOrderNoScore, getOrderByOrderNoScore,
getOrderByOrderNoScorePayStatus, getOrderByOrderNoScorePayStatus,
getOrderByOrderNo, getOrderByOrderNo,
updateOrderPackage, updateOrderPackage,
cancelOrder cancelOrder
} from '@/config/user.js' } from '@/config/api/order.js'
import { import {
URL URL
} from "@/config/url.js" } from "@/config/url.js"
+4 -2
View File
@@ -50,12 +50,14 @@
onLoad onLoad
} from '@dcloudio/uni-app' } from '@dcloudio/uni-app'
import { import {
queryById, queryById
} from '@/config/api/order.js'
import {
applyExpressReturn, applyExpressReturn,
getExpressReturnByOrder, getExpressReturnByOrder,
getExpressReturnDetail, getExpressReturnDetail,
fillExpressTrackingNumber fillExpressTrackingNumber
} from '@/config/user.js' } from '@/config/api/expressReturn.js'
const orderId = ref('') const orderId = ref('')
const recordId = ref('') const recordId = ref('')
+1 -1
View File
@@ -87,7 +87,7 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { getExpressReturnDetail } from '@/config/user.js' import { getExpressReturnDetail } from '@/config/api/expressReturn.js'
// 详情数据 // 详情数据
const detailData = ref({ const detailData = ref({
+1 -1
View File
@@ -51,7 +51,7 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { getExpressReturnList } from '@/config/user.js' import { getExpressReturnList } from '@/config/api/expressReturn.js'
const returnList = ref([]) const returnList = ref([])
const loading = ref(false) const loading = ref(false)
+4 -1
View File
@@ -60,7 +60,10 @@
} from '../../config/url' } from '../../config/url'
import { import {
uploadOssResource uploadOssResource
} from '../../config/user' } from '../../config/api/user'
import {
addUserFeedback
} from '../../config/api/feedback'
// 响应式数据 // 响应式数据
const types = ref(['设备故障', '收费问题', '使用建议', '其他']) const types = ref(['设备故障', '收费问题', '使用建议', '其他'])
+8 -4
View File
@@ -1,6 +1,6 @@
<template> <template>
<view class="container fullscreen"> <view class="container fullscreen">
<view class="" style="font-size: 32rpx;font-weight: 600;margin: 15rpx 20rpx;">风电者共享风扇&充电宝</view> <view class="" style="font-size: 32rpx;font-weight: 600;margin: 15rpx 20rpx;">风电者共享风扇&暖手充电宝</view>
<view class="map-notice" v-if="noticeText"> <view class="map-notice" v-if="noticeText">
<uv-notice-bar :text="noticeText" :speed="50" :show-icon="true" color="#07c160" bg-color="#E8F8EF" <uv-notice-bar :text="noticeText" :speed="50" :show-icon="true" color="#07c160" bg-color="#E8F8EF"
icon="volume"></uv-notice-bar> icon="volume"></uv-notice-bar>
@@ -138,10 +138,14 @@
URL URL
} from "../../config/url.js" } from "../../config/url.js"
import { import {
getDeviceInfo, getDeviceInfo
getPotionsDetail, } from '../../config/api/device.js'
import {
getPotionsDetail
} from '../../config/api/order.js'
import {
getNoticeTextData getNoticeTextData
} from '../../config/user.js' } from '../../config/api/system.js'
// 导入地图工具函数 // 导入地图工具函数
import { import {
getUserLocation, getUserLocation,
+28 -22
View File
@@ -1,20 +1,16 @@
<template> <template>
<view class="my-page"> <view class="my-page">
<view class="user-card"> <view class="user-card" @click="navigateTo('/pages/userProfile/index')">
<view class="avatar-box"> <view class="avatar-box">
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image> <image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image>
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill"></image> <image v-else class="avatar" src="@/static/head.png" mode="aspectFill"></image>
<!-- 覆盖在头像上的微信选择头像授权按钮仅小程序生效 -->
<!-- #ifdef MP-WEIXIN -->
<button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button>
<!-- #endif -->
</view>
<view class="user-text">
<view class="nickname">{{ userInfo.nickName || '点击登录' }}</view>
<view class="subtext">{{ userInfo.phone ? maskPhone(userInfo.phone) : '授权登录后可查看订单与资产' }}</view>
</view>
<uv-icon type="right" size="16" color="#999"></uv-icon>
</view> </view>
<view class="user-text">
<view class="nickname">{{ userInfo.nickName || '点击登录' }}</view>
<view class="subtext">{{ userInfo.phone ? maskPhone(userInfo.phone) : '授权登录后可查看订单与资产' }}</view>
</view>
<uv-icon type="right" size="16" color="#999"></uv-icon>
</view>
<!-- <view class="assets-card"> <!-- <view class="assets-card">
@@ -36,11 +32,11 @@
<view class="list-item" @click="handleQuickReturn"> <view class="list-item" @click="handleQuickReturn">
<view class="left"> <view class="left">
<image class="icon" src="/static/express_return.png" mode="aspectFit"></image> <image class="icon" src="/static/express_return.png" mode="aspectFit"></image>
<text class="title">快速归还</text> <text class="title">快速归还<text style="font-size: 18rpx;">直接查看使用中的订单</text></text>
</view> </view>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon> <uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view> </view>
<view class="list-item" @click="navigateTo('/pages/expressReturn/index')"> <view class="list-item" @click="navigateTo('/pages/expressReturn/index')" v-if="showMenuItem">
<view class="left"> <view class="left">
<image class="icon" src="/static/express.png" mode="aspectFit"></image> <image class="icon" src="/static/express.png" mode="aspectFit"></image>
<text class="title">快递归还记录</text> <text class="title">快递归还记录</text>
@@ -68,13 +64,13 @@
</view> </view>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon> <uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view> </view>
<view class="list-item" @click="navigateTo('/pages/legal/agreement')"> <!-- <view class="list-item" @click="navigateTo('/pages/legal/agreement')">
<view class="left"> <view class="left">
<image class="icon" src="/static/business-licence.png" mode="aspectFit"></image> <image class="icon" src="/static/business-licence.png" mode="aspectFit"></image>
<text class="title">营业资质</text> <text class="title">营业资质</text>
</view> </view>
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon> <uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
</view> </view> -->
<view class="list-item" @click="navigateTo('/pages/join/index')"> <view class="list-item" @click="navigateTo('/pages/join/index')">
<view class="left"> <view class="left">
<image class="icon" src="/static/peopleInWork.png" mode="aspectFit"></image> <image class="icon" src="/static/peopleInWork.png" mode="aspectFit"></image>
@@ -94,7 +90,7 @@
<view class="footer-agreements"> <view class="footer-agreements">
<view class="link-box"> <view class="link-box">
<text class="link" @click="navigateTo('/pages/legal/agreement')">服务条款</text> <text class="link" @click="navigateTo('/pages/legal/agreement')">用户协议</text>
<text class="sep"></text> <text class="sep"></text>
<text class="link" @click="navigateTo('/pages/legal/privacy')">隐私政策</text> <text class="link" @click="navigateTo('/pages/legal/privacy')">隐私政策</text>
</view> </view>
@@ -123,14 +119,17 @@
reactive, reactive,
onMounted onMounted
} from 'vue'; } from 'vue';
import {
onShow
} from '@dcloudio/uni-app';
import { import {
wxLogin, wxLogin,
getUserInfo getUserInfo
} from '../../util/index.js'; } from '../../util/index.js';
import { import {
uploadUserAvatar uploadUserAvatar
} from '../../config/user.js' } from '../../config/api/user.js'
import { import {
URL URL
} from '../../config/url.js' } from '../../config/url.js'
@@ -143,6 +142,8 @@
const authPopup = ref(null); // u-popup 的引用 const authPopup = ref(null); // u-popup 的引用
const isPopupVisible = ref(false); const isPopupVisible = ref(false);
const appVersion = ref('1.0.0'); const appVersion = ref('1.0.0');
const showMenuItem = ref(false)
// 页面加载时初始化 // 页面加载时初始化
onMounted(() => { onMounted(() => {
@@ -150,6 +151,11 @@
initVersion(); initVersion();
}); });
// 页面显示时刷新用户信息
onShow(() => {
getInfo();
});
// 获取用户信息 // 获取用户信息
const getInfo = async () => { const getInfo = async () => {
try { try {
+4 -2
View File
@@ -118,9 +118,11 @@
<script> <script>
import { import {
queryById, queryById,
cancelOrder, cancelOrder
} from '@/config/api/order.js'
import {
getSystemConfig getSystemConfig
} from '@/config/user.js' } from '@/config/api/system.js'
import { import {
URL URL
} from "@/config/url.js" } from "@/config/url.js"
+7 -3
View File
@@ -45,10 +45,14 @@
getOrderList, getOrderList,
queryById, queryById,
getOrderByOrderNoScorePayStatus, getOrderByOrderNoScorePayStatus,
cancelOrder, cancelOrder
confirmPaymentAndRent, } from '../../config/api/order.js';
import {
confirmPaymentAndRent
} from '../../config/api/device.js';
import {
updateUserBalance updateUserBalance
} from '../../config/user.js'; } from '../../config/api/user.js';
import { import {
URL URL
} from '../../config/url.js'; } from '../../config/url.js';
+3 -4
View File
@@ -60,10 +60,9 @@
</template> </template>
<script> <script>
import { queryById } from '@/config/user.js' import { queryById, updateOrderPackage } from '@/config/api/order.js'
import { getDeviceInfo } from '@/config/user.js' import { getDeviceInfo } from '@/config/api/device.js'
import { updateOrderPackage } from '@/config/user.js' import { updateUserBalance } from '@/config/api/user.js'
import { updateUserBalance } from '@/config/user.js'
import { import {
URL URL
}from"@/config/url.js" }from"@/config/url.js"
+1 -1
View File
@@ -84,7 +84,7 @@
</template> </template>
<script> <script>
import { queryById } from '@/config/user.js' import { queryById } from '@/config/api/order.js'
import { import {
URL URL
}from"@/config/url.js" }from"@/config/url.js"
+2 -1
View File
@@ -45,7 +45,8 @@
</template> </template>
<script> <script>
import { queryById, confirmPaymentAndRent } from '@/config/user.js' import { queryById } from '@/config/api/order.js'
import { confirmPaymentAndRent } from '@/config/api/device.js'
export default { export default {
data() { data() {
+4 -2
View File
@@ -143,9 +143,11 @@
<script> <script>
import { import {
queryById, queryById,
cancelOrder, cancelOrder
} from '@/config/api/order.js'
import {
getSystemConfig getSystemConfig
} from '@/config/user.js' } from '@/config/api/system.js'
import { import {
URL URL
} from "@/config/url.js" } from "@/config/url.js"
+5 -3
View File
@@ -155,9 +155,11 @@
'Clientid': uni.getStorageSync('client_id') 'Clientid': uni.getStorageSync('client_id')
} }
}) })
if (res.statusCode === 200 && res.data?.code === 200) { if (res.statusCode === 200 && res.data?.code === 200) {
positionList.value = res.data.rows || [] // 过滤掉特定的 positionId
calculateDistances(center) const filteredData = (res.data.rows || []).filter(item => item.positionId !== '1979008434641670145')
positionList.value = filteredData
calculateDistances(center)
} else if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) { } else if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) {
uni.reLaunch({ uni.reLaunch({
url: '/pages/login/index' url: '/pages/login/index'
+3 -5
View File
@@ -11,13 +11,11 @@
import { import {
getMyIndexInfo getMyIndexInfo
} from "../../../config/user.js"; } from "../../../config/api/user.js";
import {
queryHasOrder
} from "../../../config/user.js";
import { import {
queryHasOrder,
checkOrdersByStatus checkOrdersByStatus
} from "../../../config/user.js"; } from "../../../config/api/order.js";
export default { export default {
data() { data() {
+1 -1
View File
@@ -20,7 +20,7 @@
</template> </template>
<script setup> <script setup>
import { userLogout } from '@/config/user.js' import { userLogout } from '@/config/api/user.js'
const navigateTo = (url) => { const navigateTo = (url) => {
uni.navigateTo({ url }) uni.navigateTo({ url })
+407
View File
@@ -0,0 +1,407 @@
<template>
<view class="profile-page">
<view class="avatar-section">
<view class="avatar-container">
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image>
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill"></image>
<!-- 覆盖在头像上的微信选择头像授权按钮仅小程序生效 -->
<!-- #ifdef MP-WEIXIN -->
<button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button>
<!-- #endif -->
</view>
<view class="avatar-tip">点击头像更换</view>
</view>
<view class="form-section">
<!-- 昵称编辑区域 -->
<view class="form-item nickname-item" :class="{ editing: isEditingNickname }">
<view class="label">昵称</view>
<view class="value" v-if="!isEditingNickname" @click="startEditNickname">
<text class="value-text">{{ userInfo.nickName || '未设置' }}</text>
<uv-icon name="edit-pen" size="16" color="#999999"></uv-icon>
</view>
</view>
<!-- 昵称编辑输入框展开状态 -->
<view class="nickname-edit-area" v-if="isEditingNickname">
<input
class="nickname-input"
v-model="newNickname"
placeholder="请输入新昵称"
maxlength="20"
:focus="true"
/>
<view class="edit-buttons">
<button class="cancel-btn" @click="cancelEditNickname">取消</button>
<button class="save-btn" @click="saveNickname">保存</button>
</view>
</view>
<view class="form-item">
<view class="label">手机号</view>
<view class="value">
<text class="value-text">{{ userInfo.phone ? maskPhone(userInfo.phone) : '未绑定' }}</text>
</view>
</view>
<view class="form-item" v-if="userInfo.balanceAmount !== undefined">
<view class="label">余额</view>
<view class="value">
<text class="value-text amount">¥{{ userInfo.balanceAmount || '0.00' }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { getMyIndexInfo, uploadUserAvatar, updateUserInfo } from '../../config/api/user.js';
// 响应式状态
const userInfo = ref({
nickName: '',
phone: '',
avatar: '',
balanceAmount: '0.00'
});
const newNickname = ref('');
const isEditingNickname = ref(false);
// 页面加载时初始化
onMounted(() => {
loadUserInfo();
});
// 获取用户信息
const loadUserInfo = async () => {
try {
const res = await getMyIndexInfo();
console.log('User info response:', res);
if (res.code == 401 || res.code == 40101) {
redirectToLogin();
return;
} else if (res.code == 200) {
userInfo.value = {
nickName: res.data.nickname,
phone: res.data.phone,
avatar: res.data.iconUrl,
balanceAmount: res.data.balanceAmount || '0.00',
isAdmin: res.data.isAdmin
};
uni.setStorageSync('userInfo', userInfo.value);
}
} catch (error) {
console.error('获取用户信息失败:', error);
uni.showToast({
title: '获取用户信息失败',
icon: 'none'
});
}
};
// 跳转登录
const redirectToLogin = () => {
try {
const pages = getCurrentPages();
const current = pages && pages.length ? pages[pages.length - 1] : null;
const route = current && current.route ? ('/' + current.route) : '/pages/index/index';
const query = current && current.options ? Object.keys(current.options).map(k =>
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : '';
const redirect = encodeURIComponent(query ? `${route}?${query}` : route);
uni.reLaunch({
url: `/pages/login/index?redirect=${redirect}`
});
} catch (e) {
uni.reLaunch({
url: '/pages/login/index'
});
}
};
// 小程序原生选择头像回调
const onChooseAvatar = async (e) => {
try {
const token = uni.getStorageSync('token');
if (!token) {
redirectToLogin();
return;
}
const avatarLocalPath = e?.detail?.avatarUrl;
if (!avatarLocalPath) {
uni.showToast({
title: '未选择头像',
icon: 'none'
});
return;
}
uni.showLoading({
title: '上传中...',
mask: true
});
const uploadRes = await uploadUserAvatar(avatarLocalPath);
const serverAvatar = uploadRes?.data?.url || uploadRes?.url || uploadRes?.data || '';
if (serverAvatar) {
userInfo.value = {
...userInfo.value,
avatar: serverAvatar
};
uni.setStorageSync('userInfo', userInfo.value);
}
uni.showToast({
title: '头像更新成功',
icon: 'success'
});
await loadUserInfo();
} catch (err) {
console.error('选择/上传头像失败:', err);
uni.showToast({
title: '头像更新失败',
icon: 'none'
});
} finally {
uni.hideLoading();
}
};
// 开始编辑昵称
const startEditNickname = () => {
newNickname.value = userInfo.value.nickName || '';
isEditingNickname.value = true;
};
// 取消编辑昵称
const cancelEditNickname = () => {
isEditingNickname.value = false;
newNickname.value = '';
};
// 保存昵称
const saveNickname = async () => {
if (!newNickname.value || !newNickname.value.trim()) {
uni.showToast({
title: '昵称不能为空',
icon: 'none'
});
return;
}
try {
uni.showLoading({
title: '保存中...',
mask: true
});
// 先获取最新的用户信息,确保数据是最新的
const latestUserInfo = await getMyIndexInfo();
if (latestUserInfo.code !== 200) {
throw new Error('获取用户信息失败');
}
// 使用最新的服务器数据,只修改昵称字段
const updateData = {
nickname: newNickname.value.trim(),
phone: latestUserInfo.data.phone,
iconUrl: latestUserInfo.data.iconUrl,
// 保留其他可能的字段
...latestUserInfo.data
};
// 确保昵称使用新值
updateData.nickname = newNickname.value.trim();
// 调用后端接口更新用户信息
const res = await updateUserInfo(updateData);
if (res.code === 200) {
// 更新成功后重新获取用户信息,确保数据同步
await loadUserInfo();
uni.hideLoading();
uni.showToast({
title: '昵称修改成功',
icon: 'success'
});
isEditingNickname.value = false;
} else {
throw new Error(res.message || '修改失败');
}
} catch (error) {
console.error('修改昵称失败:', error);
uni.hideLoading();
uni.showToast({
title: error.message || '修改失败',
icon: 'none'
});
}
};
// 手机号掩码函数
function maskPhone(phone) {
if (!phone) return '';
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
</script>
<style lang="scss" scoped>
.profile-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: env(safe-area-inset-bottom);
}
.avatar-section {
background: linear-gradient(180deg, #D1FFE1 0%, #ffffff 100%);
padding: 60rpx 0 40rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.avatar-container {
position: relative;
margin-bottom: 20rpx;
}
.avatar {
width: 160rpx;
height: 160rpx;
border-radius: 80rpx;
background-color: #f0f0f0;
display: block;
}
/* 仅小程序端存在,此按钮覆盖在头像上捕获点击以触发选择头像 */
/* #ifdef MP-WEIXIN */
.avatar-choose-btn {
position: absolute;
left: 0;
top: 0;
width: 160rpx;
height: 160rpx;
border: none;
background: transparent;
padding: 0;
margin: 0;
opacity: 0;
border-radius: 80rpx;
}
/* #endif */
.avatar-tip {
font-size: 24rpx;
color: #999999;
}
.form-section {
margin: 20rpx 30rpx;
background-color: #ffffff;
border-radius: 20rpx;
overflow: hidden;
}
.form-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 32rpx 30rpx;
border-bottom: 1rpx solid #f5f5f5;
transition: all 0.3s ease;
}
.form-item:last-child {
border-bottom: none;
}
.form-item.nickname-item.editing {
border-bottom: none;
padding-bottom: 20rpx;
}
.label {
font-size: 30rpx;
color: #333333;
font-weight: 500;
}
.value {
display: flex;
align-items: center;
}
.value-text {
font-size: 28rpx;
color: #666666;
margin-right: 10rpx;
}
.value-text.amount {
color: #e2231a;
font-weight: 600;
font-size: 32rpx;
}
/* 昵称编辑区域样式 */
.nickname-edit-area {
padding: 0 30rpx 30rpx 30rpx;
border-bottom: 1rpx solid #f5f5f5;
animation: slideDown 0.3s ease;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20rpx);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.nickname-input {
width: 100%;
height: 80rpx;
border: 1rpx solid #e0e0e0;
border-radius: 10rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333333;
box-sizing: border-box;
margin-bottom: 20rpx;
background-color: #fafafa;
}
.edit-buttons {
display: flex;
justify-content: flex-end;
gap: 20rpx;
}
.cancel-btn,
.save-btn {
padding: 0 40rpx;
height: 64rpx;
line-height: 64rpx;
text-align: center;
border-radius: 32rpx;
font-size: 28rpx;
border: none;
min-width: 120rpx;
}
.cancel-btn {
background-color: #f5f5f5;
color: #666666;
}
.save-btn {
background: linear-gradient(135deg, #42d392 0%, #28c76f 100%);
color: #ffffff;
}
</style>
+1 -1
View File
@@ -23,7 +23,7 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from 'vue' import { ref, onMounted, onUnmounted } from 'vue'
import { onLoad, onUnload } from '@dcloudio/uni-app' import { onLoad, onUnload } from '@dcloudio/uni-app'
import { getOrderByOrderNoScorePayStatus, cancelOrder } from '@/config/user.js' import { getOrderByOrderNoScorePayStatus, cancelOrder } from '@/config/api/order.js'
const progress = ref(0) const progress = ref(0)
const leftRotateDeg = ref(0) const leftRotateDeg = ref(0)
+1 -1
View File
@@ -1,7 +1,7 @@
import { import {
login, login,
getMyIndexInfo getMyIndexInfo
} from "../config/user" } from "../config/api/user"
import { import {
URL, URL,
appid appid
+1 -1
View File
@@ -1,4 +1,4 @@
import { queryById } from '@/config/user.js' import { queryById } from '@/config/api/order.js'
/** /**
* 订单监控服务 * 订单监控服务