diff --git a/src/app.ts b/src/app.ts index 23efcb8..c426558 100644 --- a/src/app.ts +++ b/src/app.ts @@ -105,15 +105,11 @@ App({ return true } - if (loginIdentity && types.includes(loginIdentity) && loginIdentity === 1) { - return true - } - if (!isLogin) { const typeRegPageUrl = { - 2: '/pages/register/index', - 3: '/ground/pages/register/index', - 4: '/doctor/pages/register/index', + 2: '/pages/tourists/index', + 3: '/ground/pages/login/index', + 4: '/doctor/pages/login/index', }[loginIdentity as 2 | 3 | 4] wx.reLaunch({ url: typeRegPageUrl || '/pages/statr/index', diff --git a/src/components/popupDoctor/index.wxml b/src/components/popupDoctor/index.wxml index 51a6fc5..193d193 100644 --- a/src/components/popupDoctor/index.wxml +++ b/src/components/popupDoctor/index.wxml @@ -14,7 +14,7 @@ 医生介绍 - + {{doctorInfo.doctorName}} diff --git a/src/doctor/pages/article/index.ts b/src/doctor/pages/article/index.ts index 4cde3d3..accb959 100644 --- a/src/doctor/pages/article/index.ts +++ b/src/doctor/pages/article/index.ts @@ -5,18 +5,8 @@ Page({ // 文章ID articleId: 0, - // 文章详情(模拟数据,接口上线后删除) - articleDetail: { - id: 1, - title: '银屑病日常护理指南', - content: - '

银屑病是一种慢性、复发性、炎症性皮肤病,需要长期的管理和护理。

一、日常护理要点

1. 保持皮肤湿润,每天使用保湿霜

2. 避免过度清洁,使用温和的洗浴产品

3. 穿着宽松、透气的棉质衣物

二、饮食建议

1. 多吃新鲜蔬菜水果

2. 避免辛辣刺激食物

3. 适量补充优质蛋白

三、心理调节

保持良好的心态,积极配合治疗,定期复诊。

', - imageUrl: '', - viewCount: 100, - likeCount: 10, - isLiked: false, - updateTime: 1700000000, - }, + // 文章详情 + articleDetail: {} as any, // 是否已点赞 isLiked: false, @@ -27,10 +17,9 @@ Page({ const articleId = option.id ? Number.parseInt(option.id) : 0 this.setData({ articleId }) - // TODO: 接口上线后取消注释 - // if (articleId) { - // this.getArticleDetail(articleId) - // } + if (articleId) { + this.getArticleDetail(articleId) + } }) }, // 获取文章详情 diff --git a/src/doctor/pages/articleList/index.ts b/src/doctor/pages/articleList/index.ts index 3e8037a..aa37c2f 100644 --- a/src/doctor/pages/articleList/index.ts +++ b/src/doctor/pages/articleList/index.ts @@ -2,48 +2,15 @@ const app = getApp() Page({ data: { - // 分类列表(模拟数据,接口上线后删除) - categoryList: [ - { id: 1, name: '学习专栏', images: [] }, - { id: 2, name: '社区热帖', images: [] }, - { id: 3, name: '行业热点', images: [] }, - { id: 4, name: '中国药店', images: [] }, - ] as any[], - currentCategoryId: 1, + // 分类列表 + categoryList: [] as any[], + currentCategoryId: 0, // Banner列表 bannerList: [] as any[], - // 文章列表(模拟数据,接口上线后删除) - articleList: [ - { - id: 1, - title: '银屑病日常护理指南', - imageUrl: '', - viewCount: 100, - likeCount: 10, - updateTime: 1700000000, - updateTimeFormatted: '2023-11-14', - }, - { - id: 2, - title: '从强降糖到防事件,那些糖尿病指南走过的路', - imageUrl: '', - viewCount: 256, - likeCount: 32, - updateTime: 1700086400, - updateTimeFormatted: '2023-11-15', - }, - { - id: 3, - title: '特诺雅患者援助项目介绍', - imageUrl: '', - viewCount: 89, - likeCount: 15, - updateTime: 1700172800, - updateTimeFormatted: '2023-11-16', - }, - ] as any[], + // 文章列表 + articleList: [] as any[], // 分页 page: 1, @@ -51,7 +18,7 @@ Page({ loading: false, hasMore: true, pagination: { - count: 3, + count: 0, page: 1, pages: 1, }, @@ -59,8 +26,7 @@ Page({ onLoad() { // 药店端教育页面,仅允许药店人员访问 app.waitLogin({ types: [4] }).then(() => { - // TODO: 接口上线后取消注释 - // this.getCategoryList() + this.getCategoryList() }) }, // 获取教育分类列表 @@ -110,36 +76,29 @@ Page({ page: this.data.page, pageSize: this.data.pageSize, }, - }).then((res: any) => { - const list = (res.list || []).map((item: any) => ({ - ...item, - updateTimeFormatted: item.updateTime ? this.formatDate(item.updateTime) : '', - })) - const total = res.total || 0 - const currentPage = this.data.page + }) + .then((res: any) => { + const list = (res.list || []).map((item: any) => ({ + ...item, + })) + const total = res.total || 0 + const currentPage = this.data.page - this.setData({ - articleList: [...this.data.articleList, ...list], - page: currentPage + 1, - hasMore: list.length >= this.data.pageSize, - loading: false, - pagination: { - count: total, - page: currentPage, - pages: Math.ceil(total / this.data.pageSize) || 1, - }, + this.setData({ + articleList: [...this.data.articleList, ...list], + page: currentPage + 1, + hasMore: list.length >= this.data.pageSize, + loading: false, + pagination: { + count: total, + page: currentPage, + pages: Math.ceil(total / this.data.pageSize) || 1, + }, + }) + }) + .catch(() => { + this.setData({ loading: false }) }) - }).catch(() => { - this.setData({ loading: false }) - }) - }, - // 格式化日期 - formatDate(timestamp: number): string { - const date = new Date(timestamp * 1000) - const year = date.getFullYear() - const month = String(date.getMonth() + 1).padStart(2, '0') - const day = String(date.getDate()).padStart(2, '0') - return `${year}-${month}-${day}` }, // 切换分类 handleTabChange(e: WechatMiniprogram.CustomEvent) { diff --git a/src/doctor/pages/articleList/index.wxml b/src/doctor/pages/articleList/index.wxml index 5c17194..e924763 100644 --- a/src/doctor/pages/articleList/index.wxml +++ b/src/doctor/pages/articleList/index.wxml @@ -36,7 +36,6 @@ {{item.likeCount || 0}}
- {{item.updateTimeFormatted}} diff --git a/src/doctor/pages/changeNickname/index.ts b/src/doctor/pages/changeNickname/index.ts index 04008a9..d7eb08b 100644 --- a/src/doctor/pages/changeNickname/index.ts +++ b/src/doctor/pages/changeNickname/index.ts @@ -2,13 +2,25 @@ const app = getApp() Page({ data: { - // 新姓名 name: '', + loading: false, }, onLoad() { // 药店端修改昵称页面,仅允许药店人员访问 app.waitLogin({ types: [4] }).then(() => { - // 页面加载完成 + // 获取当前姓名 + this.getCurrentName() + }) + }, + // 获取当前姓名 + getCurrentName() { + wx.ajax({ + method: 'GET', + url: '/app/pharmacist/pharmacist/profile', + }).then((res: any) => { + this.setData({ + name: res.name || '', + }) }) }, // 输入姓名 @@ -28,7 +40,8 @@ Page({ return } - wx.showLoading({ title: '提交中...' }) + if (this.data.loading) return + this.setData({ loading: true }) wx.ajax({ method: 'POST', @@ -37,11 +50,7 @@ Page({ name: name.trim(), }, }).then(() => { - wx.hideLoading() - // 更新全局数据 - if (app.globalData.initLoginInfo?.pharmacistInfo) { - app.globalData.initLoginInfo.pharmacistInfo.name = name.trim() - } + this.setData({ loading: false }) wx.showToast({ title: '修改成功', icon: 'success', @@ -50,7 +59,7 @@ Page({ wx.navigateBack() }, 1500) }).catch(() => { - wx.hideLoading() + this.setData({ loading: false }) wx.showToast({ title: '修改失败', icon: 'none', diff --git a/src/doctor/pages/changeTel/index.ts b/src/doctor/pages/changeTel/index.ts index 647a31c..e3c46c0 100644 --- a/src/doctor/pages/changeTel/index.ts +++ b/src/doctor/pages/changeTel/index.ts @@ -1,14 +1,14 @@ const app = getApp() +let timer = null as null | number + Page({ data: { mobile: '', code: '', codeText: '发送验证码', - counting: false, - countdown: 60, + loading: false, }, - timer: null as any, onLoad() { // 药店端修改手机号页面,仅允许药店人员访问 app.waitLogin({ types: [4] }).then(() => { @@ -16,23 +16,25 @@ Page({ }) }, onUnload() { - // 清除定时器 - if (this.timer) { - clearInterval(this.timer) + // 页面卸载时清除定时器 + if (timer) { + clearInterval(timer) + timer = null } }, // 获取验证码 getCode() { - if (this.data.counting) return + if (timer) return - const { mobile } = this.data + const mobile = this.data.mobile if (!mobile) { wx.showToast({ - title: '请输入手机号', + title: '手机号不能为空', icon: 'none', }) return } + // 验证手机号 if (!/^1[3-9]\d{9}$/.test(mobile)) { wx.showToast({ title: '手机号格式不正确', @@ -46,85 +48,60 @@ Page({ url: '/app/common/common/send-code', data: { phone: mobile, - type: 2, // 2-绑定手机号 + type: 3, // 3-修改手机号 }, }).then(() => { wx.showToast({ - title: '验证码已发送', - icon: 'success', - }) - this.startCountdown() - }).catch(() => { - wx.showToast({ - title: '发送失败', icon: 'none', + title: '验证码已发送~', }) - }) - }, - // 开始倒计时 - startCountdown() { - this.setData({ - counting: true, - countdown: 60, - codeText: '60s', - }) - - this.timer = setInterval(() => { - const countdown = this.data.countdown - 1 - if (countdown <= 0) { - clearInterval(this.timer) + let time = 60 + timer = setInterval(() => { + time-- this.setData({ - counting: false, - codeText: '发送验证码', + codeText: `${time}s后重新发送`, }) - } else { - this.setData({ - countdown, - codeText: `${countdown}s`, - }) - } - }, 1000) + if (time <= 0) { + clearInterval(timer as number) + timer = null + this.setData({ + codeText: '发送验证码', + }) + } + }, 1000) + }) }, - // 确认修改 + // 提交修改 handleSubmit() { const { mobile, code } = this.data + if (!mobile) { wx.showToast({ - title: '请输入手机号', - icon: 'none', - }) - return - } - if (!/^1[3-9]\d{9}$/.test(mobile)) { - wx.showToast({ - title: '手机号格式不正确', icon: 'none', + title: '请输入手机号', }) return } if (!code) { wx.showToast({ - title: '请输入验证码', icon: 'none', + title: '请输入验证码', }) return } - wx.showLoading({ title: '提交中...' }) + if (this.data.loading) return + this.setData({ loading: true }) wx.ajax({ method: 'POST', url: '/app/pharmacist/pharmacist/update-phone', data: { phone: mobile, - code: code, + code, }, }).then(() => { - wx.hideLoading() - // 更新全局数据 - if (app.globalData.initLoginInfo?.pharmacistInfo) { - app.globalData.initLoginInfo.pharmacistInfo.phone = mobile - } + this.setData({ loading: false }) wx.showToast({ title: '修改成功', icon: 'success', @@ -133,7 +110,7 @@ Page({ wx.navigateBack() }, 1500) }).catch(() => { - wx.hideLoading() + this.setData({ loading: false }) wx.showToast({ title: '修改失败', icon: 'none', diff --git a/src/doctor/pages/home/index.ts b/src/doctor/pages/home/index.ts index 2326307..081286e 100644 --- a/src/doctor/pages/home/index.ts +++ b/src/doctor/pages/home/index.ts @@ -10,6 +10,12 @@ Page({ pharmacistAvatar: '', pharmacyName: '', + // 项目列表 + projectList: [] as Array<{ projectId: number; projectName: string; projectDescription: string }>, + currentProjectId: 0, + currentProjectName: '特诺雅', + projectIndex: 0, + // 待处理患者数 pendingCount: 0, @@ -28,11 +34,20 @@ Page({ }>, // 图表数据 - chartData: [] as Array<{ date: string, count: number }>, + chartData: [] as Array<{ date: string; count: number }>, - // 日期范围 + // 日期范围 - 邀约患者统计卡片(单日) startDate: '', - endDate: '', + today: '', + // 统计卡片显示用的月份(YYYY-MM) + startMonth: '', + + // 日期范围 - 图表(日期范围) + chartStartDate: '', + chartEndDate: '', + // 图表显示用的月份(YYYY-MM) + chartStartMonth: '', + chartEndMonth: '', // 统计类型: day-日统计, month-月统计 statType: 'day', @@ -45,17 +60,25 @@ Page({ // 药店端页面,仅允许药店人员(4)访问 app.waitLogin({ types: [4] }).then(() => { this.getUserInfo() - this.getPendingCount() - this.getStatistics() - this.getPatientChart() + this.getProjectList() }) - // 初始化日期范围为最近30天 - const endDate = this.formatDate(new Date()) - const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + // 初始化日期 + const today = this.formatDate(new Date()) + const currentMonth = this.formatMonth(new Date()) + const defaultStartDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + const defaultStartMonth = this.formatMonth(new Date(Date.now() - 365 * 24 * 60 * 60 * 1000)) this.setData({ - startDate, - endDate, + today, + // 邀约患者统计卡片(单日)- 默认为今天 + startDate: today, + startMonth: currentMonth, + // 图表(日期范围)- 默认为最近30天 + chartStartDate: defaultStartDate, + chartEndDate: today, + // 图表月份显示 - 默认为最近12个月 + chartStartMonth: defaultStartMonth, + chartEndMonth: currentMonth, }) }, @@ -67,6 +90,13 @@ Page({ return `${year}-${month}-${day}` }, + // 格式化月份(YYYY-MM) + formatMonth(date: Date): string { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + return `${year}-${month}` + }, + // 获取用户信息 getUserInfo() { wx.ajax({ @@ -78,31 +108,89 @@ Page({ pharmacistAvatar: res.avatar, pharmacyName: res.pharmacyName, }) - }).catch(() => { - // 接口失败时使用模拟数据 + }) + }, + + // 获取项目列表 + getProjectList() { + wx.ajax({ + method: 'GET', + url: '/app/pharmacist/pharmacist/project-list', + }).then((res: any) => { + const projectList = res.list || [] + const currentProjectId = res.currentProjectId || projectList[0]?.projectId || 0 + const currentProject = projectList.find((item: any) => item.projectId === currentProjectId) || projectList[0] + const projectIndex = projectList.findIndex((item: any) => item.projectId === currentProjectId) + this.setData({ - pharmacistName: '李药师', - pharmacistAvatar: '', - pharmacyName: '康泰大药房(人民路店)', + projectList, + currentProjectId, + currentProjectName: currentProject?.projectName || '特诺雅', + projectIndex: projectIndex >= 0 ? projectIndex : 0, }) + + // 获取其他数据 + this.getPendingCount() + this.getStatistics() + this.getPatientChart() }) }, + // 切换项目 + onProjectChange(e: WechatMiniprogram.CustomEvent) { + const index = e.detail.value + const project = this.data.projectList[index] + if (project && project.projectId !== this.data.currentProjectId) { + // 先调用切换项目接口 + wx.ajax({ + method: 'POST', + url: '/app/pharmacist/pharmacist/switch-project', + data: { + projectId: project.projectId, + }, + }) + .then(() => { + // 切换成功后更新页面数据 + this.setData({ + currentProjectId: project.projectId, + currentProjectName: project.projectName, + projectIndex: index, + }) + // 重新加载数据 + this.getPendingCount() + this.getStatistics() + this.getPatientChart() + wx.showToast({ + title: '切换成功', + icon: 'success', + }) + }) + .catch(() => { + wx.showToast({ + title: '切换失败', + icon: 'none', + }) + }) + } + }, + // 获取待处理患者数 getPendingCount() { wx.ajax({ method: 'GET', url: '/app/pharmacist/pharmacist/pending-count', - }).then((res: any) => { - this.setData({ - pendingCount: res.count || 0, + }) + .then((res: any) => { + this.setData({ + pendingCount: res.count || 0, + }) }) - }).catch(() => { - // 接口失败时使用模拟数据 - this.setData({ - pendingCount: 12, + .catch(() => { + // 接口失败时使用模拟数据 + this.setData({ + pendingCount: 12, + }) }) - }) }, // 获取统计数据看板 @@ -117,44 +205,40 @@ Page({ enrollPatientCount: res.enrollPatientCount || 0, indicationStats: res.indicationStats || [], }) - }).catch(() => { - // 接口失败时使用模拟数据 - this.setData({ - invitePatientCount: 156, - jumpPatientCount: 128, - enrollPatientCount: 89, - indicationStats: [ - { indicationId: 1, indicationName: '斑块状银屑病', invitePatientCount: 80, jumpPatientCount: 65, enrollPatientCount: 45 }, - { indicationId: 2, indicationName: '溃疡性结肠炎', invitePatientCount: 45, jumpPatientCount: 38, enrollPatientCount: 28 }, - { indicationId: 3, indicationName: '克罗恩病', invitePatientCount: 31, jumpPatientCount: 25, enrollPatientCount: 16 }, - ], - }) }) }, - // 获取邀约患者统计图表 + // 获取邀约患者统计图表(使用 chart 的日期范围) getPatientChart() { + // 根据统计类型格式化日期 + const startDate = + this.data.statType === 'month' + ? this.data.chartStartDate.substring(0, 7) // YYYY-MM + : this.data.chartStartDate // YYYY-MM-DD + const endDate = + this.data.statType === 'month' + ? this.data.chartEndDate.substring(0, 7) // YYYY-MM + : this.data.chartEndDate // YYYY-MM-DD + wx.ajax({ method: 'GET', url: '/app/pharmacist/pharmacist/patient-chart', data: { type: this.data.statType, - startDate: this.data.startDate, - endDate: this.data.endDate, + startDate, + endDate, }, }).then((res: any) => { const list = res.list || [] + // 转换为图表需要的格式 + const chartData = list.map((item: any) => ({ + date: item.statDate || item.date, + count: item.invitePatientCount || item.count || 0, + })) this.setData({ - chartData: list, - }) - this.initChartBar(list) - }).catch(() => { - // 接口失败时使用模拟数据 - const mockData = this.generateMockChartData() - this.setData({ - chartData: mockData, + chartData, }) - this.initChartBar(mockData) + this.initChartBar(chartData) }) }, // 生成模拟图表数据 @@ -183,26 +267,178 @@ Page({ // 切换统计类型 switchStatType(e: WechatMiniprogram.CustomEvent) { const type = e.currentTarget.dataset.type + const isMonth = type === 'month' + + // 根据统计类型重置日期范围 + let startDate = this.data.startDate + let startMonth = this.data.startMonth + let chartStartDate = this.data.chartStartDate + let chartEndDate = this.data.chartEndDate + let chartStartMonth = this.data.chartStartMonth + let chartEndMonth = this.data.chartEndMonth + + if (isMonth) { + // 切换到月统计,设置默认月份 + startMonth = this.formatMonth(new Date()) + startDate = `${startMonth}-01` + // 图表月份范围为最近12个月 + chartEndMonth = this.formatMonth(new Date()) + chartStartMonth = this.formatMonth(new Date(Date.now() - 365 * 24 * 60 * 60 * 1000)) + chartEndDate = `${chartEndMonth}-01` + chartStartDate = `${chartStartMonth}-01` + } else { + // 切换到日统计,设置默认日期为今天 + startDate = this.formatDate(new Date()) + startMonth = startDate.substring(0, 7) + // 图表日期范围为最近30天 + chartEndDate = this.formatDate(new Date()) + chartStartDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + chartEndMonth = chartEndDate.substring(0, 7) + chartStartMonth = chartStartDate.substring(0, 7) + } + this.setData({ statType: type, + startDate, + startMonth, + chartStartDate, + chartEndDate, + chartStartMonth, + chartEndMonth, }) + this.getStatistics() this.getPatientChart() }, // 日期选择变化 onDateChange(e: WechatMiniprogram.CustomEvent) { - const { field } = e.currentTarget.dataset - const value = e.detail.value + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) + + this.setData({ + startDate: fullDate, + startMonth: monthValue, + }) + // 重新加载统计数据 + this.getStatistics() + }, + + // 切换到上一天/上月 + prevDate() { + const isMonth = this.data.statType === 'month' + let newDate: Date + let startDate: string + let startMonth: string + + if (isMonth) { + // 月统计:切换到上个月 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1) + startDate = this.formatDate(newDate) + startMonth = this.formatMonth(newDate) + } else { + // 日统计:切换到上一天 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000) + startDate = this.formatDate(newDate) + startMonth = startDate.substring(0, 7) + } + + this.setData({ startDate, startMonth }) + // 重新加载统计数据 + this.getStatistics() + }, + + // 切换到下一天/下月 + nextDate() { + const isMonth = this.data.statType === 'month' + const today = new Date() + let newDate: Date + let startDate: string + let startMonth: string + + if (isMonth) { + // 月统计:切换到下个月 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1) + + // 最大月份不能大于当前月份 + const currentMonth = new Date(today.getFullYear(), today.getMonth(), 1) + if (newDate > currentMonth) { + wx.showToast({ + title: '不能选择未来月份', + icon: 'none', + }) + return + } + + startDate = this.formatDate(newDate) + startMonth = this.formatMonth(newDate) + } else { + // 日统计:切换到下一天 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000) + + // 最大日期不能大于当前日期 + if (newDate > today) { + wx.showToast({ + title: '不能选择未来日期', + icon: 'none', + }) + return + } + + startDate = this.formatDate(newDate) + startMonth = startDate.substring(0, 7) + } + + this.setData({ startDate, startMonth }) + // 重新加载统计数据 + this.getStatistics() + }, + + // 图表日期选择变化(开始日期) + onChartStartDateChange(e: WechatMiniprogram.CustomEvent) { + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + const chartEndDate = this.data.chartEndDate + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) // 验证日期范围 - if (field === 'startDate' && this.data.endDate && value > this.data.endDate) { + if (chartEndDate && fullDate > chartEndDate) { wx.showToast({ title: '开始时间不能大于结束时间', icon: 'none', }) return } - if (field === 'endDate' && this.data.startDate && value < this.data.startDate) { + + this.setData({ + chartStartDate: fullDate, + chartStartMonth: monthValue, + }) + this.getPatientChart() + }, + + // 图表日期选择变化(结束日期) + onChartEndDateChange(e: WechatMiniprogram.CustomEvent) { + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + const chartStartDate = this.data.chartStartDate + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) + + // 验证日期范围 + if (chartStartDate && fullDate < chartStartDate) { wx.showToast({ title: '结束时间不能小于开始时间', icon: 'none', @@ -211,9 +447,9 @@ Page({ } this.setData({ - [field]: value, + chartEndDate: fullDate, + chartEndMonth: monthValue, }) - // 重新加载图表数据 this.getPatientChart() }, diff --git a/src/doctor/pages/home/index.wxml b/src/doctor/pages/home/index.wxml index b07ad18..72caef8 100644 --- a/src/doctor/pages/home/index.wxml +++ b/src/doctor/pages/home/index.wxml @@ -1,9 +1,9 @@ - - 特诺雅 + + {{currentProjectName}} ® - + - + {{pharmacistName || '药师'}} @@ -112,11 +112,11 @@ - + - - {{startDate}} - + + {{statType === 'month' ? startMonth : startDate}} + @@ -157,16 +157,16 @@ - + - {{startDate}} + {{statType === 'month' ? chartStartMonth : chartStartDate}} - + - {{endDate}} + {{statType === 'month' ? chartEndMonth : chartEndDate}} diff --git a/src/doctor/pages/invite/index.ts b/src/doctor/pages/invite/index.ts index 4438a6e..9af1904 100644 --- a/src/doctor/pages/invite/index.ts +++ b/src/doctor/pages/invite/index.ts @@ -17,41 +17,16 @@ Page({ onLoad() { // 药店端邀约页面,仅允许药店人员访问 app.waitLogin({ types: [4] }).then(() => { - this.getUserInfo() - }) - }, - // 获取药店人员信息 - getUserInfo() { - wx.ajax({ - method: 'GET', - url: '/app/pharmacist/pharmacist/profile', - }).then((res: any) => { - this.setData({ - pharmacistName: res.name || '', - pharmacistAvatar: res.avatar || '', - pharmacistId: res.id || '', - }) - // 获取小程序码 + // 生成小程序码(接口会返回所有需要的信息) this.generateQrCode() }) }, // 生成药店邀约小程序码 generateQrCode() { - const { projectId } = this.data - if (!projectId) { - wx.showToast({ - title: '获取项目信息失败', - icon: 'none', - }) - return - } - wx.ajax({ method: 'POST', url: '/app/pharmacist/pharmacist/generate-code', - data: { - projectId: parseInt(projectId), - }, + data: {}, }).then((res: any) => { this.setData({ qrCodeUrl: res.imageUrl || '', diff --git a/src/doctor/pages/invite/index.wxml b/src/doctor/pages/invite/index.wxml index 8ff4416..c3c7325 100644 --- a/src/doctor/pages/invite/index.wxml +++ b/src/doctor/pages/invite/index.wxml @@ -14,11 +14,7 @@ style="background: url('{{imageUrl}}bg9.png?t={{Timestamp}}') no-repeat top center/100% 964rpx" > - + {{pharmacistName || '药师'}} 药师 @@ -40,6 +36,5 @@ 扫码立即加入 - 点击二维码保存到相册 diff --git a/src/doctor/pages/login/index.ts b/src/doctor/pages/login/index.ts index 9e95690..27db5f6 100644 --- a/src/doctor/pages/login/index.ts +++ b/src/doctor/pages/login/index.ts @@ -91,15 +91,13 @@ Page({ data: { phone: this.data.mobile, code: this.data.code, + promoterId: app.globalData.promoterId || '', + projectId: app.globalData.projectId || '', }, }).then((res: any) => { - app.globalData.initLoginInfo = { - ...app.globalData.initLoginInfo, - isLogin: 1, - loginIdentity: 4, - userId: res.userId, - } - this.submitCallback() + app.startLogin(() => { + this.submitCallback(res) + }) }) }, handleWxSubmit(e: WechatMiniprogram.CustomEvent) { @@ -121,23 +119,31 @@ Page({ sessionKey, encryptedData, iv, + promoterId: app.globalData.promoterId || '', + projectId: app.globalData.projectId || '', }, }).then((res: any) => { - // 更新登录信息 - app.globalData.initLoginInfo = { - ...app.globalData.initLoginInfo, - isLogin: 1, - loginIdentity: 4, - userId: res.userId, - } - this.submitCallback() + app.startLogin(() => { + this.submitCallback(res) + }) }) } }, - submitCallback() { - wx.reLaunch({ - url: '/doctor/pages/loginForm/index', - }) + submitCallback(res: any) { + // 根据 isRegister 判断是否已注册 + // isRegister: 0-未注册,1-已注册 + if (res.isRegister === 1) { + // 已注册,设置isLogin并跳转到首页 + app.globalData.initLoginInfo.isLogin = 1 + wx.reLaunch({ + url: '/doctor/pages/home/index', + }) + } else { + // 未注册,跳转到注册页面(isLogin仍为0) + wx.reLaunch({ + url: '/doctor/pages/loginForm/index', + }) + } }, handlePatient() { wx.redirectTo({ diff --git a/src/doctor/pages/loginForm/index.ts b/src/doctor/pages/loginForm/index.ts index 491108f..d27f8fa 100644 --- a/src/doctor/pages/loginForm/index.ts +++ b/src/doctor/pages/loginForm/index.ts @@ -2,10 +2,6 @@ const app = getApp() Page({ data: { - // 扫码参数 - promoterId: '', - projectId: '', - // 表单数据 name: '', pharmacyId: '', @@ -39,29 +35,8 @@ Page({ pages: 0, }, }, - onLoad(options) { - // 解析扫码参数 - const promoterId = app.globalData.promoterId || '' - const projectId = app.globalData.projectId || '' - - this.setData({ - promoterId, - projectId, - }) - }, - // 解析 scene 参数 - parseScene(scene: string): { promoterId?: string; projectId?: string } { - const params: { promoterId?: string; projectId?: string } = {} - const pairs = scene.split('&') - pairs.forEach((pair) => { - const [key, value] = pair.split('=') - if (key === 'promoterId') { - params.promoterId = value - } else if (key === 'projectId') { - params.projectId = value - } - }) - return params + onLoad() { + // 页面加载 }, // 输入姓名 handleNameInput(e: WechatMiniprogram.CustomEvent) { @@ -113,8 +88,13 @@ Page({ const currentPage = this.data.page const total = res.total || 0 const pages = Math.ceil(total / this.data.pageSize) + const otherPharmacy = { + id: '-1', + name: '其他药店', + address: '没有找到所在药店', + } this.setData({ - pharmacyList: [...this.data.pharmacyList, ...list], + pharmacyList: [...this.data.pharmacyList, ...list, otherPharmacy], total, page: currentPage + 1, hasMore: currentPage < pages, @@ -179,9 +159,9 @@ Page({ show: false, }) }, - // 提交绑定 + // 提交注册 handleSubmit() { - const { promoterId, projectId, name, pharmacyId } = this.data + const { name, pharmacyId } = this.data if (!name.trim()) { wx.showToast({ @@ -203,10 +183,8 @@ Page({ wx.ajax({ method: 'POST', - url: '/app/pharmacist/pharmacist/bind-promoter', + url: '/app/pharmacist/pharmacist/register', data: { - promoterId, - projectId, name: name.trim(), pharmacyId, }, @@ -215,13 +193,13 @@ Page({ wx.hideLoading() // 保存登录信息 app.globalData.initLoginInfo = { - loginType: 4, + ...app.globalData.initLoginInfo, isLogin: 1, - isReg: 1, - ...res, + loginIdentity: 4, + loginIdentityId: res.pharmacistId, } wx.showToast({ - title: '绑定成功', + title: '注册成功', icon: 'success', }) // 跳转到药店端首页 @@ -234,7 +212,7 @@ Page({ .catch(() => { wx.hideLoading() wx.showToast({ - title: '绑定失败', + title: '注册失败', icon: 'none', }) }) diff --git a/src/doctor/pages/my/index.ts b/src/doctor/pages/my/index.ts index 7bef2fe..b91def0 100644 --- a/src/doctor/pages/my/index.ts +++ b/src/doctor/pages/my/index.ts @@ -11,11 +11,12 @@ Page({ pharmacyName: '', }, - // 邀约人信息 - inviterInfo: { - promoterName: '', - promoterPhone: '', - }, + // 邀约人列表 + inviterList: [] as Array<{ + promoterName: string + promoterPhone: string + projectName: string + }>, }, onLoad() { // 药店端我的页面,仅允许药店人员访问 @@ -24,14 +25,6 @@ Page({ this.getInviterInfo() }) }, - onShow() { - // 页面显示时刷新用户信息 - if (app.globalData.initLoginInfo?.pharmacistInfo) { - this.setData({ - pharmacistInfo: app.globalData.initLoginInfo.pharmacistInfo, - }) - } - }, // 获取药店人员信息 getProfile() { wx.ajax({ @@ -47,10 +40,6 @@ Page({ pharmacyName: res.pharmacyName || '', }, }) - // 更新全局数据 - if (app.globalData.initLoginInfo) { - app.globalData.initLoginInfo.pharmacistInfo = this.data.pharmacistInfo - } }) }, // 获取邀约人信息 @@ -59,12 +48,13 @@ Page({ method: 'GET', url: '/app/pharmacist/pharmacist/inviter-info', }).then((res: any) => { - this.setData({ - inviterInfo: { - promoterName: res.promoterName || '', - promoterPhone: res.promoterPhone || '', - }, - }) + const list = res.list || res || [] + const inviterList = list.map((item: any) => ({ + promoterName: item.promoterName || '', + promoterPhone: item.promoterPhone || '', + projectName: item.projectName || '', + })) + this.setData({ inviterList }) }) }, // 修改头像 @@ -72,74 +62,75 @@ Page({ wx.chooseMedia({ count: 1, mediaType: ['image'], - sizeType: ['compressed'], sourceType: ['album', 'camera'], - }).then((res: any) => { - const tempFilePath = res.tempFiles[0].tempFilePath - wx.showLoading({ title: '上传中...' }) + }) + .then((res) => { + const tempFilePath = res.tempFiles[0].tempFilePath + // 上传图片 + this.uploadAvatar(tempFilePath) + }) + .catch(() => { + // 用户取消选择 + }) + }, + // 上传头像 + uploadAvatar(filePath: string) { + wx.showLoading({ title: '上传中...' }) - wx.uploadFile({ - url: `${app.globalData.url }/app/common/common/upload`, - filePath: tempFilePath, - name: 'file', - header: { - loginState: app.globalData.loginState, - }, - success: (uploadRes: any) => { - try { - const data = JSON.parse(uploadRes.data) - if (data.code === 200) { - const avatarUrl = data.data.url - // 更新头像 - wx.ajax({ - method: 'POST', - url: '/app/pharmacist/pharmacist/update-avatar', - data: { avatar: avatarUrl }, - }).then(() => { - wx.hideLoading() - this.setData({ - 'pharmacistInfo.avatar': avatarUrl, - }) - // 更新全局数据 - if (app.globalData.initLoginInfo?.pharmacistInfo) { - app.globalData.initLoginInfo.pharmacistInfo.avatar = avatarUrl - } - wx.showToast({ - title: '头像更新成功', - icon: 'success', - }) - }).catch(() => { - wx.hideLoading() - wx.showToast({ - title: '头像更新失败', - icon: 'none', - }) - }) - } else { - wx.hideLoading() - wx.showToast({ - title: data.msg || '上传失败', - icon: 'none', - }) - } - } catch (e) { - wx.hideLoading() - wx.showToast({ - title: '上传失败', - icon: 'none', - }) - } - }, - fail: () => { - wx.hideLoading() + wx.uploadFile({ + url: `${app.globalData.url}/app/common/common/upload`, + filePath, + name: 'file', + header: { + loginState: app.globalData.loginState || '', + }, + success: (res) => { + wx.hideLoading() + const data = JSON.parse(res.data) + if (data.code === 0) { + const avatarUrl = data.data?.url || data.data + // 更新头像 + this.updateAvatar(avatarUrl) + } else { wx.showToast({ - title: '上传失败', + title: data.msg || '上传失败', icon: 'none', }) - }, - }) + } + }, + fail: () => { + wx.hideLoading() + wx.showToast({ + title: '上传失败', + icon: 'none', + }) + }, }) }, + // 更新头像 + updateAvatar(avatarUrl: string) { + wx.ajax({ + method: 'POST', + url: '/app/pharmacist/pharmacist/update-avatar', + data: { + avatar: avatarUrl, + }, + }) + .then(() => { + wx.showToast({ + title: '头像修改成功', + icon: 'success', + }) + // 刷新用户信息 + this.getProfile() + }) + .catch(() => { + wx.showToast({ + title: '头像修改失败', + icon: 'none', + }) + }) + }, handleNickname() { wx.navigateTo({ url: '/doctor/pages/changeNickname/index', @@ -166,10 +157,10 @@ Page({ method: 'POST', url: '/app/pharmacist/pharmacist/logout', }).finally(() => { - // 清除登录信息 - app.globalData.initLoginInfo = {} - wx.reLaunch({ - url: '/pages/work/index', + app.startLogin(() => { + wx.reLaunch({ + url: '/pages/work/index', + }) }) }) } diff --git a/src/doctor/pages/my/index.wxml b/src/doctor/pages/my/index.wxml index 657fc60..ab146b7 100644 --- a/src/doctor/pages/my/index.wxml +++ b/src/doctor/pages/my/index.wxml @@ -6,7 +6,7 @@ > - + @@ -30,9 +30,9 @@ 我的邀约码 - + - 我的邀约人 ({{inviterInfo.promoterName}} {{inviterInfo.promoterPhone}}) + 我的邀约人 ({{item.promoterName}} {{item.promoterPhone}}) 退出登录 diff --git a/src/doctor/pages/stat/index.ts b/src/doctor/pages/stat/index.ts index 1b35888..4982ee7 100644 --- a/src/doctor/pages/stat/index.ts +++ b/src/doctor/pages/stat/index.ts @@ -1,13 +1,163 @@ const app = getApp() Page({ - data: {}, + data: { + imageUrl: '', + Timestamp: Date.now(), + + // 日期范围 + startDate: '', + endDate: '', + today: '', + + // 统计类型 day-按日 month-按月 + statType: 'day', + + // 汇总数据 + summary: { + invitePatientCount: 0, + jumpPatientCount: 0, + enrollPatientCount: 0, + }, + + // 统计列表 + statList: [] as any[], + + // 分页 + page: 1, + pageSize: 20, + total: 0, + loading: false, + hasMore: true, + }, + onLoad() { // 药店端统计页面,仅允许药店人员访问 app.waitLogin({ types: [4] }).then(() => { - // 页面加载完成 + this.initDate() + this.getStatisticsList() + }) + }, + + // 初始化日期 + initDate() { + const today = this.formatDate(new Date()) + const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + + this.setData({ + startDate, + endDate: today, + today, + }) + }, + + // 格式化日期 + formatDate(date: Date): string { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + return `${year}-${month}-${day}` + }, + + // 获取统计列表 + getStatisticsList() { + if (this.data.loading || !this.data.hasMore) return + + this.setData({ loading: true }) + + wx.ajax({ + method: 'GET', + url: '/app/pharmacist/pharmacist/patient-statistics-list', + data: { + startDate: this.data.startDate, + endDate: this.data.endDate, + type: this.data.statType, + page: this.data.page, + pageSize: this.data.pageSize, + }, + }).then((res: any) => { + const list = res.list || [] + const summary = res.summary || { + invitePatientCount: 0, + jumpPatientCount: 0, + enrollPatientCount: 0, + } + + this.setData({ + summary, + statList: this.data.page === 1 ? list : [...this.data.statList, ...list], + total: res.total || 0, + page: this.data.page + 1, + hasMore: list.length >= this.data.pageSize, + loading: false, + }) + }).catch(() => { + this.setData({ loading: false }) }) }, + + // 切换统计类型 + switchStatType(e: WechatMiniprogram.CustomEvent) { + const type = e.currentTarget.dataset.type + if (type === this.data.statType) return + + this.setData({ + statType: type, + page: 1, + hasMore: true, + statList: [], + }) + this.getStatisticsList() + }, + + // 开始日期变化 + handleStartDateChange(e: WechatMiniprogram.CustomEvent) { + const startDate = e.detail.value + if (startDate > this.data.endDate) { + wx.showToast({ + title: '开始日期不能大于结束日期', + icon: 'none', + }) + return + } + + this.setData({ + startDate, + page: 1, + hasMore: true, + statList: [], + }) + this.getStatisticsList() + }, + + // 结束日期变化 + handleEndDateChange(e: WechatMiniprogram.CustomEvent) { + const endDate = e.detail.value + if (endDate < this.data.startDate) { + wx.showToast({ + title: '结束日期不能小于开始日期', + icon: 'none', + }) + return + } + + this.setData({ + endDate, + page: 1, + hasMore: true, + statList: [], + }) + this.getStatisticsList() + }, + + // 页面上拉触底事件 + onReachBottom() { + if (this.data.loading || !this.data.hasMore) { + return + } + this.getStatisticsList() + }, + handleBack() { wx.navigateBack() }, diff --git a/src/ground/pages/changeNickname/index.wxml b/src/ground/pages/changeNickname/index.wxml index fe61cbe..62ad461 100644 --- a/src/ground/pages/changeNickname/index.wxml +++ b/src/ground/pages/changeNickname/index.wxml @@ -1,7 +1,7 @@ - 资料姓名 + 修改姓名 diff --git a/src/ground/pages/home/index.ts b/src/ground/pages/home/index.ts index c3aec36..9d8770e 100644 --- a/src/ground/pages/home/index.ts +++ b/src/ground/pages/home/index.ts @@ -44,18 +44,29 @@ Page({ // 日期范围 - 邀约患者统计卡片(单日) startDate: '', today: '', + // 统计卡片显示用的月份(YYYY-MM) + startMonth: '', // 日期范围 - 图表1(邀约患者统计) chart1StartDate: '', chart1EndDate: '', + // 图表1显示用的月份(YYYY-MM) + chart1StartMonth: '', + chart1EndMonth: '', // 日期范围 - 图表2(邀约药师统计) chart2StartDate: '', chart2EndDate: '', + // 图表2显示用的月份(YYYY-MM) + chart2StartMonth: '', + chart2EndMonth: '', // 日期范围 - 图表3(邀约药店统计) chart3StartDate: '', chart3EndDate: '', + // 图表3显示用的月份(YYYY-MM) + chart3StartMonth: '', + chart3EndMonth: '', // 统计类型: day-日统计, month-月统计 statType: 'day', @@ -81,18 +92,27 @@ Page({ // 初始化日期 const today = this.formatDate(new Date()) + const currentMonth = this.formatMonth(new Date()) const defaultStartDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + const defaultStartMonth = this.formatMonth(new Date(Date.now() - 365 * 24 * 60 * 60 * 1000)) this.setData({ today, // 邀约患者统计卡片(单日)- 默认为今天 startDate: today, + startMonth: currentMonth, // 图表1-3(日期范围)- 默认为最近30天 chart1StartDate: defaultStartDate, chart1EndDate: today, + chart1StartMonth: defaultStartMonth, + chart1EndMonth: currentMonth, chart2StartDate: defaultStartDate, chart2EndDate: today, + chart2StartMonth: defaultStartMonth, + chart2EndMonth: currentMonth, chart3StartDate: defaultStartDate, chart3EndDate: today, + chart3StartMonth: defaultStartMonth, + chart3EndMonth: currentMonth, }) }, @@ -104,6 +124,13 @@ Page({ return `${year}-${month}-${day}` }, + // 格式化月份(YYYY-MM) + formatMonth(date: Date): string { + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + return `${year}-${month}` + }, + // 获取个人信息 getUserInfo() { wx.ajax({ @@ -292,8 +319,80 @@ Page({ // 切换统计类型 switchStatType(e: WechatMiniprogram.CustomEvent) { const type = e.currentTarget.dataset.type + const isMonth = type === 'month' + + // 根据统计类型重置日期范围 + let startDate = this.data.startDate + let startMonth = this.data.startMonth + let chart1StartDate = this.data.chart1StartDate + let chart1EndDate = this.data.chart1EndDate + let chart1StartMonth = this.data.chart1StartMonth + let chart1EndMonth = this.data.chart1EndMonth + let chart2StartDate = this.data.chart2StartDate + let chart2EndDate = this.data.chart2EndDate + let chart2StartMonth = this.data.chart2StartMonth + let chart2EndMonth = this.data.chart2EndMonth + let chart3StartDate = this.data.chart3StartDate + let chart3EndDate = this.data.chart3EndDate + let chart3StartMonth = this.data.chart3StartMonth + let chart3EndMonth = this.data.chart3EndMonth + + if (isMonth) { + // 切换到月统计,设置默认月份 + startMonth = this.formatMonth(new Date()) + startDate = `${startMonth}-01` + // 图表月份范围为最近12个月 + const currentMonth = this.formatMonth(new Date()) + const defaultStartMonth = this.formatMonth(new Date(Date.now() - 365 * 24 * 60 * 60 * 1000)) + chart1StartMonth = defaultStartMonth + chart1EndMonth = currentMonth + chart1StartDate = `${chart1StartMonth}-01` + chart1EndDate = `${chart1EndMonth}-01` + chart2StartMonth = defaultStartMonth + chart2EndMonth = currentMonth + chart2StartDate = `${chart2StartMonth}-01` + chart2EndDate = `${chart2EndMonth}-01` + chart3StartMonth = defaultStartMonth + chart3EndMonth = currentMonth + chart3StartDate = `${chart3StartMonth}-01` + chart3EndDate = `${chart3EndMonth}-01` + } else { + // 切换到日统计,设置默认日期为今天 + startDate = this.formatDate(new Date()) + startMonth = startDate.substring(0, 7) + // 图表日期范围为最近30天 + const today = this.formatDate(new Date()) + const defaultStartDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) + chart1StartDate = defaultStartDate + chart1EndDate = today + chart1StartMonth = chart1StartDate.substring(0, 7) + chart1EndMonth = chart1EndDate.substring(0, 7) + chart2StartDate = defaultStartDate + chart2EndDate = today + chart2StartMonth = chart2StartDate.substring(0, 7) + chart2EndMonth = chart2EndDate.substring(0, 7) + chart3StartDate = defaultStartDate + chart3EndDate = today + chart3StartMonth = chart3StartDate.substring(0, 7) + chart3EndMonth = chart3EndDate.substring(0, 7) + } + this.setData({ statType: type, + startDate, + startMonth, + chart1StartDate, + chart1EndDate, + chart1StartMonth, + chart1EndMonth, + chart2StartDate, + chart2EndDate, + chart2StartMonth, + chart2EndMonth, + chart3StartDate, + chart3EndDate, + chart3StartMonth, + chart3EndMonth, }) this.getPatientStatistics() this.getPatientChart() @@ -303,10 +402,16 @@ Page({ // 日期选择变化(邀约患者统计卡片 - 单日选择) onDateChange(e: WechatMiniprogram.CustomEvent) { - const value = e.detail.value + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) this.setData({ - startDate: value, + startDate: fullDate, + startMonth: monthValue, }) // 重新加载统计数据 this.getPatientStatistics() @@ -315,19 +420,25 @@ Page({ // 图表1日期选择变化 onChart1DateChange(e: WechatMiniprogram.CustomEvent) { const { field } = e.currentTarget.dataset - const value = e.detail.value + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) + const startDate = this.data.chart1StartDate const endDate = this.data.chart1EndDate // 验证日期范围 - if (field === 'startDate' && endDate && value > endDate) { + if (field === 'startDate' && endDate && fullDate > endDate) { wx.showToast({ title: '开始时间不能大于结束时间', icon: 'none', }) return } - if (field === 'endDate' && startDate && value < startDate) { + if (field === 'endDate' && startDate && fullDate < startDate) { wx.showToast({ title: '结束时间不能小于开始时间', icon: 'none', @@ -335,28 +446,42 @@ Page({ return } - this.setData({ - [field === 'startDate' ? 'chart1StartDate' : 'chart1EndDate']: value, - }) + if (field === 'startDate') { + this.setData({ + chart1StartDate: fullDate, + chart1StartMonth: monthValue, + }) + } else { + this.setData({ + chart1EndDate: fullDate, + chart1EndMonth: monthValue, + }) + } this.getPatientChart() }, // 图表2日期选择变化 onChart2DateChange(e: WechatMiniprogram.CustomEvent) { const { field } = e.currentTarget.dataset - const value = e.detail.value + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) + const startDate = this.data.chart2StartDate const endDate = this.data.chart2EndDate // 验证日期范围 - if (field === 'startDate' && endDate && value > endDate) { + if (field === 'startDate' && endDate && fullDate > endDate) { wx.showToast({ title: '开始时间不能大于结束时间', icon: 'none', }) return } - if (field === 'endDate' && startDate && value < startDate) { + if (field === 'endDate' && startDate && fullDate < startDate) { wx.showToast({ title: '结束时间不能小于开始时间', icon: 'none', @@ -364,28 +489,42 @@ Page({ return } - this.setData({ - [field === 'startDate' ? 'chart2StartDate' : 'chart2EndDate']: value, - }) + if (field === 'startDate') { + this.setData({ + chart2StartDate: fullDate, + chart2StartMonth: monthValue, + }) + } else { + this.setData({ + chart2EndDate: fullDate, + chart2EndMonth: monthValue, + }) + } this.getPharmacistChart() }, // 图表3日期选择变化 onChart3DateChange(e: WechatMiniprogram.CustomEvent) { const { field } = e.currentTarget.dataset - const value = e.detail.value + const value = e.detail.value // YYYY-MM-DD 或 YYYY-MM + + // 月统计时,value 是 YYYY-MM 格式,需要补全为 YYYY-MM-DD + const isMonth = value.length === 7 + const fullDate = isMonth ? `${value}-01` : value + const monthValue = isMonth ? value : value.substring(0, 7) + const startDate = this.data.chart3StartDate const endDate = this.data.chart3EndDate // 验证日期范围 - if (field === 'startDate' && endDate && value > endDate) { + if (field === 'startDate' && endDate && fullDate > endDate) { wx.showToast({ title: '开始时间不能大于结束时间', icon: 'none', }) return } - if (field === 'endDate' && startDate && value < startDate) { + if (field === 'endDate' && startDate && fullDate < startDate) { wx.showToast({ title: '结束时间不能小于开始时间', icon: 'none', @@ -393,40 +532,90 @@ Page({ return } - this.setData({ - [field === 'startDate' ? 'chart3StartDate' : 'chart3EndDate']: value, - }) + if (field === 'startDate') { + this.setData({ + chart3StartDate: fullDate, + chart3StartMonth: monthValue, + }) + } else { + this.setData({ + chart3EndDate: fullDate, + chart3EndMonth: monthValue, + }) + } this.getPharmacyChart() }, - // 切换到上一天(只更新邀约患者统计卡片) + // 切换到上一天/上月(只更新邀约患者统计卡片) prevDate() { - const currentDate = new Date(this.data.startDate) - const newDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000) - const startDate = this.formatDate(newDate) + const isMonth = this.data.statType === 'month' + let newDate: Date + let startDate: string + let startMonth: string + + if (isMonth) { + // 月统计:切换到上个月 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1) + startDate = this.formatDate(newDate) + startMonth = this.formatMonth(newDate) + } else { + // 日统计:切换到上一天 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getTime() - 24 * 60 * 60 * 1000) + startDate = this.formatDate(newDate) + startMonth = startDate.substring(0, 7) + } - this.setData({ startDate }) + this.setData({ startDate, startMonth }) // 只重新加载统计数据 this.getPatientStatistics() }, - // 切换到下一天(只更新邀约患者统计卡片) + // 切换到下一天/下月(只更新邀约患者统计卡片) nextDate() { - const currentDate = new Date(this.data.startDate) - const newDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000) + const isMonth = this.data.statType === 'month' const today = new Date() + let newDate: Date + let startDate: string + let startMonth: string + + if (isMonth) { + // 月统计:切换到下个月 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1) + + // 最大月份不能大于当前月份 + const currentMonth = new Date(today.getFullYear(), today.getMonth(), 1) + if (newDate > currentMonth) { + wx.showToast({ + title: '不能选择未来月份', + icon: 'none', + }) + return + } + + startDate = this.formatDate(newDate) + startMonth = this.formatMonth(newDate) + } else { + // 日统计:切换到下一天 + const currentDate = new Date(this.data.startDate) + newDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000) + + // 最大日期不能大于当前日期 + if (newDate > today) { + wx.showToast({ + title: '不能选择未来日期', + icon: 'none', + }) + return + } - // 最大日期不能大于当前日期 - if (newDate > today) { - wx.showToast({ - title: '不能选择未来日期', - icon: 'none', - }) - return + startDate = this.formatDate(newDate) + startMonth = startDate.substring(0, 7) } - const startDate = this.formatDate(newDate) - this.setData({ startDate }) + this.setData({ startDate, startMonth }) // 只重新加载统计数据 this.getPatientStatistics() }, diff --git a/src/ground/pages/home/index.wxml b/src/ground/pages/home/index.wxml index a581d32..4a244a4 100644 --- a/src/ground/pages/home/index.wxml +++ b/src/ground/pages/home/index.wxml @@ -11,7 +11,7 @@ style="background:url('{{imageUrl}}bg1.png?t={{Timestamp}}') no-repeat top center/100% 602rpx; padding-top: {{pageTop+20}}px" > - + {{promoterName || '地推人员'}} {{label}} @@ -95,10 +95,10 @@ - + - {{startDate}} + {{statType === 'month' ? startMonth : startDate}} @@ -140,16 +140,16 @@ - + - {{chart1StartDate}} + {{statType === 'month' ? chart1StartMonth : chart1StartDate}} - + - {{chart1EndDate}} + {{statType === 'month' ? chart1EndMonth : chart1EndDate}} @@ -168,16 +168,16 @@ 邀约药师数统计 - + - {{chart2StartDate}} + {{statType === 'month' ? chart2StartMonth : chart2StartDate}} - + - {{chart2EndDate}} + {{statType === 'month' ? chart2EndMonth : chart2EndDate}} @@ -192,16 +192,16 @@ 邀约药店统计 - + - {{chart3StartDate}} + {{statType === 'month' ? chart3StartMonth : chart3StartDate}} - + - {{chart3EndDate}} + {{statType === 'month' ? chart3EndMonth : chart3EndDate}} diff --git a/src/ground/pages/login/index.ts b/src/ground/pages/login/index.ts index 1921b74..2f922ce 100644 --- a/src/ground/pages/login/index.ts +++ b/src/ground/pages/login/index.ts @@ -1,3 +1,4 @@ +const app = getApp() let timer = null as null | number Page({ @@ -91,15 +92,10 @@ Page({ phone: this.data.mobile, code: this.data.code, }, - }).then((res: any) => { - const app = getApp() - app.globalData.initLoginInfo = { - ...app.globalData.initLoginInfo, - isLogin: 1, - loginIdentity: 3, - userId: res.userId, - } - this.submitCallback() + }).then(() => { + app.startLogin(() => { + this.submitCallback() + }) }) }, handleWxSubmit(e: WechatMiniprogram.CustomEvent) { @@ -112,7 +108,6 @@ Page({ } const { iv, encryptedData } = e.detail if (iv && encryptedData) { - const app = getApp() const sessionKey = app.globalData.initLoginInfo?.sessionKey || '' wx.ajax({ @@ -123,15 +118,10 @@ Page({ encryptedData, iv, }, - }).then((res: any) => { - // 更新登录信息 - app.globalData.initLoginInfo = { - ...app.globalData.initLoginInfo, - isLogin: 1, - loginIdentity: 3, - userId: res.userId, - } - this.submitCallback() + }).then(() => { + app.startLogin(() => { + this.submitCallback() + }) }) } }, diff --git a/src/ground/pages/my/index.ts b/src/ground/pages/my/index.ts index 12c8992..dedbaea 100644 --- a/src/ground/pages/my/index.ts +++ b/src/ground/pages/my/index.ts @@ -55,7 +55,7 @@ Page({ filePath, name: 'file', header: { - 'loginState': app.globalData.loginState || '', + loginState: app.globalData.loginState || '', }, success: (res) => { wx.hideLoading() @@ -130,10 +130,10 @@ Page({ method: 'POST', url: '/app/promoter/promoter/logout', }).finally(() => { - // 清除登录信息 - app.globalData.initLoginInfo = {} - wx.reLaunch({ - url: '/pages/work/index', + app.startLogin(() => { + wx.reLaunch({ + url: '/pages/work/index', + }) }) }) } diff --git a/src/ground/pages/my/index.wxml b/src/ground/pages/my/index.wxml index d9aec46..ebb5625 100644 --- a/src/ground/pages/my/index.wxml +++ b/src/ground/pages/my/index.wxml @@ -6,7 +6,7 @@ > - + diff --git a/src/ground/pages/pharmacist/index.wxml b/src/ground/pages/pharmacist/index.wxml index 4310ab1..42ffe4b 100644 --- a/src/ground/pages/pharmacist/index.wxml +++ b/src/ground/pages/pharmacist/index.wxml @@ -43,7 +43,7 @@ - + {{item.name}} diff --git a/src/pages/index/index.scss b/src/pages/index/index.scss index 997aa6b..167040a 100644 --- a/src/pages/index/index.scss +++ b/src/pages/index/index.scss @@ -1,7 +1,8 @@ page { background-color: #f8fafa; } -.page-title { +.page-title, +.page-switch { font-weight: 900; font-size: 44rpx; line-height: 52rpx; diff --git a/src/pages/index/index.ts b/src/pages/index/index.ts index 1d148f7..2fd7273 100644 --- a/src/pages/index/index.ts +++ b/src/pages/index/index.ts @@ -13,6 +13,9 @@ Page({ projectId: '', projectName: '', + currentProjectName: '', + projectIndex: 0, + projectList: [] as Array<{ projectId: number; projectName: string; projectDescription: string }>, // 扫码获取的药师ID pharmacistId: '', @@ -33,14 +36,67 @@ Page({ // 从 globalData 初始化扫码参数 const pharmacistId = app.globalData.pharmacistId || '' - const projectId = app.globalData.projectId || '0' + const projectId = app.globalData.projectId || '' this.setData({ pharmacistId, projectId, }) - app.waitLogin({ types: [1, 2] }).then(() => { + app.waitLogin().then(() => { + this.getProjectList() + this.getBanner() + this.checkStatus() + }) + }, + + // 获取项目列表 + getProjectList() { + wx.ajax({ + method: 'GET', + url: '/app/patient/patient/project-list', + }).then((res: any) => { + const projectList = res.list || [] + const currentProjectId = res.currentProjectId + + // 找到当前项目的索引 + let projectIndex = 0 + projectList.forEach((item: any, index: number) => { + if (item.projectId === currentProjectId) { + projectIndex = index + } + }) + + this.setData({ + projectList, + projectIndex, + currentProjectName: projectList[projectIndex]?.projectName || '华观健康', + }) + }) + }, + + // 切换项目 + onProjectChange(e: WechatMiniprogram.CustomEvent) { + const index = e.detail.value + const project = this.data.projectList[index] + + if (!project || project.projectId === this.data.projectList[this.data.projectIndex]?.projectId) { + return + } + + wx.ajax({ + method: 'POST', + url: '/app/patient/patient/switch-project', + data: { + projectId: project.projectId, + }, + }).then(() => { + this.setData({ + projectIndex: index, + currentProjectName: project.projectName, + projectId: String(project.projectId), + }) + // 刷新页面数据 this.getBanner() this.checkStatus() }) @@ -179,54 +235,38 @@ Page({ method: 'POST', url: '/app/patient/patient/wx-login', data: params, - }) - .then(() => { - // 选择适应症 - return wx.ajax({ + }).then((res: any) => { + const jumpUrl = res.jumpUrl + + // 如果有药师ID,创建绑定关系 + if (this.data.pharmacistId) { + wx.ajax({ method: 'POST', - url: '/app/patient/patient/select-indication', + url: '/app/patient/patient/bind-pharmacist', data: { + pharmacistId: Number.parseInt(this.data.pharmacistId), projectId: this.data.projectId, indicationId: selectedOption.indicationId, }, - }) - }) - .then((res: any) => { - const jumpUrl = res.jumpUrl - - // 如果有药师ID,创建绑定关系 - if (this.data.pharmacistId) { - wx.ajax({ - method: 'POST', - url: '/app/patient/patient/bind-pharmacist', - data: { - pharmacistId: Number.parseInt(this.data.pharmacistId), - projectId: this.data.projectId, - indicationId: selectedOption.indicationId, - }, - }) - .then(() => { - // 绑定成功后跳转 - wx.navigateToMiniProgram({ - appId: 'wx05551c5ee1fd1c12', - path: jumpUrl, - }) - }) - .catch(() => { - // 绑定失败也跳转 - wx.navigateToMiniProgram({ - appId: 'wx05551c5ee1fd1c12', - path: jumpUrl, - }) - }) - } else { - // 没有药师ID,直接跳转 + }).then(() => { + // 绑定成功后跳转 wx.navigateToMiniProgram({ appId: 'wx05551c5ee1fd1c12', path: jumpUrl, }) - } - }) + this.checkStatus() + }) + } else { + // 没有药师ID,直接跳转 + wx.navigateToMiniProgram({ + appId: 'wx05551c5ee1fd1c12', + path: jumpUrl, + success: () => { + this.checkStatus() + }, + }) + } + }) } }, @@ -235,6 +275,11 @@ Page({ agreementChecked: !this.data.agreementChecked, }) }, + handleAgreement() { + wx.navigateTo({ + url: '/privacy/pages/policy/index', + }) + }, handleWork() { wx.navigateTo({ diff --git a/src/pages/index/index.wxml b/src/pages/index/index.wxml index 93a2c36..0000ea9 100644 --- a/src/pages/index/index.wxml +++ b/src/pages/index/index.wxml @@ -1,5 +1,10 @@ - 华观健康 + + {{currentProjectName}} + ® + + + 华观健康 同意 - 《用户与隐私保护协议》 + 《用户与隐私保护协议》 diff --git a/src/pages/start/index.ts b/src/pages/start/index.ts index 71dca82..24c36fa 100644 --- a/src/pages/start/index.ts +++ b/src/pages/start/index.ts @@ -5,12 +5,21 @@ Page({ data: {}, onLoad(options) { // 解析扫码参数 - let pharmacistId = '' + let t = '' + let pharmacistId = '' // 药店人员ID + let promoterId = '' // 地推人员ID let projectId = '' if (options.scene) { - const sceneData = parseScene(options.scene) as { pharmacistId?: string; projectId?: string } + const sceneData = parseScene(options.scene) as { + t: string + pharmacistId?: string + projectId?: string + promoterId?: string + } + t = sceneData.t || '' // 1-地推人员码,2-药店人员码 pharmacistId = sceneData.pharmacistId || '' + promoterId = sceneData.promoterId || '' projectId = sceneData.projectId || '' } @@ -18,31 +27,44 @@ Page({ if (pharmacistId) { app.globalData.pharmacistId = pharmacistId } + if (promoterId) { + app.globalData.promoterId = promoterId + } if (projectId) { app.globalData.projectId = projectId } app.waitLogin().then(() => { - const { isLogin, loginIdentity } = app.globalData.initLoginInfo + const { isLogin, isRegister, loginIdentity } = app.globalData.initLoginInfo - // 游客(1)或患者端(2)且有扫码参数,进入患者首页 - if ((loginIdentity === 1 || loginIdentity === 2) && pharmacistId && projectId) { - wx.reLaunch({ - url: '/pages/index/index', - }) + // 扫码进入用户处理 + if (t == '1') { + if (loginIdentity === 4 && isLogin && isRegister) { + wx.reLaunch({ + url: '/doctor/pages/home/index?bind=1', + }) + } else { + wx.reLaunch({ + url: '/doctor/pages/login/index', + }) + } return } - - // 游客(1)或患者端(2)无扫码参数,进入游客页面 - if (loginIdentity === 1 || loginIdentity === 2) { + if (t == '2') { wx.reLaunch({ - url: '/pages/tourists/index', + url: '/pages/index/index', }) return } // 未注册,根据身份跳转到对应注册页面 if (!isLogin) { + if (loginIdentity === 2) { + wx.reLaunch({ + url: '/pages/index/index', + }) + return + } wx.reLaunch({ url: '/pages/tourists/index', }) diff --git a/src/pages/start/index.wxml b/src/pages/start/index.wxml index c07334d..9514360 100644 --- a/src/pages/start/index.wxml +++ b/src/pages/start/index.wxml @@ -1 +1 @@ - + diff --git a/src/pages/tourists/index.ts b/src/pages/tourists/index.ts index cae7106..ad202bf 100644 --- a/src/pages/tourists/index.ts +++ b/src/pages/tourists/index.ts @@ -4,7 +4,25 @@ Page({ data: {}, onLoad() { app.waitLogin().then(() => { - // 页面加载完成 + // 检查用户是否已有绑定的项目 + this.checkProjectStatus() + }) + }, + // 检查用户项目状态 + checkProjectStatus() { + wx.ajax({ + method: 'GET', + url: '/app/patient/patient/recent-project', + }).then((res: any) => { + if (res && res.projectId) { + // 已有绑定的项目,跳转到患者首页 + wx.reLaunch({ + url: '/pages/index/index', + }) + } + // 没有项目,停留在当前页面 + }).catch(() => { + // 接口失败,停留在当前页面 }) }, // 跳转到药店工作人员登录页 diff --git a/src/pages/tourists/index.wxml b/src/pages/tourists/index.wxml index add026a..5fc59a8 100644 --- a/src/pages/tourists/index.wxml +++ b/src/pages/tourists/index.wxml @@ -2,8 +2,8 @@ 华观健康 - - + + 我是药店工作人员 我是地推人员 diff --git a/src/pages/work/index.ts b/src/pages/work/index.ts index c85641e..58df175 100644 --- a/src/pages/work/index.ts +++ b/src/pages/work/index.ts @@ -20,7 +20,7 @@ Page({ }, hadlePatient() { wx.navigateTo({ - url: '/pages/start/index', + url: '/pages/tourists/index', }) }, }) diff --git a/typings/index.d.ts b/typings/index.d.ts index 2943a9a..17bf06c 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -42,7 +42,7 @@ interface IAppOption { initLoginInfo: Partial<{ isLogin: 0 | 1 isReg: 0 | 1 - isRegistered: 0 | 1 + isRegister: 0 | 1 // 1-游客,2-患者端,3-地推人员端,4-药店人员端 loginType: 1 | 2 | 3 | 4 loginIdentity: 1 | 2 | 3 | 4