|
|
|
|
const echarts = require('../../../components/ec-canvas/echarts.js')
|
|
|
|
|
|
|
|
|
|
Page({
|
|
|
|
|
data: {
|
|
|
|
|
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',
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
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',
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
handleFold(e) {
|
|
|
|
|
const { key } = e.currentTarget.dataset
|
|
|
|
|
this.setData({
|
|
|
|
|
[key]: !this.data[key],
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
})
|