|
|
@@ -31,47 +31,60 @@
|
|
|
|
|
|
<!-- 产品信息 -->
|
|
|
<div class="product-info">
|
|
|
- <div class="product-name" :title="item.product_name">{{ item.product_name }}</div>
|
|
|
-
|
|
|
- <!-- 套餐信息 -->
|
|
|
- <div class="package-info">
|
|
|
- <el-tag size="small" type="primary" effect="plain">{{ item.package_type_text }}</el-tag>
|
|
|
- <el-tag size="small" type="warning" effect="plain">{{ item.card_type_text }}</el-tag>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 使用情况 -->
|
|
|
- <div class="usage-info">
|
|
|
- <!-- 次卡显示剩余次数 -->
|
|
|
- <div v-if="item.card_type == 1" class="usage-item">
|
|
|
- <el-icon>
|
|
|
- <Tickets />
|
|
|
- </el-icon>
|
|
|
- <span>剩余次数: <strong>{{ item.remaining_times }}</strong></span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 积分卡显示剩余积分 -->
|
|
|
- <div v-if="item.card_type == 2" class="usage-item">
|
|
|
- <el-icon>
|
|
|
- <Coin />
|
|
|
- </el-icon>
|
|
|
- <span>剩余积分: <strong>{{ item.remaining_points }}</strong></span>
|
|
|
+ <div class="product-main">
|
|
|
+ <!-- 左侧:产品基本信息 -->
|
|
|
+ <div class="product-main-left">
|
|
|
+ <div class="product-name" :title="item.product_name">{{ item.product_name }}</div>
|
|
|
+
|
|
|
+ <!-- 套餐信息 -->
|
|
|
+ <div class="package-info">
|
|
|
+ <el-tag size="small" type="primary" effect="plain">{{ item.package_type_text }}</el-tag>
|
|
|
+ <el-tag size="small" type="warning" effect="plain">{{ item.card_type_text }}</el-tag>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 使用情况 -->
|
|
|
+ <div class="usage-info">
|
|
|
+ <!-- 次卡显示剩余次数 -->
|
|
|
+ <div v-if="item.card_type == 1" class="usage-item">
|
|
|
+ <el-icon>
|
|
|
+ <Tickets />
|
|
|
+ </el-icon>
|
|
|
+ <span>剩余次数: <strong>{{ item.remaining_times }}</strong></span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 积分卡显示剩余积分 -->
|
|
|
+ <div v-if="item.card_type == 2" class="usage-item">
|
|
|
+ <el-icon>
|
|
|
+ <Coin />
|
|
|
+ </el-icon>
|
|
|
+ <span>剩余积分: <strong>{{ item.remaining_points }}</strong></span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 日期卡显示到期时间 -->
|
|
|
+ <div v-if="[3, 4, 5, 6, 7].includes(item.card_type)" class="usage-item">
|
|
|
+ <el-icon>
|
|
|
+ <Calendar />
|
|
|
+ </el-icon>
|
|
|
+ <span>{{ item.display_info }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 日期卡显示到期时间 -->
|
|
|
- <div v-if="[3, 4, 5, 6, 7].includes(item.card_type)" class="usage-item">
|
|
|
- <el-icon>
|
|
|
- <Calendar />
|
|
|
- </el-icon>
|
|
|
- <span>{{ item.display_info }}</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 席位信息(企业套餐) -->
|
|
|
- <div v-if="item.package_type == 2 && item.total_seats" class="seats-info">
|
|
|
- <el-progress :percentage="getSeatPercentage(item)" :color="getSeatColor(item)" :stroke-width="6" />
|
|
|
- <div class="seats-text">
|
|
|
- <span>已分配: {{ item.assigned_seats || 0 }}/{{ item.total_seats }}</span>
|
|
|
- <span class="available">可用: {{ item.available_seats || 0 }}</span>
|
|
|
+ <!-- 右侧:席位信息(企业套餐)- 仅日期卡显示(次卡/积分卡不展示“已分配”相关信息) -->
|
|
|
+ <div
|
|
|
+ v-if="item.package_type == 2 && item.total_seats && [3, 4, 5, 6, 7].includes(item.card_type)"
|
|
|
+ class="product-main-right"
|
|
|
+ >
|
|
|
+ <div class="seats-info">
|
|
|
+ <div class="seats-row">
|
|
|
+ <div class="seats-label">席位</div>
|
|
|
+ <div class="seats-value">
|
|
|
+ <span class="seats-number strong">{{ item.assigned_seats || 0 }}</span>
|
|
|
+ <span class="seats-split">/</span>
|
|
|
+ <span class="seats-number">{{ item.total_seats }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -195,20 +208,6 @@ const getStatusClass = (status: number) => {
|
|
|
return classMap[status] || ''
|
|
|
}
|
|
|
|
|
|
-// 计算席位使用百分比
|
|
|
-const getSeatPercentage = (item: ProductItem) => {
|
|
|
- if (!item.total_seats || item.total_seats === 0) return 0
|
|
|
- return Math.round(((item.assigned_seats || 0) / item.total_seats) * 100)
|
|
|
-}
|
|
|
-
|
|
|
-// 获取席位进度条颜色
|
|
|
-const getSeatColor = (item: ProductItem) => {
|
|
|
- const percentage = getSeatPercentage(item)
|
|
|
- if (percentage >= 90) return '#f56c6c'
|
|
|
- if (percentage >= 70) return '#e6a23c'
|
|
|
- return '#67c23a'
|
|
|
-}
|
|
|
-
|
|
|
// 格式化日期
|
|
|
const formatDate = (dateStr: string) => {
|
|
|
if (!dateStr) return ''
|
|
|
@@ -409,6 +408,28 @@ onMounted(() => {
|
|
|
gap: 12px;
|
|
|
}
|
|
|
|
|
|
+ .product-main {
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: flex-end;
|
|
|
+ }
|
|
|
+
|
|
|
+ .product-main-left {
|
|
|
+ flex: 1.3;
|
|
|
+ min-width: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .product-main-right {
|
|
|
+ flex: 1;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: flex-end;
|
|
|
+ min-width: 150px;
|
|
|
+ }
|
|
|
+
|
|
|
.product-name {
|
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
|
@@ -462,22 +483,53 @@ onMounted(() => {
|
|
|
}
|
|
|
|
|
|
.seats-info {
|
|
|
- padding: 10px 12px;
|
|
|
+ width: 100%;
|
|
|
+ padding: 8px 12px;
|
|
|
background: #f5f7fa;
|
|
|
border-radius: 8px;
|
|
|
+ border: 1px solid #e0e6f1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
|
|
|
- .seats-text {
|
|
|
+ .seats-row {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
- margin-top: 8px;
|
|
|
+ align-items: center;
|
|
|
font-size: 12px;
|
|
|
color: #606266;
|
|
|
+ }
|
|
|
|
|
|
- .available {
|
|
|
- color: #67c23a;
|
|
|
+ .seats-label {
|
|
|
+ color: #909399;
|
|
|
+ }
|
|
|
+
|
|
|
+ .seats-value {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+
|
|
|
+ .seats-number {
|
|
|
+ font-weight: 500;
|
|
|
+ color: #303133;
|
|
|
+
|
|
|
+ &.strong {
|
|
|
+ color: #409eff;
|
|
|
font-weight: 600;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ .seats-split {
|
|
|
+ margin: 0 4px;
|
|
|
+ color: #c0c4cc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .seats-text {
|
|
|
+ margin-left: 6px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #909399;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.product-footer {
|