You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

412 lines
9.9 KiB

const echarts = require('../../../components/ec-canvas/echarts.js')
Page({
1 month ago
data: {
1 month ago
fold1: true,
fold2: true,
// 用户信息
promoterName: '',
promoterAvatar: '',
label: '邀约专员',
// 统计数据
invitePharmacyCount: 0,
invitePharmacistCount: 0,
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 }>,
// 日期范围
startDate: '',
endDate: '',
// 统计类型: day-日统计, month-月统计
statType: 'day',
1 month ago
},
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.getStatistics()
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
})
// 初始化日期范围为最近30天
const endDate = this.formatDate(new Date())
const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000))
this.setData({
startDate,
endDate,
})
},
// 格式化日期
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}`
},
// 获取用户信息
getUserInfo() {
wx.ajax({
method: 'GET',
url: '/app/promoter/promoter/info',
}).then((res: any) => {
this.setData({
promoterName: res.name,
promoterAvatar: res.avatar,
})
})
},
// 获取统计数据看板
getStatistics() {
wx.ajax({
method: 'GET',
url: '/app/promoter/promoter/statistics',
}).then((res: any) => {
this.setData({
invitePharmacyCount: res.invitePharmacyCount,
invitePharmacistCount: res.invitePharmacistCount,
invitePatientCount: res.invitePatientCount,
jumpPatientCount: res.jumpPatientCount,
enrollPatientCount: res.enrollPatientCount,
indicationStats: res.indicationStats || [],
})
})
},
// 获取邀约患者统计图表
getPatientChart() {
wx.ajax({
method: 'GET',
url: '/app/promoter/promoter/patient-chart',
data: {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
},
}).then((res: any) => {
this.setData({
chartData: res.list || [],
})
this.initChartBar(res.list || [])
})
},
// 获取邀约药师统计图表
getPharmacistChart() {
wx.ajax({
method: 'GET',
url: '/app/promoter/promoter/pharmacist-chart',
data: {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
},
}).then((res: any) => {
this.initChartLine(res.list || [], '#chart2_1', 'ecDataTrendComponent2_1')
})
},
// 获取邀约药店统计图表
getPharmacyChart() {
wx.ajax({
method: 'GET',
url: '/app/promoter/promoter/pharmacy-chart',
data: {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
},
}).then((res: any) => {
this.initChartLine(res.list || [], '#chart3_1', 'ecDataTrendComponent3_1')
})
},
// 切换统计类型
switchStatType(e: WechatMiniprogram.CustomEvent) {
const type = e.currentTarget.dataset.type
this.setData({
statType: type,
})
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
},
// 日期选择变化
onDateChange(e: WechatMiniprogram.CustomEvent) {
const { field } = e.currentTarget.dataset
this.setData({
[field]: e.detail.value,
})
// 重新加载图表数据
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
},
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: string[] = []
list.forEach((item) => {
x.push(item.date || item.StatMonth)
y1.push(item.count || item.MonthInvitePCount)
})
const option = {
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: y1,
},
{
name: '入组患者数',
type: 'bar',
stack: 'a',
color: '#3ADDC8',
barWidth: 12,
data: y1,
},
],
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 = {
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() {
wx.navigateTo({
url: '/ground/pages/stat/index',
})
},
1 month ago
handleFold(e) {
const { key } = e.currentTarget.dataset
this.setData({
[key]: !this.data[key],
})
},
})