2026-05-20 11:09:08 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view class="todo-container">
|
|
|
|
|
|
<!-- 自定义导航栏 -->
|
|
|
|
|
|
<view class="custom-nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
|
|
|
|
|
|
<view class="nav-content">
|
|
|
|
|
|
<text class="nav-title">待办事项</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tab切换 -->
|
|
|
|
|
|
<view class="tab-bar">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-for="tab in tabs"
|
|
|
|
|
|
:key="tab.key"
|
|
|
|
|
|
class="tab-item"
|
|
|
|
|
|
:class="{ active: activeTab === tab.key }"
|
|
|
|
|
|
@click="handleTabChange(tab.key)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<text class="tab-text">{{ tab.label }}</text>
|
|
|
|
|
|
<text v-if="tab.badge > 0" class="tab-badge">{{ tab.badge }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 筛选栏 -->
|
|
|
|
|
|
<filter-bar
|
|
|
|
|
|
:loading="loading"
|
|
|
|
|
|
:total="total"
|
|
|
|
|
|
@search="handleSearch"
|
|
|
|
|
|
@reset="handleReset"
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 列表内容 -->
|
2026-05-23 17:49:12 +08:00
|
|
|
|
<scroll-view
|
|
|
|
|
|
scroll-y
|
2026-05-20 11:09:08 +08:00
|
|
|
|
class="list-container"
|
2026-05-23 17:49:12 +08:00
|
|
|
|
:style="{ height: scrollViewHeight + 'px' }"
|
2026-05-20 11:09:08 +08:00
|
|
|
|
:refresher-enabled="true"
|
|
|
|
|
|
:refresher-triggered="refreshing"
|
|
|
|
|
|
@refresherrefresh="onRefresh"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- 待贴标签列表 -->
|
|
|
|
|
|
<view v-if="activeTab === 'label'" class="coil-list">
|
|
|
|
|
|
<coil-card
|
|
|
|
|
|
v-for="item in list"
|
2026-05-23 16:50:46 +08:00
|
|
|
|
:key="item.coilId"
|
2026-05-20 11:09:08 +08:00
|
|
|
|
:data="item"
|
|
|
|
|
|
@relabel="handleRelabel"
|
|
|
|
|
|
@view-record="handleViewRecord"
|
|
|
|
|
|
@view-detail="handleViewDetail"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 其他Tab占位 -->
|
|
|
|
|
|
<view v-else class="placeholder-page">
|
|
|
|
|
|
<text class="placeholder-icon">🚧</text>
|
|
|
|
|
|
<text class="placeholder-text">功能开发中</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 空状态 -->
|
|
|
|
|
|
<view v-if="activeTab === 'label' && list.length === 0 && !loading" class="empty-state">
|
|
|
|
|
|
<text class="empty-icon">📭</text>
|
|
|
|
|
|
<text class="empty-text">暂无待办事项</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 加载状态 -->
|
|
|
|
|
|
<view v-if="loading && list.length === 0" class="loading-state">
|
|
|
|
|
|
<uni-load-more status="loading" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
<!-- 加载更多 -->
|
|
|
|
|
|
<view v-if="activeTab === 'label' && list.length > 0 && list.length < total" class="load-more-wrapper" @click="onLoadMore">
|
|
|
|
|
|
<view v-if="loading" class="load-more-loading">
|
|
|
|
|
|
<text class="loading-text">加载中...</text>
|
2026-05-23 17:49:12 +08:00
|
|
|
|
</view>
|
2026-05-25 10:10:53 +08:00
|
|
|
|
<view v-else class="load-more-btn">
|
|
|
|
|
|
<text class="btn-text">点击加载更多</text>
|
|
|
|
|
|
<text class="btn-hint">(已加载 {{ list.length }} / {{ total }} 条)</text>
|
2026-05-23 17:49:12 +08:00
|
|
|
|
</view>
|
2026-05-20 11:09:08 +08:00
|
|
|
|
</view>
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 已加载全部 -->
|
|
|
|
|
|
<view v-if="activeTab === 'label' && list.length > 0 && list.length >= total" class="load-more-wrapper no-more">
|
|
|
|
|
|
<text class="no-more-text">已加载全部 {{ total }} 条数据</text>
|
|
|
|
|
|
</view>
|
2026-05-20 11:09:08 +08:00
|
|
|
|
</scroll-view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 记录弹窗 -->
|
|
|
|
|
|
<record-popup ref="recordPopup" />
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 重贴标签弹窗 -->
|
|
|
|
|
|
<relabel-popup ref="relabelPopup" @success="handleRelabelSuccess" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
import { listMaterialCoil } from '@/api/wms/coil'
|
|
|
|
|
|
import FilterBar from './components/filter-bar.vue'
|
|
|
|
|
|
import CoilCard from './components/coil-card.vue'
|
|
|
|
|
|
import RecordPopup from './components/record-popup.vue'
|
|
|
|
|
|
import RelabelPopup from './components/relabel-popup.vue'
|
|
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
|
components: {
|
|
|
|
|
|
FilterBar,
|
|
|
|
|
|
CoilCard,
|
|
|
|
|
|
RecordPopup,
|
|
|
|
|
|
RelabelPopup
|
|
|
|
|
|
},
|
|
|
|
|
|
data() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
statusBarHeight: 0,
|
2026-05-23 17:49:12 +08:00
|
|
|
|
scrollViewHeight: 0, // scroll-view 计算高度
|
2026-05-20 11:09:08 +08:00
|
|
|
|
tabs: [
|
|
|
|
|
|
{ key: 'label', label: '待贴标签', badge: 0 },
|
|
|
|
|
|
{ key: 'inspect', label: '检验任务', badge: 0 },
|
|
|
|
|
|
{ key: 'approval', label: '质保书审批', badge: 0 },
|
|
|
|
|
|
{ key: 'other', label: '其他代办', badge: 0 }
|
|
|
|
|
|
],
|
|
|
|
|
|
activeTab: 'label',
|
|
|
|
|
|
list: [],
|
|
|
|
|
|
loading: false,
|
|
|
|
|
|
refreshing: false,
|
|
|
|
|
|
query: {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
enterCoilNo: '',
|
|
|
|
|
|
currentCoilNo: '',
|
|
|
|
|
|
itemName: '',
|
|
|
|
|
|
itemSpecification: '',
|
|
|
|
|
|
itemMaterial: '',
|
|
|
|
|
|
itemManufacturer: '',
|
|
|
|
|
|
hasTransferType: true // 待贴标签只显示有调拨类型的钢卷
|
|
|
|
|
|
},
|
2026-05-25 10:10:53 +08:00
|
|
|
|
total: 0,
|
|
|
|
|
|
loadMoreTimer: null // 加载更多防抖定时器
|
2026-05-20 11:09:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
created() {
|
|
|
|
|
|
// 获取状态栏高度
|
|
|
|
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
|
|
|
|
this.statusBarHeight = systemInfo.statusBarHeight || 0
|
2026-05-23 17:49:12 +08:00
|
|
|
|
// 计算 scroll-view 高度
|
|
|
|
|
|
this.calcScrollViewHeight()
|
|
|
|
|
|
},
|
|
|
|
|
|
onReady() {
|
|
|
|
|
|
// 页面就绪后再次计算高度(确保布局完成)
|
2026-05-25 10:10:53 +08:00
|
|
|
|
this.calcScrollViewHeight()
|
2026-05-20 11:09:08 +08:00
|
|
|
|
},
|
|
|
|
|
|
computed: {
|
|
|
|
|
|
loadMoreStatus() {
|
2026-05-25 10:10:53 +08:00
|
|
|
|
if (this.loading) return 'loading'
|
2026-05-20 11:09:08 +08:00
|
|
|
|
if (this.list.length >= this.total) return 'noMore'
|
|
|
|
|
|
return 'more'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
onLoad() {
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-05-23 17:49:12 +08:00
|
|
|
|
// 计算 scroll-view 高度
|
|
|
|
|
|
calcScrollViewHeight() {
|
|
|
|
|
|
const systemInfo = uni.getSystemInfoSync()
|
|
|
|
|
|
const windowHeight = systemInfo.windowHeight
|
|
|
|
|
|
const statusBarHeight = systemInfo.statusBarHeight || 0
|
|
|
|
|
|
|
|
|
|
|
|
// 各区域高度(单位:px)
|
|
|
|
|
|
const navBarHeight = 44 // 导航栏高度
|
|
|
|
|
|
const tabBarHeight = 50 // Tab栏高度
|
2026-05-25 10:10:53 +08:00
|
|
|
|
const filterBarHeight = 50 // 筛选栏高度(收起状态)
|
2026-05-23 17:49:12 +08:00
|
|
|
|
const bottomSafeArea = systemInfo.safeAreaInsets?.bottom || 0 // 底部安全区域
|
|
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
// 计算 scroll-view 可用高度
|
|
|
|
|
|
this.scrollViewHeight = windowHeight - statusBarHeight - navBarHeight - tabBarHeight - filterBarHeight - bottomSafeArea
|
2026-05-23 17:49:12 +08:00
|
|
|
|
|
|
|
|
|
|
console.log('scroll-view 高度计算:', {
|
|
|
|
|
|
windowHeight,
|
|
|
|
|
|
statusBarHeight,
|
|
|
|
|
|
navBarHeight,
|
|
|
|
|
|
tabBarHeight,
|
|
|
|
|
|
filterBarHeight,
|
|
|
|
|
|
bottomSafeArea,
|
|
|
|
|
|
scrollViewHeight: this.scrollViewHeight
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-05-20 11:09:08 +08:00
|
|
|
|
// 切换Tab
|
|
|
|
|
|
handleTabChange(key) {
|
|
|
|
|
|
this.activeTab = key
|
|
|
|
|
|
if (key === 'label') {
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-05-23 16:50:46 +08:00
|
|
|
|
// 数据字段映射 - 将后端字段映射到前端使用的字段
|
|
|
|
|
|
// 后端 WmsMaterialCoilVo 字段:coilId, enterCoilNo, currentCoilNo,
|
|
|
|
|
|
// itemName, specification, material, manufacturer,
|
|
|
|
|
|
// actualWarehouseName, warehouseName, remark, transferType
|
|
|
|
|
|
mapDataFields(row) {
|
|
|
|
|
|
return {
|
|
|
|
|
|
// 钢卷ID
|
|
|
|
|
|
coilId: row.coilId,
|
|
|
|
|
|
// 钢卷号
|
|
|
|
|
|
enterCoilNo: row.enterCoilNo || '-',
|
|
|
|
|
|
currentCoilNo: row.currentCoilNo || '-',
|
|
|
|
|
|
// 产品信息(注意后端使用 specification/material/manufacturer,非 item 前缀)
|
|
|
|
|
|
itemName: row.itemName || '-',
|
|
|
|
|
|
itemSpecification: row.specification || '-',
|
|
|
|
|
|
itemMaterial: row.material || '-',
|
|
|
|
|
|
itemManufacturer: row.manufacturer || '-',
|
|
|
|
|
|
// 库区信息
|
|
|
|
|
|
actualWarehouseName: row.actualWarehouseName || row.warehouseName || '-',
|
|
|
|
|
|
// 其他字段
|
|
|
|
|
|
remark: row.remark || '-',
|
|
|
|
|
|
transferType: row.transferType || '',
|
|
|
|
|
|
// 改判原因(后端 WmsMaterialCoilVo 无此字段,仅通过 listWithRejudge 接口传入)
|
|
|
|
|
|
changeReason: row.changeReason || ''
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-05-20 11:09:08 +08:00
|
|
|
|
// 获取列表数据
|
|
|
|
|
|
async fetchList(isLoadMore = false) {
|
|
|
|
|
|
if (this.loading) return
|
|
|
|
|
|
|
|
|
|
|
|
this.loading = true
|
|
|
|
|
|
try {
|
|
|
|
|
|
console.log('开始获取列表,查询参数:', this.query)
|
|
|
|
|
|
const res = await listMaterialCoil(this.query)
|
|
|
|
|
|
console.log('获取列表响应:', res)
|
|
|
|
|
|
|
|
|
|
|
|
const rows = res.rows || []
|
|
|
|
|
|
this.total = res.total || 0
|
|
|
|
|
|
|
2026-05-23 16:50:46 +08:00
|
|
|
|
// 映射数据字段
|
|
|
|
|
|
const mappedRows = rows.map(row => this.mapDataFields(row))
|
|
|
|
|
|
console.log('映射后的数据:', { mappedRows, total: this.total })
|
2026-05-20 11:09:08 +08:00
|
|
|
|
|
|
|
|
|
|
if (isLoadMore) {
|
2026-05-23 16:50:46 +08:00
|
|
|
|
this.list = [...this.list, ...mappedRows]
|
2026-05-20 11:09:08 +08:00
|
|
|
|
} else {
|
2026-05-23 16:50:46 +08:00
|
|
|
|
this.list = mappedRows
|
2026-05-20 11:09:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新待贴标签数量
|
|
|
|
|
|
const labelTab = this.tabs.find(t => t.key === 'label')
|
|
|
|
|
|
if (labelTab) {
|
|
|
|
|
|
labelTab.badge = this.total
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取列表失败:', error)
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '获取数据失败: ' + (error.message || '未知错误'),
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
this.loading = false
|
|
|
|
|
|
this.refreshing = false
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 搜索
|
|
|
|
|
|
handleSearch(form) {
|
|
|
|
|
|
this.query = {
|
|
|
|
|
|
...this.query,
|
|
|
|
|
|
...form,
|
|
|
|
|
|
pageNum: 1
|
|
|
|
|
|
}
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 重置
|
|
|
|
|
|
handleReset() {
|
|
|
|
|
|
this.query = {
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
enterCoilNo: '',
|
|
|
|
|
|
currentCoilNo: '',
|
|
|
|
|
|
itemName: '',
|
|
|
|
|
|
itemSpecification: '',
|
|
|
|
|
|
itemMaterial: '',
|
|
|
|
|
|
itemManufacturer: '',
|
|
|
|
|
|
hasTransferType: true
|
|
|
|
|
|
}
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 下拉刷新
|
|
|
|
|
|
onRefresh() {
|
|
|
|
|
|
this.refreshing = true
|
|
|
|
|
|
this.query.pageNum = 1
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
// 加载更多
|
|
|
|
|
|
onLoadMore() {
|
|
|
|
|
|
console.log('触发加载更多', {
|
2026-05-20 11:09:08 +08:00
|
|
|
|
listLength: this.list.length,
|
|
|
|
|
|
total: this.total,
|
|
|
|
|
|
loading: this.loading,
|
|
|
|
|
|
pageNum: this.query.pageNum
|
|
|
|
|
|
})
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查是否已加载全部数据
|
|
|
|
|
|
if (this.list.length >= this.total) {
|
|
|
|
|
|
console.log('加载更多被阻止:已加载全部数据')
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '已加载全部数据',
|
|
|
|
|
|
icon: 'none',
|
|
|
|
|
|
duration: 1500
|
|
|
|
|
|
})
|
2026-05-20 11:09:08 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查是否正在加载中
|
|
|
|
|
|
if (this.loading) {
|
|
|
|
|
|
console.log('加载更多被阻止:正在加载中')
|
|
|
|
|
|
return
|
2026-05-23 17:49:12 +08:00
|
|
|
|
}
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
|
|
|
|
|
// 防抖保护:防止重复点击
|
|
|
|
|
|
if (this.loadMoreTimer) {
|
|
|
|
|
|
console.log('加载更多被阻止:防抖保护中')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置防抖定时器
|
|
|
|
|
|
this.loadMoreTimer = setTimeout(() => {
|
|
|
|
|
|
this.loadMoreTimer = null
|
|
|
|
|
|
}, 800)
|
|
|
|
|
|
|
|
|
|
|
|
// 执行加载
|
|
|
|
|
|
this.query.pageNum++
|
|
|
|
|
|
console.log('加载第', this.query.pageNum, '页')
|
|
|
|
|
|
this.fetchList(true)
|
2026-05-20 11:09:08 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 重贴标签
|
|
|
|
|
|
handleRelabel(coilInfo) {
|
|
|
|
|
|
this.$refs.relabelPopup.open(coilInfo)
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 重贴标签成功回调
|
|
|
|
|
|
handleRelabelSuccess() {
|
|
|
|
|
|
this.fetchList()
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 查看记录
|
|
|
|
|
|
handleViewRecord(coilInfo) {
|
2026-05-23 16:50:46 +08:00
|
|
|
|
const coilId = coilInfo.coilId
|
2026-05-20 11:09:08 +08:00
|
|
|
|
if (!coilId) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '无法获取钢卷ID',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
this.$refs.recordPopup.open(coilId)
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 查看详情
|
|
|
|
|
|
handleViewDetail(coilInfo) {
|
2026-05-23 16:50:46 +08:00
|
|
|
|
const coilId = coilInfo.coilId
|
2026-05-20 11:09:08 +08:00
|
|
|
|
if (!coilId) {
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
title: '无法获取钢卷ID',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
uni.navigateTo({
|
|
|
|
|
|
url: `/pages/todo/coil-detail?coilId=${coilId}`
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
.todo-container {
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
|
|
|
|
|
|
.custom-nav-bar {
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
|
|
|
|
|
|
.nav-content {
|
|
|
|
|
|
height: 88rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
|
|
|
|
|
|
.nav-title {
|
|
|
|
|
|
font-size: 34rpx;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: #333333;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tab-bar {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
padding: 0 10rpx;
|
|
|
|
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
|
|
|
|
|
scrollbar-width: none;
|
|
|
|
|
|
&::-webkit-scrollbar {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tab-item {
|
|
|
|
|
|
flex: 0 0 auto;
|
|
|
|
|
|
min-width: 140rpx;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding: 20rpx 16rpx;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
|
|
|
|
|
|
.tab-text {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #666666;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
line-height: 1.2;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tab-badge {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 8rpx;
|
|
|
|
|
|
right: 8rpx;
|
|
|
|
|
|
min-width: 32rpx;
|
|
|
|
|
|
height: 32rpx;
|
|
|
|
|
|
line-height: 32rpx;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
background: #ff4d4f;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
font-size: 20rpx;
|
|
|
|
|
|
border-radius: 16rpx;
|
|
|
|
|
|
padding: 0 8rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
|
.tab-text {
|
|
|
|
|
|
color: #1a73e8;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
&::after {
|
|
|
|
|
|
content: '';
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
left: 50%;
|
|
|
|
|
|
transform: translateX(-50%);
|
|
|
|
|
|
width: 40rpx;
|
|
|
|
|
|
height: 4rpx;
|
|
|
|
|
|
background: #1a73e8;
|
|
|
|
|
|
border-radius: 2rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.list-container {
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
box-sizing: border-box;
|
2026-05-23 17:49:12 +08:00
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
-webkit-overflow-scrolling: touch;
|
2026-05-20 11:09:08 +08:00
|
|
|
|
|
|
|
|
|
|
.coil-list {
|
2026-05-25 10:10:53 +08:00
|
|
|
|
padding-bottom: 20rpx;
|
2026-05-20 11:09:08 +08:00
|
|
|
|
}
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
2026-05-20 11:09:08 +08:00
|
|
|
|
.load-more-wrapper {
|
2026-05-25 10:10:53 +08:00
|
|
|
|
padding: 16rpx 0;
|
2026-05-20 11:09:08 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
2026-05-23 17:49:12 +08:00
|
|
|
|
|
2026-05-20 11:09:08 +08:00
|
|
|
|
&:active {
|
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
}
|
2026-05-23 17:49:12 +08:00
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
.load-more-btn {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 12rpx 32rpx;
|
|
|
|
|
|
background: #ffffff;
|
|
|
|
|
|
border-radius: 8rpx;
|
|
|
|
|
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
|
|
|
|
|
|
|
|
|
|
|
|
.btn-text {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #1a73e8;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
2026-05-23 17:49:12 +08:00
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
.btn-hint {
|
|
|
|
|
|
font-size: 20rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
margin-top: 4rpx;
|
|
|
|
|
|
}
|
2026-05-23 17:49:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-25 10:10:53 +08:00
|
|
|
|
.load-more-loading {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 12rpx 32rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.loading-text {
|
|
|
|
|
|
font-size: 26rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
}
|
2026-05-23 17:49:12 +08:00
|
|
|
|
}
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
|
|
|
|
|
&.no-more {
|
|
|
|
|
|
padding: 16rpx 0;
|
|
|
|
|
|
|
|
|
|
|
|
.no-more-text {
|
|
|
|
|
|
font-size: 22rpx;
|
|
|
|
|
|
color: #bbbbbb;
|
|
|
|
|
|
}
|
2026-05-23 17:49:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-25 10:10:53 +08:00
|
|
|
|
|
2026-05-20 11:09:08 +08:00
|
|
|
|
.placeholder-page {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding: 200rpx 0;
|
|
|
|
|
|
|
|
|
|
|
|
.placeholder-icon {
|
|
|
|
|
|
font-size: 120rpx;
|
|
|
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.placeholder-text {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty-state {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
padding: 200rpx 0;
|
|
|
|
|
|
|
|
|
|
|
|
.empty-icon {
|
|
|
|
|
|
font-size: 120rpx;
|
|
|
|
|
|
margin-bottom: 30rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.empty-text {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
color: #999999;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.loading-state {
|
|
|
|
|
|
padding: 100rpx 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 浏览器环境适配 */
|
|
|
|
|
|
@media screen and (min-width: 768px) {
|
|
|
|
|
|
.todo-container {
|
|
|
|
|
|
max-width: 750rpx;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
|
|
|
|
|
|
.tab-bar {
|
|
|
|
|
|
.tab-item {
|
|
|
|
|
|
min-width: 160rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.tab-text {
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* H5 浏览器特定样式 */
|
|
|
|
|
|
/* #ifdef H5 */
|
|
|
|
|
|
.todo-container {
|
|
|
|
|
|
.tab-bar {
|
|
|
|
|
|
.tab-item {
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
background: rgba(26, 115, 232, 0.05);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.coil-card {
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
|
box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/* #endif */
|
|
|
|
|
|
</style>
|