chore: initial import
This commit is contained in:
190
components/contract-alert/contract-alert.vue
Normal file
190
components/contract-alert/contract-alert.vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<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.t('pendingTitle'),
|
||||
desc: this.t('pendingDesc', { count: this.pendingContracts.length }),
|
||||
actionText: this.t('actionText')
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeAlert: {
|
||||
immediate: true,
|
||||
handler(value) {
|
||||
if (!value) {
|
||||
this.clearCollapseTimer()
|
||||
return
|
||||
}
|
||||
this.isExpanded = true
|
||||
this.startCollapseTimer()
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.clearCollapseTimer()
|
||||
},
|
||||
methods: {
|
||||
t(key, params) {
|
||||
return this.$translate(this.i18n, key, params)
|
||||
},
|
||||
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>
|
||||
Reference in New Issue
Block a user