Files
medical-mall/pages/mall/admin/marketing/member/card.uvue
2026-02-05 09:01:16 +08:00

344 lines
10 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="marketing-member-card">
<view class="filter-card border-shadow">
<view class="filter-row">
<view class="filter-item">
<text class="label">批次搜索:</text>
<input class="input-mock" placeholder="请输入批次名" />
</view>
<view class="filter-item">
<text class="label">是否开启:</text>
<view class="select-mock">
<text class="select-val">全部</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="btn-group">
<button class="btn btn-search">查询</button>
<button class="btn btn-reset">重置</button>
</view>
</view>
<view class="action-row">
<button class="btn btn-primary" @click="showAddBatch = true">+ 添加批次</button>
</view>
</view>
<view class="table-card border-shadow">
<view class="table-container">
<view class="table-head">
<view class="th cell-id">ID</view>
<view class="th cell-name">批次名称</view>
<view class="th cell-num">体验卡数量</view>
<view class="th cell-type">会员类型</view>
<view class="th cell-time">生效时间</view>
<view class="th cell-status">是否启用</view>
<view class="th cell-op">操作</view>
</view>
<view class="table-body">
<view v-for="item in cards" :key="item.id" class="table-row">
<view class="td cell-id"><text class="td-txt">{{ item.id }}</text></view>
<view class="td cell-name"><text class="td-txt">{{ item.title }}</text></view>
<view class="td cell-num"><text class="td-txt">{{ item.use_num }}/{{ item.total_num }}</text></view>
<view class="td cell-type"><text class="td-txt">{{ item.member_type }}</text></view>
<view class="td cell-time"><text class="td-txt">{{ item.create_time }}</text></view>
<view class="td cell-status">
<view class="switch-mock" :class="{ active: item.status }" @click="toggleStatus(item)">
<view class="switch-dot"></view>
<text class="switch-txt">{{ item.status ? '开启' : '关闭' }}</text>
</view>
</view>
<view class="td cell-op">
<text class="op-link" @click="showQrCode(item)">二维码</text>
<text class="op-link ml-10" @click="viewDetails(item)">详情</text>
</view>
</view>
</view>
</view>
</view>
<!-- 添加批次弹窗 -->
<view v-if="showAddBatch" class="modal-mask">
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">添加批次</text>
<text class="modal-close" @click="showAddBatch = false">×</text>
</view>
<view class="modal-body">
<view class="form-item">
<text class="form-label">批次名称:</text>
<input class="form-input" placeholder="请输入批次名称" />
</view>
<view class="form-item">
<text class="form-label">导入数量:</text>
<input class="form-input" type="number" placeholder="请输入生成数量" />
</view>
<view class="form-item">
<text class="form-label">会员类型:</text>
<view class="form-select">
<text>请选择会员类型</text>
<text class="arrow">▼</text>
</view>
</view>
<view class="form-item">
<text class="form-label">备注:</text>
<textarea class="form-textarea" placeholder="请输入备注"></textarea>
</view>
</view>
<view class="modal-footer">
<button class="btn btn-cancel" @click="showAddBatch = false">取消</button>
<button class="btn btn-submit" @click="handleAddSubmit">提交</button>
</view>
</view>
</view>
<!-- 二维码弹窗 -->
<view v-if="showQrModal" class="modal-mask">
<view class="modal-content qr-modal">
<view class="modal-header">
<text class="modal-title">预览体验卡二维码</text>
<text class="modal-close" @click="showQrModal = false">×</text>
</view>
<view class="modal-body qr-body">
<image class="qr-img" src="https://demo26.crmeb.net/uploads/attach/2021/11/20211115/a6f3b06e9d6d5a1b3c9d6d5a1b3c9d6d.png" mode="aspectFit"></image>
<text class="qr-tips">请扫码体验会员卡</text>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref } from 'vue'
const showAddBatch = ref(false)
const showQrModal = ref(false)
const cards = ref([
{ id: 4, title: '双11体验卡', use_num: 1, total_num: 100, member_type: '年卡会员', create_time: '2023-11-01 12:00:00', status: true },
{ id: 3, title: '新人体验卷', use_num: 50, total_num: 200, member_type: '月卡会员', create_time: '2023-10-25 09:30:00', status: true },
{ id: 2, title: '测试批次', use_num: 0, total_num: 10, member_type: '季卡会员', create_time: '2023-10-20 15:45:00', status: false }
])
const toggleStatus = (item: any) => {
item.status = !item.status
uni.showToast({ title: '操作成功', icon: 'success' })
}
const showQrCode = (item: any) => {
showQrModal.value = true
}
const viewDetails = (item: any) => {
uni.showToast({ title: '查看详情: ' + item.title, icon: 'none' })
}
const handleAddSubmit = () => {
showAddBatch.value = false
uni.showToast({ title: '添加成功', icon: 'success' })
}
</script>
<style scoped lang="scss">
.marketing-member-card {
padding: 16px;
background: #f0f2f5;
min-height: 100vh;
}
.border-shadow {
background: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}
.filter-card {
padding: 24px;
margin-bottom: 16px;
}
.filter-row {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.filter-item {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 24px;
margin-bottom: 16px;
}
.label {
font-size: 14px;
color: #333;
width: 80px;
}
.input-mock {
width: 200px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
}
.select-mock {
width: 200px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.select-val { font-size: 14px; color: #606266; }
.arrow { font-size: 10px; color: #c0c4cc; }
.btn-group {
display: flex;
flex-direction: row;
margin-bottom: 16px;
}
.btn {
height: 32px;
line-height: 32px;
padding: 0 20px;
font-size: 14px;
border-radius: 4px;
cursor: pointer;
margin-right: 8px;
background: #fff;
border: 1px solid #dcdfe6;
color: #606266;
}
.btn-primary { background: #1890ff; color: #fff; border: none; }
.btn-search { background: #1890ff; color: #fff; border: none; }
.btn-reset { margin-left: 8px; }
.action-row {
margin-top: 8px;
}
.table-card { padding: 24px; }
.table-head {
display: flex;
flex-direction: row;
background-color: #f8f8f9;
border-bottom: 1px solid #e8eaec;
}
.th { padding: 12px 8px; font-size: 13px; color: #515a6e; font-weight: bold; }
.table-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #e8eaec;
align-items: center;
}
.td { padding: 16px 8px; }
.td-txt { font-size: 13px; color: #515a6e; }
.cell-id { width: 60px; }
.cell-name { flex: 1; }
.cell-num { width: 120px; }
.cell-type { width: 120px; }
.cell-time { width: 160px; }
.cell-status { width: 100px; }
.cell-op { width: 120px; text-align: right; }
.op-link { color: #1890ff; font-size: 13px; cursor: pointer; }
.ml-10 { margin-left: 10px; }
.switch-mock {
width: 44px;
height: 22px;
background-color: #bfbfbf;
border-radius: 11px;
display: flex;
flex-direction: row;
align-items: center;
padding: 0 4px;
position: relative;
transition: background-color 0.3s;
cursor: pointer;
}
.switch-mock.active { background-color: #1890ff; }
.switch-dot {
width: 14px;
height: 14px;
background-color: #fff;
border-radius: 50%;
position: absolute;
left: 4px;
transition: left 0.3s;
}
.switch-mock.active .switch-dot { left: 26px; }
.switch-txt { font-size: 10px; color: #fff; margin-left: 18px; }
.switch-mock.active .switch-txt { margin-left: 4px; }
/* Modal Styles */
.modal-mask {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-content {
width: 500px;
background: #fff;
border-radius: 4px;
overflow: hidden;
}
.modal-header {
padding: 16px 24px;
border-bottom: 1px solid #e8eaec;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.modal-title { font-size: 16px; font-weight: bold; color: #17233d; }
.modal-close { font-size: 24px; color: #909399; cursor: pointer; }
.modal-body { padding: 24px; }
.modal-footer {
padding: 12px 24px;
border-top: 1px solid #e8eaec;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.form-item {
display: flex;
flex-direction: row;
margin-bottom: 20px;
align-items: flex-start;
}
.form-label { width: 100px; font-size: 14px; color: #606266; padding-top: 6px; }
.form-input { flex: 1; height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 0 12px; }
.form-select { flex: 1; height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 0 12px; display: flex; flex-direction: row; align-items: center; justify-content: space-between; color: #c0c4cc; font-size: 14px; }
.form-textarea { flex: 1; height: 80px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 8px 12px; }
.btn-cancel { margin-right: 8px; }
.btn-submit { background: #1890ff; color: #fff; border: none; }
.qr-modal { width: 300px; }
.qr-body { display: flex; flex-direction: column; align-items: center; }
.qr-img { width: 200px; height: 200px; margin-bottom: 16px; }
.qr-tips { font-size: 14px; color: #666; }
</style>