You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1213 lines
38 KiB

4 months ago
<template>
<div class="member-card-create">
<!-- 顶部标题和统计 -->
<div class="page-header">
<h2>办理会员卡</h2>
<div class="statistics">
<el-tag type="success">今日办理{{ todayCount }} </el-tag>
4 months ago
</div>
</div>
<div>
</div>
<el-card shadow="never" class="main-card">
<!-- 步骤条 -->
<el-steps :active="activeStep" finish-status="success" class="steps">
<el-step title="选择会员" description="选择或创建会员"></el-step>
<el-step title="选择卡类型" description="选择会员卡类型"></el-step>
<el-step title="填写信息" description="填写办理信息"></el-step>
</el-steps>
<!-- 步骤1选择会员 -->
<div v-if="activeStep === 0" class="step-content">
<el-row :gutter="20">
<el-col :span=12>
<div class="section-title">
<h3>搜索会员</h3>
<el-button type="primary" size="small" @click="handleAddStudent">
创建新会员
</el-button>
</div>
<el-input
v-model="searchKeyword"
placeholder="请输入会员手机号"
clearable
@keyup.enter="searchMember"
class="search-input"
4 months ago
>
<el-button slot="append" icon="el-icon-search" @click="searchMember"></el-button>
</el-input>
<div v-if="memberList.length > 0" class="member-list">
<el-radio-group v-model="selectedMemberId" @change="handleMemberSelect">
<div v-for="member in memberList" :key="member.studentId" class="member-item">
<el-radio :label="member.studentId" class="member-radio">
<div class="member-info">
<div class="member-name">{{ member.studentName }}</div>
<div class="member-phone">{{ member.phone }}</div>
<div class="member-phone">{{ member.age }}</div>
<div class="member-tags">
{{sexFormat(member)}}
<el-tag size="mini" type="info">生日{{ member.birthDay || '未设置生日' }}</el-tag>
4 months ago
</div>
</div>
</el-radio>
</div>
</el-radio-group>
</div>
<div v-else-if="searched" class="empty-state">
<el-empty description="未找到相关会员"></el-empty>
</div>
</el-col>
<el-col :span=12>
<div class="selected-member" v-if="selectedMember">
<div class="section-title">
<h3>已选会员信息</h3>
</div>
<el-descriptions :column="1" border>
<el-descriptions-item label="会员编号">{{ selectedMember.studentId || '-' }}</el-descriptions-item>
<el-descriptions-item label="姓名">{{ selectedMember.studentName }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ selectedMember.phone }}</el-descriptions-item>
<el-descriptions-item label="性别">
{{sexFormat(selectedMember)}}
</el-descriptions-item>
<el-descriptions-item label="生日">{{ selectedMember.birthDay || '-' }}</el-descriptions-item>
<el-descriptions-item label="注册时间">{{ selectedMember.inTime || '-' }}</el-descriptions-item>
</el-descriptions>
<div v-if="memberCards.length > 0" class="current-cards">
<h4>名下会员卡</h4>
<el-table :data="memberCards" size="small">
<el-table-column prop="cardNo" label="卡号"></el-table-column>
<el-table-column prop="cardTypeName" label="类型"></el-table-column>
<el-table-column prop="chargeType" label="扣费方式">
<template slot-scope="scope">
{{ scope.row.chargeType=='count'?'按次数':scope.row.chargeType=='total_fee'?'按储值':'按周期' }}
{{scope.row.chargeType=='count'?'(余 '+scope.row.remainingCount+' 次)':''}}
{{scope.row.chargeType=='total_fee'?'(余 '+scope.row.remainingTotalFee+' ¥)':''}}
{{scope.row.chargeType=='days'?'(余 '+scope.row.remainingDays+' 天)':''}}
</template>
</el-table-column>
<el-table-column prop="status" label="状态">
<template slot-scope="scope">
<el-tag :type="getStatusTagType(scope.row.status)" size="mini">
{{ scope.row.statusDesc }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="expiryDate" label="到期时间"></el-table-column>
</el-table>
4 months ago
</div>
</div>
<div v-else class="placeholder">
<el-empty description="请选择会员"></el-empty>
</div>
4 months ago
</el-col>
</el-row>
<div class="step-actions">
<el-button type="primary" :disabled="!selectedMemberId" @click="nextStep">
下一步选择卡类型
</el-button>
</div>
4 months ago
</div>
<!-- 步骤2选择卡类型 -->
<div v-if="activeStep === 1" class="step-content">
<member-card-Type-table ref="memberCardtype" />
<div class="step-actions">
<el-button @click="prevStep"></el-button>
<el-button
type="primary"
@click="nextStepFor2"
>
下一步填写信息
</el-button>
4 months ago
</div>
</div>
<!-- 步骤3填写信息 -->
<div v-if="activeStep === 2" class="step-content">
<el-form ref="form" :model="formData" :rules="formRules" label-width="120px">
<el-row :gutter="10" style="background-color: #e7e9ea;">
<el-col span="12">
<el-form-item label="会员信息">
<div class="member-info-display">
<div style="font-weight: bold;font-size: 16px">{{ selectedMember.studentName }}</div>
<div class="sub-info">{{ selectedMember.phone }}</div>
4 months ago
</div>
</el-form-item>
4 months ago
</el-col>
<el-col span="12" >
<el-form-item label="卡类名称">
<div v-if="chargeType=='days'" class="card-type-display" >
<div style="color: #00afff;font-weight: bold;font-size: 16px">{{selectedCardType.cardName }}</div>
<div class="sub-info" >会员卡扣费方式 按周期</div>
<div class="sub-info" >总天数/有效期 {{ selectedCardType.days }}</div>
<div class="sub-info" v-if="selectedCardType.days">
根据卡类型默认有效期为 {{ selectedCardType.days }} </div>
</div>
<div v-if="chargeType=='count'" class="card-type-display">
<div style="color: #00afff;font-weight: bold;font-size: 16px">{{selectedCardType.cardName }}</div>
<div class="sub-info" >会员卡扣费方式 按次数</div>
<div class="sub-info" >默认课程总次数 {{ selectedCardType.count }}</div>
<div class="sub-info" v-if="selectedCardType.days">
根据卡类型默认有效期为 {{ selectedCardType.days }} </div>
4 months ago
</div>
<div v-if="chargeType=='total_fee'" class="card-type-display">
<div style="color: #00afff;font-weight: bold;font-size: 16px">{{ selectedCardType.cardName }}</div>
<div class="sub-info" >会员卡扣费方式 按储值</div>
<div class="sub-info" >默认储值金额{{ selectedCardType.totalFee }} ¥</div>
<div class="sub-info" v-if="selectedCardType.days">
根据卡类型默认有效期为 {{ selectedCardType.days }} </div>
</div>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 10px">
<el-col :span=12>
<el-form-item label="经办校区" prop="handleDepartId">
4 months ago
<el-select
v-model="formData.handleDepartId"
placeholder="请选择经办校区"
clearable
size="small"
4 months ago
filterable
default-first-option
>
<el-option
v-for="item in campusOptions"
:key="item.id"
:label="item.label"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="销售员工" prop="saleStaffId">
<user-select v-model="formData.saleStaffId" style="width: 180px" />
</el-form-item >
<el-form-item label="佣金方案" prop="commissionPlansId">
<commission-select v-model="formData.commissionPlansId" />
</el-form-item>
<el-form-item label="收款账户" prop="accountId">
<el-select
v-model="formData.accountId"
placeholder="请选择收款账户"
clearable
4 months ago
size="small"
filterable
default-first-option
4 months ago
>
<el-option
v-for="item in receiptAccountOptions"
:key="item.accountId"
:label="item.accountName"
:value="item.accountId"
4 months ago
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span=12>
<el-form-item label="实付金额" prop="price">
4 months ago
<el-input-number
v-model="formData.price"
4 months ago
:min="0"
:step="100"
:precision="2"
placeholder="请输入购买价格"
></el-input-number>
</el-form-item>
<div v-if="chargeType=='days'">
<el-form-item label="开卡日期:" prop="haveActivationDate" class="align-left">
<el-radio-group v-model="formData.haveActivationDate" @change="changeHaveActivationDate" >
<el-radio label="1">立即开卡</el-radio>
<el-radio label="2">首次预约开卡</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="激活日期" v-if="formData.haveActivationDate=='1'" prop="activationDate">
<el-date-picker
v-model="formData.activationDate"
type="date"
placeholder="选择激活日期"
value-format="yyyy-MM-dd"
:picker-options="activationDateOptions"
@change="calculateExpiryDate"
>
</el-date-picker>
</el-form-item>
<el-form-item label="到期日期" v-if="formData.haveActivationDate=='1'" prop="expiryDate">
<el-date-picker
v-model="formData.expiryDate"
type="date"
placeholder="选择到期日期"
value-format="yyyy-MM-dd"
:picker-options="expiryDateOptions"
@change="calculateDays"
>
</el-date-picker>
<span class="form-tip" > {{ formData.totalDays }}截止至当天23:59:59</span>
</el-form-item>
<el-form-item label="储值天数" v-if="formData.haveActivationDate=='2'" prop="totalDays" >
<el-input-number
v-model="formData.totalDays"
:min="0"
:step="100"
:precision="0"
placeholder="请输入储值天数"
>
</el-input-number>
<span class="form-tip" > * 该卡从会员首次约课时算第一天再往后共{{ formData.totalDays }}</span>
</el-form-item>
</div >
<div v-else>
<el-form-item label="卡有效期:" prop="haveExpiryDate" class="align-left">
<el-radio-group v-model="formData.haveExpiryDate" @change="changeHaveExpiryDate">
<el-radio label="1">不限期用完失效</el-radio>
<el-radio label="2">设置有效期</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="到期日期" v-if="formData.haveExpiryDate=='2'" prop="expiryDate">
<el-date-picker
v-model="formData.expiryDate"
type="date"
placeholder="选择到期日期"
value-format="yyyy-MM-dd"
:picker-options="expiryDateOptions"
>
</el-date-picker>
<span class="form-tip" > 截止至当天23:59:59</span>
</el-form-item>
4 months ago
</div>
<el-form-item v-if="chargeType=='total_fee'" label="储值金额" prop="totalFee">
4 months ago
<el-input-number
v-model="formData.totalFee"
4 months ago
:min="0"
:step="100"
:precision="2"
placeholder="请输入购买价格"
>
</el-input-number>
<span class="form-tip"> * 举例若实付金额1000送200则储值金额应填写1200</span>
</el-form-item>
<el-form-item v-if="chargeType=='count'" label="充值课时" prop="totalCount">
<el-input-number
v-model="formData.totalCount"
:min="0"
:step="1"
:precision="1"
placeholder="请输入充值次数"
>
</el-input-number>
</el-form-item>
<el-form-item label="备注" prop="notes">
4 months ago
<el-input
v-model="formData.notes"
type="textarea"
:rows="3"
placeholder="请输入备注信息"
></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="summary-card">
<h3>办理信息汇总</h3>
<el-descriptions :column="2" border>
<el-descriptions-item label="会员">{{ selectedMember.studentName }}</el-descriptions-item>
<el-descriptions-item label="手机号">{{ selectedMember.phone }}</el-descriptions-item>
<el-descriptions-item label="卡类名称">{{ selectedCardType.cardName }}</el-descriptions-item>
<el-descriptions-item v-if="chargeType=='total_fee'" label="储值金额">{{ formData.totalFee }} &nbsp;&nbsp;¥</el-descriptions-item>
<el-descriptions-item v-if="chargeType=='count'" label="充值课时">{{ formData.totalCount }} </el-descriptions-item>
<el-descriptions-item v-if="chargeType=='days'" label="有效天数">{{ formData.totalDays }} </el-descriptions-item>
<el-descriptions-item label="实付金额">{{ formData.price }}&nbsp;&nbsp;¥</el-descriptions-item>
<el-descriptions-item label="收款账户">
{{ getPaymentMethodName(formData.accountId) }}
</el-descriptions-item>
<el-descriptions-item label="激活日期">
{{ formData.activationDate || '暂不激活' }}
</el-descriptions-item>
<el-descriptions-item label="到期日期">
{{ formData.expiryDate }}
</el-descriptions-item>
</el-descriptions>
4 months ago
</div>
<div class="step-actions">
<el-button @click="prevStep"></el-button>
<el-button
type="primary"
@click="validateAndNext"
:loading="validating"
>
确认办理
</el-button>
4 months ago
</div>
</div>
</el-card>
<change-student ref="changeStudent" @success="handleMemberSelect" />
4 months ago
</div>
4 months ago
</template>
4 months ago
<script>
import {select as cardTypeSelect} from '@/api/school/sc/memberCardType/index'
import {listStudent} from '@/api/school/sc/student/index'
import { select as receiptSelect} from '@/api/school/system/receipt'
import {selectDictLabel} from "@/utils/commonUtils";
4 months ago
import { campusList } from '@/api/school/system/dept'
import memberCardTypeTable from '@/components/sc/memberCardTypes/memberCardTypeTable.vue'
4 months ago
import changeStudent from '@/components/sc/student/changeStudent'
import memberCardApi from '@/api/school/sc/memberCard/index'
import commissionSelect from '@/components/sc/commission/commissionSelect'
import userSelect from '@/components/system/user/userSelect'
4 months ago
export default {
name: 'MemberCardCreate',
4 months ago
components: {
memberCardTypeTable,
4 months ago
changeStudent,
commissionSelect,
userSelect
4 months ago
},
data() {
return {
activeStep: 0,
// 统计信息
todayCount: 0,
monthCount: 0,
// 会员相关
searchKeyword: '',
memberList: [],
selectedMemberId: null,
selectedMember: null,
memberCards: [],
searched: false,
sexOptions:[],
// 卡类型相关
cardTypes: [],
selectedCardTypeId: null,
selectedCardType: null,
chargeType: null,
4 months ago
// 经办校区
campusOptions: [],
// 表单数据
formData: {
handleDepartId:'',
saleStaffId:'',
commissionPlansId:'',
accountId: '',//收款账户
haveActivationDate:'1',//时间卡 是否激活
haveExpiryDate:'1',//储值or次数卡 是否设置有效期
activationDate: '',//激活时间
expiryDate: '',//过期时间
price: 0,
totalFee: 0,
totalCount: 0,
totalDays: 0,
notes: '',
orderId:''
},
autoGenerateCardNo: true,
// 支付相关
receiptAccountOptions:[],
paymentType: 'WECHAT',
paying: false,
saving: false,
validating: false,
// 对话框控制
showCreateMemberDialog: false,
showCardTypeDetailDialog: false,
// 表单验证规则
formRules: {
accountId: [
{ required: true, message: '请选择收款账户', trigger: 'change' }
],
handleDepartId: [
{ required: true, message: '请选择经办校区', trigger: 'change' }
],
saleStaffId: [
{ required: true, message: '请选择销售员工', trigger: 'change' }
],
commissionPlansId: [
{ required: true, message: '请选择佣金方案', trigger: 'change' }
],
price: [
{ required: true, message: '请输入购买价格', trigger: 'blur' },
{ type: 'number', min: 0, message: '价格不能小于0', trigger: 'blur' }
],
activationDate: [
{ validator: (rule, value, callback) => {
// 如果 haveActivationDate 为 1activationDate 不能为空
if (this.formData.haveActivationDate === '1' && !value) {
callback(new Error('请选择激活日期'));
} else {
callback(); // 验证通过
}
},
trigger: 'change' // 日期选择器用 change 触发
},
],
expiryDate: [
{ validator: (rule, value, callback) => {
// 条件1haveActivationDate 为 1 时,有效期不能为空
// 条件2haveExpiryDate 为 2 时,有效期不能为空
const needExpiryDate = this.formData.haveActivationDate === '1' || this.formData.haveExpiryDate === '2';
if (needExpiryDate && !value) {
callback(new Error('请选择有效期'));
} else {
callback(); // 验证通过
}
},
trigger: 'blur'// 日期选择器用 change 触发
},
],
days: [
{
validator: (rule, value, callback) => {
// 如果 haveActivationDate 为 2days 不能为空且不能为 0
if (this.formData.haveActivationDate === '2') {
if (!value || value === 0) {
callback(new Error('请输入有效天数'));
} else if (value < 0) {
callback(new Error('有效天数不能小于0'));
} else {
callback();
}
} else {
callback(); // 其他情况不验证
}
},
trigger: ['blur', 'change']// 输入框用 blur 触发
},
],
},
// 日期选择器选项
activationDateOptions: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7 // 不能选择过去的时间
}
},
expiryDateOptions: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7 // 不能选择过去的时间
}
}
4 months ago
}
},
created() {
this.loadCardTypes()
this.loadStatistics()
this.loadReceiptAccount()
this.getDictListByDictType('sys_user_sex').then(response => {
this.sexOptions = response.data
})
campusList().then(response => {
this.campusOptions = response.data
if (this.campusOptions.length === 1) {
this.formData.handleDepartId = this.campusOptions[0].id
}
})
},
methods: {
loadReceiptAccount(){
receiptSelect().then(response => {
this.receiptAccountOptions = response.data
4 months ago
})
},
// 加载统计信息
async loadStatistics() {
try {
memberCardApi.getTodayCardCount().then(response => {
this.todayCount = response.data || 0
})
} catch (error) {
console.error('加载统计信息失败:', error)
}
},
// 加载卡类型
async loadCardTypes() {
try {
cardTypeSelect({}).then(response => {
this.cardTypes = response.data || []
})
} catch (error) {
this.$message.error('加载卡类型失败')
console.error('加载卡类型失败:', error)
}
},
// 搜索会员
async searchMember() {
if (!this.searchKeyword.trim()) {
this.$message.warning('请输入搜索关键词')
return
}
try {
listStudent({phone:this.searchKeyword}).then(response => {
this.memberList = response.data.rows || []
this.searched = true
if (this.memberList.length === 0) {
this.$message.info('未找到相关会员')
4 months ago
}
})
} catch (error) {
this.$message.error('搜索会员失败')
console.error('搜索会员失败:', error)
}
4 months ago
},
// 性别字典翻译
sexFormat(row, column) {
return selectDictLabel(this.sexOptions, row.sex)
4 months ago
},
// 选择会员
async handleMemberSelect(studentId) {
const member = this.memberList.find(m => m.studentId === studentId)
if (member) {
this.selectedMember = member
await this.loadMemberCards(studentId)
}
4 months ago
},
// 加载会员的会员卡
async loadMemberCards(memberId) {
try {
const response = await memberCardApi.getMemberCards(memberId)
this.memberCards = response.data || []
} catch (error) {
console.error('加载会员卡失败:', error)
}
4 months ago
},
// 新建学员信息
handleAddStudent() {
this.$refs.changeStudent.handleAdd()
4 months ago
},
// 获取收款账户名称
getPaymentMethodName(method) {
let item=this.receiptAccountOptions.find(item => item.accountId == method);
let methodName=item==null?'':item.accountName;
return methodName;
4 months ago
},
// 获取状态标签类型
getStatusTagType(status) {
const typeMap = {
'ACTIVE': 'success',
'INACTIVE': 'info',
'EXPIRED': 'warning',
'SUSPENDED': 'danger',
'DEPLETED': 'danger'
}
return typeMap[status] || 'info'
},
changeHaveActivationDate(){
this.formData.activationDate=''
this.formData.expiryDate=''
this.formData.totalDays=0
4 months ago
},
changeHaveExpiryDate(){
if (this.formData.haveExpiryDate=='2'){
this.calculateExpiryDate()
return;
4 months ago
}
this.formData.expiryDate='' ;
4 months ago
},
// 计算到期日期
calculateExpiryDate( ) {
if (!this.selectedCardType || !this.selectedCardType.days) {
return '未设置'
4 months ago
}
const activationDate = this.formData.activationDate
? new Date(this.formData.activationDate)
: new Date()
const expiryDate = new Date(activationDate)
expiryDate.setDate(expiryDate.getDate() + this.selectedCardType.days)
this.formData.expiryDate=expiryDate.toISOString().split('T')[0];
this.calculateDays()
4 months ago
},
calculateDays(){
if (!this.formData.activationDate || !this.formData.expiryDate){
return;
4 months ago
}
const activationDate =new Date(this.formData.activationDate);
const expiryDate =new Date(this.formData.expiryDate);
const timeDiff = Math.abs(activationDate.getTime() - expiryDate.getTime());
const dayDiff = Math.floor(timeDiff / (1000 * 60 * 60 * 24));
this.formData.totalDays=dayDiff;
4 months ago
},
// 验证并进入下一步
async validateAndNext() {
this.$refs.form.validate(async (valid) => {
if (valid) {
this.validating = true
try {
// 这里可以添加一些业务验证
await this.handlePayment()
} catch (error) {
console.error('验证失败:', error)
} finally {
this.validating = false
}
4 months ago
} else {
this.$message.warning('请填写完整信息')
4 months ago
}
})
4 months ago
},
// 下一步
nextStep() {
if (this.activeStep < 2) {
this.activeStep++
4 months ago
}
},
// 上一步
prevStep() {
if (this.activeStep > 0) {
this.activeStep--
4 months ago
}
},
cleanForm(){
this.formData.haveActivationDate='1';
this.formData.haveExpiryDate='1';
this.formData.activationDate='';
this.formData.expiryDate='';
this.formData.price=0;
this.formData.totalFee=0;
this.formData.totalCount=0;
this.formData.totalDays=0;
},
nextStepFor2(){
if (this.$refs.memberCardtype.queryParams.cardType==undefined || this.$refs.memberCardtype.queryParams.cardType==''){
this.msgError('请选择收费模式!')
return ;
4 months ago
}
this.cleanForm()
this.formData.activationDate=new Date().toISOString().split('T')[0]
// if (this.$refs.memberCardtype.queryParams.cardType=='total_fee'){
// this.chargeType=this.$refs.memberCardtype.queryParams.cardType;
// this.selectedCardTypeId=this.$refs.memberCardtype.chooseCardTypeId[0];
// this.selectedCardType=this.$refs.memberCardtype.chooseCardTypes[0];
//
// if (this.selectedCardType ==null){
// this.selectedCardType={
// cardName:'储值卡',
// totalFee:0
// }
// }
// this.activeStep++
// return ;
// }
if (this.$refs.memberCardtype.chooseCardTypeId.length>1 || this.$refs.memberCardtype.chooseCardTypeId.length==0){
this.msgError('请选择1项确认选择数量')
return ;
4 months ago
}
this.chargeType=this.$refs.memberCardtype.queryParams.cardType;
this.selectedCardTypeId=this.$refs.memberCardtype.chooseCardTypeId[0];
this.selectedCardType=this.$refs.memberCardtype.chooseCardTypes[0];
this.calculateExpiryDate()
this.activeStep++
4 months ago
},
// 处理订单信息
async handlePayment() {
if (!this.selectedMemberId ) {
this.$message.error('请完成前面的步骤')
4 months ago
return
}
// if ( !this.selectedCardTypeId && this.chargeType!='total_fee') {
if ( !this.selectedCardTypeId) {
this.$message.error('请完成前面的步骤')
return
}
this.paying = true
try {
// 构建办理会员卡的请求数据
const requestData = {
memberId: this.selectedMemberId,
cardTypeId: this.selectedCardTypeId,
handleDepartId:this.formData.handleDepartId,
saleStaffId:this.formData.saleStaffId,
commissionPlansId:this.formData.commissionPlansId,
haveActivationDate:this.formData.haveActivationDate,//时间卡 是否激活
haveExpiryDate:this.formData.haveExpiryDate,//储值or次数卡 是否设置有效期
activationDate: this.formData.activationDate || null,
expiryDate: this.formData.expiryDate || null,
price: this.formData.price,
accountId: this.formData.accountId,
orderNo: this.formData.orderNo,
totalFee: this.formData.totalFee || 0,
totalCount: this.formData.totalCount || 0,
totalDays: this.formData.totalDays || 0,
notes: this.formData.notes,
chargeType:this.chargeType
4 months ago
}
const response = await memberCardApi.createMemberCard(requestData)
if (response.respCode === '0000') {
this.$message.success('会员卡办理成功!')
// 重置表单
this.resetForm()
// 跳转到会员卡详情页
const cardId = response.data.id
// this.$router.push({
// name: 'MemberCardDetail',
// params: { id: cardId }
// })
} else {
this.$message.error(response.respMsg || '办理失败')
4 months ago
}
} catch (error) {
console.error('办理会员卡失败:', error)
this.$message.error('办理失败:' + (error.message || '网络错误'))
} finally {
this.paying = false
}
4 months ago
},
// 保存为草稿
async saveAsDraft() {
this.saving = true
try {
// TODO: 实现保存草稿功能
this.$message.success('已保存为草稿')
} catch (error) {
console.error('保存草稿失败:', error)
this.$message.error('保存草稿失败')
} finally {
this.saving = false
}
4 months ago
},
// 查看卡类型详情
showCardTypeDetail(cardType) {
this.selectedCardType = cardType
this.showCardTypeDetailDialog = true
4 months ago
},
// 处理会员创建成功
handleMemberCreateSuccess(newMember) {
this.showCreateMemberDialog = false
this.memberList.unshift(newMember)
this.selectedMemberId = newMember.id
this.selectedMember = newMember
this.searchKeyword = ''
this.$message.success('会员创建成功')
4 months ago
},
// 处理创建会员对话框关闭
handleCreateMemberClose() {
if (this.$refs.memberCreateForm) {
this.$refs.memberCreateForm.resetForm()
}
},
// 重置表单
resetForm() {
this.activeStep = 0
this.selectedMemberId = null
this.selectedMember = null
this.memberCards = []
this.selectedCardTypeId = null
this.selectedCardType = null
this.formData = {
handleDepartId:'',
saleStaffId:'',
commissionPlansId:'',
accountId: '',//收款账户
haveActivationDate:'1',//时间卡 是否激活
haveExpiryDate:'1',//储值or次数卡 是否设置有效期
activationDate: '',//激活时间
expiryDate: '',//过期时间
price: 0,
totalFee: 0,
totalCount: 0,
totalDays: 0,
notes: '',
orderNo: ''
}
this.autoGenerateCardNo = true
this.paymentType = 'WECHAT'
if (this.$refs.form) {
this.$refs.form.resetFields()
}
// 重新加载卡类型
this.loadCardTypes()
this.loadStatistics()
}
}
}
</script>
<style scoped lang="scss">
.member-card-create {
padding: 20px;
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h2 {
margin: 0;
color: #333;
}
.statistics {
display: flex;
gap: 10px;
}
}
.main-card {
margin-top: 20px;
.steps {
margin-bottom: 40px;
}
.step-content {
padding: 20px;
.section-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
h3 {
margin: 0;
color: #333;
}
}
.search-input {
margin-bottom: 20px;
}
.member-list {
max-height: 400px;
overflow-y: auto;
.member-item {
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ebeef5;
border-radius: 4px;
transition: all 0.3s;
&:hover {
border-color: #409eff;
background-color: #f5f7fa;
4 months ago
}
.member-radio {
width: 100%;
4 months ago
}
.member-info {
display: flex;
flex-direction: column;
margin-left: 10px;
.member-name {
font-weight: bold;
font-size: 14px;
color: #333;
}
.member-phone {
font-size: 12px;
color: #666;
margin: 4px 0;
}
.member-tags {
display: flex;
gap: 5px;
}
}
4 months ago
}
}
.empty-state {
text-align: center;
padding: 40px 0;
}
.selected-member {
.current-cards {
margin-top: 20px;
h4 {
margin: 20px 0 10px;
color: #333;
}
4 months ago
}
}
.placeholder {
text-align: center;
padding: 40px 0;
color: #999;
4 months ago
}
.card-type-list {
.card-type-item {
border: 2px solid #ebeef5;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
cursor: pointer;
transition: all 0.3s;
height: 100%;
&:hover {
border-color: #409eff;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
&.selected {
border-color: #67c23a;
background-color: #f0f9eb;
}
.card-type-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
h3 {
margin: 0;
color: #333;
}
}
.card-type-price {
margin-bottom: 15px;
.price {
font-size: 24px;
font-weight: bold;
color: #f56c6c;
}
.original-price {
font-size: 14px;
color: #999;
text-decoration: line-through;
margin-left: 10px;
}
}
.card-type-details {
margin-bottom: 15px;
.detail-item {
display: flex;
align-items: center;
margin-bottom: 8px;
font-size: 13px;
color: #666;
i {
margin-right: 8px;
color: #409eff;
}
}
}
.card-type-benefits {
h4 {
margin: 0 0 8px;
font-size: 14px;
color: #333;
}
p {
margin: 0;
font-size: 13px;
color: #666;
line-height: 1.5;
}
}
.card-type-footer {
margin-top: 15px;
text-align: center;
}
}
4 months ago
}
.selected-card-type {
margin: 20px 0;
.selected-alert {
.selected-info {
display: flex;
align-items: center;
justify-content: space-between;
.price {
font-weight: bold;
color: #f56c6c;
}
}
4 months ago
}
}
.member-info-display,
.card-type-display {
padding: 8px 0;
.sub-info {
font-size: 12px;
color: #666;
margin-top: 4px;
}
4 months ago
}
.form-tip {
font-size: 12px;
color: #999;
margin-top: 4px;
}
.summary-card {
margin-top: 30px;
padding: 20px;
background-color: #f5f7fa;
border-radius: 4px;
h3 {
margin: 0 0 15px;
color: #333;
4 months ago
}
}
.payment-options {
margin: 30px 0;
h3 {
margin: 0 0 15px;
color: #333;
}
.payment-buttons {
display: flex;
gap: 10px;
.icon-wechat,
.icon-alipay {
margin-right: 5px;
font-size: 16px;
}
}
}
.step-actions {
margin-top: 30px;
text-align: center;
}
.final-actions {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 30px;
}
4 months ago
}
}
}
// 响应式调整
@media (max-width: 1200px) {
.member-card-create {
.card-type-list {
.card-type-item {
.card-type-details {
.detail-item {
flex-direction: column;
align-items: flex-start;
}
}
}
4 months ago
}
}
}
4 months ago
@media (max-width: 768px) {
.member-card-create {
.page-header {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
.step-content {
.section-title {
flex-direction: column;
align-items: flex-start;
gap: 10px;
}
}
}
}
4 months ago
</style>