818 lines
23 KiB
Vue
818 lines
23 KiB
Vue
<template>
|
||
<view>
|
||
<clinic-page-layout title="商品订单" :show-back="true">
|
||
<!-- page-flex 高度=视口减导航与 layout 底部 32rpx;header 不可再设 relative top -->
|
||
<view
|
||
class="order-list-container page-flex"
|
||
:style="{ height: 'calc(100vh - ' + navTopOffset + 'px - 32rpx)' }"
|
||
>
|
||
<view class="native-sticky-header rx-flex-fixed">
|
||
<view class="header-solid-bg">
|
||
<view class="tabs-wrap">
|
||
<u-tabs
|
||
:list="statusTabsList"
|
||
:is-scroll="true"
|
||
:current="statusIndex"
|
||
active-color="#6ACDBB"
|
||
inactive-color="#86909C"
|
||
bg-color="#ffffff"
|
||
:bold="true"
|
||
@change="onStatusTabChange"
|
||
/>
|
||
</view>
|
||
<view class="quick-filter">
|
||
<view class="filter-row date-row">
|
||
<picker mode="date" :value="dateStart" @change="onStart">
|
||
<view class="filter-picker date-picker">{{ dateStart || '开始日期' }}</view>
|
||
</picker>
|
||
<text class="sep">至</text>
|
||
<picker mode="date" :value="dateEnd" @change="onEnd">
|
||
<view class="filter-picker date-picker">{{ dateEnd || '结束日期' }}</view>
|
||
</picker>
|
||
<view class="btn-query" @click="reload">查询</view>
|
||
</view>
|
||
</view>
|
||
|
||
<collapsible-filter-panel title="订单筛选" @clear="resetFilter">
|
||
<view class="filter-row">
|
||
<text class="filter-label">订单号</text>
|
||
<input class="filter-input" v-model="orderNo" placeholder="输入订单号" placeholder-style="color:#BDBDBD" />
|
||
</view>
|
||
<view class="filter-row">
|
||
<text class="filter-label">发货方式</text>
|
||
<picker :range="deliveryLabels" @change="onDelivery">
|
||
<view class="filter-picker">{{ deliveryLabels[deliveryIndex] }}</view>
|
||
</picker>
|
||
</view>
|
||
<view class="filter-row">
|
||
<text class="filter-label">订单类型</text>
|
||
<picker :range="prescriptionTypeLabels" @change="onPrescriptionType">
|
||
<view class="filter-picker">{{ prescriptionTypeLabels[prescriptionTypeIndex] }}</view>
|
||
</picker>
|
||
</view>
|
||
</collapsible-filter-panel>
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view v-if="statItems.length" class="stats-scroll rx-flex-fixed" scroll-x>
|
||
<view class="stats">
|
||
<view v-for="s in statItems" :key="s.key" class="stat-card">
|
||
<text class="stat-label">{{ s.label }}</text>
|
||
<text class="stat-value">{{ s.value }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<swiper
|
||
class="order-swiper"
|
||
:current="statusIndex"
|
||
:disable-touch="statusOptions.length < 2"
|
||
@change="onStatusSwiperChange"
|
||
>
|
||
<swiper-item
|
||
v-for="(cat, idx) in statusOptions"
|
||
:key="idx"
|
||
>
|
||
<scroll-view
|
||
scroll-y
|
||
class="order-scroll"
|
||
refresher-enabled="true"
|
||
:refresher-triggered="isRefreshing"
|
||
@refresherrefresh="onRefresherRefresh"
|
||
@scrolltolower="onScrollToLower"
|
||
>
|
||
<block v-if="statusIndex === idx">
|
||
<list-skeleton v-if="loading && !list.length" type="order" :rows="4" />
|
||
<view v-else class="card-list-wrap">
|
||
<view
|
||
v-for="item in list"
|
||
:key="item._wxKey"
|
||
class="premium-card"
|
||
hover-class="card-hover"
|
||
:hover-stay-time="150"
|
||
@click="goDetail(item)"
|
||
>
|
||
<view class="card-head">
|
||
<view class="order-id">
|
||
<text class="id-icon">单</text>
|
||
<text class="id-text">{{ item.orderNo }}</text>
|
||
</view>
|
||
<view
|
||
class="status-badge"
|
||
:class="['status-' + (item.statusKey || 'default')]"
|
||
>
|
||
{{ item.statusText }}
|
||
</view>
|
||
</view>
|
||
<view class="card-body">
|
||
<view class="main-info">
|
||
<view class="title-wrap">
|
||
<text class="goods-title">{{ item.productSummary || '药品订单' }}</text>
|
||
<view class="goods-tags">
|
||
<text class="modern-tag tag-type">{{ item.prescriptionTypeText }}</text>
|
||
<text class="modern-tag tag-delivery">{{ item.deliveryText }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="price-wrap">
|
||
<text class="currency">¥</text>
|
||
<text class="amount">{{ item.payAmountText }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="info-island">
|
||
<view
|
||
class="island-row"
|
||
v-if="item.patientName !== '-' || item.userNickname !== '-'"
|
||
@click.stop="openPatient(item)"
|
||
>
|
||
<text class="island-label">就诊人</text>
|
||
<text class="island-value link">{{ item.patientName !== '-' ? item.patientName : item.userNickname }}</text>
|
||
</view>
|
||
<view class="island-row">
|
||
<text class="island-label">收件人</text>
|
||
<text class="island-value">
|
||
{{ item.receiverName }}
|
||
<text class="muted" v-if="item.receiverMobile"> · {{ item.receiverMobile }}</text>
|
||
</text>
|
||
</view>
|
||
<view class="island-row" v-if="item.storeName !== '-'">
|
||
<text class="island-label">开方诊所</text>
|
||
<text class="island-value">{{ item.storeName }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="card-foot">
|
||
<text class="time">{{ item.createdAt }}</text>
|
||
<view class="actions">
|
||
<view
|
||
v-if="item.canViewPrescription"
|
||
class="btn-ghost"
|
||
@click.stop="openPrescription(item.pId)"
|
||
>
|
||
查看处方
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="!loading && !list.length" class="empty-state">
|
||
<text>暂无订单记录</text>
|
||
</view>
|
||
</block>
|
||
<view v-else class="rx-swiper-placeholder"></view>
|
||
</scroll-view>
|
||
</swiper-item>
|
||
</swiper>
|
||
</view>
|
||
</clinic-page-layout>
|
||
<prescription-detail-popup ref="prescriptionPopup" />
|
||
<user-patient-detail
|
||
v-if="patientDetailVisible"
|
||
:visible="patientDetailVisible"
|
||
:up-id="patientDetailUpId"
|
||
:patient-name="patientDetailName"
|
||
@close="patientDetailVisible = false"
|
||
/>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import ClinicPageLayout from '@/subPackages/sub_clinic_admin/components/clinic-page-layout.vue'
|
||
import CollapsibleFilterPanel from '@/subPackages/sub_clinic_admin/components/CollapsibleFilterPanel.vue'
|
||
import ListSkeleton from '@/subPackages/sub_business_shared/components/ListSkeleton.vue'
|
||
import PrescriptionDetailPopup from './components/PrescriptionDetailPopup.vue'
|
||
import UserPatientDetail from '@/subPackages/sub_business_shared/components/UserPatientDetail.vue'
|
||
import {
|
||
getOrderList,
|
||
getOrderStatusOption,
|
||
getOrderSaleAmount,
|
||
getOrderStatusCount,
|
||
} from '@/api/clinicAdmin.js'
|
||
import { toOrderCardRow } from '@/subPackages/sub_clinic_admin/common/display.js'
|
||
import { formatMoney } from '@/subPackages/sub_clinic_admin/common/format.js'
|
||
import {
|
||
buildOrderListParams,
|
||
buildOrderSaleAmountParams,
|
||
buildOrderStatusCountParams,
|
||
} from '@/subPackages/sub_clinic_admin/common/orderParams.js'
|
||
import {
|
||
loadOrderFilter,
|
||
saveOrderFilter,
|
||
clearOrderFilter,
|
||
defaultOrderFilter,
|
||
} from '@/subPackages/sub_clinic_admin/common/filterCache.js'
|
||
import { defaultTodayDate } from '@/subPackages/sub_clinic_admin/common/reconciliationParams.js'
|
||
|
||
const DELIVERY_OPTIONS = [
|
||
{ label: '全部', value: '' },
|
||
{ label: '快递到家', value: 0 },
|
||
{ label: '诊所自提', value: 1 },
|
||
]
|
||
const PRESCRIPTION_TYPE_OPTIONS = [
|
||
{ label: '全部', value: '' },
|
||
{ label: '中药', value: 1 },
|
||
{ label: '西药', value: 2 },
|
||
{ label: '中成药', value: 3 },
|
||
{ label: '产品服务包', value: 5 },
|
||
]
|
||
|
||
export default {
|
||
components: {
|
||
ClinicPageLayout,
|
||
CollapsibleFilterPanel,
|
||
ListSkeleton,
|
||
PrescriptionDetailPopup,
|
||
UserPatientDetail,
|
||
},
|
||
data() {
|
||
return {
|
||
list: [],
|
||
page: 1,
|
||
pageSize: 15,
|
||
loading: false,
|
||
hasMore: true,
|
||
isRefreshing: false,
|
||
tabChanging: false,
|
||
orderNo: '',
|
||
statusOptions: [{ label: '全部', value: '', count: 0 }],
|
||
statusIndex: 0,
|
||
deliveryIndex: 0,
|
||
prescriptionTypeIndex: 0,
|
||
dateStart: '',
|
||
dateEnd: '',
|
||
statItems: [],
|
||
navTopOffset: 0,
|
||
patientDetailVisible: false,
|
||
patientDetailUpId: 0,
|
||
patientDetailName: '',
|
||
}
|
||
},
|
||
computed: {
|
||
statusTabsList() {
|
||
return (this.statusOptions || []).map((s) => {
|
||
const count = Number(s.count) > 0 ? Number(s.count) : 0
|
||
return {
|
||
name: s.label || s.name || '全部',
|
||
count,
|
||
}
|
||
}) || []
|
||
},
|
||
deliveryLabels() {
|
||
return DELIVERY_OPTIONS.map(o => o.label)
|
||
},
|
||
prescriptionTypeLabels() {
|
||
return PRESCRIPTION_TYPE_OPTIONS.map(o => o.label)
|
||
},
|
||
},
|
||
created() {
|
||
// 仅用于 page-flex 高度 calc;layout 已 paddingTop,勿再绑到 header 的 relative top
|
||
const sys = uni.getSystemInfoSync()
|
||
const statusBarHeight = this.$statusBarHeight || sys.statusBarHeight || 0
|
||
const navbarHeight = this.$navbarHeight || 44
|
||
this.navTopOffset = statusBarHeight + navbarHeight
|
||
},
|
||
onLoad() {
|
||
this.applyOrderFilter(loadOrderFilter())
|
||
getOrderStatusOption().then(w => {
|
||
const opts = (w.data && (w.data.items || w.data)) || []
|
||
if (Array.isArray(opts) && opts.length) {
|
||
this.statusOptions = [{ label: '全部', value: '', count: 0 }].concat(opts.map(o => ({
|
||
label: o.label || o.name,
|
||
value: o.value != null ? o.value : o.id,
|
||
count: 0,
|
||
})))
|
||
if (this.statusIndex >= this.statusOptions.length) this.statusIndex = 0
|
||
}
|
||
this.loadStatusCount()
|
||
})
|
||
this.checkDateEndAndReload()
|
||
},
|
||
onHide() {
|
||
this.closePrescriptionPopup()
|
||
},
|
||
onUnload() {
|
||
this.closePrescriptionPopup()
|
||
},
|
||
methods: {
|
||
closePrescriptionPopup() {
|
||
const pop = this.$refs.prescriptionPopup
|
||
if (pop && typeof pop.onClose === 'function') {
|
||
pop.onClose()
|
||
}
|
||
},
|
||
applyOrderFilter(f) {
|
||
this.orderNo = f.orderNo
|
||
this.statusIndex = f.statusIndex
|
||
this.deliveryIndex = f.deliveryIndex
|
||
this.prescriptionTypeIndex = f.prescriptionTypeIndex
|
||
this.dateStart = f.dateStart
|
||
this.dateEnd = f.dateEnd
|
||
},
|
||
persistOrderFilter() {
|
||
saveOrderFilter({
|
||
orderNo: this.orderNo,
|
||
statusIndex: this.statusIndex,
|
||
deliveryIndex: this.deliveryIndex,
|
||
prescriptionTypeIndex: this.prescriptionTypeIndex,
|
||
dateStart: this.dateStart,
|
||
dateEnd: this.dateEnd,
|
||
})
|
||
},
|
||
resetFilter() {
|
||
this.applyOrderFilter(defaultOrderFilter())
|
||
clearOrderFilter()
|
||
this.reload()
|
||
},
|
||
checkDateEndAndReload() {
|
||
const today = defaultTodayDate()
|
||
if (this.dateEnd && this.dateEnd !== today) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '筛选结束日期不是今天,是否更新到今天?',
|
||
success: (r) => {
|
||
if (r.confirm) {
|
||
this.dateEnd = today
|
||
this.persistOrderFilter()
|
||
}
|
||
this.reload()
|
||
},
|
||
})
|
||
return
|
||
}
|
||
this.reload()
|
||
},
|
||
filterValues() {
|
||
const st = this.statusOptions[this.statusIndex]
|
||
const del = DELIVERY_OPTIONS[this.deliveryIndex]
|
||
const pt = PRESCRIPTION_TYPE_OPTIONS[this.prescriptionTypeIndex]
|
||
return {
|
||
orderNo: this.orderNo.trim(),
|
||
status: st && st.value !== '' && st.value != null ? st.value : undefined,
|
||
deliveryMethod: del.value !== '' ? del.value : undefined,
|
||
prescriptionType: pt.value !== '' ? pt.value : undefined,
|
||
dateStart: this.dateStart,
|
||
dateEnd: this.dateEnd,
|
||
}
|
||
},
|
||
reload() {
|
||
this.persistOrderFilter()
|
||
this.page = 1
|
||
this.hasMore = true
|
||
this.load(1, false)
|
||
this.loadSaleAmount()
|
||
this.loadStatusCount()
|
||
},
|
||
loadSaleAmount() {
|
||
const params = buildOrderSaleAmountParams(this.filterValues())
|
||
getOrderSaleAmount(params).then(w => {
|
||
if (!w.ok || !w.data) {
|
||
this.statItems = []
|
||
return
|
||
}
|
||
const d = w.data
|
||
this.statItems = [
|
||
{ key: 'total', label: '销售金额', value: formatMoney(d.total) },
|
||
{ key: 'income', label: '我的收益', value: formatMoney(d.income) },
|
||
]
|
||
})
|
||
},
|
||
loadStatusCount() {
|
||
const params = buildOrderStatusCountParams(this.filterValues())
|
||
getOrderStatusCount(params).then((w) => {
|
||
if (!w.ok || !w.data) return
|
||
const total = Number(w.data.total || 0)
|
||
const map = {}
|
||
const items = w.data.items || []
|
||
items.forEach((it) => {
|
||
map[Number(it.id)] = Number(it.count || 0)
|
||
})
|
||
this.statusOptions = (this.statusOptions || []).map((s, i) => {
|
||
const isAll = i === 0 || s.value === '' || s.value == null
|
||
return {
|
||
...s,
|
||
count: isAll ? total : (map[Number(s.value)] || 0),
|
||
}
|
||
})
|
||
})
|
||
},
|
||
load(page, append) {
|
||
this.loading = true
|
||
const pageSize = this.pageSize || 15
|
||
const params = buildOrderListParams({
|
||
page,
|
||
pageSize,
|
||
...this.filterValues(),
|
||
})
|
||
getOrderList(params).then(w => {
|
||
// 只写入卡片瘦字段,避免把处方 content / 明细整包 setData
|
||
const rawItems = (w.data && w.data.items) || []
|
||
const items = rawItems.map((raw) => toOrderCardRow(raw))
|
||
this.list = append ? this.list.concat(items) : items
|
||
this.page = page
|
||
this.hasMore = rawItems.length >= pageSize
|
||
}).finally(() => {
|
||
this.loading = false
|
||
if (this.isRefreshing) this.isRefreshing = false
|
||
})
|
||
},
|
||
onRefresherRefresh() {
|
||
this.isRefreshing = true
|
||
this.reload()
|
||
},
|
||
onScrollToLower() {
|
||
if (this.loading || !this.hasMore) return
|
||
this.load(this.page + 1, true)
|
||
},
|
||
onStatusTabChange(index) {
|
||
if (this.tabChanging) return
|
||
this.tabChanging = true
|
||
const idx = typeof index === 'object' ? Number(index.index != null ? index.index : index) : Number(index)
|
||
if (!Number.isNaN(idx) && idx !== this.statusIndex) {
|
||
this.statusIndex = idx
|
||
this.reload()
|
||
}
|
||
this.$nextTick(() => {
|
||
this.tabChanging = false
|
||
})
|
||
},
|
||
onStatusSwiperChange(e) {
|
||
if (this.tabChanging) return
|
||
this.tabChanging = true
|
||
const idx = Number((e.detail && e.detail.current) || 0)
|
||
if (idx !== this.statusIndex) {
|
||
this.statusIndex = idx
|
||
this.reload()
|
||
}
|
||
this.$nextTick(() => {
|
||
this.tabChanging = false
|
||
})
|
||
},
|
||
onDelivery(e) {
|
||
this.deliveryIndex = Number(e.detail.value)
|
||
},
|
||
onPrescriptionType(e) {
|
||
this.prescriptionTypeIndex = Number(e.detail.value)
|
||
},
|
||
onStart(e) { this.dateStart = e.detail.value },
|
||
onEnd(e) { this.dateEnd = e.detail.value },
|
||
goDetail(item) {
|
||
uni.navigateTo({ url: '/subPackages/sub_clinic_admin/order/detail?id=' + item.id })
|
||
},
|
||
openPrescription(pId) {
|
||
if (!pId) return
|
||
this.$refs.prescriptionPopup.open(pId)
|
||
},
|
||
openPatient(item) {
|
||
const upId = Number(item.upId || 0)
|
||
if (!upId) {
|
||
uni.showToast({ title: '缺少就诊人信息', icon: 'none' })
|
||
return
|
||
}
|
||
this.patientDetailUpId = upId
|
||
this.patientDetailName = item.patientName !== '-' ? item.patientName : ''
|
||
this.patientDetailVisible = true
|
||
},
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
$theme-primary: #6acdbb;
|
||
$color-bg-base: #F2F4F7; /* Apple 风格的冷调高级灰底色 */
|
||
$color-text-main: #1D2129;
|
||
$color-text-body: #4E5969;
|
||
$color-text-muted: #86909C;
|
||
|
||
.order-list-container {
|
||
background-color: $color-bg-base;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
.page-flex {
|
||
/* height 由行内 calc(100vh - navTopOffset) 控制,避免再叠 layout 的 paddingTop */
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
min-height: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
.rx-flex-fixed {
|
||
flex-shrink: 0;
|
||
}
|
||
.order-swiper {
|
||
flex: 1;
|
||
height: 0;
|
||
min-height: 0;
|
||
width: 100%;
|
||
}
|
||
.order-scroll {
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
}
|
||
.rx-swiper-placeholder {
|
||
min-height: 200rpx;
|
||
}
|
||
|
||
/* 筛选区 */
|
||
.tabs-wrap {
|
||
background: #fff;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
overflow: hidden;
|
||
}
|
||
.quick-filter {
|
||
background: #fff;
|
||
padding: 24rpx;
|
||
margin-bottom: 16rpx;
|
||
border-radius: 0 0 16rpx 16rpx;
|
||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
.filter-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.filter-label {
|
||
font-size: 28rpx;
|
||
color: $color-text-body;
|
||
min-width: 140rpx;
|
||
}
|
||
.filter-input, .filter-picker {
|
||
flex: 1;
|
||
font-size: 28rpx;
|
||
padding: 16rpx 20rpx;
|
||
background: #F7F8FA;
|
||
border-radius: 12rpx;
|
||
color: $color-text-main;
|
||
}
|
||
.date-row { flex-wrap: nowrap; }
|
||
.date-picker { text-align: center; }
|
||
.sep { color: $color-text-muted; margin: 0 8rpx; font-size: 24rpx; }
|
||
.filter-query-btn {
|
||
text-align: center;
|
||
padding: 24rpx;
|
||
background: $theme-primary;
|
||
color: #fff;
|
||
border-radius: 16rpx;
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
margin-top: 32rpx;
|
||
box-shadow: 0 8rpx 24rpx rgba(106, 205, 187, 0.2);
|
||
}
|
||
|
||
/* 统计卡片 */
|
||
.stats-scroll {
|
||
margin-bottom: 20rpx;
|
||
white-space: nowrap;
|
||
}
|
||
.stats {
|
||
display: inline-flex;
|
||
gap: 20rpx;
|
||
padding: 16rpx 32rpx;
|
||
}
|
||
.stat-card {
|
||
display: inline-block;
|
||
width: 320rpx;
|
||
background: #fff;
|
||
padding: 32rpx;
|
||
border-radius: 24rpx;
|
||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.02);
|
||
vertical-align: top;
|
||
white-space: normal;
|
||
}
|
||
.stat-label {
|
||
display: block;
|
||
font-size: 26rpx;
|
||
color: $color-text-muted;
|
||
}
|
||
.stat-value {
|
||
display: block;
|
||
font-size: 42rpx;
|
||
color: $color-text-main;
|
||
font-weight: 700;
|
||
margin-top: 12rpx;
|
||
}
|
||
|
||
/* ================= 核心高级卡片样式 ================= */
|
||
.card-list-wrap {
|
||
//padding: 0 24rpx;
|
||
}
|
||
|
||
.premium-card {
|
||
background: #ffffff;
|
||
border-radius: 32rpx; /* 超大圆角带来前沿视觉享受 */
|
||
margin-bottom: 24rpx;
|
||
padding: 32rpx;
|
||
border: 1rpx solid #E5E6EB;
|
||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.015); /* 极其克制的阴影 */
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.card-hover {
|
||
transform: scale(0.98);
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.01);
|
||
background-color: #FAFAFA;
|
||
}
|
||
|
||
/* 卡片头部 */
|
||
.card-head {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 28rpx;
|
||
}
|
||
|
||
.order-id {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.id-icon {
|
||
font-size: 20rpx;
|
||
color: #fff;
|
||
background-color: #C9CDD4;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 6rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.id-text {
|
||
font-size: 26rpx;
|
||
color: $color-text-muted;
|
||
font-family: SF Pro Text, monospace, sans-serif;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
|
||
/* 状态标签配色优化 */
|
||
.status-badge {
|
||
font-size: 26rpx;
|
||
font-weight: 600;
|
||
color: $theme-primary;
|
||
}
|
||
/* 可根据实际的状态值(status)配置置灰 */
|
||
.status-done { color: $color-text-muted; font-weight: 400; }
|
||
.status-cancel { color: #F53F3F; }
|
||
|
||
/* 核心内容区 */
|
||
.card-body {
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.main-info {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
margin-bottom: 24rpx;
|
||
gap: 20rpx;
|
||
}
|
||
|
||
.title-wrap {
|
||
flex: 1;
|
||
}
|
||
|
||
.goods-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: $color-text-main;
|
||
line-height: 1.4;
|
||
margin-bottom: 16rpx;
|
||
/* 多行截断 */
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.goods-tags {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 12rpx;
|
||
}
|
||
|
||
.modern-tag {
|
||
font-size: 22rpx;
|
||
padding: 4rpx 14rpx;
|
||
border-radius: 8rpx;
|
||
font-weight: 500;
|
||
}
|
||
.tag-type { background: #FFF3E8; color: #FF7D00; } /* 柔和爱马仕橙 */
|
||
.tag-delivery { background: #E8F3FF; color: #165DFF; } /* 科技蓝 */
|
||
|
||
.price-wrap {
|
||
display: flex;
|
||
align-items: baseline;
|
||
color: $color-text-main;
|
||
}
|
||
|
||
.currency {
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
margin-right: 4rpx;
|
||
}
|
||
|
||
.amount {
|
||
font-size: 44rpx;
|
||
font-weight: 700;
|
||
font-family: DIN Alternate, SF Pro Display, sans-serif;
|
||
}
|
||
|
||
/* 高级信息岛 (Inset Info Box) */
|
||
.info-island {
|
||
background-color: #F7F8FA;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx;
|
||
}
|
||
|
||
.island-row {
|
||
display: flex;
|
||
font-size: 24rpx;
|
||
line-height: 1.6;
|
||
margin-bottom: 12rpx;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
|
||
.island-label {
|
||
color: $color-text-muted;
|
||
width: 110rpx;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.island-value {
|
||
color: $color-text-body;
|
||
flex: 1;
|
||
word-break: break-all;
|
||
&.link {
|
||
color: $theme-primary;
|
||
}
|
||
}
|
||
|
||
.muted {
|
||
color: $color-text-muted;
|
||
}
|
||
}
|
||
|
||
/* 卡片底部 */
|
||
.card-foot {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
border-top: 1rpx solid #F2F3F5;
|
||
padding-top: 24rpx;
|
||
}
|
||
|
||
.time {
|
||
font-size: 24rpx;
|
||
color: $color-text-muted;
|
||
}
|
||
|
||
.btn-ghost {
|
||
font-size: 26rpx;
|
||
color: $theme-primary;
|
||
background: rgba(106, 205, 187, 0.08);
|
||
padding: 10rpx 32rpx;
|
||
border-radius: 30rpx;
|
||
font-weight: 500;
|
||
transition: background-color 0.2s;
|
||
|
||
&:active {
|
||
background: rgba(106, 205, 187, 0.15);
|
||
}
|
||
}
|
||
|
||
.empty-state {
|
||
text-align: center;
|
||
color: $color-text-muted;
|
||
padding: 120rpx 0;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
|
||
/* ================= 顶部筛选区(flex 布局下不再用 sticky,由 page-flex 固定) ================= */
|
||
.native-sticky-header {
|
||
position: relative;
|
||
z-index: 100;
|
||
background-color: $color-bg-base;
|
||
}
|
||
|
||
.header-solid-bg {
|
||
padding: 16rpx 24rpx 16rpx;
|
||
}
|
||
|
||
/* 重新设计的紧凑型查询按钮 */
|
||
.btn-query {
|
||
flex-shrink: 0;
|
||
background: $theme-primary;
|
||
color: #fff;
|
||
padding: 0 32rpx;
|
||
height: 60rpx;
|
||
line-height: 60rpx;
|
||
border-radius: 30rpx; /* 胶囊圆角 */
|
||
font-size: 26rpx;
|
||
font-weight: 500;
|
||
box-shadow: 0 4rpx 12rpx rgba(106, 205, 187, 0.3);
|
||
transition: opacity 0.2s;
|
||
&:active { opacity: 0.8; }
|
||
}
|
||
</style> |