|
|
|
|
const echarts = require('../../../components/ec-canvas/echarts.js')
|
|
|
|
|
|
|
|
|
|
Page({
|
|
|
|
|
data: {
|
|
|
|
|
fold1: true,
|
|
|
|
|
fold2: true,
|
|
|
|
|
|
|
|
|
|
// 用户信息
|
|
|
|
|
promoterName: '',
|
|
|
|
|
promoterAvatar: '',
|
|
|
|
|
label: '邀约专员',
|
|
|
|
|
|
|
|
|
|
// 累计统计数据(来自 getStatistics)
|
|
|
|
|
totalInvitePharmacyCount: 0,
|
|
|
|
|
totalInvitePharmacistCount: 0,
|
|
|
|
|
totalInvitePatientCount: 0,
|
|
|
|
|
totalJumpPatientCount: 0,
|
|
|
|
|
totalEnrollPatientCount: 0,
|
|
|
|
|
totalIndicationStats: [] as Array<{
|
|
|
|
|
indicationId: number
|
|
|
|
|
indicationName: string
|
|
|
|
|
invitePatientCount: number
|
|
|
|
|
jumpPatientCount: number
|
|
|
|
|
enrollPatientCount: number
|
|
|
|
|
}>,
|
|
|
|
|
|
|
|
|
|
// 日期筛选统计数据(来自 getPatientStatistics)
|
|
|
|
|
invitePatientCount: 0,
|
|
|
|
|
jumpPatientCount: 0,
|
|
|
|
|
enrollPatientCount: 0,
|
|
|
|
|
indicationStats: [] as Array<{
|
|
|
|
|
indicationId: number
|
|
|
|
|
indicationName: string
|
|
|
|
|
invitePatientCount: number
|
|
|
|
|
jumpPatientCount: number
|
|
|
|
|
enrollPatientCount: number
|
|
|
|
|
}>,
|
|
|
|
|
|
|
|
|
|
// 图表数据
|
|
|
|
|
chartData: [] as Array<{ date: string, count: number }>,
|
|
|
|
|
pharmacistChartData: [] as Array<{ date: string, count: number }>,
|
|
|
|
|
pharmacyChartData: [] as Array<{ date: string, count: number }>,
|
|
|
|
|
|
|
|
|
|
// 日期范围 - 邀约患者统计卡片(单日)
|
|
|
|
|
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',
|
|
|
|
|
|
|
|
|
|
// 项目列表
|
|
|
|
|
projectList: [] as Array<{ projectId: number; projectName: string; projectDescription: string }>,
|
|
|
|
|
currentProjectId: 0,
|
|
|
|
|
currentProjectName: '',
|
|
|
|
|
projectIndex: 0,
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
ecDataTrendComponent1_1: null as any,
|
|
|
|
|
ecDataTrendComponent2_1: null as any,
|
|
|
|
|
ecDataTrendComponent3_1: null as any,
|
|
|
|
|
|
|
|
|
|
async onLoad() {
|
|
|
|
|
const app = getApp<IAppOption>()
|
|
|
|
|
// 地推端页面,仅允许地推人员(3)访问
|
|
|
|
|
app.waitLogin({ types: [3] }).then(() => {
|
|
|
|
|
this.getUserInfo()
|
|
|
|
|
this.getProjectList()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 初始化日期
|
|
|
|
|
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,
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 格式化日期
|
|
|
|
|
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}`
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 格式化月份(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({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/profile',
|
|
|
|
|
}).then((res: any) => {
|
|
|
|
|
this.setData({
|
|
|
|
|
promoterName: res.name,
|
|
|
|
|
promoterAvatar: res.avatar,
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取项目列表
|
|
|
|
|
getProjectList() {
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/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({
|
|
|
|
|
projectList,
|
|
|
|
|
currentProjectId,
|
|
|
|
|
currentProjectName: currentProject?.projectName || '',
|
|
|
|
|
projectIndex: projectIndex >= 0 ? projectIndex : 0,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 获取统计数据
|
|
|
|
|
this.getStatistics()
|
|
|
|
|
this.getPatientStatistics()
|
|
|
|
|
this.getPatientChart()
|
|
|
|
|
this.getPharmacistChart()
|
|
|
|
|
this.getPharmacyChart()
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 切换项目
|
|
|
|
|
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/promoter/promoter/switch-project',
|
|
|
|
|
data: {
|
|
|
|
|
projectId: project.projectId,
|
|
|
|
|
},
|
|
|
|
|
}).then(() => {
|
|
|
|
|
// 切换成功后更新页面数据
|
|
|
|
|
this.setData({
|
|
|
|
|
currentProjectId: project.projectId,
|
|
|
|
|
currentProjectName: project.projectName,
|
|
|
|
|
projectIndex: index,
|
|
|
|
|
})
|
|
|
|
|
// 重新加载数据
|
|
|
|
|
this.getStatistics()
|
|
|
|
|
this.getPatientStatistics()
|
|
|
|
|
this.getPatientChart()
|
|
|
|
|
this.getPharmacistChart()
|
|
|
|
|
this.getPharmacyChart()
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '切换成功',
|
|
|
|
|
icon: 'success',
|
|
|
|
|
})
|
|
|
|
|
}).catch(() => {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '切换失败',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取统计数据看板(累计数据)
|
|
|
|
|
getStatistics() {
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/statistics',
|
|
|
|
|
}).then((res: any) => {
|
|
|
|
|
this.setData({
|
|
|
|
|
// 累计数据
|
|
|
|
|
totalInvitePharmacyCount: res.invitePharmacyCount || 0,
|
|
|
|
|
totalInvitePharmacistCount: res.invitePharmacistCount || 0,
|
|
|
|
|
totalInvitePatientCount: res.invitePatientCount || 0,
|
|
|
|
|
totalJumpPatientCount: res.jumpPatientCount || 0,
|
|
|
|
|
totalEnrollPatientCount: res.enrollPatientCount || 0,
|
|
|
|
|
totalIndicationStats: res.indicationStats || [],
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取日/月度邀约患者统计数据(按日期筛选)
|
|
|
|
|
getPatientStatistics() {
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/patient-statistics',
|
|
|
|
|
data: {
|
|
|
|
|
statDate: this.data.startDate,
|
|
|
|
|
type: this.data.statType,
|
|
|
|
|
},
|
|
|
|
|
}).then((res: any) => {
|
|
|
|
|
this.setData({
|
|
|
|
|
invitePatientCount: res.invitePatientCount || 0,
|
|
|
|
|
jumpPatientCount: res.jumpPatientCount || 0,
|
|
|
|
|
enrollPatientCount: res.enrollPatientCount || 0,
|
|
|
|
|
indicationStats: res.indicationStats || [],
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取邀约患者统计图表(使用 chart1 的日期)
|
|
|
|
|
getPatientChart() {
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/patient-chart',
|
|
|
|
|
data: {
|
|
|
|
|
type: this.data.statType,
|
|
|
|
|
startDate: this.data.chart1StartDate,
|
|
|
|
|
endDate: this.data.chart1EndDate,
|
|
|
|
|
},
|
|
|
|
|
}).then((list: any) => {
|
|
|
|
|
// 新接口返回的数据格式包含 invitePatientCount, jumpPatientCount, enrollPatientCount, indicationStats
|
|
|
|
|
// 转换为图表需要的格式
|
|
|
|
|
const chartData = (list || []).map((item: any) => ({
|
|
|
|
|
date: item.statDate,
|
|
|
|
|
inviteCount: item.invitePatientCount || 0,
|
|
|
|
|
jumpCount: item.jumpPatientCount || 0,
|
|
|
|
|
enrollCount: item.enrollPatientCount || 0,
|
|
|
|
|
}))
|
|
|
|
|
this.setData({
|
|
|
|
|
chartData,
|
|
|
|
|
})
|
|
|
|
|
this.initChartBar(chartData)
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取邀约药师统计图表(使用 chart2 的日期)
|
|
|
|
|
getPharmacistChart() {
|
|
|
|
|
const data: any = {
|
|
|
|
|
type: this.data.statType,
|
|
|
|
|
startDate: this.data.chart2StartDate,
|
|
|
|
|
endDate: this.data.chart2EndDate,
|
|
|
|
|
}
|
|
|
|
|
if (this.data.currentProjectId) {
|
|
|
|
|
data.projectId = this.data.currentProjectId
|
|
|
|
|
}
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/pharmacist-chart',
|
|
|
|
|
data,
|
|
|
|
|
}).then((list: any) => {
|
|
|
|
|
this.setData({
|
|
|
|
|
pharmacistChartData: list || [],
|
|
|
|
|
})
|
|
|
|
|
this.initChartLine(list || [], '#chart2_1', 'ecDataTrendComponent2_1')
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取邀约药店统计图表(使用 chart3 的日期)
|
|
|
|
|
getPharmacyChart() {
|
|
|
|
|
const data: any = {
|
|
|
|
|
type: this.data.statType,
|
|
|
|
|
startDate: this.data.chart3StartDate,
|
|
|
|
|
endDate: this.data.chart3EndDate,
|
|
|
|
|
}
|
|
|
|
|
if (this.data.currentProjectId) {
|
|
|
|
|
data.projectId = this.data.currentProjectId
|
|
|
|
|
}
|
|
|
|
|
wx.ajax({
|
|
|
|
|
method: 'GET',
|
|
|
|
|
url: '/app/promoter/promoter/pharmacy-chart',
|
|
|
|
|
data,
|
|
|
|
|
}).then((list: any) => {
|
|
|
|
|
this.setData({
|
|
|
|
|
pharmacyChartData: list || [],
|
|
|
|
|
})
|
|
|
|
|
this.initChartLine(list || [], '#chart3_1', 'ecDataTrendComponent3_1')
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 切换统计类型
|
|
|
|
|
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()
|
|
|
|
|
this.getPharmacistChart()
|
|
|
|
|
this.getPharmacyChart()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 日期选择变化(邀约患者统计卡片 - 单日选择)
|
|
|
|
|
onDateChange(e: WechatMiniprogram.CustomEvent) {
|
|
|
|
|
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.getPatientStatistics()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 图表1日期选择变化
|
|
|
|
|
onChart1DateChange(e: WechatMiniprogram.CustomEvent) {
|
|
|
|
|
const { field } = e.currentTarget.dataset
|
|
|
|
|
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 && fullDate > endDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '开始时间不能大于结束时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (field === 'endDate' && startDate && fullDate < startDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '结束时间不能小于开始时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 // 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 && fullDate > endDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '开始时间不能大于结束时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (field === 'endDate' && startDate && fullDate < startDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '结束时间不能小于开始时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 // 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 && fullDate > endDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '开始时间不能大于结束时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (field === 'endDate' && startDate && fullDate < startDate) {
|
|
|
|
|
wx.showToast({
|
|
|
|
|
title: '结束时间不能小于开始时间',
|
|
|
|
|
icon: 'none',
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (field === 'startDate') {
|
|
|
|
|
this.setData({
|
|
|
|
|
chart3StartDate: fullDate,
|
|
|
|
|
chart3StartMonth: monthValue,
|
|
|
|
|
})
|
|
|
|
|
} else {
|
|
|
|
|
this.setData({
|
|
|
|
|
chart3EndDate: fullDate,
|
|
|
|
|
chart3EndMonth: monthValue,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
this.getPharmacyChart()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 切换到上一天/上月(只更新邀约患者统计卡片)
|
|
|
|
|
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.getPatientStatistics()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 切换到下一天/下月(只更新邀约患者统计卡片)
|
|
|
|
|
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.getPatientStatistics()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
initChartBar(list: any[]) {
|
|
|
|
|
return new Promise((reslove) => {
|
|
|
|
|
this.ecDataTrendComponent1_1 = this.selectComponent('#chart1_1')
|
|
|
|
|
this.ecDataTrendComponent1_1.init((canvas, width, height, dpr) => {
|
|
|
|
|
const chart = echarts.init(canvas, null, {
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
devicePixelRatio: dpr,
|
|
|
|
|
})
|
|
|
|
|
canvas.setChart(chart)
|
|
|
|
|
const x: string[] = []
|
|
|
|
|
const y1: number[] = []
|
|
|
|
|
const y2: number[] = []
|
|
|
|
|
const y3: number[] = []
|
|
|
|
|
list.forEach((item) => {
|
|
|
|
|
x.push(item.date || item.StatMonth)
|
|
|
|
|
y1.push(item.inviteCount || item.count || item.MonthInvitePCount || 0)
|
|
|
|
|
y2.push(item.jumpCount || 0)
|
|
|
|
|
y3.push(item.enrollCount || 0)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'shadow',
|
|
|
|
|
},
|
|
|
|
|
formatter (params) {
|
|
|
|
|
let result = `${params[0].axisValue }\n`
|
|
|
|
|
params.forEach((item, index) => {
|
|
|
|
|
result += `${item.marker } ${ item.seriesName }: ${ item.value}`
|
|
|
|
|
if (index < params.length - 1) {
|
|
|
|
|
result += '\n'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return result
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
top: 0,
|
|
|
|
|
right: 0,
|
|
|
|
|
itemWidth: 8,
|
|
|
|
|
itemHeight: 8,
|
|
|
|
|
icon: 'rect',
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: '0',
|
|
|
|
|
},
|
|
|
|
|
textStyle: {
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
fontSize: '12',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
top: '10%',
|
|
|
|
|
left: '3%',
|
|
|
|
|
right: '4%',
|
|
|
|
|
bottom: '0',
|
|
|
|
|
containLabel: true,
|
|
|
|
|
},
|
|
|
|
|
xAxis: [
|
|
|
|
|
{
|
|
|
|
|
type: 'category',
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false,
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false,
|
|
|
|
|
},
|
|
|
|
|
data: x,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
yAxis: [
|
|
|
|
|
{
|
|
|
|
|
type: 'value',
|
|
|
|
|
minInterval: 1,
|
|
|
|
|
splitLine: {
|
|
|
|
|
lineStyle: {
|
|
|
|
|
type: 'dashed',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
formatter(value) {
|
|
|
|
|
return Math.abs(value)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '邀约患者数',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
stack: 'a',
|
|
|
|
|
width: 4,
|
|
|
|
|
color: '#FED877',
|
|
|
|
|
barWidth: 12,
|
|
|
|
|
data: y1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '跳转患者数',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
stack: 'a',
|
|
|
|
|
color: '#4A8DFF',
|
|
|
|
|
barWidth: 12,
|
|
|
|
|
data: y2,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: '入组患者数',
|
|
|
|
|
type: 'bar',
|
|
|
|
|
stack: 'a',
|
|
|
|
|
color: '#3ADDC8',
|
|
|
|
|
barWidth: 12,
|
|
|
|
|
data: y3,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
dataZoom: {
|
|
|
|
|
type: 'inside',
|
|
|
|
|
startValue: x.length - 6,
|
|
|
|
|
endValue: x.length - 1,
|
|
|
|
|
filterMode: 'none',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chart.setOption(option)
|
|
|
|
|
reslove(chart)
|
|
|
|
|
return chart
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
initChartLine(list: any[], name: string, componentName: string) {
|
|
|
|
|
return new Promise((reslove) => {
|
|
|
|
|
this[componentName] = this.selectComponent(name)
|
|
|
|
|
this[componentName].init((canvas, width, height, dpr) => {
|
|
|
|
|
const chart = echarts.init(canvas, null, {
|
|
|
|
|
width,
|
|
|
|
|
height,
|
|
|
|
|
devicePixelRatio: dpr,
|
|
|
|
|
})
|
|
|
|
|
canvas.setChart(chart)
|
|
|
|
|
const x: string[] = []
|
|
|
|
|
const y1: string[] = []
|
|
|
|
|
list.forEach((item) => {
|
|
|
|
|
x.push(item.date || item.StatMonth)
|
|
|
|
|
y1.push(item.count || item.MonthInvitePCount)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const option = {
|
|
|
|
|
tooltip: {
|
|
|
|
|
trigger: 'axis',
|
|
|
|
|
axisPointer: {
|
|
|
|
|
type: 'line',
|
|
|
|
|
},
|
|
|
|
|
formatter (params) {
|
|
|
|
|
let result = `${params[0].axisValue }\n`
|
|
|
|
|
params.forEach((item, index) => {
|
|
|
|
|
result += `${item.marker } ${ item.seriesName }: ${ item.value}`
|
|
|
|
|
if (index < params.length - 1) {
|
|
|
|
|
result += '\n'
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return result
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
legend: {
|
|
|
|
|
top: 0,
|
|
|
|
|
right: 0,
|
|
|
|
|
itemWidth: 8,
|
|
|
|
|
itemHeight: 8,
|
|
|
|
|
icon: 'rect',
|
|
|
|
|
lineStyle: {
|
|
|
|
|
width: '0',
|
|
|
|
|
},
|
|
|
|
|
textStyle: {
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
fontSize: '12',
|
|
|
|
|
},
|
|
|
|
|
data: [],
|
|
|
|
|
},
|
|
|
|
|
grid: {
|
|
|
|
|
top: '10%',
|
|
|
|
|
left: '3%',
|
|
|
|
|
right: '4%',
|
|
|
|
|
bottom: '0',
|
|
|
|
|
containLabel: true,
|
|
|
|
|
},
|
|
|
|
|
xAxis: [
|
|
|
|
|
{
|
|
|
|
|
type: 'category',
|
|
|
|
|
axisTick: {
|
|
|
|
|
show: false,
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
},
|
|
|
|
|
axisLine: {
|
|
|
|
|
show: false,
|
|
|
|
|
},
|
|
|
|
|
data: x,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
yAxis: [
|
|
|
|
|
{
|
|
|
|
|
type: 'value',
|
|
|
|
|
minInterval: 1,
|
|
|
|
|
splitLine: {
|
|
|
|
|
lineStyle: {
|
|
|
|
|
type: 'dashed',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
axisLabel: {
|
|
|
|
|
fontSize: 10,
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
formatter(value) {
|
|
|
|
|
return Math.abs(value)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
series: [
|
|
|
|
|
{
|
|
|
|
|
name: '邀约患者数',
|
|
|
|
|
type: 'line',
|
|
|
|
|
stack: 'a',
|
|
|
|
|
width: 4,
|
|
|
|
|
color: '#FED877',
|
|
|
|
|
barWidth: 12,
|
|
|
|
|
data: y1,
|
|
|
|
|
smooth: 0.5,
|
|
|
|
|
label: {
|
|
|
|
|
show: true,
|
|
|
|
|
position: 'top',
|
|
|
|
|
fontSize: 12,
|
|
|
|
|
color: '#B5B8BB',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
dataZoom: {
|
|
|
|
|
type: 'inside',
|
|
|
|
|
startValue: x.length - 6,
|
|
|
|
|
endValue: x.length - 1,
|
|
|
|
|
filterMode: 'none',
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chart.setOption(option)
|
|
|
|
|
reslove(chart)
|
|
|
|
|
return chart
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleInvite() {
|
|
|
|
|
wx.navigateTo({
|
|
|
|
|
url: '/ground/pages/invite/index',
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleInfo() {
|
|
|
|
|
const { chart1StartDate, chart1EndDate, statType } = this.data
|
|
|
|
|
wx.navigateTo({
|
|
|
|
|
url: `/ground/pages/stat/index?startDate=${chart1StartDate}&endDate=${chart1EndDate}&type=${statType}`,
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleFold(e) {
|
|
|
|
|
const { key } = e.currentTarget.dataset
|
|
|
|
|
this.setData({
|
|
|
|
|
[key]: !this.data[key],
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
})
|