赛事管理bug
This commit is contained in:
parent
1c15442978
commit
762483d07d
@ -124,7 +124,7 @@ const localFormData = ref({
|
|||||||
// init from parent
|
// init from parent
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(v) => {
|
async (v) => {
|
||||||
console.log('init from parent', v);
|
console.log('init from parent', v);
|
||||||
if (!v) return;
|
if (!v) return;
|
||||||
Object.keys(localFormData.value).forEach((k) => {
|
Object.keys(localFormData.value).forEach((k) => {
|
||||||
@ -137,6 +137,21 @@ watch(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log('after init', localFormData.value);
|
console.log('after init', localFormData.value);
|
||||||
|
|
||||||
|
// 如果有省份数据,重新加载对应的城市和区县数据
|
||||||
|
if(localFormData.value.regionIds[0]) {
|
||||||
|
try {
|
||||||
|
const cityRes = await regionCitiesbyprovinceGet({ provincecode: localFormData.value.regionIds[0] });
|
||||||
|
cities.value = cityRes?.data ?? [];
|
||||||
|
if(localFormData.value.regionIds[1]) {
|
||||||
|
const districtRes = await regionDistrictsbycityGet({ citycode: localFormData.value.regionIds[1] });
|
||||||
|
districts.value = districtRes?.data ?? [];
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
cities.value = [];
|
||||||
|
districts.value = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
|
|||||||
@ -47,7 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="account-item">
|
<div class="account-item">
|
||||||
<div class="account-item__label">营业执照</div>
|
<div class="account-item__label">营业执照</div>
|
||||||
<img :src="businessLicenseUrl" style="width: 100px; height: 100px;" />
|
<el-image :src="localFormData.businessLicenseUrl" style="width: 100px; height: 100px;" fit="cover" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -149,15 +149,67 @@ const localFormData = ref({
|
|||||||
creditCode: '',
|
creditCode: '',
|
||||||
bankName: '',
|
bankName: '',
|
||||||
accountNumber: '',
|
accountNumber: '',
|
||||||
|
businessLicenseUrl: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const merchantOptions = ref([]);
|
||||||
|
const isInitialized = ref(false);
|
||||||
|
|
||||||
|
const syncMerchantInfo = () => {
|
||||||
|
const id = localFormData.value.merchantId;
|
||||||
|
|
||||||
|
// 如果已经有商户信息(merchantName 不为空),即使没有 merchantId 也正常显示
|
||||||
|
if (localFormData.value.merchantName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有 id,不强制清空,保留已有数据
|
||||||
|
if (!id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试从 merchantOptions 中查找商户
|
||||||
|
const m = (merchantOptions.value ?? []).find((x) => x?.value == id);
|
||||||
|
if (m) {
|
||||||
|
// 只在 localFormData 中的值为空时才从 merchantOptions 中获取
|
||||||
|
if (!localFormData.value.merchantName) {
|
||||||
|
localFormData.value.merchantName = m.merchantName ?? '';
|
||||||
|
}
|
||||||
|
if (!localFormData.value.creditCode) {
|
||||||
|
localFormData.value.creditCode = m.creditCode ?? '';
|
||||||
|
}
|
||||||
|
if (!localFormData.value.bankName) {
|
||||||
|
localFormData.value.bankName = m.bankName ?? '';
|
||||||
|
}
|
||||||
|
if (!localFormData.value.accountNumber) {
|
||||||
|
localFormData.value.accountNumber = m.accountNumber ?? '';
|
||||||
|
}
|
||||||
|
// 只在营业执照 URL 为空时才从 merchantOptions 中获取
|
||||||
|
if (!localFormData.value.businessLicenseUrl) {
|
||||||
|
localFormData.value.businessLicenseUrl = m.businessLicenseUrl ?? '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(v) => {
|
(v) => {
|
||||||
if (!v) return;
|
if (!v) return;
|
||||||
Object.keys(localFormData.value).forEach((k) => {
|
|
||||||
if (v[k] !== undefined) localFormData.value[k] = v[k];
|
// 直接复制所有属性,强制覆盖
|
||||||
});
|
localFormData.value.chargeMode = v.chargeMode ?? 0;
|
||||||
|
localFormData.value.price = v.price ?? 0;
|
||||||
|
localFormData.value.merchantId = v.merchantId;
|
||||||
|
localFormData.value.merchantName = v.merchantName ?? '';
|
||||||
|
localFormData.value.creditCode = v.creditCode ?? '';
|
||||||
|
localFormData.value.bankName = v.bankName ?? '';
|
||||||
|
localFormData.value.accountNumber = v.accountNumber ?? '';
|
||||||
|
localFormData.value.businessLicenseUrl = v.businessLicenseUrl ?? '';
|
||||||
|
|
||||||
|
// 如果已经初始化完成,调用 syncMerchantInfo
|
||||||
|
if (isInitialized.value) {
|
||||||
|
syncMerchantInfo();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
);
|
);
|
||||||
@ -167,8 +219,7 @@ watch(
|
|||||||
(v) => emit('update:modelValue', { ...props.modelValue, ...v }),
|
(v) => emit('update:modelValue', { ...props.modelValue, ...v }),
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
const businessLicenseUrl = ref('');
|
|
||||||
const merchantOptions = ref([]);
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await merchantPageGet({ PageNo: 1, PageSize: 200 });
|
const res = await merchantPageGet({ PageNo: 1, PageSize: 200 });
|
||||||
@ -185,27 +236,11 @@ onMounted(async () => {
|
|||||||
} catch {
|
} catch {
|
||||||
merchantOptions.value = [];
|
merchantOptions.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isInitialized.value = true;
|
||||||
syncMerchantInfo();
|
syncMerchantInfo();
|
||||||
});
|
});
|
||||||
|
|
||||||
const syncMerchantInfo = () => {
|
|
||||||
const id = localFormData.value.merchantId;
|
|
||||||
if (!id) {
|
|
||||||
localFormData.value.merchantName = '';
|
|
||||||
localFormData.value.creditCode = '';
|
|
||||||
localFormData.value.bankName = '';
|
|
||||||
localFormData.value.accountNumber = '';
|
|
||||||
businessLicenseUrl.value = '';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const m = (merchantOptions.value ?? []).find((x) => x?.value == id);
|
|
||||||
localFormData.value.merchantName = m?.merchantName ?? '';
|
|
||||||
localFormData.value.creditCode = m?.creditCode ?? '';
|
|
||||||
localFormData.value.bankName = m?.bankName ?? '';
|
|
||||||
localFormData.value.accountNumber = m?.accountNumber ?? '';
|
|
||||||
businessLicenseUrl.value = m?.businessLicenseUrl ?? '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 商户选择弹窗相关
|
// 商户选择弹窗相关
|
||||||
const merchantDialogVisible = ref(false);
|
const merchantDialogVisible = ref(false);
|
||||||
const merchantList = ref([]);
|
const merchantList = ref([]);
|
||||||
@ -256,16 +291,47 @@ const selectMerchant = (row) => {
|
|||||||
localFormData.value.creditCode = row.creditCode ?? '';
|
localFormData.value.creditCode = row.creditCode ?? '';
|
||||||
localFormData.value.bankName = row.bankName ?? '';
|
localFormData.value.bankName = row.bankName ?? '';
|
||||||
localFormData.value.accountNumber = row.accountNumber ?? '';
|
localFormData.value.accountNumber = row.accountNumber ?? '';
|
||||||
businessLicenseUrl.value = row.businessLicenseUrl ?? '';
|
localFormData.value.businessLicenseUrl = row.businessLicenseUrl ?? '';
|
||||||
merchantDialogVisible.value = false;
|
merchantDialogVisible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(merchantOptions, syncMerchantInfo, { deep: true });
|
watch(merchantOptions, () => {
|
||||||
|
if (isInitialized.value) {
|
||||||
|
syncMerchantInfo();
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
|
const validatePrice = (rule, value, callback) => {
|
||||||
|
// 当收费模式为定价(赛事)或单价(赛事)时,价格必填
|
||||||
|
if (localFormData.value.chargeMode === 1 || localFormData.value.chargeMode === 2) {
|
||||||
|
if (value === '' || value === null || value === undefined || value <= 0) {
|
||||||
|
callback(new Error('请输入价格,且价格必须大于0'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateMerchantId = (rule, value, callback) => {
|
||||||
|
// 当收费模式为非免费时,收款商户必填
|
||||||
|
if (localFormData.value.chargeMode !== 0) {
|
||||||
|
// 如果有 merchantName,说明数据已经从后端回填了,即使没有 merchantId 也通过
|
||||||
|
if (!value && !localFormData.value.merchantName) {
|
||||||
|
callback(new Error('请选择收款商户'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
chargeMode: [{ required: true, message: '请选择收费模式', trigger: 'change' }],
|
chargeMode: [{ required: true, message: '请选择收费模式', trigger: 'change' }],
|
||||||
price: [{ required: false, message: '请输入价格', trigger: 'change' }],
|
price: [
|
||||||
merchantId: [{ required: true, message: '请选择收款商户', trigger: 'change' }],
|
{ validator: validatePrice, trigger: 'change' }
|
||||||
|
],
|
||||||
|
merchantId: [
|
||||||
|
{ validator: validateMerchantId, trigger: 'change' }
|
||||||
|
],
|
||||||
bankName: [{ required: false, message: '请输入开户银行', trigger: 'blur' }],
|
bankName: [{ required: false, message: '请输入开户银行', trigger: 'blur' }],
|
||||||
accountNumber: [{ required: false, message: '请输入银行账号', trigger: 'blur' }],
|
accountNumber: [{ required: false, message: '请输入银行账号', trigger: 'blur' }],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,9 +12,7 @@
|
|||||||
|
|
||||||
<!-- 步骤内容区域 -->
|
<!-- 步骤内容区域 -->
|
||||||
<div class="step-content">
|
<div class="step-content">
|
||||||
<keep-alive>
|
<component :is="currentStepComponent" :key="activeStep" ref="stepRef" :model-value="currentStepData" @update:model-value="handleStepDataUpdate" />
|
||||||
<component :is="currentStepComponent" ref="stepRef" :model-value="currentStepData" @update:model-value="handleStepDataUpdate" />
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
@ -160,13 +158,14 @@ const formData = ref({
|
|||||||
},
|
},
|
||||||
// 步骤4:费用与账户配置
|
// 步骤4:费用与账户配置
|
||||||
feeConfig: {
|
feeConfig: {
|
||||||
chargeMode: 'Free',
|
chargeMode: 0, // 0=免费,1=定价(赛事),2=单价(赛事),3=单价(项目)
|
||||||
price: 0,
|
price: 0,
|
||||||
merchantId: undefined,
|
merchantId: undefined,
|
||||||
merchantName: '',
|
merchantName: '',
|
||||||
creditCode: '',
|
creditCode: '',
|
||||||
bankName: '',
|
bankName: '',
|
||||||
accountNumber: '',
|
accountNumber: '',
|
||||||
|
businessLicenseUrl: '',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -191,6 +190,10 @@ const openDialog = async (id) => {
|
|||||||
console.log('openDialog called with id:', id);
|
console.log('openDialog called with id:', id);
|
||||||
dialog.isShowDialog = true;
|
dialog.isShowDialog = true;
|
||||||
dialog.loading = true;
|
dialog.loading = true;
|
||||||
|
|
||||||
|
// 先重置表单,清除前一个赛事的数据残留
|
||||||
|
handleReset();
|
||||||
|
|
||||||
if (id) {
|
if (id) {
|
||||||
dialog.title = '编辑赛事';
|
dialog.title = '编辑赛事';
|
||||||
dialog.submitTxt = '保 存';
|
dialog.submitTxt = '保 存';
|
||||||
@ -223,14 +226,24 @@ const openDialog = async (id) => {
|
|||||||
projects: d.projects ?? [],
|
projects: d.projects ?? [],
|
||||||
registrationLimit: d.registrationLimit ?? { individualProjectLimit: 1, teamProjectLimit: 1 },
|
registrationLimit: d.registrationLimit ?? { individualProjectLimit: 1, teamProjectLimit: 1 },
|
||||||
};
|
};
|
||||||
formData.value.feeConfig = { ...formData.value.feeConfig, ...(d.feeConfig ?? {}) };
|
// 完全覆盖 feeConfig,不要保留旧数据
|
||||||
console.log('formData.value', formData.value);
|
if (d.feeConfig) {
|
||||||
|
formData.value.feeConfig = {
|
||||||
|
chargeMode: d.feeConfig.chargeMode ?? 0,
|
||||||
|
price: d.feeConfig.price ?? 0,
|
||||||
|
merchantId: d.feeConfig.merchantId,
|
||||||
|
merchantName: d.feeConfig.merchantName ?? '',
|
||||||
|
creditCode: d.feeConfig.creditCode ?? '',
|
||||||
|
bankName: d.feeConfig.bankName ?? '',
|
||||||
|
accountNumber: d.feeConfig.accountNumber ?? '',
|
||||||
|
businessLicenseUrl: d.feeConfig.businessLicenseUrl ?? '',
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ElMessage.error('加载赛事详情失败');
|
ElMessage.error('加载赛事详情失败');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
handleReset();
|
|
||||||
dialog.title = '新增赛事';
|
dialog.title = '新增赛事';
|
||||||
dialog.submitTxt = '新 增';
|
dialog.submitTxt = '新 增';
|
||||||
}
|
}
|
||||||
@ -360,6 +373,7 @@ const handleReset = () => {
|
|||||||
creditCode: '',
|
creditCode: '',
|
||||||
bankName: '',
|
bankName: '',
|
||||||
accountNumber: '',
|
accountNumber: '',
|
||||||
|
businessLicenseUrl: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重置步骤
|
// 重置步骤
|
||||||
|
|||||||
@ -80,13 +80,13 @@ const refreshTable = () =>{
|
|||||||
}
|
}
|
||||||
const columns = reactive([
|
const columns = reactive([
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '80px',
|
||||||
prop: 'index',
|
prop: 'index',
|
||||||
label: '序号',
|
label: '序号',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '200px',
|
||||||
prop: 'eventName',
|
prop: 'eventName',
|
||||||
label: '赛事名称',
|
label: '赛事名称',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
@ -99,10 +99,9 @@ const columns = reactive([
|
|||||||
prop: 'coverImage',
|
prop: 'coverImage',
|
||||||
label: '封面',
|
label: '封面',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '120px',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '100px',
|
||||||
prop: 'eventType',
|
prop: 'eventType',
|
||||||
label: '赛事类型',
|
label: '赛事类型',
|
||||||
search: {
|
search: {
|
||||||
@ -115,7 +114,7 @@ const columns = reactive([
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '130px',
|
||||||
prop: 'registrationType',
|
prop: 'registrationType',
|
||||||
label: '报名方式',
|
label: '报名方式',
|
||||||
enum: [
|
enum: [
|
||||||
@ -125,7 +124,7 @@ const columns = reactive([
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '130px',
|
||||||
prop: 'chargeMode',
|
prop: 'chargeMode',
|
||||||
label: '收费模式',
|
label: '收费模式',
|
||||||
search: {
|
search: {
|
||||||
@ -139,10 +138,9 @@ const columns = reactive([
|
|||||||
{ label: '单价(项目)', value: 3 },
|
{ label: '单价(项目)', value: 3 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{ prop: 'merchantName', label: '收款账户', width: '150px', },
|
||||||
{ prop: 'merchantName', label: '收款账户',width: '120px', },
|
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '100px',
|
||||||
prop: 'eventStatus',
|
prop: 'eventStatus',
|
||||||
label: '赛事状态',
|
label: '赛事状态',
|
||||||
search: {
|
search: {
|
||||||
@ -157,7 +155,7 @@ const columns = reactive([
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '160px',
|
||||||
prop: 'registrationStartTime',
|
prop: 'registrationStartTime',
|
||||||
label: '报名开始时间',
|
label: '报名开始时间',
|
||||||
search: {
|
search: {
|
||||||
@ -168,7 +166,7 @@ const columns = reactive([
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '160px',
|
||||||
prop: 'registrationEndTime',
|
prop: 'registrationEndTime',
|
||||||
label: '报名结束时间',
|
label: '报名结束时间',
|
||||||
search: {
|
search: {
|
||||||
@ -179,7 +177,7 @@ const columns = reactive([
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '160px',
|
||||||
prop: 'matchStartTime',
|
prop: 'matchStartTime',
|
||||||
label: '比赛开始时间',
|
label: '比赛开始时间',
|
||||||
search: {
|
search: {
|
||||||
@ -190,7 +188,7 @@ const columns = reactive([
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
width: '120px',
|
width: '160px',
|
||||||
prop: 'matchEndTime',
|
prop: 'matchEndTime',
|
||||||
label: '比赛结束时间',
|
label: '比赛结束时间',
|
||||||
search: {
|
search: {
|
||||||
@ -200,7 +198,7 @@ const columns = reactive([
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ prop: 'action', label: '操作', align: 'center', width: 160, fixed: 'right', isShow: auths(['event:edit', 'event:delete']) },
|
{ prop: 'action', label: '操作', align: 'center', width: 200, fixed: 'right', isShow: auths(['event:edit', 'event:delete']) },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const exportableColumns = computed(() =>
|
const exportableColumns = computed(() =>
|
||||||
|
|||||||
@ -420,7 +420,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, nextTick, onUnmounted } from 'vue';
|
import { ref, computed, nextTick, onUnmounted } from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { Close, Picture, Loading, CircleCheck, ArrowRight } from '@element-plus/icons-vue';
|
import { Close, Picture, Loading, CircleCheck, ArrowRight } from '@element-plus/icons-vue';
|
||||||
import ProTable from '/@/components/ProTable/index.vue';
|
import ProTable from '/@/components/ProTable/index.vue';
|
||||||
import { formatDate } from '/@/utils/formatTime';
|
import { formatDate } from '/@/utils/formatTime';
|
||||||
@ -954,9 +954,6 @@ const openRegistrationDialog = async (row) => {
|
|||||||
|
|
||||||
clearRegisterState();
|
clearRegisterState();
|
||||||
currentEventId.value = eventId;
|
currentEventId.value = eventId;
|
||||||
isShowRegisterDialog.value = true;
|
|
||||||
|
|
||||||
activeStep.value = 0;
|
|
||||||
registerLoading.value = true;
|
registerLoading.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -965,9 +962,26 @@ const openRegistrationDialog = async (row) => {
|
|||||||
ElMessage.error(data ?? '项目加载失败');
|
ElMessage.error(data ?? '项目加载失败');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查报名类型,如果是只允许个人报名,则显示提示并阻止继续
|
||||||
|
const registrationType = data?.registrationType;
|
||||||
|
if (registrationType === 'OnlyIndividual') {
|
||||||
|
ElMessageBox.alert(
|
||||||
|
'当前赛事只允许个人报名,请到移动端进行个人报名',
|
||||||
|
'提示',
|
||||||
|
{
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
type: 'warning'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 保存完整的详情数据,用于项目类型显示等
|
// 保存完整的详情数据,用于项目类型显示等
|
||||||
detailData.value = data;
|
detailData.value = data;
|
||||||
projects.value = Array.isArray(data?.projects) ? data.projects : [];
|
projects.value = Array.isArray(data?.projects) ? data.projects : [];
|
||||||
|
isShowRegisterDialog.value = true;
|
||||||
|
activeStep.value = 0;
|
||||||
} catch {
|
} catch {
|
||||||
ElMessage.error('项目加载失败');
|
ElMessage.error('项目加载失败');
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user