Files
medical-mall/pages/mall/admin/order/cashier-order/index.uvue
2026-02-06 16:18:04 +08:00

395 lines
11 KiB
Plaintext
Raw 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="admin-cashier-order">
<view class="content-body">
<!-- 顶部过滤栏 -->
<view class="filter-card border-shadow">
<view class="filter-item">
<text class="label-txt">创建时间:</text>
<view class="date-picker-mock">
<text class="date-txt">开始日期</text>
<text class="date-split">-</text>
<text class="date-txt">结束日期</text>
<text class="calendar-ic">📅</text>
</view>
</view>
<view class="filter-item">
<text class="label-txt">订单号:</text>
<input class="search-input" placeholder="请输入订单号" v-model="orderId" />
</view>
<view class="filter-item">
<text class="label-txt">用户名:</text>
<input class="search-input" placeholder="请输入用户名" v-model="username" />
</view>
<view class="btn-query" @click="handleQuery">
<text class="query-txt">查询</text>
</view>
</view>
<!-- 主要内容区域 -->
<view class="table-card border-shadow">
<view class="card-header">
<view class="btn-primary-blue" @click="openQrModal">
<text class="btn-txt">查看收款二维码</text>
</view>
</view>
<!-- 数据表格 -->
<view class="table-container">
<view class="table-header-row">
<view class="th" style="flex: 1.5;">订单号</view>
<view class="th" style="flex: 1.2;">用户信息</view>
<view class="th" style="width: 150px;">实际支付</view>
<view class="th" style="width: 150px;">优惠价格</view>
<view class="th" style="width: 200px;">支付时间</view>
</view>
<view class="table-body">
<view v-for="(item, index) in orderList" :key="index" class="table-row">
<view class="td" style="flex: 1.5;"><text class="td-txt">{{ item.orderId }}</text></view>
<view class="td" style="flex: 1.2;"><text class="td-txt">{{ item.userInfo }}</text></view>
<view class="td" style="width: 150px;"><text class="td-txt">{{ item.payPrice.toFixed(2) }}</text></view>
<view class="td" style="width: 150px;"><text class="td-txt">{{ item.discountPrice.toFixed(2) }}</text></view>
<view class="td" style="width: 200px;"><text class="td-txt">{{ item.payTime }}</text></view>
</view>
</view>
</view>
<!-- 分页 -->
<view class="pagination-footer">
<view class="page-total">
<text class="total-txt">共 {{ total }} 条</text>
</view>
<view class="page-select">
<text class="page-val">15条/页 ▼</text>
</view>
<view class="page-btns">
<text class="p-btn disabled"><</text>
<text class="p-btn active">1</text>
<text class="p-btn">></text>
</view>
<view class="page-jump">
<text class="jump-txt">前往</text>
<input class="jump-input" placeholder="1" />
<text class="jump-txt">页</text>
</view>
</view>
</view>
</view>
<!-- 收款码弹窗 -->
<view v-if="showQrModal" :class="['modal-mask', isClosing ? 'mask-fade-out' : '']" @click="closeQrModal">
<view :class="['modal-content', isClosing ? 'scale-out' : 'scale-in']" @click.stop="">
<view class="modal-header">
<text class="modal-title">收款码</text>
<text class="close-btn" @click="closeQrModal">×</text>
</view>
<view class="modal-body">
<view class="qr-item">
<image class="qr-img" src="/static/logo.png" mode="aspectFit"></image>
<text class="qr-label">公众号二维码</text>
</view>
<view class="qr-item">
<view class="qr-placeholder-mp">
<image class="mp-qr-mock" src="/static/logo.png" mode="aspectFit"></image>
</view>
<text class="qr-label">小程序二维码</text>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
interface CashierOrder {
orderId: string
userInfo: string
payPrice: number
discountPrice: number
payTime: string
}
const orderId = ref('')
const username = ref('')
const total = ref(12)
const orderList = ref<CashierOrder[]>([
{ orderId: 'hy536720518414336000', userInfo: '东流 | 76058', payPrice: 1.00, discountPrice: 0.00, payTime: '2026-01-21 01:35:43' },
{ orderId: 'hy529509398574268416', userInfo: '半个栗子 | 81997', payPrice: 10000.00, discountPrice: 0.00, payTime: '2026-01-01 04:01:18' },
{ orderId: 'hy511477797936431104', userInfo: '莉莉 | 80736', payPrice: 10.00, discountPrice: 0.00, payTime: '2025-11-12 09:50:09' },
{ orderId: 'hy507152261823070208', userInfo: '. . . | 71546', payPrice: 0.10, discountPrice: 0.00, payTime: '2025-10-31 11:22:01' },
{ orderId: 'hy506826113427701760', userInfo: 'A梁 | 80363', payPrice: 0.10, discountPrice: 0.00, payTime: '2025-10-30 13:46:01' },
{ orderId: 'hy504707908026499072', userInfo: '前前前前 | 80225', payPrice: 2252.00, discountPrice: 0.00, payTime: '2025-10-24 17:29:02' },
{ orderId: 'hy494505602832138240', userInfo: '张总说 | 40028', payPrice: 1.00, discountPrice: 0.00, payTime: '2025-09-26 13:48:43' },
{ orderId: 'hy490819329198129152', userInfo: '虚伪 | 79027', payPrice: 10.00, discountPrice: 0.00, payTime: '2025-09-16 09:40:47' }
])
const showQrModal = ref(false)
const isClosing = ref(false)
const handleQuery = () => { console.log('Querying...') }
const openQrModal = () => {
showQrModal.value = true
isClosing.value = false
}
const closeQrModal = () => {
isClosing.value = true
setTimeout(() => {
showQrModal.value = false
isClosing.value = false
}, 300)
}
</script>
<style scoped lang="scss">
.admin-cashier-order {
background-color: #f0f2f5;
min-height: 100vh;
padding: 24px;
}
.border-shadow {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
.content-body {
display: flex;
flex-direction: column;
gap: 20px;
}
/* 过滤栏 */
.filter-card {
padding: 24px;
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
gap: 24px;
}
.filter-item {
display: flex;
flex-direction: row;
align-items: center;
gap: 8px;
}
.label-txt { font-size: 14px; color: #606266; }
.date-picker-mock {
width: 240px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 12px;
gap: 8px;
}
.date-txt { font-size: 14px; color: #c0c4cc; }
.date-split { color: #dcdfe6; }
.calendar-ic { font-size: 14px; color: #c0c4cc; margin-left: auto; }
.search-input {
width: 220px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
}
.btn-query {
background-color: #2d8cf0;
padding: 0 24px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
}
.query-txt { color: #fff; font-size: 14px; }
/* 表格区域 */
.table-card {
background-color: #fff;
display: flex;
flex-direction: column;
}
.card-header { padding: 20px; }
.btn-primary-blue {
background-color: #2d8cf0;
padding: 8px 16px;
border-radius: 4px;
display: inline-flex;
cursor: pointer;
}
.btn-txt { color: #fff; font-size: 14px; }
.table-container {
display: flex;
flex-direction: column;
}
.table-header-row {
display: flex;
flex-direction: row;
background-color: #f8f8f9;
border-bottom: 1px solid #e8eaec;
}
.th {
padding: 15px 10px;
font-size: 14px;
color: #515a6e;
font-weight: bold;
}
.table-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #e8eaec;
}
.td {
padding: 15px 10px;
display: flex;
align-items: center;
}
.td-txt { font-size: 14px; color: #515a6e; }
/* 分页 */
.pagination-footer {
padding: 24px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
gap: 12px;
}
.total-txt { font-size: 14px; color: #606266; }
.page-val { font-size: 14px; color: #606266; border: 1px solid #dcdfe6; padding: 4px 10px; border-radius: 4px; }
.page-btns { display: flex; flex-direction: row; gap: 8px; }
.p-btn {
width: 32px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.p-btn.active { background-color: #2d8cf0; border-color: #2d8cf0; color: #fff; }
.p-btn.disabled { color: #c0c4cc; background-color: #f5f7fa; }
.page-jump { display: flex; flex-direction: row; align-items: center; gap: 8px; }
.jump-txt { font-size: 14px; color: #606266; }
.jump-input { width: 40px; height: 32px; border: 1px solid #dcdfe6; text-align: center; border-radius: 4px; font-size: 14px; }
/* Modal 弹窗逻辑 */
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.4);
z-index: 3000;
display: flex;
align-items: center;
justify-content: center;
}
.modal-content {
width: 600px;
background-color: #fff;
border-radius: 8px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.modal-header {
padding: 20px;
border-bottom: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.modal-title { font-size: 16px; font-weight: bold; color: #333; }
.close-btn { font-size: 24px; color: #999; cursor: pointer; line-height: 1; }
.modal-body {
padding: 40px;
display: flex;
flex-direction: row;
justify-content: center;
gap: 60px;
}
.qr-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.qr-img {
width: 160px;
height: 160px;
border: 1px solid #f0f0f0;
}
.qr-placeholder-mp {
width: 160px;
height: 160px;
border: 1px solid #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 80px;
overflow: hidden;
}
.mp-qr-mock { width: 140px; height: 140px; border-radius: 70px; }
.qr-label { font-size: 14px; color: #666; }
/* 动画 */
.scale-in { animation: scaleIn 0.3s ease-out forwards; }
@keyframes scaleIn {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
.scale-out { animation: scaleOut 0.3s ease-in forwards; }
@keyframes scaleOut {
from { opacity: 1; transform: scale(1); }
to { opacity: 0; transform: scale(0.9); }
}
.mask-fade-out { animation: fadeOut 0.3s ease-in forwards; }
@keyframes fadeOut {
from { background-color: rgba(0, 0, 0, 0.4); }
to { background-color: rgba(0, 0, 0, 0); }
}
</style>