From 63960ac1d04a9e2a15442cfb8524d0ed125b1b8d Mon Sep 17 00:00:00 2001 From: "3321822538@qq.com" <3321822538@qq.com> Date: Tue, 2 Jun 2026 10:34:22 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E9=B9=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- page_shanghu/guanli/area_ability_add.vue | 63 ++- page_shanghu/guanli/device_detail.vue | 512 +++++++++++++++++++++-- 2 files changed, 533 insertions(+), 42 deletions(-) diff --git a/page_shanghu/guanli/area_ability_add.vue b/page_shanghu/guanli/area_ability_add.vue index 7d54062..c5c465c 100644 --- a/page_shanghu/guanli/area_ability_add.vue +++ b/page_shanghu/guanli/area_ability_add.vue @@ -42,6 +42,7 @@ + + + 确定添加 + @@ -130,12 +140,29 @@ if (this.submitting) return this.showPicker = false }, + isAbilitySelected(item) { + return this.selectedAbility && item && this.selectedAbility.id === item.id + }, onSelectAbility(item) { if (this.submitting || !item || item.id == null) return this.selectedAbility = item - this.submitAbility(item) + this.showPicker = false }, - submitAbility(item) { + confirmAdd() { + if (this.submitting) return + if (!this.areaId) { + uni.showToast({ title: '缺少运营区信息', icon: 'none' }) + return + } + if (!this.selectedAbility || this.selectedAbility.id == null) { + uni.showToast({ title: '请先选择拓展能力', icon: 'none' }) + return + } + this.submitAbility() + }, + submitAbility() { + const item = this.selectedAbility + if (!item || item.id == null) return this.submitting = true uni.showLoading({ title: '提交中...', mask: true }) this.$u @@ -145,7 +172,6 @@ }) .then((res) => { if (res.code == 200) { - this.showPicker = false uni.showToast({ title: '新增成功', icon: 'success' }) const pages = getCurrentPages() const prev = pages[pages.length - 2] @@ -154,12 +180,10 @@ } setTimeout(() => uni.navigateBack(), 500) } else { - this.selectedAbility = null uni.showToast({ title: res.msg || '新增失败', icon: 'none' }) } }) .catch(() => { - this.selectedAbility = null uni.showToast({ title: '新增失败', icon: 'none' }) }) .finally(() => { @@ -177,10 +201,36 @@ } .page { min-height: 100vh; + padding-bottom: calc(140rpx + env(safe-area-inset-bottom)); + box-sizing: border-box; } .form-container { padding: 24rpx; } + .page-footer { + position: fixed; + left: 0; + right: 0; + bottom: 0; + padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom)); + background: #fff; + box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.06); + z-index: 10; + } + .footer-btn { + height: 88rpx; + line-height: 88rpx; + text-align: center; + font-size: 32rpx; + font-weight: 600; + color: #fff; + background: #4297F3; + border-radius: 44rpx; + } + .footer-btn--disabled { + background: #cbd5e1; + color: #f8fafc; + } .area-tip { background: #fff; border-radius: 16rpx; @@ -348,6 +398,9 @@ padding: 28rpx 32rpx; border-bottom: 1rpx solid #f3f4f6; } + .ability-row--active { + background: #eff6ff; + } .ability-row-icon { width: 80rpx; height: 80rpx; diff --git a/page_shanghu/guanli/device_detail.vue b/page_shanghu/guanli/device_detail.vue index 226f6ae..b20c2c6 100644 --- a/page_shanghu/guanli/device_detail.vue +++ b/page_shanghu/guanli/device_detail.vue @@ -42,10 +42,10 @@ - + - + @@ -354,30 +354,59 @@ - - 蓝牙自检中 - {{ btStepMessage }} - - - - - 进度 - {{ btProgress }}% - - {{ btErrorMessage }} - - - 去设置 + + + + + + + + + + + + + - - 去授权 + + + + - - 我知道了 + + {{ btErrorMessage ? '连接异常' : '蓝牙连接' }} + + + {{ btStepMessage }} + + + + + 连接进度 + + {{ btProgress }} + % + + + + + + + + + + ! + {{ btErrorMessage }} + + + 去设置 + 去授权 + 我知道了 + + + + 蓝牙操作中请靠近车辆 - - - 蓝牙操作中请靠近车辆 @@ -741,7 +770,7 @@ }, async connectMatchedDeviceWithRetry(matchedDevice, maxRetry = 3) { for (let attempt = 1; attempt <= maxRetry; attempt++) { - this.btStepMessage = '已搜索到设备,正在建立蓝牙连接...(第' + attempt + '/' + maxRetry + '次)' + this.btStepMessage = '已搜索到设备,正在连接...(第' + attempt + '/' + maxRetry + '次)' this.ver_dataflag = 2 try { // 先清理上一轮连接状态,降低串线概率 @@ -2879,25 +2908,15 @@ height: 36rpx; margin-right: 8rpx; } - .glow-image { - width: 36rpx; - height: 36rpx; - margin-right: 8rpx; - transition: all 1s ease-in-out; - filter: drop-shadow(0 0 5px rgba(255, 0, 0, 0.7)); - /* 青色外发光 */ - } .visible { opacity: 1; transform: scale(1); - filter: drop-shadow(0 0 5px rgba(255, 50, 50, 1)); - /* 增强发光 */ + filter: drop-shadow(0 0 5px rgba(76, 151, 231, 0.9)); } .hidden { - opacity: 0.3; + opacity: 0.35; transform: scale(0.95); - filter: drop-shadow(0 0 5px rgba(255, 0, 0, 0.3)); - /* 减弱发光 */ + filter: drop-shadow(0 0 4rpx rgba(76, 151, 231, 0.35)); } } .bikexx { @@ -3159,6 +3178,425 @@ } } + /* ========== 蓝牙连接弹窗(品牌色 #2E4975 / #4C97E7) ========== */ + @keyframes bt-orbit-spin { + from { transform: translate(-50%, -50%) rotate(0deg); } + to { transform: translate(-50%, -50%) rotate(360deg); } + } + + @keyframes bt-orbit-spin-rev { + from { transform: translate(-50%, -50%) rotate(360deg); } + to { transform: translate(-50%, -50%) rotate(0deg); } + } + + @keyframes bt-sweep-spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + @keyframes bt-core-breathe { + 0%, 100% { + box-shadow: + 0 0 0 1rpx rgba(255, 255, 255, 0.8), + 0 10rpx 32rpx rgba(46, 73, 117, 0.14); + } + 50% { + box-shadow: + 0 0 0 1rpx rgba(255, 255, 255, 1), + 0 14rpx 40rpx rgba(76, 151, 231, 0.22); + } + } + + @keyframes bt-progress-shine-move { + 0% { left: -55%; } + 100% { left: 130%; } + } + + @keyframes bt-status-dot-blink { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.5; transform: scale(0.9); } + } + + @keyframes bt-panel-enter { + 0% { + opacity: 0; + transform: translate(-50%, -48%) scale(0.97); + } + 100% { + opacity: 1; + transform: translate(-50%, -50%) scale(1); + } + } + + .bt-process-panel { + position: fixed; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + z-index: 102; + width: 608rpx; + box-sizing: border-box; + overflow: hidden; + border-radius: 30rpx; + background: #ffffff; + border: 1rpx solid #e8ecf1; + box-shadow: + 0 0 0 1rpx rgba(255, 255, 255, 0.6) inset, + 0 20rpx 50rpx rgba(46, 73, 117, 0.1), + 0 8rpx 24rpx rgba(46, 73, 117, 0.06); + animation: bt-panel-enter 0.38s cubic-bezier(0.22, 1, 0.36, 1) forwards; + } + + .bt-process-panel__accent { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 6rpx; + background: linear-gradient(90deg, #2679d1 0%, #4c97e7 50%, #7eb8ff 100%); + pointer-events: none; + z-index: 4; + } + + .bt-process-panel__glow { + position: absolute; + left: 50%; + top: 80rpx; + width: 320rpx; + height: 200rpx; + margin-left: -160rpx; + background: radial-gradient(ellipse at 50% 50%, rgba(76, 151, 231, 0.09) 0%, transparent 72%); + pointer-events: none; + } + + .bt-process-panel__inner { + position: relative; + z-index: 2; + padding: 56rpx 48rpx 48rpx; + } + + .bt-process-panel__visual { + display: flex; + justify-content: center; + margin-bottom: 44rpx; + } + + .bt-process-panel__visual--err { + margin-bottom: 36rpx; + } + + .bt-process-panel__orbit { + position: relative; + width: 216rpx; + height: 216rpx; + + &::after { + content: ''; + position: absolute; + left: 50%; + top: 50%; + width: 216rpx; + height: 216rpx; + margin: -108rpx 0 0 -108rpx; + border-radius: 50%; + border: 1rpx solid rgba(46, 73, 117, 0.06); + box-sizing: border-box; + } + } + + .bt-process-panel__ring { + position: absolute; + left: 50%; + top: 50%; + border-radius: 50%; + border: 2rpx solid transparent; + transform: translate(-50%, -50%); + } + + .bt-process-panel__ring--a { + width: 208rpx; + height: 208rpx; + border-top-color: rgba(76, 151, 231, 0.45); + border-right-color: rgba(76, 151, 231, 0.08); + animation: bt-orbit-spin 4.8s linear infinite; + } + + .bt-process-panel__ring--b { + width: 172rpx; + height: 172rpx; + border-top-color: rgba(38, 121, 209, 0.28); + border-left-color: rgba(38, 121, 209, 0.06); + animation: bt-orbit-spin-rev 3.8s linear infinite; + } + + .bt-process-panel__sweep { + position: absolute; + left: 50%; + top: 50%; + width: 208rpx; + height: 208rpx; + margin: -104rpx 0 0 -104rpx; + border-radius: 50%; + background: conic-gradient(from 0deg, transparent 0deg, transparent 284deg, rgba(76, 151, 231, 0.05) 300deg, rgba(76, 151, 231, 0.18) 360deg); + animation: bt-sweep-spin 4.2s linear infinite; + } + + .bt-process-panel__core { + position: absolute; + left: 50%; + top: 50%; + z-index: 3; + width: 108rpx; + height: 108rpx; + margin: -54rpx 0 0 -54rpx; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(160deg, #ffffff 15%, #e8f2fc 50%, #4c97e7 100%); + animation: bt-core-breathe 3.2s ease-in-out infinite; + } + + .bt-process-panel__core--err { + position: relative; + left: auto; + top: auto; + margin: 0 auto; + background: linear-gradient(160deg, #ffffff 15%, #fceeee 55%, #e57373 100%); + animation: none; + box-shadow: 0 10rpx 32rpx rgba(180, 90, 90, 0.14); + } + + .bt-process-panel__icon { + width: 48rpx; + height: 48rpx; + } + + .bt-process-panel--error { + .bt-process-panel__accent { + background: linear-gradient(90deg, #c75c5c 0%, #e57373 50%, #f0a8a8 100%); + } + + .bt-process-panel__glow { + background: radial-gradient(ellipse at 50% 50%, rgba(200, 100, 100, 0.08) 0%, transparent 72%); + } + + .bt-process-panel__title { + color: #c75c5c; + } + + .bt-process-panel__status-pill { + background: #fdf9f9; + border-color: #f5e0e0; + } + + .bt-process-panel__status-dot { + background: #e57373; + } + + .bt-process-panel__message { + color: #9a7070; + } + + .bt-process-panel__progress-num { + color: #c75c5c; + } + } + + .bt-process-panel__head { + text-align: center; + margin-bottom: 0; + } + + .bt-process-panel__title { + display: block; + font-size: 34rpx; + font-weight: 600; + color: #2e4975; + line-height: 1.35; + letter-spacing: 1rpx; + } + + .bt-process-panel__status-pill { + display: inline-flex; + align-items: center; + justify-content: center; + max-width: 100%; + margin-top: 20rpx; + padding: 14rpx 28rpx; + background: #f7fafe; + border: 1rpx solid #e3ebf5; + border-radius: 999rpx; + box-sizing: border-box; + } + + .bt-process-panel__status-dot { + width: 10rpx; + height: 10rpx; + border-radius: 50%; + margin-right: 12rpx; + flex-shrink: 0; + background: #4c97e7; + animation: bt-status-dot-blink 2s ease-in-out infinite; + } + + .bt-process-panel__message { + font-size: 26rpx; + font-weight: 400; + color: #7c7c7c; + line-height: 1.55; + } + + .bt-process-panel__progress-card { + margin-top: 36rpx; + padding: 32rpx 30rpx 30rpx; + background: linear-gradient(180deg, #f7fafe 0%, #f3f6fa 100%); + border: 1rpx solid #e3ebf5; + border-radius: 20rpx; + } + + .bt-process-panel__progress-top { + display: flex; + align-items: flex-end; + justify-content: space-between; + margin-bottom: 24rpx; + } + + .bt-process-panel__progress-label { + font-size: 24rpx; + font-weight: 500; + color: #808080; + padding-bottom: 6rpx; + } + + .bt-process-panel__progress-num-wrap { + display: flex; + align-items: baseline; + } + + .bt-process-panel__progress-num { + font-size: 44rpx; + font-weight: 600; + color: #2e4975; + font-variant-numeric: tabular-nums; + line-height: 1; + } + + .bt-process-panel__progress-unit { + margin-left: 6rpx; + font-size: 26rpx; + font-weight: 500; + color: #4c97e7; + } + + .bt-process-panel__progress-track { + position: relative; + height: 10rpx; + background: #dce4ee; + border-radius: 999rpx; + overflow: hidden; + box-shadow: inset 0 1rpx 3rpx rgba(46, 73, 117, 0.08); + } + + .bt-process-panel__progress-bar { + position: relative; + height: 100%; + min-width: 0; + border-radius: 999rpx; + background: linear-gradient(90deg, #7eb8ff 0%, #4c97e7 100%); + transition: width 0.42s cubic-bezier(0.22, 1, 0.36, 1); + overflow: hidden; + } + + .bt-process-panel__progress-shine { + position: absolute; + top: 0; + bottom: 0; + width: 36%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent); + animation: bt-progress-shine-move 2.6s ease-in-out infinite; + pointer-events: none; + } + + .bt-process-panel__alert { + display: flex; + align-items: flex-start; + margin-top: 32rpx; + padding: 24rpx 22rpx; + background: #fdf9f9; + border: 1rpx solid #f5e0e0; + border-radius: 16rpx; + } + + .bt-process-panel__alert-icon { + flex-shrink: 0; + width: 38rpx; + height: 38rpx; + margin-right: 14rpx; + border-radius: 50%; + background: #e57373; + color: #fff; + font-size: 24rpx; + font-weight: 600; + line-height: 38rpx; + text-align: center; + } + + .bt-process-panel__alert-text { + flex: 1; + font-size: 26rpx; + color: #9a5a5a; + line-height: 1.6; + } + + .bt-process-panel__actions { + display: flex; + justify-content: center; + flex-wrap: wrap; + gap: 20rpx; + margin-top: 32rpx; + } + + .bt-process-panel__btn { + min-width: 200rpx; + height: 76rpx; + line-height: 76rpx; + padding: 0 40rpx; + text-align: center; + border-radius: 8rpx; + font-size: 28rpx; + font-weight: 500; + color: #fff; + box-sizing: border-box; + } + + .bt-process-panel__btn--accent { + background: #5a9a6b; + box-shadow: 0 6rpx 18rpx rgba(90, 154, 107, 0.22); + } + + .bt-process-panel__btn--main { + background: #4c97e7; + box-shadow: 0 8rpx 22rpx rgba(76, 151, 231, 0.28); + } + + .bt-process-panel__hint { + display: flex; + align-items: center; + justify-content: center; + margin-top: 24rpx; + padding: 0; + font-size: 22rpx; + color: #ababab; + line-height: 1.5; + } + + .bt-process-panel__hint-icon { + margin-right: 8rpx; + font-size: 24rpx; + color: #b0b0b0; + } + /* 添加声音选择组件样式 */ .sound-select { position: fixed;