|
|
@@ -0,0 +1,690 @@
|
|
|
+<template>
|
|
|
+ <page-meta root-font-size="system" />
|
|
|
+ <view>
|
|
|
+ <view class="container">
|
|
|
+ <view v-if="currentUser" class="user-info">
|
|
|
+ <view class="user-card">
|
|
|
+ <text class="user-label">当前用户:</text>
|
|
|
+ <text class="user-account">{{ currentUser }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 绑定房间按钮 -->
|
|
|
+ <view v-if="currentUser" class="bind-btn-container">
|
|
|
+ <button class="bind-btn" @click="showBindDialog">
|
|
|
+ <text class="bind-icon">+</text>
|
|
|
+ <text>绑定房间</text>
|
|
|
+ </button>
|
|
|
+ </view>
|
|
|
+ <!-- 用户绑定的房间列表 -->
|
|
|
+ <view v-if="currentUser" class="user-room-list">
|
|
|
+ <view v-if="loading" class="loading">
|
|
|
+ <text>加载中...</text>
|
|
|
+ </view>
|
|
|
+ <view v-else-if="userRoomList.length === 0" class="empty">
|
|
|
+ <text>该用户暂无绑定的房间</text>
|
|
|
+ </view>
|
|
|
+ <view v-else>
|
|
|
+ <view v-for="userRoom in userRoomList" :key="userRoom.id" class="user-room-item">
|
|
|
+ <view class="room-info">
|
|
|
+ <text class="room-name">{{ userRoom.room_name }}</text>
|
|
|
+ <text class="room-url">{{ userRoom.room_url }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="room-actions">
|
|
|
+ <button class="action-btn delete-btn" @click="deleteUserRoomConfirm(userRoom)">解绑</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 绑定房间弹窗 -->
|
|
|
+ <uni-popup ref="bindPopup" type="center" :mask-click="false">
|
|
|
+ <view class="popup-content">
|
|
|
+ <view class="popup-header">
|
|
|
+ <text class="popup-title">绑定房间</text>
|
|
|
+ <text class="close-btn" @click="closeBindDialog">×</text>
|
|
|
+ </view>
|
|
|
+ <view class="popup-body">
|
|
|
+ <view class="form-item">
|
|
|
+ <text class="label">选择房间</text>
|
|
|
+ <picker :value="selectedRoomIndex" :range="selectableRooms" range-key="room_name" @change="onRoomChange">
|
|
|
+ <view class="picker-view">
|
|
|
+ <text v-if="selectedRoomIndex >= 0">{{ selectableRooms[selectedRoomIndex]?.room_name }}</text>
|
|
|
+ <text v-else class="placeholder">请选择房间</text>
|
|
|
+ <text class="picker-arrow">></text>
|
|
|
+ </view>
|
|
|
+ </picker>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="popup-footer">
|
|
|
+ <button class="cancel-btn" @click="closeBindDialog">取消</button>
|
|
|
+ <button class="confirm-btn" @click="submitBind">确定</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </uni-popup>
|
|
|
+
|
|
|
+ <!-- 解绑确认弹窗 -->
|
|
|
+ <uni-popup ref="deletePopup" type="center">
|
|
|
+ <view class="delete-popup">
|
|
|
+ <view class="delete-content">
|
|
|
+ <text class="delete-title">确认解绑</text>
|
|
|
+ <text
|
|
|
+ class="delete-message">确定要解绑用户"{{ currentUserRoom?.user_account }}"与房间"{{ currentUserRoom?.room_name }}"的绑定吗?</text>
|
|
|
+ <view class="delete-actions">
|
|
|
+ <button class="cancel-btn" @click="closeDeleteDialog">取消</button>
|
|
|
+ <button class="delete-confirm-btn" @click="confirmUnbind">解绑</button>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </uni-popup>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+ import { ref, onMounted } from 'vue'
|
|
|
+ import { onLoad } from '@dcloudio/uni-app'
|
|
|
+ import { bindUserRoom, deleteUserRoom, getUserRoomByUser, getRoomList, getUserRoomList } from '@/api/work.js'
|
|
|
+
|
|
|
+ onLoad((options) => {
|
|
|
+ if (options && options.userName) {
|
|
|
+ currentUser.value = String(options.userName).trim()
|
|
|
+ searchUserAccount.value = currentUser.value
|
|
|
+ loading.value = true
|
|
|
+ Promise.resolve()
|
|
|
+ .then(() => loadUserRooms())
|
|
|
+ .then(() => loadAvailableRooms())
|
|
|
+ .finally(() => { loading.value = false })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 响应式数据
|
|
|
+ const searchUserAccount = ref('')
|
|
|
+ const currentUser = ref('')
|
|
|
+ const userRoomList = ref([])
|
|
|
+ const allBindList = ref([])
|
|
|
+ const availableRooms = ref([])
|
|
|
+ const selectableRooms = ref([])
|
|
|
+ const loading = ref(false)
|
|
|
+ const selectedRoomIndex = ref(-1)
|
|
|
+ const currentUserRoom = ref(null)
|
|
|
+
|
|
|
+ // 弹窗引用
|
|
|
+ const bindPopup = ref(null)
|
|
|
+ const deletePopup = ref(null)
|
|
|
+
|
|
|
+ const showBindDialog = () => {
|
|
|
+ selectedRoomIndex.value = -1
|
|
|
+ // 打开前仅基于本地数据计算,避免重复请求
|
|
|
+ computeSelectableRooms()
|
|
|
+ bindPopup.value.open()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 页面加载时获取所有绑定数据
|
|
|
+ onMounted(() => {
|
|
|
+ // 若无路由参数,可在此回退到输入账号搜索
|
|
|
+ })
|
|
|
+
|
|
|
+ // 加载所有用户绑定数据
|
|
|
+ const loadAllBindList = () => {
|
|
|
+ loading.value = true
|
|
|
+ getUserRoomList().then((res) => {
|
|
|
+ console.log('getUserRoomList', res)
|
|
|
+ if (res) {
|
|
|
+ allBindList.value = res
|
|
|
+ } else {
|
|
|
+ allBindList.value = []
|
|
|
+ }
|
|
|
+ loading.value = false
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('获取所有绑定数据失败:', error)
|
|
|
+ allBindList.value = []
|
|
|
+ loading.value = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 搜索用户
|
|
|
+ const searchUser = () => {
|
|
|
+ if (!searchUserAccount.value.trim()) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请输入用户账号',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ loading.value = true
|
|
|
+ currentUser.value = searchUserAccount.value.trim()
|
|
|
+
|
|
|
+ loadUserRooms().then(() => {
|
|
|
+ return loadAvailableRooms()
|
|
|
+ }).then(() => {
|
|
|
+ loading.value = false
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('搜索用户失败:', error)
|
|
|
+ uni.showToast({
|
|
|
+ title: '搜索用户失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ loading.value = false
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载用户绑定的房间
|
|
|
+ const loadUserRooms = () => {
|
|
|
+ return getUserRoomByUser(currentUser.value).then((res) => {
|
|
|
+ console.log('getUserRoomByUser', res)
|
|
|
+ if (res) {
|
|
|
+ userRoomList.value = res
|
|
|
+ } else {
|
|
|
+ userRoomList.value = []
|
|
|
+ }
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('获取用户房间失败:', error)
|
|
|
+ userRoomList.value = []
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 加载可用房间列表
|
|
|
+ const loadAvailableRooms = () => {
|
|
|
+ return getRoomList().then((res) => {
|
|
|
+ console.log('getRoomList', res)
|
|
|
+ if (res) {
|
|
|
+ availableRooms.value = res
|
|
|
+ computeSelectableRooms()
|
|
|
+ }
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('获取房间列表失败:', error)
|
|
|
+ availableRooms.value = []
|
|
|
+ selectableRooms.value = []
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 基于本地数据计算可选房间,避免额外网络请求
|
|
|
+ const computeSelectableRooms = () => {
|
|
|
+ const norm = (v) => (v == null ? '' : String(v).trim())
|
|
|
+ const getRoomUrl = (room) => norm(room?.url ?? room?.room_url)
|
|
|
+ const boundUrlSet = new Set((userRoomList.value || []).map(item => norm(item.room_url ?? item.roomUrl ?? item.url)))
|
|
|
+ const filtered = (availableRooms.value || []).filter((room) => {
|
|
|
+ const urlKey = getRoomUrl(room)
|
|
|
+ return !boundUrlSet.has(urlKey)
|
|
|
+ })
|
|
|
+ const uniqueMap = new Map()
|
|
|
+ for (const room of filtered) {
|
|
|
+ const key = getRoomUrl(room)
|
|
|
+ if (!uniqueMap.has(key)) uniqueMap.set(key, room)
|
|
|
+ }
|
|
|
+ selectableRooms.value = Array.from(uniqueMap.values())
|
|
|
+ }
|
|
|
+
|
|
|
+ // 房间选择变化
|
|
|
+ const onRoomChange = (e) => {
|
|
|
+ selectedRoomIndex.value = e.detail.value
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解绑房间确认
|
|
|
+ const deleteUserRoomConfirm = (userRoom) => {
|
|
|
+ currentUserRoom.value = userRoom
|
|
|
+ deletePopup.value.open()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭绑定弹窗
|
|
|
+ const closeBindDialog = () => {
|
|
|
+ bindPopup.value.close()
|
|
|
+ selectedRoomIndex.value = -1
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关闭删除确认弹窗
|
|
|
+ const closeDeleteDialog = () => {
|
|
|
+ deletePopup.value.close()
|
|
|
+ currentUserRoom.value = null
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提交绑定
|
|
|
+ const submitBind = () => {
|
|
|
+ if (selectedRoomIndex.value < 0) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '请选择房间',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const selectedRoom = selectableRooms.value[selectedRoomIndex.value]
|
|
|
+
|
|
|
+ // 再次校验是否已绑定(防止数据滞后/并发重复)仅根据 URL 判断
|
|
|
+ const norm = (v) => (v == null ? '' : String(v).trim())
|
|
|
+ const getRoomUrl = (room) => norm(room?.url ?? room?.room_url)
|
|
|
+ const alreadyBoundUrls = new Set(userRoomList.value.map(item => norm(item.room_url ?? item.roomUrl ?? item.url)))
|
|
|
+ if (alreadyBoundUrls.has(getRoomUrl(selectedRoom))) {
|
|
|
+ uni.showToast({
|
|
|
+ title: '该房间已绑定',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ bindUserRoom(currentUser.value, selectedRoom.id + "").then((res) => {
|
|
|
+ console.log('bindUserRoom', res)
|
|
|
+ uni.showToast({
|
|
|
+ title: '绑定成功',
|
|
|
+ icon: 'success'
|
|
|
+ })
|
|
|
+ closeBindDialog()
|
|
|
+ return loadUserRooms()
|
|
|
+ }).then(() => {
|
|
|
+ return loadAvailableRooms()
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('绑定失败:', error)
|
|
|
+ uni.showToast({
|
|
|
+ title: '绑定失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确认解绑
|
|
|
+ const confirmUnbind = () => {
|
|
|
+ deleteUserRoom(currentUserRoom.value.id).then((res) => {
|
|
|
+ console.log('deleteUserRoom', res)
|
|
|
+ uni.showToast({
|
|
|
+ title: '解绑成功',
|
|
|
+ icon: 'success'
|
|
|
+ })
|
|
|
+ closeDeleteDialog()
|
|
|
+ // 如果当前有搜索用户,也重新加载用户房间数据
|
|
|
+ loadUserRooms().then(() => {
|
|
|
+ return loadAvailableRooms()
|
|
|
+ })
|
|
|
+ }).catch((error) => {
|
|
|
+ console.error('解绑失败:', error)
|
|
|
+ uni.showToast({
|
|
|
+ title: '解绑失败',
|
|
|
+ icon: 'none'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 格式化时间
|
|
|
+ const formatTime = (timeStr) => {
|
|
|
+ if (!timeStr) return ''
|
|
|
+ const date = new Date(timeStr)
|
|
|
+ return date.toLocaleString('zh-CN')
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ .container {
|
|
|
+ padding: 20rpx;
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ min-height: 100vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header {
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-size: 36rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-bind-container {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .add-bind-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 28rpx;
|
|
|
+
|
|
|
+ .add-icon {
|
|
|
+ margin-right: 10rpx;
|
|
|
+ font-size: 32rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-container {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .search-box {
|
|
|
+ display: flex;
|
|
|
+ background: white;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ padding: 10rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
+
|
|
|
+ .search-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 60rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border: none;
|
|
|
+ outline: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .search-btn {
|
|
|
+ width: 120rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ border-radius: 30rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-info {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .user-card {
|
|
|
+ background: white;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
+
|
|
|
+ .user-label {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-account {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bind-btn-container {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .bind-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 28rpx;
|
|
|
+
|
|
|
+ .bind-icon {
|
|
|
+ margin-right: 10rpx;
|
|
|
+ font-size: 32rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .all-bind-list {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .loading,
|
|
|
+ .empty {
|
|
|
+ text-align: center;
|
|
|
+ padding: 100rpx 0;
|
|
|
+ color: #999;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bind-item {
|
|
|
+ background: white;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .bind-info {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .user-account {
|
|
|
+ display: block;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .room-id {
|
|
|
+ display: block;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .bind-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ .action-btn {
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ border: none;
|
|
|
+
|
|
|
+ &.delete-btn {
|
|
|
+ background-color: #ff3b30;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-room-list {
|
|
|
+
|
|
|
+ .loading,
|
|
|
+ .empty {
|
|
|
+ text-align: center;
|
|
|
+ padding: 100rpx 0;
|
|
|
+ color: #999;
|
|
|
+ font-size: 28rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-room-item {
|
|
|
+ background: white;
|
|
|
+ border-radius: 16rpx;
|
|
|
+ padding: 30rpx;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .room-info {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .room-name {
|
|
|
+ display: block;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .room-url {
|
|
|
+ display: block;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #666;
|
|
|
+ word-break: break-all;
|
|
|
+ margin-bottom: 10rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .bind-time {
|
|
|
+ display: block;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .room-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ .action-btn {
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ border: none;
|
|
|
+
|
|
|
+ &.delete-btn {
|
|
|
+ background-color: #ff3b30;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup-content {
|
|
|
+ width: 600rpx;
|
|
|
+ background: white;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .popup-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 30rpx;
|
|
|
+ border-bottom: 1rpx solid #eee;
|
|
|
+
|
|
|
+ .popup-title {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+
|
|
|
+ .close-btn {
|
|
|
+ font-size: 40rpx;
|
|
|
+ color: #999;
|
|
|
+ width: 60rpx;
|
|
|
+ height: 60rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup-body {
|
|
|
+ padding: 30rpx;
|
|
|
+
|
|
|
+ .form-item {
|
|
|
+ margin-bottom: 30rpx;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ display: block;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 15rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-view {
|
|
|
+ width: 100%;
|
|
|
+ height: 80rpx;
|
|
|
+ border: 1rpx solid #ddd;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ padding: 0 20rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .placeholder {
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-arrow {
|
|
|
+ color: #999;
|
|
|
+ font-size: 24rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .popup-footer {
|
|
|
+ display: flex;
|
|
|
+ border-top: 1rpx solid #eee;
|
|
|
+
|
|
|
+ button {
|
|
|
+ flex: 1;
|
|
|
+ height: 100rpx;
|
|
|
+ border: none;
|
|
|
+ font-size: 28rpx;
|
|
|
+
|
|
|
+ &.cancel-btn {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.confirm-btn {
|
|
|
+ background-color: #007aff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-popup {
|
|
|
+ .delete-content {
|
|
|
+ width: 500rpx;
|
|
|
+ background: white;
|
|
|
+ border-radius: 20rpx;
|
|
|
+ padding: 40rpx;
|
|
|
+ text-align: center;
|
|
|
+
|
|
|
+ .delete-title {
|
|
|
+ display: block;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-message {
|
|
|
+ display: block;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #666;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+ line-height: 1.5;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 20rpx;
|
|
|
+
|
|
|
+ button {
|
|
|
+ flex: 1;
|
|
|
+ height: 80rpx;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
+ border: none;
|
|
|
+
|
|
|
+ &.cancel-btn {
|
|
|
+ background-color: #f5f5f5;
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.delete-confirm-btn {
|
|
|
+ background-color: #ff3b30;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|