feat:国际化多语言适配
This commit is contained in:
@@ -14,23 +14,23 @@
|
||||
@click="$emit('select', item)">
|
||||
<view class="position-info">
|
||||
<view class="position-name">{{ item.name }}</view>
|
||||
<view class="tag-row">
|
||||
<view class="status-tag rent" v-if="isRentable(item)"><text>可租借</text></view>
|
||||
<view class="status-tag return" v-if="isReturnable(item)"><text>可归还</text></view>
|
||||
</view>
|
||||
<view class="position-time" v-if="item.workTime && item.workTime !== '0'"><text>营业时间:{{ item.workTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="position-actions">
|
||||
<view class="distance-info" v-if="item.distance"><text>{{ item.distance }}</text></view>
|
||||
<view class="nav-btn" @click.stop="$emit('navigate', item)"><text>导航</text></view>
|
||||
<view class="tag-row">
|
||||
<view class="status-tag rent" v-if="isRentable(item)"><text>{{ $t('location.rent') }}</text></view>
|
||||
<view class="status-tag return" v-if="isReturnable(item)"><text>{{ $t('location.return') }}</text></view>
|
||||
</view>
|
||||
<view class="position-time" v-if="item.workTime && item.workTime !== '0'"><text>{{ $t('location.businessHours') }}{{ item.workTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="position-actions">
|
||||
<view class="distance-info" v-if="item.distance"><text>{{ item.distance }}</text></view>
|
||||
<view class="nav-btn" @click.stop="$emit('navigate', item)"><text>{{ $t('location.navigate') }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="empty-state" v-if="!isLoading && (!positions || positions.length === 0)">
|
||||
<image class="empty-icon" src="/static/scan-icon.png" mode="aspectFit" />
|
||||
<text class="empty-text">附近暂无设备</text>
|
||||
</view>
|
||||
<view class="empty-state" v-if="!isLoading && (!positions || positions.length === 0)">
|
||||
<image class="empty-icon" src="/static/scan-icon.png" mode="aspectFit" />
|
||||
<text class="empty-text">{{ $t('home.noNearbyDevice') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -39,12 +39,17 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
const instance = getCurrentInstance()
|
||||
const $t = instance?.proxy?.$t || ((key) => key)
|
||||
|
||||
const props = defineProps({
|
||||
show: { type: Boolean, default: false },
|
||||
expanded: { type: Boolean, default: false },
|
||||
positions: { type: Array, default: () => [] },
|
||||
isLoading: { type: Boolean, default: false },
|
||||
title: { type: String, default: '附近设备场地' }
|
||||
title: { type: String, default: '' }
|
||||
})
|
||||
|
||||
const isRentable = (item) => {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<view class="map-loading" v-if="isLoading">
|
||||
<view class="loading-content">
|
||||
<view class="loading-spinner"></view>
|
||||
<text>地图加载中...</text>
|
||||
<text>{{ $t('common.loadingMap') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -58,28 +58,13 @@
|
||||
calculateDistanceSync
|
||||
} from '../utils/mapUtils.js'
|
||||
|
||||
// 获取 i18n 实例
|
||||
const instance = getCurrentInstance()
|
||||
const $t = instance?.proxy?.$t || ((key) => key)
|
||||
|
||||
// 引用折叠面板组件的ref
|
||||
const collapseRef = ref(null)
|
||||
|
||||
// 使用指南步骤
|
||||
const guideSteps = ref([{
|
||||
title: '扫码使用',
|
||||
desc: '找到附近设备,扫描设备上的二维码'
|
||||
},
|
||||
{
|
||||
title: '免押金支付',
|
||||
desc: '无需支付押金,使用支付分免押即可完成租借'
|
||||
},
|
||||
{
|
||||
title: '开始使用',
|
||||
desc: '设备自动解锁,风扇弹出后取出即可开始使用'
|
||||
},
|
||||
{
|
||||
title: '归还设备',
|
||||
desc: '使用完毕后,按照设备规格要求将风扇还入即可结束订单'
|
||||
}
|
||||
])
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
userLocation: {
|
||||
@@ -436,8 +421,9 @@ const handleSearch = () => {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 94vw;
|
||||
height: var(--map-height, 78vh);
|
||||
height: calc(100% - 20rpx); /* 减少高度,避免覆盖底部按钮 */
|
||||
margin: 20rpx;
|
||||
margin-bottom: 0; /* 底部不需要边距 */
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -520,7 +506,7 @@ const handleSearch = () => {
|
||||
.map-side-controls {
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
bottom: 20rpx;
|
||||
bottom: 160rpx; /* 向上移动,避免被底部按钮遮挡 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -11,18 +11,18 @@
|
||||
<view class="payment-badge wx-score" v-if="order.payWay == 'wx_score_pay'">
|
||||
<image src="/static/images/wxpayflag.png" mode="aspectFit" class="badge-icon"></image>
|
||||
<view class="badge-text">
|
||||
<text>微信支付分</text>
|
||||
<text>{{ $t('order.wxPayScore') }}</text>
|
||||
<text class="divider">|</text>
|
||||
<text class="highlight">免押租借</text>
|
||||
<text class="highlight">{{ $t('order.depositFree') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="payment-badge member" v-else-if="order.payWay == 'wx_member_pay'">
|
||||
<text class="badge-text">会员订单</text>
|
||||
<text class="badge-text">{{ $t('order.memberOrder') }}</text>
|
||||
</view>
|
||||
<view class="payment-badge deposit" v-else>
|
||||
<text class="badge-text">微信支付</text>
|
||||
<text class="badge-text">{{ $t('order.wxPay') }}</text>
|
||||
<text class="divider">|</text>
|
||||
<text class="badge-text">押金租借</text>
|
||||
<text class="badge-text">{{ $t('order.depositPay') }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -39,11 +39,11 @@
|
||||
<!-- 订单时间信息 -->
|
||||
<view class="order-times">
|
||||
<view class="time-row">
|
||||
<text class="time-label">租借地点:</text>
|
||||
<text class="time-label">{{ $t('order.rentLocation') }}:</text>
|
||||
<text class="time-value">{{ order.deviceName || order.positionName }}</text>
|
||||
</view>
|
||||
<view class="time-row">
|
||||
<text class="time-label">租借时间:</text>
|
||||
<text class="time-label">{{ $t('order.rentTime') }}:</text>
|
||||
<text class="time-value">{{ order.startTime }}</text>
|
||||
</view>
|
||||
<view class="arrow" @click="onDetails">
|
||||
@@ -59,7 +59,7 @@
|
||||
<!-- 订单底部 -->
|
||||
<view class="order-footer">
|
||||
<view class="footer-left">
|
||||
<view v-if="isInUse" class="renting"><text class="dot"></text>租借中</view>
|
||||
<view v-if="isInUse" class="renting"><text class="dot"></text>{{ $t('order.renting') }}</view>
|
||||
<view v-else-if="isFinished" class="meta">
|
||||
<view class="meta-item"><text class="dot"></text>{{ usedDurationText }}</view>
|
||||
<view class="meta-item"><text class="currency">¥</text>{{ displayAmount }}</view>
|
||||
@@ -68,19 +68,22 @@
|
||||
|
||||
<view class="actions">
|
||||
<!-- 待支付状态显示支付和取消按钮 -->
|
||||
<view v-if="isWaitingForPayment" class="action-item primary" @click="onPay">立即支付</view>
|
||||
<view v-if="isWaitingForPayment" class="action-item secondary" @click="onCancel">取消订单</view>
|
||||
<view v-if="isWaitingForPayment" class="action-item primary" @click="onPay">{{ $t('order.payNow') }}</view>
|
||||
<view v-if="isWaitingForPayment" class="action-item secondary" @click="onCancel">{{ $t('order.cancelOrder') }}</view>
|
||||
<!-- 使用中状态显示归还设备按钮 -->
|
||||
<view v-if="isInUse" class="action-item primary" @click="onReturn">快速归还</view>
|
||||
<view v-if="isInUse" class="action-item primary" @click="onReturn">{{ $t('order.quickReturn') }}</view>
|
||||
<!-- 查看详情按钮对所有订单都显示 -->
|
||||
<!-- <view class="action-item secondary" >查看详情</view> -->
|
||||
<!-- <view class="action-item secondary" >{{ $t('order.viewDetails') }}</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { computed, getCurrentInstance } from 'vue';
|
||||
|
||||
const instance = getCurrentInstance()
|
||||
const $t = instance?.proxy?.$t || ((key) => key)
|
||||
|
||||
const props = defineProps({
|
||||
order: { type: Object, required: true },
|
||||
@@ -125,7 +128,7 @@
|
||||
const isInUse = computed(() => normalizedStatus.value === 'in_used');
|
||||
const isFinished = computed(() => normalizedStatus.value === 'used_done');
|
||||
|
||||
const titleText = computed(() => props.order.deviceName ? '租借风扇' : '租借风扇');
|
||||
const titleText = computed(() => $t('order.rentFan'));
|
||||
|
||||
// 显示金额(优先后端给定字段)
|
||||
const displayAmount = computed(() => props.order.amount || props.order.payAmount || props.order.actualDeviceAmount || props.order.currentFee || '0.00');
|
||||
@@ -139,8 +142,8 @@
|
||||
const minutes = Math.floor(diffMs / 60000);
|
||||
const hours = Math.floor(minutes / 60);
|
||||
const mins = minutes % 60;
|
||||
if (hours > 0) return `${hours}小时${mins}分钟`;
|
||||
return `${mins}分钟`;
|
||||
if (hours > 0) return `${hours}${$t('time.hour')}${mins}${$t('time.minute')}`;
|
||||
return `${mins}${$t('time.minute')}`;
|
||||
});
|
||||
|
||||
function parseDate(str) {
|
||||
|
||||
Reference in New Issue
Block a user