将组件级 i18n 对象重构为统一由全局 locales/messages.js 管理,确保中英文语言切换时正确显示对应文本。 - 新增 utils/i18n.js 国际化工具函数 - 更新 store/$t.mixin.js 翻译混入逻辑 - 迁移 pkgService、pkgBooking、pkgAccount、pkgExplore、pages 等共 58 个组件的中英文文本至全局消息表
188 lines
4.2 KiB
Vue
188 lines
4.2 KiB
Vue
<template>
|
|
<view v-if="activeAlert" class="contract-alert-float">
|
|
<view class="alert-panel" :class="{ 'is-collapsed': !isExpanded }" @click="handleBoxClick">
|
|
<view class="alert-icon-wrap">
|
|
<text class="tn-icon-edit-write-fill"></text>
|
|
</view>
|
|
<view class="alert-main">
|
|
<view class="alert-text">
|
|
<view class="alert-title">{{ activeAlert.title }}</view>
|
|
<view class="alert-desc">{{ activeAlert.desc }}</view>
|
|
</view>
|
|
<view class="alert-action" @click.stop="handlePrimaryAction">{{ activeAlert.actionText }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'ContractAlert',
|
|
props: {
|
|
pendingContracts: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
isExpanded: true,
|
|
collapseTimer: null
|
|
}
|
|
},
|
|
computed: {
|
|
activeAlert() {
|
|
if (!Array.isArray(this.pendingContracts) || !this.pendingContracts.length) {
|
|
return null
|
|
}
|
|
return {
|
|
title: this.$tr('待签合同提醒'),
|
|
desc: this.$tr('您有 {count} 份合同待签署', { count: this.pendingContracts.length }),
|
|
actionText: this.$tr('去签署')
|
|
}
|
|
}
|
|
},
|
|
watch: {
|
|
activeAlert: {
|
|
immediate: true,
|
|
handler(value) {
|
|
if (!value) {
|
|
this.clearCollapseTimer()
|
|
return
|
|
}
|
|
this.isExpanded = true
|
|
this.startCollapseTimer()
|
|
}
|
|
}
|
|
},
|
|
beforeDestroy() {
|
|
this.clearCollapseTimer()
|
|
},
|
|
methods: {
|
|
clearCollapseTimer() {
|
|
if (this.collapseTimer) {
|
|
clearTimeout(this.collapseTimer)
|
|
this.collapseTimer = null
|
|
}
|
|
},
|
|
startCollapseTimer() {
|
|
this.clearCollapseTimer()
|
|
this.collapseTimer = setTimeout(() => {
|
|
this.isExpanded = false
|
|
}, 3000)
|
|
},
|
|
handleBoxClick() {
|
|
if (!this.activeAlert) {
|
|
return
|
|
}
|
|
if (!this.isExpanded) {
|
|
this.isExpanded = true
|
|
this.startCollapseTimer()
|
|
return
|
|
}
|
|
this.handlePrimaryAction()
|
|
},
|
|
handlePrimaryAction() {
|
|
const contract = this.pendingContracts[0]
|
|
if (!contract) {
|
|
return
|
|
}
|
|
uni.navigateTo({
|
|
url: `/pkgService/contract_sign/contract_sign?no=${encodeURIComponent(contract.no || contract.contractNo || '')}&orderNo=${encodeURIComponent(contract.orderNo || '')}`
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.contract-alert-float {
|
|
position: fixed;
|
|
right: 0;
|
|
bottom: calc(180rpx + env(safe-area-inset-bottom));
|
|
z-index: 999;
|
|
}
|
|
|
|
.alert-panel {
|
|
display: flex;
|
|
align-items: center;
|
|
max-width: 530rpx;
|
|
padding: 16rpx 18rpx;
|
|
border-radius: 28rpx 0 0 28rpx;
|
|
background: rgba(255, 255, 255, 0.98);
|
|
border: 1px solid rgba($brand-primary, 0.12);
|
|
border-right: none;
|
|
box-shadow: 0 16rpx 36rpx rgba($brand-primary, 0.12);
|
|
backdrop-filter: blur(16px);
|
|
transition: all 0.35s ease;
|
|
}
|
|
|
|
.alert-panel.is-collapsed {
|
|
transform: translateX(calc(100% - 106rpx));
|
|
padding-right: 0;
|
|
}
|
|
|
|
.alert-panel.is-collapsed .alert-main {
|
|
width: 0;
|
|
margin-left: 0;
|
|
opacity: 0;
|
|
}
|
|
|
|
.alert-icon-wrap {
|
|
width: 68rpx;
|
|
height: 68rpx;
|
|
border-radius: 20rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 16rpx;
|
|
flex-shrink: 0;
|
|
color: #ffffff;
|
|
background: linear-gradient(135deg, rgba($brand-primary, 0.9) 0%, $brand-primary 100%);
|
|
box-shadow: 0 6rpx 16rpx rgba($brand-primary, 0.2);
|
|
}
|
|
|
|
.alert-main {
|
|
display: flex;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
opacity: 1;
|
|
transition: all 0.35s ease;
|
|
}
|
|
|
|
.alert-text {
|
|
margin-right: 18rpx;
|
|
max-width: 260rpx;
|
|
}
|
|
|
|
.alert-title {
|
|
font-size: 26rpx;
|
|
font-weight: 700;
|
|
color: #1f2d3d;
|
|
}
|
|
|
|
.alert-desc {
|
|
margin-top: 6rpx;
|
|
font-size: 22rpx;
|
|
color: #7c8da0;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.alert-action {
|
|
padding: 10rpx 28rpx;
|
|
border-radius: 30rpx;
|
|
font-size: 24rpx;
|
|
font-weight: 700;
|
|
color: #ffffff;
|
|
background: linear-gradient(135deg, rgba($brand-primary, 0.9) 0%, $brand-primary 100%);
|
|
box-shadow: 0 6rpx 16rpx rgba($brand-primary, 0.2);
|
|
white-space: nowrap;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.alert-action:active {
|
|
transform: scale(0.96);
|
|
box-shadow: 0 4rpx 10rpx rgba($brand-primary, 0.15);
|
|
}
|
|
</style>
|