赛事管理bug
This commit is contained in:
parent
1c15442978
commit
762483d07d
@ -124,7 +124,7 @@ const localFormData = ref({
|
||||
// init from parent
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
async (v) => {
|
||||
console.log('init from parent', v);
|
||||
if (!v) return;
|
||||
Object.keys(localFormData.value).forEach((k) => {
|
||||
@ -137,6 +137,21 @@ watch(
|
||||
}
|
||||
});
|
||||
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 }
|
||||
);
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
</div>
|
||||
<div class="account-item">
|
||||
<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>
|
||||
@ -149,15 +149,67 @@ const localFormData = ref({
|
||||
creditCode: '',
|
||||
bankName: '',
|
||||
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(
|
||||
() => props.modelValue,
|
||||
(v) => {
|
||||
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 }
|
||||
);
|
||||
@ -167,8 +219,7 @@ watch(
|
||||
(v) => emit('update:modelValue', { ...props.modelValue, ...v }),
|
||||
{ deep: true }
|
||||
);
|
||||
const businessLicenseUrl = ref('');
|
||||
const merchantOptions = ref([]);
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await merchantPageGet({ PageNo: 1, PageSize: 200 });
|
||||
@ -185,27 +236,11 @@ onMounted(async () => {
|
||||
} catch {
|
||||
merchantOptions.value = [];
|
||||
}
|
||||
|
||||
isInitialized.value = true;
|
||||
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 merchantList = ref([]);
|
||||
@ -256,16 +291,47 @@ const selectMerchant = (row) => {
|
||||
localFormData.value.creditCode = row.creditCode ?? '';
|
||||
localFormData.value.bankName = row.bankName ?? '';
|
||||
localFormData.value.accountNumber = row.accountNumber ?? '';
|
||||
businessLicenseUrl.value = row.businessLicenseUrl ?? '';
|
||||
localFormData.value.businessLicenseUrl = row.businessLicenseUrl ?? '';
|
||||
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 = {
|
||||
chargeMode: [{ required: true, message: '请选择收费模式', trigger: 'change' }],
|
||||
price: [{ required: false, message: '请输入价格', trigger: 'change' }],
|
||||
merchantId: [{ required: true, message: '请选择收款商户', trigger: 'change' }],
|
||||
price: [
|
||||
{ validator: validatePrice, trigger: 'change' }
|
||||
],
|
||||
merchantId: [
|
||||
{ validator: validateMerchantId, trigger: 'change' }
|
||||
],
|
||||
bankName: [{ required: false, message: '请输入开户银行', trigger: 'blur' }],
|
||||
accountNumber: [{ required: false, message: '请输入银行账号', trigger: 'blur' }],
|
||||
};
|
||||
|
||||
@ -12,9 +12,7 @@
|
||||
|
||||
<!-- 步骤内容区域 -->
|
||||
<div class="step-content">
|
||||
<keep-alive>
|
||||
<component :is="currentStepComponent" ref="stepRef" :model-value="currentStepData" @update:model-value="handleStepDataUpdate" />
|
||||
</keep-alive>
|
||||
<component :is="currentStepComponent" :key="activeStep" ref="stepRef" :model-value="currentStepData" @update:model-value="handleStepDataUpdate" />
|
||||
</div>
|
||||
|
||||
<!-- 底部操作按钮 -->
|
||||
@ -160,13 +158,14 @@ const formData = ref({
|
||||
},
|
||||
// 步骤4:费用与账户配置
|
||||
feeConfig: {
|
||||
chargeMode: 'Free',
|
||||
chargeMode: 0, // 0=免费,1=定价(赛事),2=单价(赛事),3=单价(项目)
|
||||
price: 0,
|
||||
merchantId: undefined,
|
||||
merchantName: '',
|
||||
creditCode: '',
|
||||
bankName: '',
|
||||
accountNumber: '',
|
||||
businessLicenseUrl: '',
|
||||
},
|
||||
});
|
||||
|
||||
@ -191,6 +190,10 @@ const openDialog = async (id) => {
|
||||
console.log('openDialog called with id:', id);
|
||||
dialog.isShowDialog = true;
|
||||
dialog.loading = true;
|
||||
|
||||
// 先重置表单,清除前一个赛事的数据残留
|
||||
handleReset();
|
||||
|
||||
if (id) {
|
||||
dialog.title = '编辑赛事';
|
||||
dialog.submitTxt = '保 存';
|
||||
@ -223,14 +226,24 @@ const openDialog = async (id) => {
|
||||
projects: d.projects ?? [],
|
||||
registrationLimit: d.registrationLimit ?? { individualProjectLimit: 1, teamProjectLimit: 1 },
|
||||
};
|
||||
formData.value.feeConfig = { ...formData.value.feeConfig, ...(d.feeConfig ?? {}) };
|
||||
console.log('formData.value', formData.value);
|
||||
// 完全覆盖 feeConfig,不要保留旧数据
|
||||
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) {
|
||||
ElMessage.error('加载赛事详情失败');
|
||||
}
|
||||
} else {
|
||||
handleReset();
|
||||
dialog.title = '新增赛事';
|
||||
dialog.submitTxt = '新 增';
|
||||
}
|
||||
@ -360,6 +373,7 @@ const handleReset = () => {
|
||||
creditCode: '',
|
||||
bankName: '',
|
||||
accountNumber: '',
|
||||
businessLicenseUrl: '',
|
||||
};
|
||||
|
||||
// 重置步骤
|
||||
|
||||
@ -80,13 +80,13 @@ const refreshTable = () =>{
|
||||
}
|
||||
const columns = reactive([
|
||||
{
|
||||
width: '120px',
|
||||
width: '80px',
|
||||
prop: 'index',
|
||||
label: '序号',
|
||||
align: 'center',
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '200px',
|
||||
prop: 'eventName',
|
||||
label: '赛事名称',
|
||||
align: 'center',
|
||||
@ -99,10 +99,9 @@ const columns = reactive([
|
||||
prop: 'coverImage',
|
||||
label: '封面',
|
||||
align: 'center',
|
||||
width: '120px',
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '100px',
|
||||
prop: 'eventType',
|
||||
label: '赛事类型',
|
||||
search: {
|
||||
@ -115,7 +114,7 @@ const columns = reactive([
|
||||
],
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '130px',
|
||||
prop: 'registrationType',
|
||||
label: '报名方式',
|
||||
enum: [
|
||||
@ -125,7 +124,7 @@ const columns = reactive([
|
||||
],
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '130px',
|
||||
prop: 'chargeMode',
|
||||
label: '收费模式',
|
||||
search: {
|
||||
@ -139,10 +138,9 @@ const columns = reactive([
|
||||
{ label: '单价(项目)', value: 3 },
|
||||
],
|
||||
},
|
||||
|
||||
{ prop: 'merchantName', label: '收款账户',width: '120px', },
|
||||
{ prop: 'merchantName', label: '收款账户', width: '150px', },
|
||||
{
|
||||
width: '120px',
|
||||
width: '100px',
|
||||
prop: 'eventStatus',
|
||||
label: '赛事状态',
|
||||
search: {
|
||||
@ -157,7 +155,7 @@ const columns = reactive([
|
||||
],
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '160px',
|
||||
prop: 'registrationStartTime',
|
||||
label: '报名开始时间',
|
||||
search: {
|
||||
@ -168,7 +166,7 @@ const columns = reactive([
|
||||
},
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '160px',
|
||||
prop: 'registrationEndTime',
|
||||
label: '报名结束时间',
|
||||
search: {
|
||||
@ -179,7 +177,7 @@ const columns = reactive([
|
||||
},
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '160px',
|
||||
prop: 'matchStartTime',
|
||||
label: '比赛开始时间',
|
||||
search: {
|
||||
@ -190,7 +188,7 @@ const columns = reactive([
|
||||
},
|
||||
},
|
||||
{
|
||||
width: '120px',
|
||||
width: '160px',
|
||||
prop: 'matchEndTime',
|
||||
label: '比赛结束时间',
|
||||
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(() =>
|
||||
|
||||
@ -420,7 +420,7 @@
|
||||
|
||||
<script setup>
|
||||
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 ProTable from '/@/components/ProTable/index.vue';
|
||||
import { formatDate } from '/@/utils/formatTime';
|
||||
@ -954,9 +954,6 @@ const openRegistrationDialog = async (row) => {
|
||||
|
||||
clearRegisterState();
|
||||
currentEventId.value = eventId;
|
||||
isShowRegisterDialog.value = true;
|
||||
|
||||
activeStep.value = 0;
|
||||
registerLoading.value = true;
|
||||
|
||||
try {
|
||||
@ -965,9 +962,26 @@ const openRegistrationDialog = async (row) => {
|
||||
ElMessage.error(data ?? '项目加载失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查报名类型,如果是只允许个人报名,则显示提示并阻止继续
|
||||
const registrationType = data?.registrationType;
|
||||
if (registrationType === 'OnlyIndividual') {
|
||||
ElMessageBox.alert(
|
||||
'当前赛事只允许个人报名,请到移动端进行个人报名',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning'
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 保存完整的详情数据,用于项目类型显示等
|
||||
detailData.value = data;
|
||||
projects.value = Array.isArray(data?.projects) ? data.projects : [];
|
||||
isShowRegisterDialog.value = true;
|
||||
activeStep.value = 0;
|
||||
} catch {
|
||||
ElMessage.error('项目加载失败');
|
||||
} finally {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user