fix:将侧边栏兼容移动端

This commit is contained in:
2026-01-20 17:54:45 +08:00
parent 0b57581799
commit e3e70114fb
18 changed files with 3059 additions and 316 deletions
+151 -77
View File
@@ -186,36 +186,64 @@
<el-input v-model="orderForm.table" placeholder="请输入所属表" />
</el-form-item>
<el-form-item label="用户ID" prop="user_id">
<div class="selector-field">
<div class="selector-info" v-if="selectedUserInfo">
<el-tag type="primary" effect="plain">
ID: {{ orderForm.user_id }} - {{ selectedUserInfo.user_name }}
</el-tag>
</div>
<div class="selector-actions">
<el-button type="primary" @click="userSelectorVisible = true">
<el-input
v-if="selectedUserInfo"
:model-value="`${selectedUserInfo.user_name} (ID: ${orderForm.user_id})`"
readonly
style="width: 100%"
>
<template #suffix>
<el-icon class="clear-icon" @click="clearUser"><Close /></el-icon>
</template>
<template #append>
<el-button @click="userSelectorVisible = true">
<el-icon><User /></el-icon>
{{ orderForm.user_id ? '更换用户' : '选择用户' }}
</el-button>
<el-button v-if="orderForm.user_id" @click="clearUser">清除</el-button>
</div>
</div>
</template>
</el-input>
<el-input
v-else
placeholder="请选择用户"
readonly
style="width: 100%"
@click="userSelectorVisible = true"
>
<template #append>
<el-button @click="userSelectorVisible = true">
<el-icon><User /></el-icon>
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="商品ID" prop="commodity_id">
<div class="selector-field">
<div class="selector-info" v-if="selectedProductInfo">
<el-tag type="success" effect="plain">
ID: {{ orderForm.commodity_id }} - {{ selectedProductInfo.name }}
</el-tag>
</div>
<div class="selector-actions">
<el-button type="success" @click="productSelectorVisible = true">
<el-input
v-if="selectedProductInfo"
:model-value="`${selectedProductInfo.name} (ID: ${orderForm.commodity_id})`"
readonly
style="width: 100%"
>
<template #suffix>
<el-icon class="clear-icon" @click="clearProduct"><Close /></el-icon>
</template>
<template #append>
<el-button @click="productSelectorVisible = true">
<el-icon><ShoppingCart /></el-icon>
{{ orderForm.commodity_id ? '更换商品' : '选择商品' }}
</el-button>
<el-button v-if="orderForm.commodity_id" @click="clearProduct">清除</el-button>
</div>
</div>
</template>
</el-input>
<el-input
v-else
placeholder="请选择商品"
readonly
style="width: 100%"
@click="productSelectorVisible = true"
>
<template #append>
<el-button @click="productSelectorVisible = true">
<el-icon><ShoppingCart /></el-icon>
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="购买数量" prop="pay_num">
<el-input-number v-model="orderForm.pay_num" :min="1" placeholder="请输入数量" style="width: 100%" />
@@ -227,39 +255,74 @@
<el-input-number v-model="orderForm.renew_price" :min="0" placeholder="请输入续费价格(分)" style="width: 100%" />
</el-form-item>
<el-form-item label="过期时间" prop="expire_time">
<el-input-number v-model="orderForm.expire_time" :min="0" placeholder="请输入过期时间(时间戳)" style="width: 100%" />
<el-date-picker
v-model="orderForm.expire_time"
type="datetime"
placeholder="请选择过期时间"
format="YYYY-MM-DD HH:mm:ss"
value-format="x"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="优惠码ID" prop="discount_code_id">
<div class="selector-field">
<div class="selector-info" v-if="selectedDiscountCodeInfo">
<el-tag type="warning" effect="plain">
ID: {{ orderForm.discount_code_id }} - {{ selectedDiscountCodeInfo.name || selectedDiscountCodeInfo.code }}
</el-tag>
</div>
<div class="selector-actions">
<el-button type="warning" @click="discountCodeSelectorVisible = true">
<el-input
v-if="selectedDiscountCodeInfo"
:model-value="`${selectedDiscountCodeInfo.name || selectedDiscountCodeInfo.code} (ID: ${orderForm.discount_code_id})`"
readonly
style="width: 100%"
>
<template #suffix>
<el-icon class="clear-icon" @click="clearDiscountCode"><Close /></el-icon>
</template>
<template #append>
<el-button @click="discountCodeSelectorVisible = true">
<el-icon><Ticket /></el-icon>
{{ orderForm.discount_code_id ? '更换优惠码' : '选择优惠码' }}
</el-button>
<el-button v-if="orderForm.discount_code_id" @click="clearDiscountCode">清除</el-button>
</div>
</div>
</template>
</el-input>
<el-input
v-else
placeholder="请选择优惠码(可选)"
readonly
style="width: 100%"
@click="discountCodeSelectorVisible = true"
>
<template #append>
<el-button @click="discountCodeSelectorVisible = true">
<el-icon><Ticket /></el-icon>
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="代金券ID" prop="coupon_id">
<div class="selector-field">
<div class="selector-info" v-if="selectedVoucherInfo">
<el-tag type="danger" effect="plain">
ID: {{ orderForm.coupon_id }} - {{ selectedVoucherInfo.name || selectedVoucherInfo.code }}
</el-tag>
</div>
<div class="selector-actions">
<el-button type="danger" @click="voucherSelectorVisible = true">
<el-input
v-if="selectedVoucherInfo"
:model-value="`${selectedVoucherInfo.name || selectedVoucherInfo.code} (ID: ${orderForm.coupon_id})`"
readonly
style="width: 100%"
>
<template #suffix>
<el-icon class="clear-icon" @click="clearVoucher"><Close /></el-icon>
</template>
<template #append>
<el-button @click="voucherSelectorVisible = true">
<el-icon><Money /></el-icon>
{{ orderForm.coupon_id ? '更换代金券' : '选择代金券' }}
</el-button>
<el-button v-if="orderForm.coupon_id" @click="clearVoucher">清除</el-button>
</div>
</div>
</template>
</el-input>
<el-input
v-else
placeholder="请选择代金券(可选)"
readonly
style="width: 100%"
@click="voucherSelectorVisible = true"
>
<template #append>
<el-button @click="voucherSelectorVisible = true">
<el-icon><Money /></el-icon>
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="订单状态" prop="state">
<el-radio-group v-model="orderForm.state">
@@ -319,12 +382,13 @@
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Delete, Search, Download, Refresh, User, ShoppingCart, Ticket, Money } from '@element-plus/icons-vue'
import { Plus, Delete, Search, Download, Refresh, User, ShoppingCart, Ticket, Money, Close } from '@element-plus/icons-vue'
import { getOrderList, getOrderDetail, createOrder, updateOrder, deleteOrder } from '@/api/admin/order'
import UserListSelector from '@/components/admin/UserListSelector.vue'
import ProductSelector from '@/components/admin/ProductSelector.vue'
import DiscountCodeSelector from '@/components/admin/DiscountCodeSelector.vue'
import VoucherSelector from '@/components/admin/VoucherSelector.vue'
import { isoToMilliseconds, timeToTimestamp, formatDate as formatDateTool } from '@/utils/tool'
// 查询参数
const queryParams = reactive({
@@ -415,7 +479,17 @@ const fetchOrderList = async () => {
const res = await getOrderList(params)
console.log('订单列表数据:', res.data)
if (res.data.code === 200) {
orderList.value = res.data.data.list || []
// 处理时间数据:将ISO格式转换为毫秒级时间戳(用于时间选择器)
const list = (res.data.data.list || []).map(item => {
if (item.expireTime) {
// 保存原始时间用于显示
item._originalExpireTime = item.expireTime
// 转换为毫秒级时间戳用于时间选择器
item._expireTimeMs = isoToMilliseconds(item.expireTime)
}
return item
})
orderList.value = list
total.value = res.data.data.all_count || 0
}
} catch (error) {
@@ -426,16 +500,9 @@ const fetchOrderList = async () => {
}
}
// 格式化日期
// 格式化日期 - 使用工具函数
const formatDate = (dateStr) => {
if (!dateStr) return '-'
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}`
return formatDateTool(dateStr)
}
// 获取订单状态类型
@@ -536,6 +603,14 @@ const handleEdit = (row) => {
dialogVisible.value = true
clearAllSelections()
// 处理过期时间:优先使用已转换的时间戳,否则转换ISO格式
let expireTimeMs = null
if (row._expireTimeMs !== undefined) {
expireTimeMs = row._expireTimeMs
} else if (row.expireTime) {
expireTimeMs = isoToMilliseconds(row.expireTime)
}
Object.assign(orderForm, {
order_id: row.id,
name: row.name,
@@ -545,7 +620,7 @@ const handleEdit = (row) => {
pay_num: row.payNum,
price: row.price,
renew_price: row.renewPrice,
expire_time: row.expireTime ? new Date(row.expireTime).getTime() / 1000 : 0,
expire_time: expireTimeMs,
discount_code_id: 0, // 从详情接口获取
coupon_id: 0, // 从详情接口获取
state: row.state,
@@ -604,6 +679,13 @@ const submitForm = () => {
orderFormRef.value?.validate(async (valid) => {
if (valid) {
try {
// 处理过期时间:将毫秒级时间戳转换为秒级时间戳
let expireTimeSeconds = 0
if (orderForm.expire_time) {
const timestamp = timeToTimestamp(new Date(orderForm.expire_time))
expireTimeSeconds = timestamp || 0
}
// 准备提交的数据
const submitData = {
name: orderForm.name,
@@ -613,7 +695,7 @@ const submitForm = () => {
pay_num: Number(orderForm.pay_num),
price: Number(orderForm.price),
renew_price: Number(orderForm.renew_price),
expire_time: Number(orderForm.expire_time),
expire_time: expireTimeSeconds,
discount_code_id: Number(orderForm.discount_code_id),
coupon_id: Number(orderForm.coupon_id),
state: Number(orderForm.state),
@@ -865,22 +947,14 @@ onMounted(() => {
100% { background-position: -200% 0; }
}
/* 选择器字段样式 */
.selector-field {
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;
/* 选择器清除图标样式 */
.clear-icon {
cursor: pointer;
color: #909399;
transition: color 0.2s;
}
.selector-info {
display: flex;
align-items: center;
}
.selector-actions {
display: flex;
gap: 8px;
align-items: center;
.clear-icon:hover {
color: #f56c6c;
}
</style>