diff --git a/.gitignore b/.gitignore
index 62d68fe..6828190 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,5 @@
/dist
package-lock.json
/unpackage
-/unpackage/dist
\ No newline at end of file
+/unpackage/dist
+/doc
\ No newline at end of file
diff --git a/components/LocationListSheet.vue b/components/LocationListSheet.vue
new file mode 100644
index 0000000..8160253
--- /dev/null
+++ b/components/LocationListSheet.vue
@@ -0,0 +1,234 @@
+
+
+
+
+
+
+
+
diff --git a/components/MapComponent.vue b/components/MapComponent.vue
index 063a973..f588f3b 100644
--- a/components/MapComponent.vue
+++ b/components/MapComponent.vue
@@ -3,11 +3,13 @@
-
-
-
@@ -39,15 +39,15 @@
+
+
+
+
diff --git a/config/user.js b/config/user.js
index 10ff5e3..ff513ff 100644
--- a/config/user.js
+++ b/config/user.js
@@ -249,6 +249,33 @@ export const uploadOssResource = (filePath) => {
})
}
+// 上传并更新用户头像(后端接口)
+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 = () => {
diff --git a/pages.json b/pages.json
index a8291fa..306a6d0 100644
--- a/pages.json
+++ b/pages.json
@@ -43,9 +43,19 @@
{
"path": "pages/my/index",
"style": {
- "navigationBarTitleText": "个人中心"
+ "navigationBarTitleText": "个人中心",
+ "navigationBarBackgroundColor": "#D1FFE1",
+ "navigationBarTextStyle": "black"
}
},
+ {
+ "path": "pages/setting/index",
+ "style": {
+ "navigationBarTitleText": "设置",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black"
+ }
+ },
{
"path": "pages/deposit/index",
"style": {
@@ -125,6 +135,14 @@
"navigationBarTextStyle": "black"
}
},
+ {
+ "path": "pages/order/detail",
+ "style": {
+ "navigationBarTitleText": "订单详情",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black"
+ }
+ },
{
"path": "pages/expressReturn/index",
"style": {
@@ -140,6 +158,14 @@
"navigationBarTextStyle": "black"
}
},
+ {
+ "path": "pages/search/index",
+ "style": {
+ "navigationBarTitleText": "查找设备",
+ "navigationBarBackgroundColor": "#ffffff",
+ "navigationBarTextStyle": "black"
+ }
+ },
{
"path": "pages/waiting/index",
"style": {
diff --git a/pages/device/detail.vue b/pages/device/detail.vue
index 5070336..e67e2a5 100644
--- a/pages/device/detail.vue
+++ b/pages/device/detail.vue
@@ -1,44 +1,19 @@
-
-
-
-
-
-
-
-
-
-
- 当前位置
- {{ deviceLocation }}
-
+
+
+
+ {{ deviceLocation }}
-
+
+ {{ deviceStatus.text }}
+
+
+
+ 设备号:
+ {{ deviceId }}
@@ -50,46 +25,33 @@
- ¥{{deviceFeeConfig.maxHourPrice}}
+ ¥
+ {{ deviceFeeConfig.maxHourPrice || '5.00' }}
/小时
- 封顶 ¥{{deviceInfo.depositAmount}}
+
+ {{ deviceInfo.depositAmount || '99' }}元封顶
+
-
-
-
-
- 不足60分钟按60分钟计费
+
+
+ ⓘ
-
-
- 持续计费至99元视为买断
+ 5元/小时,45元/24小时
+
+
+
+ ⓘ
+ 前15分钟内归还免费,不足60分钟按60分钟计费点总封顶99元,持续计费至99元视为买断
-
-
-
-
+
@@ -98,34 +60,25 @@
- 请在指定区域内使用设备
+ 超出使用时间将自动按小时计费
- 归还时请确保设备完好,避免损坏
+ 请在指定区域内使用设备
@@ -539,81 +492,11 @@
box-sizing: border-box;
}
- // 顶部设备信息
- .device-header {
- display: flex;
- flex-direction: column;
- margin-bottom: 30rpx;
-
- .device-status-card {
- display: flex;
- align-items: center;
- margin-bottom: 20rpx;
-
- .status-indicator {
- width: 20rpx;
- height: 20rpx;
- border-radius: 50%;
- margin-right: 10rpx;
- }
-
- &.available {
- .status-indicator {
- background-color: #10c469;
- box-shadow: 0 0 10rpx rgba(16, 196, 105, 0.5);
- }
-
- .status-text {
- color: #10c469;
- }
- }
-
- &.offline {
- .status-indicator {
- background-color: #9a9a9a;
- }
-
- .status-text {
- color: #9a9a9a;
- }
- }
-
- .status-text {
- font-size: 28rpx;
- font-weight: 500;
- }
- }
-
- .device-title {
- .name {
- font-size: 48rpx;
- font-weight: bold;
- color: #333;
- }
-
- .device-meta {
- margin-top: 10rpx;
- display: flex;
- align-items: center;
-
- .id-label {
- font-size: 26rpx;
- color: #999;
- }
-
- .id-value {
- font-size: 26rpx;
- color: #666;
- }
- }
- }
- }
-
// 卡片通用样式
.card {
background-color: #fff;
border-radius: 24rpx;
- box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.03);
+ box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
padding: 30rpx;
margin-bottom: 30rpx;
@@ -631,177 +514,161 @@
}
}
- // 设备信息卡
+ // 设备信息卡片
.device-info-card {
- .card-row {
- display: flex;
- justify-content: space-between;
- }
- .card-item {
+ .device-location {
display: flex;
align-items: center;
- flex: 1;
+ justify-content: space-between;
+ margin-bottom: 20rpx;
- .item-icon {
- width: 60rpx;
- height: 60rpx;
- border-radius: 12rpx;
- margin-right: 20rpx;
+ .location-left {
display: flex;
align-items: center;
- justify-content: center;
- font-size: 30rpx;
- color: #fff;
- &.location-icon {
- background: linear-gradient(135deg, #40c9ff, #32a5ff);
-
- // &::before {
- // content: "\e900"; // 使用字体图标,需要自行替换
- // }
+ .location-icon {
+ width: 40rpx;
+ height: 40rpx;
+ margin-right: 12rpx;
+ background-color: #10d673;
+ border-radius: 50%;
}
- &.battery-icon {
- background: linear-gradient(135deg, #33db92, #10c469);
-
- // &::before {
- // content: "\e901"; // 使用字体图标,需要自行替换
- // }
-
- &.battery-low {
- background: linear-gradient(135deg, #ff7676, #f54f4f);
- }
- }
- }
-
- .item-content {
- display: flex;
- flex-direction: column;
-
- .item-label {
- font-size: 26rpx;
- color: #999;
- margin-bottom: 4rpx;
- }
-
- .item-value {
- font-size: 30rpx;
+ .location-name {
+ font-size: 32rpx;
color: #333;
font-weight: 500;
}
}
+
+ .device-status {
+ padding: 8rpx 24rpx;
+ border-radius: 30rpx;
+ font-size: 24rpx;
+
+ &.available {
+ background-color: #d4f4dd;
+
+ .status-text {
+ color: #07c160;
+ }
+ }
+
+ &.offline {
+ background-color: #f0f0f0;
+
+ .status-text {
+ color: #999;
+ }
+ }
+
+ .status-text {
+ font-size: 24rpx;
+ }
+ }
+ }
+
+ .device-id {
+ display: flex;
+ align-items: center;
+
+ .id-label {
+ font-size: 28rpx;
+ color: #999;
+ }
+
+ .id-value {
+ font-size: 28rpx;
+ color: #666;
+ }
}
}
- // 计费规则
+ // 计费规则卡片
.pricing-card {
.pricing-banner {
- background: linear-gradient(to right, #f8f9ff, #e8f0ff);
- border-radius: 16rpx;
- padding: 30rpx;
- margin-bottom: 30rpx;
+ background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
+ border-radius: 20rpx;
+ padding: 40rpx 30rpx;
+ margin-bottom: 24rpx;
display: flex;
flex-direction: column;
align-items: center;
.pricing-main {
display: flex;
- align-items: flex-end;
+ align-items: baseline;
+ margin-bottom: 16rpx;
+
+ .price-symbol {
+ font-size: 48rpx;
+ font-weight: bold;
+ color: #07c160;
+ margin-right: 4rpx;
+ }
.price {
- font-size: 60rpx;
+ font-size: 80rpx;
font-weight: bold;
- color: #ff6b6b;
+ color: #07c160;
+ line-height: 1;
}
.unit {
+ font-size: 32rpx;
+ color: #07c160;
+ margin-left: 8rpx;
+ }
+ }
+
+ .cap-badge {
+ background-color: #07c160;
+ padding: 10rpx 32rpx;
+ border-radius: 30rpx;
+
+ .cap-text {
+ font-size: 26rpx;
+ color: #fff;
+ font-weight: 500;
+ }
+ }
+ }
+
+ .pricing-info {
+ display: flex;
+ align-items: flex-start;
+ margin-bottom: 16rpx;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ .info-icon {
+ width: 32rpx;
+ height: 32rpx;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 12rpx;
+ margin-top: 2rpx;
+
+ .icon-text {
font-size: 28rpx;
color: #999;
- margin-left: 4rpx;
- margin-bottom: 10rpx;
}
}
- .cap-price {
- margin-top: 10rpx;
+ .info-text {
+ flex: 1;
font-size: 26rpx;
color: #666;
- background-color: rgba(255, 107, 107, 0.1);
- padding: 6rpx 20rpx;
- border-radius: 20rpx;
- }
- }
-
- .pricing-rules {
- .rule-item {
- display: flex;
- align-items: center;
- margin-bottom: 16rpx;
-
- &:last-child {
- margin-bottom: 0;
- }
-
- .rule-dot {
- width: 10rpx;
- height: 10rpx;
- border-radius: 50%;
- background-color: #ff6b6b;
- margin-right: 16rpx;
- }
-
- .rule-text {
- font-size: 28rpx;
- color: #666;
-
- .highlight {
- color: #ff6b6b;
- font-weight: bold;
- }
- }
+ line-height: 1.6;
}
}
}
- // 手机号输入
- .phone-card {
- .phone-input-container {
- .input-wrapper {
- display: flex;
- align-items: center;
- height: 88rpx;
- background-color: #f5f7fa;
- border-radius: 16rpx;
- padding: 0 24rpx;
-
- .prefix {
- font-size: 28rpx;
- color: #666;
- margin-right: 16rpx;
- padding-right: 16rpx;
- border-right: 1px solid #e0e0e0;
- }
-
- .phone-input {
- flex: 1;
- height: 88rpx;
- font-size: 28rpx;
- color: #333;
- padding-left: 10rpx;
- }
- }
-
- .phone-tip {
- font-size: 24rpx;
- color: #999;
- margin-top: 16rpx;
- display: block;
- }
- }
- }
-
- // 使用须知
+ // 使用说明卡片
.notice-card {
.notice-items {
.notice-item {
@@ -814,15 +681,17 @@
}
.notice-dot {
- width: 10rpx;
- height: 10rpx;
+ width: 12rpx;
+ height: 12rpx;
border-radius: 50%;
- background-color: #32a5ff;
+ background-color: #07c160;
margin-right: 16rpx;
- margin-top: 12rpx;
+ margin-top: 10rpx;
+ flex-shrink: 0;
}
.notice-text {
+ flex: 1;
font-size: 28rpx;
color: #666;
line-height: 1.6;
@@ -838,58 +707,31 @@
left: 0;
right: 0;
background-color: #fff;
- padding: 20rpx 30rpx;
- padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
- box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.05);
+ padding: 24rpx 30rpx;
+ padding-bottom: calc(24rpx + env(safe-area-inset-bottom));
+ box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
z-index: 100;
display: flex;
flex-direction: column;
- // 添加一个变量来保存footer高度,方便管理和确保一致性
- --footer-height: 180rpx;
-
- .wechat-credit {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 10rpx;
-
- .wx-icon {
- width: 50rpx;
- height: 40rpx;
- margin-right: 10rpx;
- }
-
- .credit-text {
- font-size: 24rpx;
- color: #07c160;
- display: flex;
- align-items: center;
-
- .credit-divider {
- margin: 0 10rpx;
- }
-
- .credit-score {
- font-weight: 500;
- }
- }
- }
+ align-items: center;
.rent-button {
- height: 92rpx;
- border-radius: 46rpx;
+ width: 100%;
+ height: 96rpx;
+ border-radius: 48rpx;
background: linear-gradient(135deg, #07c160, #10d673);
color: #fff;
- font-size: 32rpx;
+ font-size: 34rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
border: none;
- width: 90%;
+ box-shadow: 0 8rpx 20rpx rgba(7, 193, 96, 0.3);
&.return-button {
background: linear-gradient(135deg, #FF9800, #FFB74D);
+ box-shadow: 0 8rpx 20rpx rgba(255, 152, 0, 0.3);
}
&:active {
@@ -897,6 +739,29 @@
opacity: 0.9;
}
}
+
+ .wechat-credit {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-top: 16rpx;
+
+ .wx-icon {
+ width: 48rpx;
+ height: 38rpx;
+ margin-right: 8rpx;
+ }
+
+ .credit-text {
+ font-size: 24rpx;
+ color: #999;
+
+ .divider {
+ margin: 0 8rpx;
+ color: #ddd;
+ }
+ }
+ }
}
/* 手机号授权弹窗样式 */
diff --git a/pages/expressReturn/addExpressReturn.vue b/pages/expressReturn/addExpressReturn.vue
index 6a1ff62..b76a713 100644
--- a/pages/expressReturn/addExpressReturn.vue
+++ b/pages/expressReturn/addExpressReturn.vue
@@ -1,7 +1,7 @@
-
-
+
+
订单号
{{ orderInfo.orderNo }}
@@ -11,32 +11,32 @@
{{ orderInfo.deviceNo }}
- 开始时间
+ 开放时间
{{ orderInfo.startTime }}
-
-
+
+
填写快递归还信息
-
- 联系电话
-
+
+
+ 联系电话
+
-
- 快递单号
-
+
+
+ 快递单号
+
+
{{ tipsText }}
-
-
- {{ isFillMode ? '确认补填' : '提交信息' }}
+
+
+ {{ isFillMode ? '确认补填' : '提交信息' }}
@@ -249,130 +249,117 @@
\ No newline at end of file
diff --git a/pages/expressReturn/index.vue b/pages/expressReturn/index.vue
index b121c89..61d2e57 100644
--- a/pages/expressReturn/index.vue
+++ b/pages/expressReturn/index.vue
@@ -1,42 +1,42 @@
-
-
+
+
+
+
+ 风电者 18163601305
+ 湖南省长沙市岳麓区麓谷街道新长海尖科技园A2栋623
+
+
+ 一键复制全部信息
+
+
-
-
-
- {{ getStatusIcon(item.status) }}
-
+
+
+
-
+
-
@@ -57,6 +57,10 @@ const returnList = ref([])
const loading = ref(false)
const query = ref({ pageNum: 1, pageSize: 20 })
+// 收件信息
+const recipientName = '风电者 18163601305'
+const recipientAddress = '湖南省长沙市岳麓区麓谷街道新长海尖科技园A2栋623'
+
const loadList = async () => {
try {
loading.value = true
@@ -103,18 +107,32 @@ const getStatusClass = (status) => ({
'pending': 'status-pending'
}[status] || 'status-pending')
-const getStatusIcon = (status) => ({
- 'completed': '✓',
- 'processing': '⏳',
- 'pending': '⏸'
-}[status] || '⏸')
-
const getStatusText = (status) => ({
+ 'completed': '暂停计费中',
+ 'processing': '暂停计费中',
+ 'pending': '暂停计费中'
+}[status] || '暂停计费中')
+
+const getStatusBadge = (status) => ({
'completed': '已完成',
'processing': '处理中',
'pending': '待处理'
}[status] || '待处理')
+// 一键复制全部信息
+const copyAllInfo = () => {
+ const allInfo = `收件人:${recipientName}\n收件地址:${recipientAddress}`
+ uni.setClipboardData({
+ data: allInfo,
+ success: () => {
+ uni.showToast({ title: '全部信息已复制', icon: 'success' })
+ },
+ fail: () => {
+ uni.showToast({ title: '复制失败', icon: 'none' })
+ }
+ })
+}
+
// 点击列表项
const handleItemClick = (item) => {
console.log('点击了归还记录:', item)
@@ -132,145 +150,135 @@ onMounted(loadList)
\ No newline at end of file
diff --git a/pages/help/index.vue b/pages/help/index.vue
index a594a83..0f3257c 100644
--- a/pages/help/index.vue
+++ b/pages/help/index.vue
@@ -127,12 +127,28 @@ export default {
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
.contact-title {
+ position: relative;
+ z-index: 4;
+ display: inline-block;
font-size: 32rpx;
color: #333;
font-weight: 500;
margin-bottom: 20rpx;
- border-left: 8rpx solid #1976D2;
- padding-left: 20rpx;
+ padding-bottom: 8rpx;
+ width:fit-content;
+
+ &::after {
+ z-index: -1;
+ content: '';
+ position: absolute;
+ left: 0;
+ bottom: 8rpx;
+ width: 88%;
+ height: 16rpx;
+ border-radius: 20rpx;
+ // background: transparent;
+ background: #07C160; // 底部高亮(微信绿)
+ }
}
.contact-content {
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 956b076..407925c 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -1,1298 +1,1447 @@
-
-
- 风电者共享风扇&充电宝
-
-
-
-
-
-
-
-
-
-
-
-
-
- 附近设备
-
-
-
-
-
-
- 扫码使用
-
-
-
-
-
-
- 个人中心
-
-
-
-
-
-
-
- 正在获取位置信息...
-
-
-
-
-
-
-
-
-
-
-
-
- 正在获取场地信息...
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pages/my/index.vue b/pages/my/index.vue
index 21ff32a..3ac3f2e 100644
--- a/pages/my/index.vue
+++ b/pages/my/index.vue
@@ -1,124 +1,109 @@
-
-
-
@@ -142,9 +128,9 @@
wxLogin,
getUserInfo
} from '../../util/index.js';
- import {
- userLogout
- } from '@/config/user.js'
+ import { uploadUserAvatar } from '../../config/user.js'
+ import { URL } from '../../config/url.js'
+// 设置页执行退出登录,此页不再直接调用
// 响应式状态
const userInfo = ref({});
@@ -152,10 +138,12 @@
const openId = ref('');
const authPopup = ref(null); // u-popup 的引用
const isPopupVisible = ref(false);
+ const appVersion = ref('1.0.0');
// 页面加载时初始化
onMounted(() => {
getInfo();
+ initVersion();
});
// 获取用户信息
@@ -194,6 +182,26 @@
}
};
+ // 初始化应用版本号(多端兼容,取可用信息)
+ const initVersion = () => {
+ // #ifdef MP-WEIXIN
+ try {
+ const info = wx.getAccountInfoSync && wx.getAccountInfoSync();
+ if (info && info.miniProgram && info.miniProgram.version) {
+ appVersion.value = info.miniProgram.version;
+ }
+ } catch (e) {}
+ // #endif
+
+ // #ifdef APP-PLUS
+ try {
+ if (typeof plus !== 'undefined' && plus.runtime && plus.runtime.version) {
+ appVersion.value = plus.runtime.version;
+ }
+ } catch (e) {}
+ // #endif
+ };
+
const redirectToLogin = () => {
try {
const pages = getCurrentPages()
@@ -219,6 +227,52 @@
});
};
+ // 处理快速归还
+ const handleQuickReturn = async () => {
+ try {
+ uni.showLoading({
+ title: '加载中'
+ });
+
+ // 获取使用中的订单
+ const res = await uni.request({
+ url: `${URL}/app/order/inUse`,
+ method: 'GET',
+ header: {
+ 'Authorization': "Bearer " + uni.getStorageSync('token'),
+ 'Clientid': uni.getStorageSync('client_id')
+ }
+ });
+
+ uni.hideLoading();
+
+ if (res.statusCode === 401 || res.data?.code === 401 || res.data?.code === 40101) {
+ redirectToLogin();
+ return;
+ }
+
+ if (res.statusCode === 200 && res.data.code === 200 && res.data.data) {
+ const inUseOrder = res.data.data;
+ // 跳转到统一订单详情页面
+ uni.navigateTo({
+ url: `/pages/order/detail?orderId=${inUseOrder.orderId}&deviceId=${inUseOrder.deviceNo}`
+ });
+ } else {
+ uni.showToast({
+ title: '暂无使用中的订单',
+ icon: 'none'
+ });
+ }
+ } catch (error) {
+ uni.hideLoading();
+ console.error('获取使用中订单失败:', error);
+ uni.showToast({
+ title: '获取订单失败',
+ icon: 'none'
+ });
+ }
+ };
+
// 处理提现按钮点击
const handleWithdraw = () => {
navigateTo('/pages/deposit/index');
@@ -226,15 +280,49 @@
// 处理用户资料点击
const handleUserProfileClick = () => {
- if (!userInfo.value) {
- // 打开授权弹窗
- openAuthPopup();
- } else {
- // 已登录用户点击个人资料,可以导航到编辑页面
- // navigateTo('/pages/profile/edit');
+ const token = uni.getStorageSync('token')
+ if (!token) {
+ redirectToLogin()
+ return
}
+ // #ifdef MP-WEIXIN
+ getUserProfile()
+ // #endif
+ // #ifndef MP-WEIXIN
+ uni.showToast({ title: '请在微信小程序中使用此功能', icon: 'none' })
+ // #endif
};
+ // 小程序原生选择头像回调(需基础库>=2.21.2)
+ 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 getInfo()
+ } catch (err) {
+ console.error('选择/上传头像失败:', err)
+ uni.showToast({ title: '头像更新失败', icon: 'none' })
+ } finally {
+ uni.hideLoading()
+ }
+ }
+
// 打开授权弹窗
const openAuthPopup = () => {
if (authPopup.value) {
@@ -270,6 +358,7 @@
success: (res) => {
console.log('获取用户信息成功:', res);
updateUserInfo(res.userInfo);
+ uploadAvatarAndRefresh(res.userInfo);
},
fail: (err) => {
console.error('获取用户信息失败:', err);
@@ -331,6 +420,46 @@
}
};
+ // 下载并上传头像,更新用户信息
+ const uploadAvatarAndRefresh = async (wxUserInfo) => {
+ try {
+ const avatarUrl = wxUserInfo?.avatarUrl
+ if (!avatarUrl) {
+ uni.showToast({ title: '未获取到头像地址', icon: 'none' })
+ return
+ }
+ // 下载微信头像为本地临时文件
+ const tempFilePath = await new Promise((resolve, reject) => {
+ uni.downloadFile({
+ url: avatarUrl,
+ success: (res) => {
+ if (res.statusCode === 200 && res.tempFilePath) {
+ resolve(res.tempFilePath)
+ return
+ }
+ reject(new Error('头像下载失败'))
+ },
+ fail: reject
+ })
+ })
+ // 上传到后端
+ const uploadRes = await uploadUserAvatar(tempFilePath)
+ // 直接使用返回的头像地址(如果有),并刷新用户信息
+ 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 getInfo()
+ } catch (error) {
+ console.error('头像上传失败:', error)
+ uni.showToast({ title: '头像上传失败', icon: 'none' })
+ } finally {
+ uni.hideLoading()
+ }
+ }
+
// 关闭授权弹窗
const closeAuthPopup = () => {
if (authPopup.value) {
@@ -362,222 +491,221 @@
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
}
- const doLogout = async () => {
- uni.showModal({
- title: '提示',
- content: '确定要退出登录吗?',
- success: async (res) => {
- if (res.confirm) {
- const response = await userLogout();
- if (response.code == 200) {
- uni.showToast({
- title:'退出成功',
- icon:'none'
- })
- setTimeout(() => {
- uni.removeStorageSync('token');
- uni.removeStorageSync('userInfo');
- uni.redirectTo({
- url: '/pages/login/index'
- })
- }, 1500)
- }
- }
- }
- })
- }
+// 退出登录移动至设置页
\ No newline at end of file
diff --git a/pages/order/detail.vue b/pages/order/detail.vue
new file mode 100644
index 0000000..241a21a
--- /dev/null
+++ b/pages/order/detail.vue
@@ -0,0 +1,1026 @@
+
+
+
+
+
+
+
+
+
+ {{ getUsedTimeNumber() }}
+ {{ getUsedTimeUnit() }}
+
+
+ {{ getOrderFee() }}
+ {{ isOrderCompleted() ? '订单金额' : '订单金额' }}
+
+
+ {{ orderInfo.packagePrice || '10' }}
+ 元
+
+
+
+ 计费规则:5.0元/60分钟 前15分钟内归还免费 不足60分钟按60分钟计费 封顶99元 持续计费至99元视为买断
+
+
+
+
+
+ 租借信息
+
+ 订单编号
+ {{ orderInfo.orderNo || '-' }}
+
+
+ 风扇编号
+ {{ deviceId || '-' }}
+
+
+ 租借时间
+ {{ orderInfo.startTime || '-' }}
+
+
+ 租借地点
+ {{ orderInfo.positionName || '新佳宜(九天银河店)' }}
+
+
+ 租借方式
+ {{ getPayWayText() }}
+
+
+ 归还时间
+ {{ orderInfo.endTime }}
+
+
+ 归还地点
+ {{ orderInfo.returnPosition || '新佳宜(九天银河店)' }}
+
+
+ 已支付
+ {{ orderInfo.currentFee || orderInfo.payAmount || '10' }}
+ 元
+
+
+
+
+
+
+
+
+
+ 客服中心
+
+
+ {{ formatCountdown(countdownRemaining) }}后可快递归还
+
+
+ 暂停计费
+
+
+ 快速归还
+
+
+
+
+
+
+
+ 费用申请
+
+
+
+ 客服中心
+
+
+ 再次租借
+
+
+
+
+
+ 取消订单
+ 立即支付
+
+
+
+
+ 返回首页
+
+
+
+
+
+
+
+
+
diff --git a/pages/order/index.vue b/pages/order/index.vue
index b89ec2a..774b4ef 100644
--- a/pages/order/index.vue
+++ b/pages/order/index.vue
@@ -11,96 +11,22 @@
-
+
+
+
暂无订单记录
-
-
-
-
-
-
-
-
- 共享风扇
- 设备号:{{ order.deviceId }}
-
-
-
-
-
-
-
-
- 微信支付分
- |
- 免押租借
-
-
-
-
- 会员订单
-
-
-
- 押金租借
-
-
-
-
-
-
-
- 开始时间:
- {{ order.startTime }}
-
-
- 结束时间:
- {{ order.endTime || '-' }}
-
-
-
-
-
-
-
+
@@ -111,6 +37,7 @@
reactive,
onMounted
} from 'vue';
+ import OrderItemCard from '../../components/OrderItemCard.vue';
import {
onLoad
} from '@dcloudio/uni-app';
@@ -215,7 +142,9 @@
payWay: orderData.payWay,
startTime: orderStartTime,
endTime: orderData.endTime || '',
- amount: orderData.payAmount || orderData.actualDeviceAmount || '0.00'
+ positionName: orderData.positionName || orderData.positionLocation || '',
+ deviceName: orderData.deviceName || '',
+ amount: orderData.payAmount || orderData.actualDeviceAmount || orderData.currentFee || orderData.residueAmount || '0.00'
};
// 将订单添加到列表开头
@@ -270,7 +199,9 @@
payWay: item.payWay,
startTime: orderStartTime,
endTime: item.endTime || '',
- amount: item.payAmount || item.actualDeviceAmount || '0.00'
+ positionName: item.positionName || item.positionLocation || '',
+ deviceName: item.deviceName || '',
+ amount: item.payAmount || item.actualDeviceAmount || item.currentFee || item.residueAmount || '0.00'
};
});
}
@@ -302,19 +233,21 @@
}
};
- // 跳转到归还设备页面
- const navigateToReturn = (deviceId, orderId) => {
- console.log(orderId);
+ // 跳转到订单详情页面(统一入口)
+ const navigateToOrderDetail = (order) => {
uni.navigateTo({
- url: `/pages/return/index?deviceId=${deviceId}&orderId=${orderId}`
+ url: `/pages/order/detail?orderId=${order.orderId || order.orderNo}&deviceId=${order.deviceId}`
});
};
+
+ // 组件事件:归还设备(实际跳转到订单详情页)
+ const onReturnDevice = (order) => {
+ navigateToOrderDetail(order);
+ };
// 跳转到订单详情页
const navigateToDetails = (order) => {
- uni.navigateTo({
- url: `/pages/return/index?orderId=${order.orderId || order.orderNo}&deviceId=${order.deviceId}`
- });
+ navigateToOrderDetail(order);
};
// 立即支付
@@ -676,7 +609,7 @@
height: 180rpx;
margin: 0 auto 30rpx;
background: #f5f5f5;
- border-radius: 50%;
+ // border-radius: 50%;
}
.empty-text {
diff --git a/pages/search/index.vue b/pages/search/index.vue
new file mode 100644
index 0000000..7ba0b1d
--- /dev/null
+++ b/pages/search/index.vue
@@ -0,0 +1,391 @@
+
+
+
+
+
+
+ 可租借
+ 可归还
+
+
+
+
+
+
+ {{ item.name }}
+
+
+
+ {{ item.location }}
+
+
+ 营业时间:{{ item.workTime }}
+
+
+ 可租借
+ 可归还
+
+
+
+
+
+
+
+ {{ item.distance }}
+
+
+
+
+
+ 附近暂无设备
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/setting/index.vue b/pages/setting/index.vue
new file mode 100644
index 0000000..c7be6fb
--- /dev/null
+++ b/pages/setting/index.vue
@@ -0,0 +1,80 @@
+
+
+
+
+ 用户协议
+
+
+
+ 隐私政策
+
+
+
+
+
+ 退出登录
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/static/customer-service.png b/static/customer-service.png
index e43f982..95275a6 100644
Binary files a/static/customer-service.png and b/static/customer-service.png differ
diff --git a/static/express_return.png b/static/express_return.png
new file mode 100644
index 0000000..fc0deff
Binary files /dev/null and b/static/express_return.png differ
diff --git a/static/index_swiper.png b/static/index_swiper.png
new file mode 100644
index 0000000..9ed81c1
Binary files /dev/null and b/static/index_swiper.png differ
diff --git a/static/location.png b/static/location.png
index 5a4517d..8472a57 100644
Binary files a/static/location.png and b/static/location.png differ
diff --git a/static/orderList.png b/static/orderList.png
new file mode 100644
index 0000000..e046e0c
Binary files /dev/null and b/static/orderList.png differ
diff --git a/static/other_device.png b/static/other_device.png
new file mode 100644
index 0000000..b00c153
Binary files /dev/null and b/static/other_device.png differ
diff --git a/static/peopleInWork.png b/static/peopleInWork.png
new file mode 100644
index 0000000..11f2b71
Binary files /dev/null and b/static/peopleInWork.png differ
diff --git a/static/setting.png b/static/setting.png
new file mode 100644
index 0000000..139862a
Binary files /dev/null and b/static/setting.png differ
diff --git a/static/suggess.png b/static/suggess.png
new file mode 100644
index 0000000..b3aff88
Binary files /dev/null and b/static/suggess.png differ
diff --git a/static/use_help.png b/static/use_help.png
new file mode 100644
index 0000000..a97d372
Binary files /dev/null and b/static/use_help.png differ
diff --git a/static/user-active.png b/static/user-active.png
deleted file mode 100644
index 892cea3..0000000
Binary files a/static/user-active.png and /dev/null differ
diff --git a/static/user.png b/static/user.png
index 1054ecf..03789be 100644
Binary files a/static/user.png and b/static/user.png differ
diff --git a/static/userCenter_swiper.png b/static/userCenter_swiper.png
new file mode 100644
index 0000000..5e4d076
Binary files /dev/null and b/static/userCenter_swiper.png differ
diff --git a/utils/orderMonitor.js b/utils/orderMonitor.js
index b6841d7..b1bfb9e 100644
--- a/utils/orderMonitor.js
+++ b/utils/orderMonitor.js
@@ -191,9 +191,9 @@ class OrderMonitor {
confirmText: '查看详情',
success: (res) => {
if (res.confirm) {
- // 跳转到归还成功页面查看详情
+ // 跳转到统一订单详情页面查看详情
uni.redirectTo({
- url: `/pages/order/return-success?orderId=${orderId}`
+ url: `/pages/order/detail?orderId=${orderId}`
})
}
}