From c4faf651879d17f5d1df29ca053ac71704694ff8 Mon Sep 17 00:00:00 2001 From: ltx <1006158920@qq.com> Date: Tue, 7 Apr 2026 16:47:13 +0800 Subject: [PATCH] =?UTF-8?q?update:=E8=B5=9B=E4=BA=8B=E8=AF=A6=E6=83=85&?= =?UTF-8?q?=E6=8A=A5=E5=90=8D=E9=99=90=E5=88=B6&openid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/apply/apply.js | 339 +++++++++++++++++++++++++++++++++- pages/apply/apply.wxml | 5 +- pages/apply/apply.wxss | 23 +++ pages/detail/detail.js | 101 +++++++++- pages/detail/detail.wxml | 7 +- pages/detail/detail.wxss | 8 + pages/home/home.js | 40 ++-- pages/home/home.wxml | 8 +- pages/home/home.wxss | 6 +- pages/mine/mine.js | 8 + pages/mine/mine.wxml | 4 + subpackages/mine/auth/auth.js | 2 +- utils/constants.js | 2 + utils/format.js | 43 ++++- 14 files changed, 557 insertions(+), 39 deletions(-) diff --git a/pages/apply/apply.js b/pages/apply/apply.js index b036950..624611c 100644 --- a/pages/apply/apply.js +++ b/pages/apply/apply.js @@ -1,6 +1,7 @@ const { API } = require('../../utils/constants'); const { request } = require('../../utils/http'); const { formatDateTime } = require('../../utils/format'); +const auth = require('../../utils/auth'); // 中文数字映射(项目一、二、三…) const CN_NUM = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十']; @@ -9,6 +10,23 @@ const CN_NUM = ['一', '二', '三', '四', '五', '六', '七', '八', '九', ' * 将 projects 数组转换为按项目分组的结构 * 每个项目下展开所有 groups,附带 selected 状态 */ +function getEventStatus(detail) { + if (!detail || typeof detail !== 'object') return null; + const v = detail.eventStatus != null ? detail.eventStatus : detail.EventStatus; + if (v == null || v === '') return null; + const n = Number(v); + return Number.isNaN(n) ? null : n; +} + +/** 仅 1=报名中 可进入报名页;与后端 EventStatus 枚举一致 */ +function toastForBlockedEventStatus(es) { + if (es === 0) return '赛事未开始'; + if (es === 2) return '报名已结束'; + if (es === 3) return '比赛进行中,暂不可报名'; + if (es === 4) return '赛事已结束'; + return '暂不可报名'; +} + function buildProjectGroups(projects) { return projects.map((p, idx) => { const groups = Array.isArray(p.groups) ? p.groups : []; @@ -25,7 +43,8 @@ function buildProjectGroups(projects) { fee: g.fee != null ? g.fee : (p.fee != null ? p.fee : 0), selected: false, ageRequirement: g.ageRequirement || g.AgeRequirement || '', - genderRequirement: g.genderRequirement || g.GenderRequirement || '不限' + genderRequirement: g.genderRequirement != null ? g.genderRequirement : g.GenderRequirement != null ? g.GenderRequirement : '', + genderRequirementText: genderRequirementText(g.genderRequirement != null ? g.genderRequirement : g.GenderRequirement) })) }; }); @@ -42,6 +61,107 @@ function calcTotalPrice(projectGroups) { return total; } +function toNonNegInt(v) { + const n = Number(v); + if (Number.isNaN(n)) return null; + const i = Math.floor(n); + return i >= 0 ? i : null; +} + +function genderRequirementText(v) { + if (v === undefined || v === null || v === '') return '不限'; + const s = String(v).trim(); + if (s === '0' || s === '男' || s.toUpperCase() === 'M') return '男'; + if (s === '1' || s === '女' || s.toUpperCase() === 'F') return '女'; + if (s === '2' || s === '不限' || s === '全部') return '不限'; + return s; +} + +function normalizeGenderToNum(v) { + if (v === undefined || v === null || v === '') return null; + const s = String(v).trim(); + if (s === '0' || s === '男' || s.toUpperCase() === 'M') return 0; + if (s === '1' || s === '女' || s.toUpperCase() === 'F') return 1; + if (s === '2' || s === '不限' || s === '全部') return 2; + const n = Number(s); + if (!Number.isNaN(n) && (n === 0 || n === 1 || n === 2)) return n; + return null; +} + +function parseYmdDate(s) { + if (!s) return null; + const str = String(s).trim(); + const m = str.match(/^(\d{4})-(\d{2})-(\d{2})/); + if (!m) return null; + const y = Number(m[1]); + const mo = Number(m[2]); + const d = Number(m[3]); + if ([y, mo, d].some((x) => Number.isNaN(x))) return null; + const dt = new Date(y, mo - 1, d); + return Number.isNaN(dt.getTime()) ? null : dt; +} + +function calcAgeYears(birthDateStr, atDateStr) { + const b = parseYmdDate(birthDateStr); + if (!b) return null; + const at = parseYmdDate(atDateStr) || new Date(); + let age = at.getFullYear() - b.getFullYear(); + const m = at.getMonth() - b.getMonth(); + if (m < 0 || (m === 0 && at.getDate() < b.getDate())) age -= 1; + return age >= 0 ? age : null; +} + +function parseAgeRangeText(text) { + if (!text) return null; + const s = String(text); + const nums = s.match(/\d+/g); + if (!nums || nums.length === 0) return null; + const a = Number(nums[0]); + if (Number.isNaN(a)) return null; + if (nums.length === 1) return { min: a, max: a }; + const b = Number(nums[1]); + if (Number.isNaN(b)) return { min: a, max: a }; + return { min: Math.min(a, b), max: Math.max(a, b) }; +} + +function isIndividualProject(p) { + const t = (p && (p.typeName || p.TypeName)) || ''; + const s = String(t); + // 只显示个人项目:个人速度、个人花样等 + return s.includes('个人'); +} + +function projectTypeOf(rawProject) { + const t = (rawProject && (rawProject.typeName || rawProject.TypeName)) || ''; + const s = String(t); + if (s.includes('团队')) return 'team'; + if (s.includes('个人')) return 'individual'; + return 'unknown'; +} + +function countSelectedByType(projectGroups, rawProjects) { + const map = new Map(); + (rawProjects || []).forEach((p) => { + const pid = Number(p.id != null ? p.id : p.Id); + if (!Number.isNaN(pid)) map.set(pid, projectTypeOf(p)); + }); + + let individual = 0; + let team = 0; + let unknown = 0; + projectGroups.forEach((pg) => { + const pid = Number(pg.projectId); + const type = map.get(pid) || 'unknown'; + pg.groups.forEach((g) => { + if (!g.selected) return; + if (type === 'individual') individual += 1; + else if (type === 'team') team += 1; + else unknown += 1; + }); + }); + return { individual, team, unknown }; +} + Page({ data: { eventId: null, @@ -51,7 +171,9 @@ Page({ projectGroups: [], // 分组后的展示数据 couponCode: '', totalPrice: 0, - submitting: false + submitting: false, + openidLoading: false, + myAuth: null }, onLoad(options) { @@ -62,7 +184,9 @@ Page({ onShow() { const accessToken = wx.getStorageSync('accessToken') || ''; - this.setData({ loggedIn: Boolean(accessToken) }); + const loggedIn = Boolean(accessToken); + this.setData({ loggedIn }); + if (loggedIn) this._ensureMyAuth(); }, onBack() { @@ -81,7 +205,22 @@ Page({ needAuth: false }) .then((detail) => { - const projects = Array.isArray(detail.projects) ? detail.projects : []; + const es = getEventStatus(detail); + console.log( 'es', es); + if (es !== null && es !== 1) { + wx.showToast({ title: toastForBlockedEventStatus(es), icon: 'none' }); + setTimeout(() => { + if (getCurrentPages().length > 1) { + wx.navigateBack(); + } else { + wx.switchTab({ url: '/pages/home/home' }); + } + }, 1600); + return; + } + + const rawProjects = Array.isArray(detail.projects) ? detail.projects : []; + const projects = rawProjects.filter(isIndividualProject); const projectGroups = buildProjectGroups(projects); this.setData({ eventDetail: detail, @@ -95,14 +234,167 @@ Page({ }); }, + _ensureMyAuth() { + // 认证信息用于年龄/性别限制校验;没有认证则引导去个人中心 + return auth + .fetchMyAuth() + .then((res) => { + const d = res && typeof res === 'object' ? res : null; + const birthDate = d ? (d.birthDate || d.birthday || '') : ''; + if (!birthDate) { + wx.showModal({ + title: '需先完成认证', + content: '报名个人项目需要先完成身份认证(用于校验年龄与性别限制)。', + confirmText: '去个人中心', + cancelText: '取消', + success: (r) => { + if (r.confirm) wx.switchTab({ url: '/pages/mine/mine' }); + } + }); + this.setData({ myAuth: null }); + return null; + } + this.setData({ myAuth: d }); + return d; + }) + .catch(() => { + wx.showModal({ + title: '获取认证信息失败', + content: '请稍后重试,或前往个人中心完成认证。', + confirmText: '去个人中心', + cancelText: '取消', + success: (r) => { + if (r.confirm) wx.switchTab({ url: '/pages/mine/mine' }); + } + }); + this.setData({ myAuth: null }); + return null; + }); + }, + onGoMineLogin() { wx.switchTab({ url: '/pages/mine/mine' }); }, + _showOpenidResult(openid) { + wx.showModal({ + title: 'openid', + content: String(openid), + confirmText: '复制', + success: (r) => { + if (r.confirm) { + wx.setClipboardData({ data: String(openid) }); + } + } + }); + }, + + /** 优先读本地登录缓存;没有则 wx.login + 后端换 openid */ + onFetchOpenId() { + if (this.data.openidLoading) return; + const app = getApp(); + const cached = + (app && app.globalData && app.globalData.openid) || wx.getStorageSync('openid') || ''; + if (cached) { + this._showOpenidResult(cached); + return; + } + + this.setData({ openidLoading: true }); + wx.showLoading({ title: '获取中', mask: true }); + wx.login({ + success: (loginRes) => { + const code = loginRes.code; + if (!code) { + wx.hideLoading(); + this.setData({ openidLoading: false }); + wx.showToast({ title: '未获取到 code', icon: 'none' }); + return; + } + request({ + path: API.wechatOpenidByJsCode, + method: 'POST', + needAuth: false, + data: { code }, + contentType: 'application/json' + }) + .then((data) => { + const oid = + data && typeof data === 'object' + ? data.openid || data.OpenId || data.openId || '' + : ''; + const openid = typeof oid === 'string' ? oid : ''; + if (openid && app && typeof app.setAuth === 'function') { + app.setAuth({ openid }); + } + wx.hideLoading(); + this.setData({ openidLoading: false }); + if (openid) { + this._showOpenidResult(openid); + } else { + wx.showToast({ title: '接口未返回 openid', icon: 'none' }); + } + }) + .catch(() => { + wx.hideLoading(); + this.setData({ openidLoading: false }); + wx.showModal({ + title: '换取 openid 失败', + content: `请确认后端接口路径:${API.wechatOpenidByJsCode}\n\n可临时复制 code 给服务端调试:\n${code}`, + confirmText: '复制 code', + cancelText: '关闭', + success: (r) => { + if (r.confirm) wx.setClipboardData({ data: code }); + } + }); + }); + }, + fail: () => { + wx.hideLoading(); + this.setData({ openidLoading: false }); + wx.showToast({ title: 'wx.login 失败', icon: 'none' }); + } + }); + }, + /** 点击组别标签切换选中状态 */ onGroupTap(e) { const { projectId, groupId } = e.currentTarget.dataset; - const projectGroups = this.data.projectGroups.map((p) => { + if (!this.data.myAuth) { + wx.showToast({ title: '请先完成身份认证', icon: 'none' }); + wx.switchTab({ url: '/pages/mine/mine' }); + return; + } + + // 年龄/性别限制校验 + const my = this.data.myAuth || {}; + const birthDate = my.birthDate || my.birthday || ''; + const myGender = normalizeGenderToNum(my.gender != null ? my.gender : my.sex); + const eventStart = (this.data.eventDetail && this.data.eventDetail.matchStartTime) || ''; + + const clickedProject = this.data.projectGroups.find((p) => p.projectId === projectId); + const clickedGroup = clickedProject ? clickedProject.groups.find((g) => g.groupId === groupId) : null; + if (clickedGroup) { + const reqGender = normalizeGenderToNum(clickedGroup.genderRequirement); + if (reqGender != null && reqGender !== 2 && myGender != null && reqGender !== myGender) { + wx.showToast({ title: `该组别仅限${genderRequirementText(reqGender)}报名`, icon: 'none' }); + return; + } + const range = parseAgeRangeText(clickedGroup.ageRequirement); + if (range) { + const age = calcAgeYears(birthDate, eventStart); + if (age == null) { + wx.showToast({ title: '无法解析出生日期,请先完善认证信息', icon: 'none' }); + return; + } + if (age < range.min || age > range.max) { + wx.showToast({ title: `年龄需在${range.min}-${range.max}岁`, icon: 'none' }); + return; + } + } + } + + const nextProjectGroups = this.data.projectGroups.map((p) => { if (p.projectId !== projectId) return p; return { ...p, @@ -112,8 +404,23 @@ Page({ }) }; }); - const totalPrice = calcTotalPrice(projectGroups); - this.setData({ projectGroups, totalPrice }); + + const detail = this.data.eventDetail || {}; + const individualLimit = toNonNegInt(detail.individualProjectLimit); + const teamLimit = toNonNegInt(detail.teamProjectLimit); + const { individual, team } = countSelectedByType(nextProjectGroups, this.data.projects); + + if (individualLimit != null && individual > individualLimit) { + wx.showToast({ title: `个人项目最多选择${individualLimit}个`, icon: 'none' }); + return; + } + if (teamLimit != null && team > teamLimit) { + wx.showToast({ title: `团队项目最多选择${teamLimit}个`, icon: 'none' }); + return; + } + + const totalPrice = calcTotalPrice(nextProjectGroups); + this.setData({ projectGroups: nextProjectGroups, totalPrice }); }, onCouponInput(e) { @@ -143,6 +450,24 @@ Page({ wx.showToast({ title: '请至少选择一个组别', icon: 'none' }); return null; } + + const detail = this.data.eventDetail || {}; + const individualLimit = toNonNegInt(detail.individualProjectLimit); + const teamLimit = toNonNegInt(detail.teamProjectLimit); + const { individual, team, unknown } = countSelectedByType(this.data.projectGroups, this.data.projects); + if (unknown > 0 && (individualLimit != null || teamLimit != null)) { + // typeName 识别不出来时,不阻断提交,但提醒后端应补齐 typeName + console.warn('存在未识别项目类型的选项,无法严格执行个人/团队限报', { unknown }); + } + if (individualLimit != null && individual > individualLimit) { + wx.showToast({ title: `个人项目最多选择${individualLimit}个`, icon: 'none' }); + return null; + } + if (teamLimit != null && team > teamLimit) { + wx.showToast({ title: `团队项目最多选择${teamLimit}个`, icon: 'none' }); + return null; + } + return { eventId: Number(this.data.eventId), registrationMode: 1, diff --git a/pages/apply/apply.wxml b/pages/apply/apply.wxml index 88c9b01..9a0dea0 100644 --- a/pages/apply/apply.wxml +++ b/pages/apply/apply.wxml @@ -1,5 +1,8 @@ + + + @@ -21,7 +24,7 @@ {{group.groupName}}| {{group.ageRequirement}}| - {{group.genderRequirement}} + {{group.genderRequirementText}} diff --git a/pages/apply/apply.wxss b/pages/apply/apply.wxss index 5c2a63c..dcc962b 100644 --- a/pages/apply/apply.wxss +++ b/pages/apply/apply.wxss @@ -4,6 +4,29 @@ background: #f5f7fa; } +.openid-row { + display: flex; + justify-content: flex-end; + padding: 8rpx 32rpx 0; + box-sizing: border-box; +} + +.openid-mini-btn { + margin: 0 !important; + padding: 0 20rpx !important; + height: 56rpx !important; + line-height: 56rpx !important; + font-size: 22rpx !important; + color: #1a56db !important; + background: rgba(26, 86, 219, 0.08) !important; + border: none !important; + border-radius: 28rpx !important; +} + +.openid-mini-btn::after { + border: none; +} + .scroll { height: calc(100vh - 88rpx); padding: 24rpx 32rpx 0; diff --git a/pages/detail/detail.js b/pages/detail/detail.js index 430646c..b35d4d4 100644 --- a/pages/detail/detail.js +++ b/pages/detail/detail.js @@ -48,6 +48,49 @@ function pick(obj, keys) { return null; } +/** + * 赛事状态(与后端枚举一致) + * 0 NotStarted 未开始 | 1 Enrolling 报名中 | 2 RegistrationEnded 报名结束 + * 3 Ongoing 比赛中 | 4 Ended 已结束 + * 未返回字段时视为旧接口,不拦截报名 + */ +function parseEventStatus(rawDetail) { + const v = pick(rawDetail, ['eventStatus', 'EventStatus']); + if (v == null || v === '') return null; + const n = Number(v); + return Number.isNaN(n) ? null : n; +} + +function applyUiFromEventStatus(es) { + if (es == null) { + return { canApply: true, applyButtonText: '报名' }; + } + if (es === 0) { + return { canApply: false, applyButtonText: '未开始' }; + } + if (es === 1) { + return { canApply: true, applyButtonText: '报名' }; + } + if (es === 2) { + return { canApply: false, applyButtonText: '报名结束' }; + } + if (es === 3) { + return { canApply: false, applyButtonText: '比赛中' }; + } + if (es === 4) { + return { canApply: false, applyButtonText: '已结束' }; + } + return { canApply: false, applyButtonText: '暂不可报名' }; +} + +function toastForEventStatus(es) { + if (es === 0) return '赛事未开始'; + if (es === 2) return '报名已结束'; + if (es === 3) return '比赛进行中,暂不可报名'; + if (es === 4) return '赛事已结束'; + return '当前不可报名'; +} + function registrationModeText(mode) { const m = mode === undefined || mode === null ? null : Number(mode); if (m === 1) return '只允许个人报名'; @@ -73,6 +116,42 @@ function splitLines(text) { .filter(Boolean); } +function toNonNegInt(v) { + const n = Number(v); + if (Number.isNaN(n)) return null; + const i = Math.floor(n); + return i >= 0 ? i : null; +} + +function buildRegistrationLimitLines(detail, projects) { + const d = detail && typeof detail === 'object' ? detail : {}; + const lines = []; + + const individualLimit = toNonNegInt(pick(d, ['individualProjectLimit', 'IndividualProjectLimit'])); + const teamLimit = toNonNegInt(pick(d, ['teamProjectLimit', 'TeamProjectLimit'])); + if (individualLimit != null || teamLimit != null) { + const a = individualLimit != null ? `个人项目${individualLimit}个` : null; + const b = teamLimit != null ? `团队项目${teamLimit}个` : null; + const joined = [a, b].filter(Boolean).join(','); + if (joined) lines.push(`每人/单位限报:${joined}`); + } + + if (Array.isArray(projects) && projects.length) { + const segs = []; + projects.forEach((p) => { + const name = p && (p.name || p.Name) ? (p.name || p.Name) : ''; + const limit = toNonNegInt(pick(p, ['projectLimitCount', 'ProjectLimitCount'])); + if (!name || limit == null) return; + segs.push(`${name}${limit}个`); + }); + if (segs.length) { + lines.push(`项目组别单位报名上限(每组别):${segs.join(',')}`); + } + } + + return lines; +} + function flattenProjectTableRows(projects) { if (!Array.isArray(projects)) return []; const rows = []; @@ -179,6 +258,10 @@ function normalizeEventDetail(raw) { registrationLimitLines = [String(registrationLimitRaw)]; } } + // 若接口未提供文本规则,则由结构化字段拼接 + if (!registrationLimitLines.length) { + registrationLimitLines = buildRegistrationLimitLines(d, projects); + } const participationPointsLabel = pick(d, ['participationPointsText', 'ParticipationPointsText']) || @@ -236,7 +319,11 @@ Page({ hasNoticeBlock: false, hasRegistrationLimit: false, projectTableRows: [], - unitGroups: [] + unitGroups: [], + /** 0未开始 1报名中 2报名结束 3比赛中 4已结束;null 表示接口未返回 */ + eventStatus: null, + canApply: true, + applyButtonText: '报名' }, onLoad(options) { @@ -353,6 +440,9 @@ Page({ .filter((t) => unitMap[t] && unitMap[t].length) .map((t) => ({ label: UNIT_TYPE_LABELS[t], names: unitMap[t] })); + const eventStatus = parseEventStatus(detail); + const { canApply, applyButtonText } = applyUiFromEventStatus(eventStatus); + this.setData({ eventDetail: detail, projects: normalizedProjects, @@ -378,7 +468,10 @@ Page({ hasNoticeBlock, hasRegistrationLimit, projectTableRows, - unitGroups + unitGroups, + eventStatus, + canApply, + applyButtonText }); }) .catch(() => { @@ -389,6 +482,10 @@ Page({ onApplyTap() { const id = this.data.id; if (!id) return; + if (!this.data.canApply) { + wx.showToast({ title: toastForEventStatus(this.data.eventStatus), icon: 'none' }); + return; + } wx.navigateTo({ url: `/pages/apply/apply?eventId=${id}` }); diff --git a/pages/detail/detail.wxml b/pages/detail/detail.wxml index 1b28b6a..dc84993 100644 --- a/pages/detail/detail.wxml +++ b/pages/detail/detail.wxml @@ -150,6 +150,11 @@ - + diff --git a/pages/detail/detail.wxss b/pages/detail/detail.wxss index 20ccfaf..374c917 100644 --- a/pages/detail/detail.wxss +++ b/pages/detail/detail.wxss @@ -516,3 +516,11 @@ page { .apply-btn::after { border: none; } + +.apply-btn.apply-btn--disabled, +.apply-btn[disabled] { + background: #c4c4c4 !important; + color: #ffffff !important; + box-shadow: none; + opacity: 1; +} diff --git a/pages/home/home.js b/pages/home/home.js index 3484a08..20ae2dc 100644 --- a/pages/home/home.js +++ b/pages/home/home.js @@ -1,6 +1,6 @@ const { API } = require('../../utils/constants'); const { request } = require('../../utils/http'); -const { formatDateTime, eventStatusText, eventFormatText } = require('../../utils/format'); +const { formatDateTime, eventStatusText, eventStatusForPill, eventFormatText } = require('../../utils/format'); /** 统一后台轮播字段(camelCase / PascalCase、枚举数字)供 wxml 绑定 */ function normalizeBannerItem(raw) { @@ -54,6 +54,7 @@ Page({ pageSize: 10, hasMore: true, + /** 列表筛选:-1=全部(不传 status),0~4 与后端 EventStatus 一致;默认报名中 */ status: 1, keyword: '', @@ -136,6 +137,7 @@ Page({ onStatusTap(e) { const status = Number(e.currentTarget.dataset.status); + if (Number.isNaN(status)) return; this.setData({ status, pageNo: 1, @@ -216,24 +218,36 @@ Page({ const status = this.data.status; const keyword = this.data.keyword; + const query = { + page: pageNo, + pagesize: pageSize, + PageNo: pageNo, + PageSize: pageSize, + keyword, + Keyword: keyword + }; + if (status >= 0) { + query.status = status; + query.Status = status; + } + return request({ path: API.eventList, method: 'GET', needAuth: false, - data: { - page: pageNo, - pagesize: pageSize, - PageNo: pageNo, - PageSize: pageSize, - status, - Status: status, - keyword, - Keyword: keyword - } + data: query }) .then((res) => { const rows = (res && Array.isArray(res.rows) ? res.rows : []).map((item) => { const id = item.id; + const rawEventStatus = + item.eventStatus != null + ? item.eventStatus + : item.EventStatus != null + ? item.EventStatus + : item.status != null + ? item.status + : item.Status; return { ...item, rowKey: `e-${id}`, @@ -241,7 +255,8 @@ Page({ registrationEndText: formatDateTime(item.registrationEndTime), matchStartText: formatDateTime(item.matchStartTime), matchEndText: formatDateTime(item.matchEndTime), - eventStatusText: eventStatusText(item.eventStatus), + eventStatusText: eventStatusText(rawEventStatus), + eventStatusPill: eventStatusForPill(rawEventStatus), eventFormatText: eventFormatText(item.eventType || item.eventFormat) }; }); @@ -309,6 +324,7 @@ Page({ eventName: item.eventName, coverImage: item.coverImage, address: '', + eventStatusPill: 1, eventStatusText: '已报名', registrationTimeText: formatDateTime(item.registrationTime), projectCount: item.projectCount, diff --git a/pages/home/home.wxml b/pages/home/home.wxml index baa6abe..c9f76a4 100644 --- a/pages/home/home.wxml +++ b/pages/home/home.wxml @@ -80,13 +80,13 @@ bindtap="onStatusTap" >报名中 比赛中 已结束 diff --git a/pages/home/home.wxss b/pages/home/home.wxss index 6bd9f29..4f4f372 100644 --- a/pages/home/home.wxss +++ b/pages/home/home.wxss @@ -281,13 +281,13 @@ page { /* box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); */ } -.status-pill-top-0 { +.status-pill-top-1 { background: linear-gradient(135deg, rgba(0, 181, 109, 0) 20%, rgba(0, 96, 216, 1) 80% , rgba(0, 96, 216, 1) 100%) ; } -.status-pill-top-1 { +.status-pill-top-3 { background: linear-gradient(135deg, rgba(0, 181, 109, 0) 20%, rgba(0, 181, 109, 1) 80% , rgba(0, 181, 109, 1) 100%) ; } -.status-pill-top-2 { +.status-pill-top-4 { background: linear-gradient(135deg, rgba(0, 181, 109, 0) 20%, rgba(230, 6, 11, 1)80% , rgba(230, 6, 11, 1)100%) ; } diff --git a/pages/mine/mine.js b/pages/mine/mine.js index a81cf29..ebdcebe 100644 --- a/pages/mine/mine.js +++ b/pages/mine/mine.js @@ -94,6 +94,14 @@ Page({ // TODO: 上传头像到服务器 } }); + }, + + onFetchOpenId() { + wx.login({ + success: (res) => { + console.log('res', res); + } + }); } }); diff --git a/pages/mine/mine.wxml b/pages/mine/mine.wxml index 41ce1b2..8685399 100644 --- a/pages/mine/mine.wxml +++ b/pages/mine/mine.wxml @@ -73,4 +73,8 @@ + + + + \ No newline at end of file diff --git a/subpackages/mine/auth/auth.js b/subpackages/mine/auth/auth.js index 1c3ac9a..23603b8 100644 --- a/subpackages/mine/auth/auth.js +++ b/subpackages/mine/auth/auth.js @@ -89,7 +89,7 @@ Page({ const passportImageUrl = d.passportImageUrl || ''; const birthDate = d.birthDate || d.birthday || ''; const gender = (d.gender || d.sex || '').toString().toUpperCase(); - const genderIndex = gender === 'F' || gender === '女' || gender === '2' ? 1 : 0; + const genderIndex = gender === 'F' || gender === '女' || gender === '1' ? 1 : 0; // 有已提交信息时,按产品稿表现为“自动识别/灰色不可修改” const readonlyName = Boolean(name); diff --git a/utils/constants.js b/utils/constants.js index fdf1654..61fa023 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -17,6 +17,8 @@ const API = { oauthRegister: '/api/oauth/register', oauthResetPassword: '/api/oauth/reset-password', sendVerificationCode: '/api/sms/sendverificationcode', + /** 小程序 wx.login 的 code 换 openid(按后端实际路径修改) */ + wechatOpenidByJsCode: '/api/wechat/jscode2session', myProfile: '/api/my/profile', myAuth: '/api/my/auth', myRegistrations: '/api/my/registrations', diff --git a/utils/format.js b/utils/format.js index 68afe13..ba9f436 100644 --- a/utils/format.js +++ b/utils/format.js @@ -15,15 +15,41 @@ function formatTime(iso) { } function eventStatusText(status) { - if (status === 'Enrolling') return '报名中'; - if (status === 'Ongoing') return '比赛中'; - if (status === 'Ended') return '已结束'; - const map = { - 0: '报名中', - 1: '比赛中', - 2: '已结束' + // 与后端 EventStatus 枚举一致 + const strMap = { + NotStarted: '未开始', + Enrolling: '报名中', + RegistrationEnded: '报名结束', + Ongoing: '比赛中', + Ended: '已结束' }; - return map[status] !== undefined ? map[status] : `状态${status}`; + if (strMap[status] != null) return strMap[status]; + + const n = status === undefined || status === null || status === '' ? NaN : Number(status); + const numMap = { + 0: '未开始', + 1: '报名中', + 2: '报名结束', + 3: '比赛中', + 4: '已结束' + }; + if (!Number.isNaN(n) && numMap[n] !== undefined) return numMap[n]; + return status !== undefined && status !== null && status !== '' ? `状态${status}` : ''; +} + +/** 列表角标样式用:0~4,未知时回退 0 */ +function eventStatusForPill(status) { + const strToNum = { + NotStarted: 0, + Enrolling: 1, + RegistrationEnded: 2, + Ongoing: 3, + Ended: 4 + }; + if (strToNum[status] !== undefined) return strToNum[status]; + const n = Number(status); + if (!Number.isNaN(n) && n >= 0 && n <= 4) return n; + return 0; } function eventFormatText(v) { @@ -36,6 +62,7 @@ module.exports = { formatDateTime, formatTime, eventStatusText, + eventStatusForPill, eventFormatText };