feat:上书记录对接shop/list和product/shop-detail接口,平台+店铺联动,分页
This commit is contained in:
parent
5a4968881a
commit
d64c9aad01
@ -5,30 +5,19 @@
|
||||
<view class="filter-card">
|
||||
<view class="filter-row">
|
||||
<view class="filter-item">
|
||||
<text class="filter-label">账号</text>
|
||||
<picker class="filter-picker" @change="handleAccountChange" :value="accountIndex" :range="accountList">
|
||||
<text class="filter-label">平台</text>
|
||||
<picker class="filter-picker" @change="handlePlatformChange" :value="platformIndex" :range="platformList">
|
||||
<view class="picker-value">
|
||||
<text class="picker-text">{{ accountList[accountIndex] }}</text>
|
||||
<text class="picker-text">{{ platformList[platformIndex] }}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="filter-label">店铺</text>
|
||||
<picker class="filter-picker" @change="handleShopChange" :value="shopIndex" :range="shopList">
|
||||
<picker class="filter-picker" @change="handleShopChange" :value="shopIndex" :range="shopNames">
|
||||
<view class="picker-value">
|
||||
<text class="picker-text">{{ shopList[shopIndex] }}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
<view class="filter-row">
|
||||
<view class="filter-item full-width">
|
||||
<text class="filter-label">日期</text>
|
||||
<picker class="filter-picker" mode="date" @change="handleDateChange" :value="selectedDate">
|
||||
<view class="picker-value">
|
||||
<text class="picker-text">{{ selectedDate }}</text>
|
||||
<text class="picker-text">{{ shopNames[shopIndex] }}</text>
|
||||
<text class="picker-arrow">▼</text>
|
||||
</view>
|
||||
</picker>
|
||||
@ -40,210 +29,300 @@
|
||||
<!-- 统计信息 -->
|
||||
<view class="stats-section">
|
||||
<view class="stats-card">
|
||||
<text class="stats-icon">📊</text>
|
||||
<text class="stats-label">总记录数</text>
|
||||
<text class="stats-value">{{ recordList.length }} 条</text>
|
||||
<view class="stats-item">
|
||||
<text class="stats-num success">{{ stats.successCount }}</text>
|
||||
<text class="stats-label">已发送</text>
|
||||
</view>
|
||||
<view class="stats-divider"></view>
|
||||
<view class="stats-item">
|
||||
<text class="stats-num pending">{{ stats.notSentCount }}</text>
|
||||
<text class="stats-label">未发送</text>
|
||||
</view>
|
||||
<view class="stats-divider"></view>
|
||||
<view class="stats-item">
|
||||
<text class="stats-num failed">{{ stats.failedCount }}</text>
|
||||
<text class="stats-label">失败</text>
|
||||
</view>
|
||||
<view class="stats-divider"></view>
|
||||
<view class="stats-item">
|
||||
<text class="stats-num total">{{ stats.total }}</text>
|
||||
<text class="stats-label">总计</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 记录列表 -->
|
||||
<view class="record-list">
|
||||
<view class="record-item" v-for="(item, index) in recordList" :key="index">
|
||||
<view class="record-main">
|
||||
<!-- 图片 -->
|
||||
<view class="record-image" @click="previewImage(item.image)">
|
||||
<image class="book-image" :src="item.image" mode="aspectFill"></image>
|
||||
<view class="image-overlay">
|
||||
<text class="zoom-icon">🔍</text>
|
||||
<scroll-view class="record-scroll" scroll-y :refresher-enabled="true" :refresher-triggered="isRefreshing" @refresherrefresh="onRefresh" @scrolltolower="loadMore">
|
||||
<view class="record-list">
|
||||
<view class="record-item" v-for="(item, index) in recordList" :key="index">
|
||||
<view class="record-main">
|
||||
<!-- 图片 -->
|
||||
<view class="record-image" @click="previewImage(item.live_image)">
|
||||
<image class="book-image" :src="getFirstImage(item.live_image)" mode="aspectFill"></image>
|
||||
</view>
|
||||
<!-- 基本信息 -->
|
||||
<view class="record-info">
|
||||
<view class="info-row">
|
||||
<text class="book-name">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">ISBN:</text>
|
||||
<text class="info-value">{{ item.barcode || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">波次:</text>
|
||||
<text class="info-value">{{ item.wave_no || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">货位:</text>
|
||||
<text class="info-value">{{ item.warehouse_name }}{{ item.location_code ? ' - ' + item.location_code : '' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">时间:</text>
|
||||
<text class="info-value">{{ formatTime(item.created_at) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 基本信息 -->
|
||||
<view class="record-info">
|
||||
<view class="info-row">
|
||||
<text class="book-name">{{ item.name }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">ISBN:</text>
|
||||
<text class="info-value">{{ item.isbn }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">品相:</text>
|
||||
<text class="condition-badge" :class="getConditionClass(item.condition)">{{ item.condition }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">上书时间:</text>
|
||||
<text class="info-value">{{ item.uploadTime }}</text>
|
||||
<!-- 价格和库存 -->
|
||||
<view class="record-detail">
|
||||
<view class="detail-row">
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">定价</text>
|
||||
<text class="detail-value">¥{{ formatPrice(item.price) }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">售价</text>
|
||||
<text class="detail-value price">¥{{ formatPrice(item.sale_price) }}</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">库存</text>
|
||||
<text class="detail-value">{{ item.quantity }}本</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 价格和库存 -->
|
||||
<view class="record-detail">
|
||||
<view class="detail-row">
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">库存</text>
|
||||
<text class="detail-value">{{ item.stock }}本</text>
|
||||
</view>
|
||||
<view class="detail-item">
|
||||
<text class="detail-label">价格</text>
|
||||
<text class="detail-value price">¥{{ item.price }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 发布状态 -->
|
||||
<view class="publish-status">
|
||||
<view class="status-row">
|
||||
<view class="status-item" :class="{ published: item.pddPublished }">
|
||||
<text class="status-icon">{{ item.pddPublished ? '✓' : '✗' }}</text>
|
||||
<text class="status-text">拼多多:{{ item.pddPublished ? '已发布' : '未发布' }}</text>
|
||||
</view>
|
||||
<view class="status-item" :class="{ published: item.kfzPublished }">
|
||||
<text class="status-icon">{{ item.kfzPublished ? '✓' : '✗' }}</text>
|
||||
<text class="status-text">孔夫子:{{ item.kfzPublished ? '已发布' : '未发布' }}</text>
|
||||
</view>
|
||||
<view class="status-item" :class="{ published: item.xianyuPublished }">
|
||||
<text class="status-icon">{{ item.xianyuPublished ? '✓' : '✗' }}</text>
|
||||
<text class="status-text">闲鱼:{{ item.xianyuPublished ? '已发布' : '未发布' }}</text>
|
||||
<!-- 状态 -->
|
||||
<view class="publish-status">
|
||||
<view class="status-row">
|
||||
<text class="status-tag" :class="getStatusClass(item.status_in_shop)">{{ item.msg || getStatusText(item.status_in_shop) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="recordList.length === 0">
|
||||
<text class="empty-icon">📭</text>
|
||||
<text class="empty-text">暂无上书记录</text>
|
||||
</view>
|
||||
<!-- 加载更多 -->
|
||||
<view class="load-more" v-if="loadingMore">
|
||||
<view class="loading-spinner"></view>
|
||||
<text class="load-more-text">加载中...</text>
|
||||
</view>
|
||||
<view class="load-more" v-if="!hasMore && recordList.length > 0">
|
||||
<text class="no-more-text">— 已全部加载 —</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="recordList.length === 0 && !isLoading">
|
||||
<text class="empty-icon">📭</text>
|
||||
<text class="empty-text">暂无上书记录</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getShopList, getShopDetail } from '@/utils/api.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
// 筛选条件
|
||||
accountIndex: 0,
|
||||
accountList: ['全部账号', '账号A', '账号B', '账号C'],
|
||||
shopIndex: 0,
|
||||
shopList: ['全部店铺', '店铺1', '店铺2', '店铺3'],
|
||||
selectedDate: this.getTodayDate(),
|
||||
// 平台筛选
|
||||
platformIndex: 0,
|
||||
platformList: ['全部平台', '拼多多', '孔夫子', '闲鱼'],
|
||||
platformTypes: [0, 1, 2, 5],
|
||||
|
||||
// 记录列表
|
||||
recordList: [
|
||||
{
|
||||
image: 'https://picsum.photos/200/280?random=1',
|
||||
name: '红楼梦',
|
||||
isbn: '9787020002207',
|
||||
condition: '全新',
|
||||
uploadTime: '2024-01-15 14:30',
|
||||
stock: 5,
|
||||
price: '45.00',
|
||||
pddPublished: true,
|
||||
kfzPublished: true,
|
||||
xianyuPublished: false
|
||||
},
|
||||
{
|
||||
image: 'https://picsum.photos/200/280?random=2',
|
||||
name: '西游记',
|
||||
isbn: '9787020002214',
|
||||
condition: '九成新',
|
||||
uploadTime: '2024-01-15 15:20',
|
||||
stock: 3,
|
||||
price: '38.00',
|
||||
pddPublished: true,
|
||||
kfzPublished: false,
|
||||
xianyuPublished: true
|
||||
},
|
||||
{
|
||||
image: 'https://picsum.photos/200/280?random=3',
|
||||
name: '水浒传',
|
||||
isbn: '9787020002221',
|
||||
condition: '八成新',
|
||||
uploadTime: '2024-01-15 16:45',
|
||||
stock: 2,
|
||||
price: '32.00',
|
||||
pddPublished: false,
|
||||
kfzPublished: true,
|
||||
xianyuPublished: true
|
||||
},
|
||||
{
|
||||
image: 'https://picsum.photos/200/280?random=4',
|
||||
name: '三国演义',
|
||||
isbn: '9787020002238',
|
||||
condition: '全新',
|
||||
uploadTime: '2024-01-15 17:10',
|
||||
stock: 8,
|
||||
price: '52.00',
|
||||
pddPublished: true,
|
||||
kfzPublished: true,
|
||||
xianyuPublished: true
|
||||
}
|
||||
]
|
||||
// 店铺筛选
|
||||
shopIndex: 0,
|
||||
shopList: [],
|
||||
shopNames: ['全部店铺'],
|
||||
|
||||
// 分页
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
hasMore: true,
|
||||
isLoading: false,
|
||||
loadingMore: false,
|
||||
isRefreshing: false,
|
||||
|
||||
// 数据
|
||||
recordList: [],
|
||||
stats: { successCount: 0, notSentCount: 0, failedCount: 0, total: 0 }
|
||||
}
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '上书记录'
|
||||
})
|
||||
uni.setNavigationBarTitle({ title: '上书记录' })
|
||||
this.loadShopList()
|
||||
this.fetchRecords()
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取今天日期
|
||||
getTodayDate() {
|
||||
const today = new Date()
|
||||
const year = today.getFullYear()
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(today.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
// 加载店铺列表
|
||||
async loadShopList() {
|
||||
try {
|
||||
const platformType = this.platformTypes[this.platformIndex]
|
||||
const params = { pageNum: 1, pageSize: 100 }
|
||||
if (platformType > 0) params.shop_type = String(platformType)
|
||||
const res = await getShopList(params)
|
||||
this.shopList = res.list || []
|
||||
this.updateShopNames()
|
||||
} catch (e) {
|
||||
console.error('加载店铺列表失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
// 账号筛选变化
|
||||
handleAccountChange(e) {
|
||||
this.accountIndex = e.detail.value
|
||||
this.filterRecords()
|
||||
// 更新店铺名下拉列表
|
||||
updateShopNames() {
|
||||
const names = ['全部店铺']
|
||||
this.shopList.forEach(function(s) {
|
||||
names.push(s.shop_alias_name || s.shop_name || '未命名')
|
||||
})
|
||||
this.shopNames = names
|
||||
if (this.shopIndex >= names.length) {
|
||||
this.shopIndex = 0
|
||||
}
|
||||
},
|
||||
|
||||
// 店铺筛选变化
|
||||
// 平台切换
|
||||
handlePlatformChange(e) {
|
||||
this.platformIndex = e.detail.value
|
||||
this.shopIndex = 0
|
||||
this.loadShopList()
|
||||
this.resetAndFetch()
|
||||
},
|
||||
|
||||
// 店铺切换
|
||||
handleShopChange(e) {
|
||||
this.shopIndex = e.detail.value
|
||||
this.filterRecords()
|
||||
this.resetAndFetch()
|
||||
},
|
||||
|
||||
// 日期筛选变化
|
||||
handleDateChange(e) {
|
||||
this.selectedDate = e.detail.value
|
||||
this.filterRecords()
|
||||
// 重置分页并加载
|
||||
resetAndFetch() {
|
||||
this.page = 1
|
||||
this.hasMore = true
|
||||
this.recordList = []
|
||||
this.stats = { successCount: 0, notSentCount: 0, failedCount: 0, total: 0 }
|
||||
this.fetchRecords()
|
||||
},
|
||||
|
||||
// 筛选记录
|
||||
filterRecords() {
|
||||
// TODO: 根据筛选条件调用接口获取数据
|
||||
uni.showToast({
|
||||
title: '筛选条件已更新',
|
||||
icon: 'none'
|
||||
})
|
||||
// 获取当前选中的店铺ID
|
||||
getSelectedShopId() {
|
||||
if (this.shopIndex <= 0) return ''
|
||||
const shop = this.shopList[this.shopIndex - 1]
|
||||
return shop ? shop.id : ''
|
||||
},
|
||||
|
||||
// 获取品相样式类
|
||||
getConditionClass(condition) {
|
||||
const classMap = {
|
||||
'全新': 'condition-new',
|
||||
'九成新': 'condition-good',
|
||||
'八成新': 'condition-fair',
|
||||
'七成新': 'condition-poor'
|
||||
// 获取上书记录
|
||||
async fetchRecords() {
|
||||
if (this.isLoading || this.loadingMore) return
|
||||
this.isLoading = true
|
||||
try {
|
||||
const shopId = this.getSelectedShopId()
|
||||
if (!shopId) {
|
||||
this.isLoading = false
|
||||
this.recordList = []
|
||||
this.hasMore = false
|
||||
return
|
||||
}
|
||||
const params = {
|
||||
page: this.page,
|
||||
page_size: this.pageSize,
|
||||
shop_id: shopId
|
||||
}
|
||||
const res = await getShopDetail(params)
|
||||
const products = res.products || []
|
||||
if (this.page === 1) {
|
||||
this.recordList = products
|
||||
} else {
|
||||
this.recordList = this.recordList.concat(products)
|
||||
}
|
||||
this.hasMore = products.length >= this.pageSize
|
||||
this.stats = {
|
||||
successCount: res.success_count || 0,
|
||||
notSentCount: res.not_sent_count || 0,
|
||||
failedCount: res.failed_count || 0,
|
||||
total: res.total || 0
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取上书记录失败:', e)
|
||||
} finally {
|
||||
this.isLoading = false
|
||||
this.loadingMore = false
|
||||
this.isRefreshing = false
|
||||
}
|
||||
return classMap[condition] || 'condition-default'
|
||||
},
|
||||
|
||||
// 下拉刷新
|
||||
onRefresh() {
|
||||
this.isRefreshing = true
|
||||
this.page = 1
|
||||
this.hasMore = true
|
||||
this.fetchRecords()
|
||||
},
|
||||
|
||||
// 上拉加载更多
|
||||
loadMore() {
|
||||
if (this.loadingMore || !this.hasMore) return
|
||||
this.loadingMore = true
|
||||
this.page++
|
||||
this.fetchRecords()
|
||||
},
|
||||
|
||||
// 获取第一张图片
|
||||
getFirstImage(images) {
|
||||
if (!images) return ''
|
||||
if (typeof images === 'string') return images
|
||||
return images[0] || ''
|
||||
},
|
||||
|
||||
// 格式化价格(分→元)
|
||||
formatPrice(price) {
|
||||
if (!price && price !== 0) return '0.00'
|
||||
return (parseFloat(price) / 100).toFixed(2)
|
||||
},
|
||||
|
||||
// 格式化时间(时间戳→日期)
|
||||
formatTime(timestamp) {
|
||||
if (!timestamp) return '-'
|
||||
const date = new Date(parseInt(timestamp) * 1000)
|
||||
const y = date.getFullYear()
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(date.getDate()).padStart(2, '0')
|
||||
const h = String(date.getHours()).padStart(2, '0')
|
||||
const mi = String(date.getMinutes()).padStart(2, '0')
|
||||
return y + '-' + m + '-' + d + ' ' + h + ':' + mi
|
||||
},
|
||||
|
||||
// 获取状态CSS类
|
||||
getStatusClass(status) {
|
||||
if (status === 1) return 'status-success'
|
||||
if (status === 0) return 'status-pending'
|
||||
return 'status-failed'
|
||||
},
|
||||
|
||||
// 获取状态文字
|
||||
getStatusText(status) {
|
||||
if (status === 1) return '已发布到店铺'
|
||||
if (status === 0) return '未发送到店铺'
|
||||
return '发布失败'
|
||||
},
|
||||
|
||||
// 预览图片
|
||||
previewImage(imageUrl) {
|
||||
previewImage(images) {
|
||||
if (!images) return
|
||||
const urls = typeof images === 'string' ? [images] : images
|
||||
if (urls.length === 0) return
|
||||
uni.previewImage({
|
||||
urls: [imageUrl],
|
||||
current: imageUrl,
|
||||
longPressActions: {
|
||||
itemList: ['发送给朋友', '保存图片', '收藏']
|
||||
}
|
||||
urls: urls,
|
||||
current: urls[0]
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -286,10 +365,6 @@ export default {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.filter-item.full-width {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 26rpx;
|
||||
color: #4e5969;
|
||||
@ -328,30 +403,47 @@ export default {
|
||||
.stats-card {
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 24rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.stats-icon {
|
||||
font-size: 40rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.stats-label {
|
||||
font-size: 28rpx;
|
||||
color: #4e5969;
|
||||
.stats-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stats-value {
|
||||
.stats-num {
|
||||
font-size: 36rpx;
|
||||
color: #1d2129;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* 记录列表 */
|
||||
.stats-num.success { color: #67c23a; }
|
||||
.stats-num.pending { color: #e6a23c; }
|
||||
.stats-num.failed { color: #f56c6c; }
|
||||
.stats-num.total { color: #409eff; }
|
||||
|
||||
.stats-label {
|
||||
font-size: 22rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.stats-divider {
|
||||
width: 1px;
|
||||
height: 48rpx;
|
||||
background: #ebeef5;
|
||||
}
|
||||
|
||||
/* 滚动列表 */
|
||||
.record-scroll {
|
||||
height: calc(100vh - 300rpx);
|
||||
}
|
||||
|
||||
.record-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -377,7 +469,6 @@ export default {
|
||||
height: 180rpx;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@ -386,34 +477,12 @@ export default {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.image-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60rpx;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.5));
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.record-image:active .image-overlay {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.zoom-icon {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
/* 基本信息 */
|
||||
.record-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
@ -422,14 +491,17 @@ export default {
|
||||
}
|
||||
|
||||
.book-name {
|
||||
font-size: 32rpx;
|
||||
font-size: 30rpx;
|
||||
color: #1d2129;
|
||||
font-weight: 600;
|
||||
lines: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-size: 24rpx;
|
||||
color: #86909c;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
@ -437,38 +509,6 @@ export default {
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
.condition-badge {
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 12rpx;
|
||||
border-radius: 8rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.condition-new {
|
||||
background: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.condition-good {
|
||||
background: #d9ecff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.condition-fair {
|
||||
background: #faecd8;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.condition-poor {
|
||||
background: #fde2e2;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.condition-default {
|
||||
background: #f4f4f5;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 价格和库存 */
|
||||
.record-detail {
|
||||
background: #f5f6fa;
|
||||
@ -504,7 +544,7 @@ export default {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 发布状态 */
|
||||
/* 状态 */
|
||||
.publish-status {
|
||||
border-top: 1rpx solid #ebeef5;
|
||||
padding-top: 16rpx;
|
||||
@ -512,40 +552,63 @@ export default {
|
||||
|
||||
.status-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
font-size: 20rpx;
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
border-radius: 50%;
|
||||
background: #c0c4cc;
|
||||
color: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-item.published .status-icon {
|
||||
background: #67c23a;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
.status-tag {
|
||||
font-size: 22rpx;
|
||||
color: #86909c;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.status-item.published .status-text {
|
||||
.status-success {
|
||||
background: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background: #faecd8;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
.status-failed {
|
||||
background: #fde2e2;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 加载更多 */
|
||||
.load-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx 0;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.load-more-text {
|
||||
font-size: 24rpx;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.no-more-text {
|
||||
font-size: 24rpx;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border: 3rpx solid #e4e7ed;
|
||||
border-top-color: #409eff;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
@ -564,4 +627,4 @@ export default {
|
||||
font-size: 28rpx;
|
||||
color: #86909c;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -199,8 +199,9 @@
|
||||
|
||||
<!-- 上书记录 -->
|
||||
<view class="form-section">
|
||||
<view class="section-title">
|
||||
<view class="section-title" @click="goRecordPage">
|
||||
<text class="title-text">上书记录</text>
|
||||
<text class="title-more">查看全部 ›</text>
|
||||
</view>
|
||||
<view class="history-list">
|
||||
<view class="history-item" v-for="(item, index) in historyList" :key="index">
|
||||
@ -505,8 +506,9 @@
|
||||
|
||||
<!-- ===== 上书记录 ===== -->
|
||||
<view class="form-section" v-if="noIsbnHistoryList.length > 0">
|
||||
<view class="section-title">
|
||||
<view class="section-title" @click="goRecordPage">
|
||||
<text class="title-text">上书记录</text>
|
||||
<text class="title-more">查看全部 ›</text>
|
||||
</view>
|
||||
<view class="history-list">
|
||||
<view class="history-item" v-for="(item, index) in noIsbnHistoryList" :key="index">
|
||||
@ -2595,6 +2597,11 @@ export default {
|
||||
this.pendingCount = 0
|
||||
},
|
||||
|
||||
// 跳转到上书记录页面
|
||||
goRecordPage() {
|
||||
uni.navigateTo({ url: '/pages/record/record' })
|
||||
},
|
||||
|
||||
// 带自动重试的请求封装(网络抖动时自动重试2次)
|
||||
requestWithRetry(options, maxRetries) {
|
||||
if (maxRetries === undefined) maxRetries = 2
|
||||
@ -3851,6 +3858,12 @@ export default {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title-more {
|
||||
font-size: 24rpx;
|
||||
color: #409eff;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.photo-count {
|
||||
font-size: 22rpx;
|
||||
color: #909399;
|
||||
|
||||
74
utils/api.js
74
utils/api.js
@ -360,6 +360,76 @@ function buildFormBodyWithImages(params, imageUrls, imageKey) {
|
||||
|
||||
export { buildFormBodyWithImages }
|
||||
|
||||
/**
|
||||
* 获取店铺列表(上书记录用)
|
||||
* @param {Object} params - { pageNum, pageSize, shop_type }
|
||||
*/
|
||||
export function getShopList(params = {}) {
|
||||
return requestWithRetry((token) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = generateSignedUrl(`${BASE_URL}/api/shop/list`, params)
|
||||
console.log('【店铺列表】请求URL:', url)
|
||||
uni.request({
|
||||
url: url,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('【店铺列表】响应:', JSON.stringify(res.data))
|
||||
if (res.statusCode === 200 && res.data && res.data.code === 0) {
|
||||
resolve(res.data.data)
|
||||
} else {
|
||||
resolve({ list: [], total: 0 })
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('【店铺列表】请求失败:', err)
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}, '店铺列表')
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取店铺上书详情(上书记录列表)
|
||||
* @param {Object} params - { page, page_size, shop_id }
|
||||
*/
|
||||
export function getShopDetail(params = {}) {
|
||||
return requestWithRetry((token) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const url = generateSignedUrl(`${BASE_URL}/api/product/shop-detail`, params)
|
||||
console.log('【上书详情】请求URL:', url)
|
||||
uni.request({
|
||||
url: url,
|
||||
method: 'GET',
|
||||
header: {
|
||||
'Authorization': 'Bearer ' + token
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('【上书详情】响应:', JSON.stringify(res.data))
|
||||
if (res.statusCode === 200 && res.data) {
|
||||
if (res.data.code === 200 && res.data.data) {
|
||||
resolve(res.data.data)
|
||||
} else if (res.data.data) {
|
||||
resolve(res.data.data)
|
||||
} else {
|
||||
resolve({ products: [], total: 0, page: 1, page_size: 10 })
|
||||
}
|
||||
} else {
|
||||
resolve({ products: [], total: 0, page: 1, page_size: 10 })
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('【上书详情】请求失败:', err)
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}, '上书详情')
|
||||
}
|
||||
|
||||
export default {
|
||||
calculateSign,
|
||||
buildFormBodyWithImages,
|
||||
@ -367,5 +437,7 @@ export default {
|
||||
getLocationList,
|
||||
psiLogin,
|
||||
searchBookByIsbn,
|
||||
generateSignedUrl
|
||||
generateSignedUrl,
|
||||
getShopList,
|
||||
getShopDetail
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user