chuangte_bike_newxcx/page_shanghu/guanli/device_nfc.vue
2026-03-12 13:54:49 +08:00

316 lines
7.8 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<u-navbar title="NFC卡管理" :border-bottom="false" :background="bgc" title-color="#2E4975" title-size="36" height="45"></u-navbar>
<view class="content">
<view v-if="list.length === 0 && !loading" class="empty">
<image src="https://api.ccttiot.com/smartmeter/img/static/uuuFxDo4XNzXJDTOQIeZ" mode="aspectFit" class="empty-img"></image>
<text class="empty-text">暂无NFC卡</text>
</view>
<view v-for="(item) in list" :key="item.id" class="nfc-item">
<view class="nfc-info">
<view class="nfc-row">
<text class="label">NFC编号</text>
<text class="value">{{ item.nfcNo }}</text>
</view>
<view class="nfc-row">
<text class="label">卡片类型:</text>
<text class="tag" :class="item.type === '1' ? 'tag-primary' : 'tag-secondary'">
{{ item.type === '1' ? '主卡' : '副卡' }}
</text>
</view>
<view class="nfc-row" v-if="item.remark">
<text class="label">备注:</text>
<text class="value remark">{{ item.remark }}</text>
</view>
<view class="nfc-row">
<text class="label">绑定时间:</text>
<text class="value">{{ item.createTime || '--' }}</text>
</view>
</view>
<view class="nfc-actions">
<view class="action-icon-btn del" @click="confirmDelete(item)">
<image src="https://api.ccttiot.com/smartmeter/img/static/u1PlutiYn3alAcF2VuTH" mode="aspectFit" class="btn-icon"></image>
<text>删除</text>
</view>
</view>
</view>
<view v-if="list.length > 0" class="load-more">
<text v-if="loading">加载中...</text>
<text v-else-if="noMore">没有更多了</text>
</view>
</view>
<!-- 添加按钮 -->
<view class="add-btn" @click="showAddDialog = true">
<image src="https://api.ccttiot.com/smartmeter/img/static/uQdKTkDuXlwaZT5WFL2l" mode="aspectFit" class="add-icon"></image>
添加NFC
</view>
<!-- 添加NFC弹窗组件 -->
<nfc-add-dialog
:show="showAddDialog"
:device-id="deviceId"
@close="showAddDialog = false"
@success="onAddSuccess"
/>
</view>
</template>
<script>
import NfcAddDialog from './components/NfcAddDialog.vue'
export default {
components: { NfcAddDialog },
data() {
return {
bgc: { backgroundColor: '#F7FAFE' },
deviceId: '',
list: [],
pageNum: 1,
pageSize: 15,
total: 0,
loading: false,
noMore: false,
showAddDialog: false
}
},
onLoad(options) {
this.deviceId = options.deviceId
this.loadList()
},
onPullDownRefresh() {
this.pageNum = 1
this.noMore = false
this.loadList(true)
},
onReachBottom() {
if (!this.noMore && !this.loading) {
this.loadList()
}
},
methods: {
loadList(isPullDown = false) {
if (this.loading || (!isPullDown && this.noMore)) return
this.loading = true
this.$u.get('/bst/deviceNfc/list', {
deviceId: this.deviceId,
pageNum: this.pageNum,
pageSize: this.pageSize
}).then(res => {
if (res.code === 200) {
const rows = res.rows || []
if (this.pageNum === 1) {
this.list = rows
} else {
this.list = this.list.concat(rows)
}
this.total = res.total || 0
this.noMore = this.list.length >= this.total
this.pageNum++
} else {
uni.showToast({ title: res.msg, icon: 'none' })
}
}).finally(() => {
this.loading = false
uni.stopPullDownRefresh()
})
},
onRefresh() {
this.pageNum = 1
this.noMore = false
this.loadList(true)
},
onAddSuccess() {
this.onRefresh()
},
confirmDelete(item) {
uni.showModal({
title: '提示',
content: `确定删除NFC卡【${item.nfcNo}】吗?`,
success: (res) => {
if (res.confirm) {
this.deleteNfc(item)
}
}
})
},
deleteNfc(item) {
uni.showLoading({ title: '删除中...', mask: true })
this.$u.delete('/bst/deviceNfc?id=' + item.id).then(res => {
uni.hideLoading()
if (res.code === 200) {
uni.showToast({ title: '删除成功', icon: 'success' })
this.onRefresh()
} else {
uni.showToast({ title: res.msg, icon: 'none' })
}
}).catch(() => {
uni.hideLoading()
uni.showToast({ title: '操作失败', icon: 'none' })
})
}
}
}
</script>
<style lang="scss">
page {
background-color: #F6F8FA;
}
.page {
min-height: 100vh;
.content {
padding: 20rpx 30rpx 160rpx;
box-sizing: border-box;
}
.empty {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding-top: 200rpx;
.empty-img {
width: 160rpx;
height: 160rpx;
opacity: 0.3;
margin-bottom: 30rpx;
}
.empty-text {
font-size: 28rpx;
color: #AAAAAA;
}
}
.nfc-item {
display: flex;
align-items: center;
justify-content: space-between;
background: #FFFFFF;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
box-sizing: border-box;
.nfc-info {
flex: 1;
.nfc-row {
display: flex;
align-items: center;
margin-bottom: 12rpx;
&:last-child {
margin-bottom: 0;
}
}
.label {
font-size: 24rpx;
color: #808080;
width: 160rpx;
flex-shrink: 0;
}
.value {
font-size: 26rpx;
color: #3D3D3D;
font-weight: 500;
&.remark {
color: #808080;
font-weight: 400;
max-width: 340rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.tag {
font-size: 22rpx;
padding: 4rpx 18rpx;
border-radius: 20rpx;
font-weight: 500;
}
.tag-primary {
background: #EBF3FF;
color: #4C97E7;
}
.tag-secondary {
background: #F0F0F0;
color: #666666;
}
}
.nfc-actions {
flex-shrink: 0;
margin-left: 16rpx;
.action-icon-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 88rpx;
height: 70rpx;
border-radius: 10rpx;
.btn-icon {
width: 36rpx;
height: 36rpx;
margin-bottom: 4rpx;
}
&.del {
background: #FFF2F2;
color: #FF4D4F;
font-size: 20rpx;
}
}
}
}
.load-more {
text-align: center;
padding: 30rpx 0;
font-size: 24rpx;
color: #AAAAAA;
}
.add-btn {
position: fixed;
bottom: 50rpx;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
justify-content: center;
width: 280rpx;
height: 80rpx;
background: #4C97E7;
border-radius: 40rpx;
font-size: 30rpx;
color: #FFFFFF;
font-weight: 500;
box-shadow: 0 8rpx 24rpx rgba(76, 151, 231, 0.4);
.add-icon {
width: 32rpx;
height: 32rpx;
margin-right: 12rpx;
}
}
}
</style>