From 13eb3115758067a589bb52976170208d0e70541c Mon Sep 17 00:00:00 2001 From: DevOps Date: Mon, 5 Jan 2026 15:12:04 +0800 Subject: [PATCH] feat: add contact management and various bug fixes - Add contact API methods in athlete.js - Add contact list display in common-info.vue - Update add-contact.vue for contact creation - Create edit-contact page for contact editing - Fix event-register.vue with contact picker modal - Fix home.vue registration status display - Fix my-registration.vue cert modal display Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> --- src/api/athlete.js | 34 ++- src/pages.json | 279 ++---------------- src/pages/add-contact/add-contact.vue | 188 +++--------- src/pages/common-info/common-info.vue | 159 ++++++---- src/pages/edit-contact/edit-contact.vue | 249 ++++++++++++++++ src/pages/event-register/event-register.vue | 166 ++++++++++- src/pages/home/home.vue | 12 +- src/pages/my-registration/my-registration.vue | 122 +++++++- 8 files changed, 720 insertions(+), 489 deletions(-) create mode 100644 src/pages/edit-contact/edit-contact.vue diff --git a/src/api/athlete.js b/src/api/athlete.js index 456e657..9bfa15c 100644 --- a/src/api/athlete.js +++ b/src/api/athlete.js @@ -41,9 +41,6 @@ export default { // ========== 集体/团队相关 API ========== - /** - * 获取集体列表 - */ getTeamList(params = {}) { return request.get('/martial/team/list', { current: params.current || 1, @@ -52,24 +49,37 @@ export default { }) }, - /** - * 获取集体详情 - */ getTeamDetail(id) { return request.get('/martial/team/detail', { id }) }, - /** - * 保存集体 - */ saveTeam(data) { return request.post('/martial/team/submit', data) }, - /** - * 删除集体 - */ removeTeam(id) { return request.post('/martial/team/remove?id=' + id, {}) + }, + + // ========== 联系人相关 API ========== + + getContactList(params = {}) { + return request.get('/martial/contact/list', { + current: params.current || 1, + size: params.size || 100, + ...params + }) + }, + + getContactDetail(id) { + return request.get('/martial/contact/detail', { id }) + }, + + saveContact(data) { + return request.post('/martial/contact/submit', data) + }, + + removeContact(id) { + return request.post('/martial/contact/remove?ids=' + id, {}) } } diff --git a/src/pages.json b/src/pages.json index a771b7f..84ae7d6 100644 --- a/src/pages.json +++ b/src/pages.json @@ -1,252 +1,35 @@ { "pages": [ - { - "path": "pages/login/login", - "style": { - "navigationBarTitleText": "登录", - "navigationStyle": "custom" - } - }, - { - "path": "pages/register/register", - "style": { - "navigationBarTitleText": "注册", - "navigationStyle": "custom" - } - }, - { - "path": "pages/home/home", - "style": { - "navigationBarTitleText": "武术赛事通", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/profile/profile", - "style": { - "navigationBarTitleText": "个人中心", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/change-password/change-password", - "style": { - "navigationBarTitleText": "修改密码", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/common-info/common-info", - "style": { - "navigationBarTitleText": "常用信息", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/add-player/add-player", - "style": { - "navigationBarTitleText": "新增选手", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/add-team/add-team", - "style": { - "navigationBarTitleText": "新增集体", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/edit-team/edit-team", - "style": { - "navigationBarTitleText": "编辑集体", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/edit-player/edit-player", - "style": { - "navigationBarTitleText": "编辑选手", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/add-contact/add-contact", - "style": { - "navigationBarTitleText": "新增联系人", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/my-registration/my-registration", - "style": { - "navigationBarTitleText": "我的报名", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-list/event-list", - "style": { - "navigationBarTitleText": "全部赛事列表", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-detail/event-detail", - "style": { - "navigationBarTitleText": "赛事详情", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/select-event/select-event", - "style": { - "navigationBarTitleText": "选择报名项目", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-register/event-register", - "style": { - "navigationBarTitleText": "赛事报名", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/register-type/register-type", - "style": { - "navigationBarTitleText": "选择报名", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-info/event-info", - "style": { - "navigationBarTitleText": "信息发布", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-info-detail/event-info-detail", - "style": { - "navigationBarTitleText": "信息详情", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-rules/event-rules", - "style": { - "navigationBarTitleText": "赛事规程", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-schedule/event-schedule", - "style": { - "navigationBarTitleText": "活动日程", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-players/event-players", - "style": { - "navigationBarTitleText": "参赛选手", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-live/event-live", - "style": { - "navigationBarTitleText": "比赛实况", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-lineup/event-lineup", - "style": { - "navigationBarTitleText": "出场顺序", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-score/event-score", - "style": { - "navigationBarTitleText": "成绩", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-medals/event-medals", - "style": { - "navigationBarTitleText": "奖牌榜", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/attachment-view/attachment-view", - "style": { - "navigationBarTitleText": "附件查看", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - }, - { - "path": "pages/event-photos/event-photos", - "style": { - "navigationBarTitleText": "图片直播", - "navigationBarBackgroundColor": "#C93639", - "navigationBarTextStyle": "white" - } - } + {"path": "pages/login/login", "style": {"navigationBarTitleText": "登录", "navigationStyle": "custom"}}, + {"path": "pages/register/register", "style": {"navigationBarTitleText": "注册", "navigationStyle": "custom"}}, + {"path": "pages/home/home", "style": {"navigationBarTitleText": "武术赛事通", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/profile/profile", "style": {"navigationBarTitleText": "个人中心", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/change-password/change-password", "style": {"navigationBarTitleText": "修改密码", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/common-info/common-info", "style": {"navigationBarTitleText": "常用信息", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/add-player/add-player", "style": {"navigationBarTitleText": "新增选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/add-team/add-team", "style": {"navigationBarTitleText": "新增集体", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/edit-team/edit-team", "style": {"navigationBarTitleText": "编辑集体", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/edit-player/edit-player", "style": {"navigationBarTitleText": "编辑选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/add-contact/add-contact", "style": {"navigationBarTitleText": "新增联系人", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/edit-contact/edit-contact", "style": {"navigationBarTitleText": "编辑联系人", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/my-registration/my-registration", "style": {"navigationBarTitleText": "我的报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-list/event-list", "style": {"navigationBarTitleText": "全部赛事列表", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-detail/event-detail", "style": {"navigationBarTitleText": "赛事详情", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/select-event/select-event", "style": {"navigationBarTitleText": "选择报名项目", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-register/event-register", "style": {"navigationBarTitleText": "赛事报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/register-type/register-type", "style": {"navigationBarTitleText": "选择报名", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-info/event-info", "style": {"navigationBarTitleText": "信息发布", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-info-detail/event-info-detail", "style": {"navigationBarTitleText": "信息详情", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-rules/event-rules", "style": {"navigationBarTitleText": "赛事规程", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-schedule/event-schedule", "style": {"navigationBarTitleText": "活动日程", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-players/event-players", "style": {"navigationBarTitleText": "参赛选手", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-live/event-live", "style": {"navigationBarTitleText": "比赛实况", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-lineup/event-lineup", "style": {"navigationBarTitleText": "出场顺序", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-score/event-score", "style": {"navigationBarTitleText": "成绩", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-medals/event-medals", "style": {"navigationBarTitleText": "奖牌榜", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/attachment-view/attachment-view", "style": {"navigationBarTitleText": "附件查看", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}}, + {"path": "pages/event-photos/event-photos", "style": {"navigationBarTitleText": "图片直播", "navigationBarBackgroundColor": "#C93639", "navigationBarTextStyle": "white"}} ], - "globalStyle": { - "navigationBarTextStyle": "white", - "navigationBarTitleText": "武术赛事", - "navigationBarBackgroundColor": "#C93639", - "backgroundColor": "#F8F8F8" - }, - "tabBar": { - "color": "#999999", - "selectedColor": "#C93639", - "backgroundColor": "#ffffff", - "borderStyle": "black", - "list": [ - { - "pagePath": "pages/home/home", - "text": "首页", - "iconPath": "static/images/首页灰@3x.png", - "selectedIconPath": "static/images/首页亮@3x.png" - }, - { - "pagePath": "pages/profile/profile", - "text": "个人中心", - "iconPath": "static/images/个人中心灰@3x.png", - "selectedIconPath": "static/images/个人中心亮@3x.png" - } - ] - } + "globalStyle": {"navigationBarTextStyle": "white", "navigationBarTitleText": "武术赛事", "navigationBarBackgroundColor": "#C93639", "backgroundColor": "#F8F8F8"}, + "tabBar": {"color": "#999999", "selectedColor": "#C93639", "backgroundColor": "#ffffff", "borderStyle": "black", "list": [{"pagePath": "pages/home/home", "text": "首页", "iconPath": "static/images/首页灰@3x.png", "selectedIconPath": "static/images/首页亮@3x.png"}, {"pagePath": "pages/profile/profile", "text": "个人中心", "iconPath": "static/images/个人中心灰@3x.png", "selectedIconPath": "static/images/个人中心亮@3x.png"}]} } diff --git a/src/pages/add-contact/add-contact.vue b/src/pages/add-contact/add-contact.vue index 1369291..796ee91 100644 --- a/src/pages/add-contact/add-contact.vue +++ b/src/pages/add-contact/add-contact.vue @@ -13,82 +13,46 @@ 姓名 - + 证件号码 - + 手机号码 - + 邮箱 - + 地址 - + 设置为默认联系人 - + - - - - {{ hintText }} - - {{ toastMessage }} @@ -96,13 +60,16 @@ - 保存 - 保存 + + {{ saving ? '保存中...' : '保存' }} + + + diff --git a/src/pages/event-register/event-register.vue b/src/pages/event-register/event-register.vue index 8e37571..6097ef2 100644 --- a/src/pages/event-register/event-register.vue +++ b/src/pages/event-register/event-register.vue @@ -98,22 +98,22 @@ {{ eventInfo.title }} - + 地点: {{ eventInfo.location }} - + 比赛时间: {{ eventInfo.matchTime }} - + 报名项目: {{ eventInfo.projects }} - + 联系人: - {{ eventInfo.contact }} - 📋 + {{ selectedContact ? selectedContact.name + " " + selectedContact.phone : "请选择联系人" }} + (注意是否用此号码接收信息) @@ -151,21 +151,21 @@ {{ eventInfo.title }} - + 地点: {{ eventInfo.location }} - + 比赛时间: {{ eventInfo.matchTime }} - + 报名项目: {{ eventInfo.projects }} - + 联系人: - {{ eventInfo.contact }} + {{ selectedContact ? selectedContact.name + " " + selectedContact.phone : "请选择联系人" }} @@ -240,6 +266,9 @@ export default { selectedPlayers: [], selectedTeams: [], showPlayerModal: false, + showContactPicker: false, + contactList: [], + selectedContact: null, totalPrice: 0, registrationId: '' }; @@ -290,6 +319,38 @@ export default { } }, methods: { + // Contact methods + async loadContactList() { + try { + const res = await athleteAPI.getContactList({ current: 1, size: 100 }) + this.contactList = (res.records || []).map(item => ({ + id: item.id, + name: item.name, + phone: item.phone, + idCard: item.idCard + })) + // Auto select default contact if exists + if (!this.selectedContact && this.contactList.length > 0) { + const defaultContact = this.contactList.find(c => c.isDefault) || this.contactList[0] + this.selectedContact = defaultContact + } + } catch (err) { + console.error('加载联系人列表失败:', err) + } + }, + + selectContact(contact) { + this.selectedContact = contact + this.showContactPicker = false + }, + + goToAddContact() { + this.showContactPicker = false + uni.navigateTo({ + url: '/pages/add-contact/add-contact' + }) + }, + async loadEventDetail(id) { try { const res = await competitionAPI.getCompetitionDetail(id) @@ -487,6 +548,7 @@ export default { } this.totalPrice = this.calculateTotalPrice() + this.loadContactList() this.$nextTick(() => { this.currentStep = 2 }) }, @@ -518,7 +580,7 @@ export default { projectIds: this.selectedProjects.map(p => String(p.id)), teamIds: selected.map(t => String(t.id)), athleteIds: [], - contactPhone: this.eventInfo.contact || '', + contactPhone: this.selectedContact ? this.selectedContact.phone : '', totalAmount: parseFloat(this.totalPrice) || 0 } } else { @@ -532,7 +594,7 @@ export default { competitionId: String(this.eventId), projectIds: this.selectedProjects.map(p => String(p.id)), athleteIds: selected.map(p => String(p.id)), - contactPhone: this.eventInfo.contact || '', + contactPhone: this.selectedContact ? this.selectedContact.phone : '', totalAmount: parseFloat(this.totalPrice) || 0 } } @@ -1014,6 +1076,84 @@ export default { color: #C93639; margin-top: 10rpx; } + +/* Contact Modal Styles */ +.contact-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: flex-end; + z-index: 1000; +} + +.contact-modal .modal-content { + background-color: #fff; + border-radius: 24rpx 24rpx 0 0; + width: 100%; + max-height: 70vh; +} + +.contact-modal .add-contact-btn { + display: flex; + align-items: center; + justify-content: center; + padding: 24rpx; + border-bottom: 1rpx solid #eee; + color: #C93639; + font-size: 28rpx; +} + +.contact-modal .add-contact-btn .add-icon { + margin-right: 10rpx; + font-size: 32rpx; +} + +.contact-modal .contact-list { + max-height: 50vh; +} + +.contact-modal .contact-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 24rpx 30rpx; + border-bottom: 1rpx solid #f5f5f5; +} + +.contact-modal .contact-info { + flex: 1; +} + +.contact-modal .contact-name { + font-size: 30rpx; + color: #333; + margin-bottom: 8rpx; +} + +.contact-modal .contact-phone { + font-size: 26rpx; + color: #999; +} + +.contact-modal .contact-check { + color: #C93639; + font-size: 36rpx; + font-weight: bold; +} + +.contact-item.clickable, +.info-item.contact-item { + cursor: pointer; +} + +.info-item .placeholder { + color: #999; +} + .empty-state { diff --git a/src/pages/home/home.vue b/src/pages/home/home.vue index 3082e06..aa55681 100644 --- a/src/pages/home/home.vue +++ b/src/pages/home/home.vue @@ -138,7 +138,7 @@ export default { matchTime: this.formatTimeRange(startTime, endTime) || item.matchTime || item.competitionTime || '待定', registerCount: item.registrationCount || item.registerCount || item.signUpCount || item.totalParticipants || '0', - status: this.getStatus(item.status) + status: this.getStatus(item.status, regEndTime) } }) @@ -174,12 +174,20 @@ export default { * @param {Number|String} status 状态码 * @returns {String} */ - getStatus(status) { + getStatus(status, regEndTime) { // 根据后端状态码映射为前端需要的状态 // 1: 报名中, 2: 进行中, 3: 已结束 if (status === 3 || status === '3' || status === 'finished') { return 'finished' } + // 根据报名结束时间判断是否已结束 + if (regEndTime) { + const endDate = new Date(regEndTime) + const now = new Date() + if (now > endDate) { + return 'finished' + } + } return 'open' }, diff --git a/src/pages/my-registration/my-registration.vue b/src/pages/my-registration/my-registration.vue index a45c694..88271f4 100644 --- a/src/pages/my-registration/my-registration.vue +++ b/src/pages/my-registration/my-registration.vue @@ -42,8 +42,8 @@ {{ item.participants }} - - + + 点击后进入【赛事详情】页面 @@ -58,6 +58,26 @@ 暂无报名记录 + + + + + + 参赛选手证件 + + + + + {{ athlete.playerName }} + 性别:{{ athlete.gender === 1 ? '男' : '女' }} + 身份证:{{ athlete.idCard || '暂无' }} + + + 暂无选手信息 + + + + @@ -80,7 +100,9 @@ export default { current: 1, size: 20 }, - hasMore: true + hasMore: true, + showCertModal: false, + certAthleteList: [] }; }, onLoad() { @@ -235,7 +257,8 @@ export default { ) || '', projects: item.projectNames || this.formatProjects(item.projects) || '', contact: item.contactPhone || item.contactPerson || '', - participants: item.athleteNames || `${item.totalParticipants || 0}人` + participants: item.athleteNames || `${item.totalParticipants || 0}人`, + athleteList: item.athleteList || [] } }, @@ -322,10 +345,20 @@ export default { }); }, handleViewCert(item) { - uni.showToast({ - title: '查看证件', - icon: 'none' - }); + // Get athlete list from the item + if (item.athleteList && item.athleteList.length > 0) { + this.certAthleteList = item.athleteList; + this.showCertModal = true; + } else { + uni.showToast({ + title: '暂无选手证件信息', + icon: 'none' + }); + } + }, + closeCertModal() { + this.showCertModal = false; + this.certAthleteList = []; } } }; @@ -446,4 +479,77 @@ export default { font-size: 28rpx; color: #999999; } + +/* Cert Modal Styles */ +.cert-modal { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.cert-modal-content { + background-color: #fff; + border-radius: 16rpx; + width: 85%; + max-height: 70vh; + overflow: hidden; +} + +.cert-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 30rpx; + border-bottom: 1rpx solid #eee; +} + +.cert-modal-title { + font-size: 32rpx; + font-weight: bold; + color: #333; +} + +.cert-close-icon { + font-size: 36rpx; + color: #999; + cursor: pointer; +} + +.cert-modal-body { + max-height: 50vh; + padding: 20rpx 30rpx; +} + +.cert-athlete-item { + padding: 20rpx; + background-color: #f9f9f9; + border-radius: 12rpx; + margin-bottom: 20rpx; +} + +.cert-athlete-name { + font-size: 30rpx; + font-weight: bold; + color: #333; + margin-bottom: 10rpx; +} + +.cert-athlete-info { + font-size: 26rpx; + color: #666; + margin-bottom: 6rpx; +} + +.cert-empty { + text-align: center; + padding: 40rpx; + color: #999; +}