Browse Source

小程序接口联调

master
kola-web 1 week ago
parent
commit
ef94ce1fdc
  1. 19
      .trae/rules/project_rules.md
  2. 6
      src/api/request.ts
  3. 105
      src/app.ts
  4. 11
      src/doctor/pages/article/index.ts
  5. 35
      src/doctor/pages/articleList/index.ts
  6. 9
      src/doctor/pages/changeNickname/index.ts
  7. 84
      src/doctor/pages/changeTel/index.ts
  8. 151
      src/doctor/pages/home/index.ts
  9. 9
      src/doctor/pages/invite/index.ts
  10. 23
      src/doctor/pages/login/index.ts
  11. 39
      src/doctor/pages/loginForm/index.ts
  12. 9
      src/doctor/pages/my/index.ts
  13. 46
      src/doctor/pages/patientList/index.ts
  14. 9
      src/doctor/pages/stat/index.ts
  15. 9
      src/ground/pages/changeNickname/index.ts
  16. 84
      src/ground/pages/changeTel/index.ts
  17. 193
      src/ground/pages/home/index.ts
  18. 9
      src/ground/pages/invite/index.ts
  19. 24
      src/ground/pages/login/index.ts
  20. 9
      src/ground/pages/my/index.ts
  21. 9
      src/ground/pages/pharmacist/index.ts
  22. 9
      src/ground/pages/stat/index.ts
  23. 142
      src/pages/index/index.ts
  24. 4
      src/pages/index/index.wxml
  25. 9
      src/pages/work/index.ts
  26. 10
      typings/index.d.ts

19
.trae/rules/project_rules.md

@ -1,9 +1,10 @@
1. 本项目是一个基于微信小程序的药品查询应用 1. 接口文档在"C:\Users\kola\project\drugs\prompt\backend\portal_api.md"
2. 使用原生微信小程序+typescript+scss 2. 本项目是一个基于微信小程序的药品查询应用
3. figma设计稿的宽度是375px,1px=2rpx 3. 使用原生微信小程序+typescript+scss
4. 小程序的scss单位是rpx 4. figma设计稿的宽度是375px,1px=2rpx
5. 导航栏使用自定义导航栏,使用自定义组件 /components/navbar 5. 小程序的scss单位是rpx
6. 除了onLoad比寻存在外,其他生命周期函数,无须额外定义 6. 导航栏使用自定义导航栏,使用自定义组件 /components/navbar
7. onLoad函数中需要隐去getApp().waitLogin(),页面使用的接口需要在登录后调用 7. 除了onLoad比寻存在外,其他生命周期函数,无须额外定义
8. 生命周期函数和事件处理函数不应使用箭头函数 8. onLoad函数中需要隐去getApp().waitLogin(),页面使用的接口需要在登录后调用
9. getApp()应提取到全局变量中,避免重复调用 9. 生命周期函数和事件处理函数不应使用箭头函数
10. getApp()应提取到全局变量中,避免重复调用

6
src/api/request.ts

@ -1,10 +1,9 @@
interface IGlobalParams { interface IGlobalParams {
gUrl: string gUrl: string
version: string
} }
export const request = function ( export const request = function (
{ gUrl, version }: IGlobalParams, { gUrl }: IGlobalParams,
{ {
url, url,
method, method,
@ -27,6 +26,7 @@ export const request = function (
wx.request({ wx.request({
header: { header: {
loginState: getApp().globalData.loginState, loginState: getApp().globalData.loginState,
'content-type': isJSON ? 'application/json' : 'application/x-www-form-urlencoded',
...header, ...header,
}, },
url: gUrl + url, url: gUrl + url,
@ -39,7 +39,7 @@ export const request = function (
success(res: any) { success(res: any) {
const { code, data } = res.data const { code, data } = res.data
if (isJSON) { if (isJSON) {
resolve(res.data) resolve(data)
} else if (code === 0) { } else if (code === 0) {
resolve(data) resolve(data)
} else if (showMsg) { } else if (showMsg) {

105
src/app.ts

@ -15,10 +15,9 @@ plugin.use(todo).use(solarLunar).use(selectable).use(week)
const dayjs = require('dayjs') const dayjs = require('dayjs')
require('/utils/dayjs/day-zh-cn.js') require('/utils/dayjs/day-zh-cn.js')
const relativeTime = require('/utils/dayjs/relativeTime.js') const relativeTime = require('/utils/dayjs/relativeTime.js')
dayjs.locale('zh-cn') // 全局使用 dayjs.locale('zh-cn')
dayjs.extend(relativeTime) dayjs.extend(relativeTime)
// page
import page from '@/utils/page' import page from '@/utils/page'
App<IAppOption>({ App<IAppOption>({
@ -43,7 +42,6 @@ App<IAppOption>({
loginState: '', loginState: '',
initLoginInfo: {}, initLoginInfo: {},
// anyWhere: true,
anyWhere: false, anyWhere: false,
userInfo: {}, userInfo: {},
@ -64,19 +62,19 @@ App<IAppOption>({
if (options.query.scene) { if (options.query.scene) {
this.globalData.scene = parseScene(options.query.scene) as { workerId: string } this.globalData.scene = parseScene(options.query.scene) as { workerId: string }
} }
// this.startLogin() this.startLogin()
}, },
startLogin(callback?: () => void) { startLogin(callback?: () => void) {
wx.login({ wx.login({
success: (res) => { success: (res) => {
wx.ajax({ wx.ajax({
method: 'GET', method: 'POST',
url: '?r=wtx/user/init-login', url: '/app/common/common/wx-login',
data: { data: {
code: res.code, code: res.code,
}, },
}).then((res) => { }).then((res) => {
this.globalData.loginState = res.loginState this.globalData.loginState = res.token || res.sessionKey
this.globalData.initLoginInfo = res this.globalData.initLoginInfo = res
if (callback) { if (callback) {
callback() callback()
@ -88,7 +86,7 @@ App<IAppOption>({
updateLoginInfo(callback?: () => void) { updateLoginInfo(callback?: () => void) {
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '?r=wtx/user/init-info', url: '/app/common/common/user-info',
data: {}, data: {},
}).then((res) => { }).then((res) => {
this.globalData.initLoginInfo = res this.globalData.initLoginInfo = res
@ -97,11 +95,11 @@ App<IAppOption>({
} }
}) })
}, },
waitLogin({ type = 0 } = { type: 'any' }) { waitLogin({ types = [] as number[] } = {}) {
return new Promise((resolve) => { return new Promise((resolve) => {
const checkLogin = () => { const checkLogin = () => {
if (this.globalData.loginState) { if (this.globalData.loginState) {
if (this.checkLoginType(type)) { if (this.checkLoginTypes(types)) {
resolve() resolve()
} }
return return
@ -113,15 +111,15 @@ App<IAppOption>({
checkLogin() checkLogin()
}) })
}, },
checkLoginType(type: 0 | 1 | 2 | 'any') { checkLoginTypes(types: number[]) {
const { loginType, isLogin, isReg } = this.globalData.initLoginInfo const { loginIdentity, isRegistered } = this.globalData.initLoginInfo
if (type === 'any') { if (!types || types.length === 0) {
return true return true
} }
if (isLogin !== 1) { if (!isRegistered) {
if (type === 0) { if (types.includes(1)) {
return true return true
} }
wx.reLaunch({ wx.reLaunch({
@ -130,40 +128,32 @@ App<IAppOption>({
return false return false
} }
if (isReg !== 1) { if (loginIdentity && !types.includes(loginIdentity)) {
const typePageUrl = { const typePageUrl = {
1: '/patient/pages/entryInfo/index', 2: '/pages/index/index',
2: '/doctor/pages/login/index', 3: '/ground/pages/home/index',
}[loginType as 1 | 2] 4: '/doctor/pages/home/index',
wx.reLaunch({ }[loginIdentity as 2 | 3 | 4]
url: typePageUrl, if (typePageUrl) {
}) wx.reLaunch({
return false url: typePageUrl,
} })
return false
if (loginType !== type) { }
const typePageUrl = {
1: '/patient/pages/index/index',
2: '/doctor/pages/index/index',
}[loginType as 1 | 2]
wx.reLaunch({
url: typePageUrl,
})
return false
} }
return true return true
}, },
mpBehavior(data: { PageName: string }) { mpBehavior(data: { PageName: string }) {
const { loginType } = this.globalData.initLoginInfo
const url = {
1: '?r=wtx/mp-behavior/add',
2: '?r=wtx/doctor/mp-behavior/add',
}[loginType as 1 | 2]
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url, url: '/app/common/common/log',
data: data, data: {
eventType: 'page_view',
eventName: data.PageName,
pagePath: data.PageName,
params: {},
},
loading: false, loading: false,
showMsg: false, showMsg: false,
}).then((res) => { }).then((res) => {
@ -171,53 +161,32 @@ App<IAppOption>({
}) })
}, },
getUserInfo(type: 0 | 1 | 2 = 0) { getUserInfo() {
const url = {
0: '?r=wtx/user/userinfo',
1: '?r=wtx/account/info',
2: '?r=wtx/doctor/account/info',
}[type]
return wx.ajax({ return wx.ajax({
method: 'GET', method: 'GET',
url: url, url: '/app/common/common/user-info',
})
},
getDoctorInfo(doctorId: string) {
return wx.ajax({
method: 'GET',
url: '?r=wtx/doctor/get-info',
data: {
doctorId,
},
}) })
}, },
autoUpdate: function () { autoUpdate: function () {
var self = this var self = this
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) { if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager() const updateManager = wx.getUpdateManager()
//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function (res) { updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
if (res.hasUpdate) { if (res.hasUpdate) {
//检测到新版本,需要更新,给出提示
wx.showModal({ wx.showModal({
title: '更新提示', title: '更新提示',
content: '检测到新版本,是否下载新版本并重启小程序?', content: '检测到新版本,是否下载新版本并重启小程序?',
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) {
//2. 用户确定下载更新小程序,小程序下载及更新静默进行
self.downLoadAndUpdate(updateManager) self.downLoadAndUpdate(updateManager)
} else if (res.cancel) { } else if (res.cancel) {
//用户点击取消按钮的处理,如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({ wx.showModal({
title: '温馨提示~', title: '温馨提示~',
content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~', content: '本次版本更新涉及到新的功能添加,旧版本无法正常访问的哦~',
showCancel: false, //隐藏取消按钮 showCancel: false,
confirmText: '确定更新', //只保留确定更新按钮 confirmText: '确定更新',
success: function (res) { success: function (res) {
if (res.confirm) { if (res.confirm) {
//下载新版本,并重新应用
self.downLoadAndUpdate(updateManager) self.downLoadAndUpdate(updateManager)
} }
}, },
@ -228,7 +197,6 @@ App<IAppOption>({
} }
}) })
} else { } else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({ wx.showModal({
title: '提示', title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。', content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。',
@ -236,14 +204,11 @@ App<IAppOption>({
} }
}, },
downLoadAndUpdate: function (updateManager) { downLoadAndUpdate: function (updateManager) {
//静默下载更新小程序新版本
updateManager.onUpdateReady(function () { updateManager.onUpdateReady(function () {
wx.hideLoading() wx.hideLoading()
//新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate() updateManager.applyUpdate()
}) })
updateManager.onUpdateFailed(function () { updateManager.onUpdateFailed(function () {
// 新的版本下载失败
wx.showModal({ wx.showModal({
title: '新版本更新失败', title: '新版本更新失败',
content: '您可删除当前小程序,重新打开尝试', content: '您可删除当前小程序,重新打开尝试',

11
src/doctor/pages/article/index.ts

File diff suppressed because one or more lines are too long

35
src/doctor/pages/articleList/index.ts

@ -1,9 +1,36 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {
onLoad() {}, names: [
handleDetail() { '张吉惟',
'林国瑞',
'林玟书',
'林雅南',
'江奕云',
'刘柏宏',
'阮建安',
'林子帆',
'夏志豪',
'吉茹定',
'李中冰',
'黄文隆',
'谢彦文',
'傅智翔',
'洪振霞',
'刘姿婷',
'荣姿康',
'吕致盈',
'方一强',
],
},
onLoad() {
// 药店端文章列表页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
},
handleInfo() {
wx.navigateTo({ wx.navigateTo({
url: '/doctor/pages/article/index', url: '/doctor/pages/article/index',
}) })

9
src/doctor/pages/changeNickname/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 药店端修改昵称页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

84
src/doctor/pages/changeTel/index.ts

@ -1,78 +1,26 @@
const app = getApp<IAppOption>(); const app = getApp<IAppOption>()
let timer = null as null | number;
Page({ Page({
data: { data: {
mobile: "", mobile: '',
code: "", code: '',
codeText: '发送验证码',
codeText: "发送验证码", },
onLoad() {
// 药店端修改手机号页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
}, },
onLoad() {},
getCode() { getCode() {
if (timer) return; // TODO: 需要更新为新的接口
const mobile = this.data.mobile;
if (!mobile) {
wx.showToast({
title: "手机号不能为空",
icon: "none",
});
return;
}
// 验证手机号
if (!/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/.test(mobile)) {
wx.showToast({
title: "手机号格式不正确",
icon: "none",
});
return;
}
wx.ajax({
method: "POST",
url: "?r=zd/login/send-verify-code",
data: {
mobile,
},
}).then((res) => {
console.log(res);
wx.showToast({
icon: "none",
title: "验证码已发送~",
});
let time = 60;
timer = setInterval(() => {
time--;
this.setData({
codeText: time + "s后重新发送",
});
if (time <= 0) {
clearInterval(timer as number);
timer = null;
this.setData({
codeText: "发送验证码",
});
}
}, 1000);
});
}, },
handleSubmit() { handleSubmit() {
const { mobile, code } = this.data; // TODO: 需要更新为新的接口
const { registrationSource, registChannel, regBusinessId } = app.globalData;
wx.ajax({
method: "POST",
url: "?r=zd/account/update-telephone",
data: {
mobile,
code,
registrationSource,
registChannel,
regBusinessId,
},
}).then((_res) => {
wx.navigateBack();
});
}, },
handleBack() { handleBack() {
wx.navigateBack(); wx.navigateBack()
}, },
}); })
export {}

151
src/doctor/pages/home/index.ts

@ -4,25 +4,137 @@ Page({
data: { data: {
fold1: true, fold1: true,
fold2: true, fold2: true,
// 用户信息
pharmacistName: '',
pharmacistAvatar: '',
pharmacyName: '',
// 待处理患者数
pendingCount: 0,
// 统计数据
invitePatientCount: 0,
jumpPatientCount: 0,
enrollPatientCount: 0,
// 图表数据
chartData: [] as Array<{ date: string, count: number }>,
// 日期范围
startDate: '',
endDate: '',
// 统计类型: day-日统计, month-月统计
statType: 'day',
}, },
ecDataTrendComponent1_1: null as any, ecDataTrendComponent1_1: null as any,
async onLoad() { async onLoad() {
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
app.waitLogin().then(() => {}) // 药店端页面,仅允许药店人员(4)访问
const list = [ app.waitLogin({ types: [4] }).then(() => {
{ StatMonth: '2026-01', MonthInvitePCount: 1 }, this.getUserInfo()
{ StatMonth: '2026-02', MonthInvitePCount: 2 }, this.getPendingCount()
{ StatMonth: '2026-03', MonthInvitePCount: 3 }, this.getStatistics()
{ StatMonth: '2026-04', MonthInvitePCount: 2 }, this.getPatientChart()
{ StatMonth: '2026-05', MonthInvitePCount: 5 }, })
{ StatMonth: '2026-06', MonthInvitePCount: 7 },
{ StatMonth: '2026-07', MonthInvitePCount: 5 }, // 初始化日期范围为最近30天
{ StatMonth: '2026-08', MonthInvitePCount: 3 }, const endDate = this.formatDate(new Date())
{ StatMonth: '2026-09', MonthInvitePCount: 8 }, const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000))
{ StatMonth: '2026-10', MonthInvitePCount: 10 }, this.setData({
] startDate,
this.initChartBar(list) 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/pharmacist/pharmacist/info',
}).then((res: any) => {
this.setData({
pharmacistName: res.name,
pharmacistAvatar: res.avatar,
pharmacyName: res.pharmacyName,
})
})
},
// 获取待处理患者数
getPendingCount() {
wx.ajax({
method: 'GET',
url: '/app/pharmacist/pharmacist/pending-count',
}).then((res: any) => {
this.setData({
pendingCount: res.count || 0,
})
})
},
// 获取统计数据看板
getStatistics() {
wx.ajax({
method: 'GET',
url: '/app/pharmacist/pharmacist/statistics',
}).then((res: any) => {
this.setData({
invitePatientCount: res.invitePatientCount,
jumpPatientCount: res.jumpPatientCount,
enrollPatientCount: res.enrollPatientCount,
})
})
}, },
// 获取邀约患者统计图表
getPatientChart() {
wx.ajax({
method: 'GET',
url: '/app/pharmacist/pharmacist/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 || [])
})
},
// 切换统计类型
switchStatType(e: WechatMiniprogram.CustomEvent) {
const type = e.currentTarget.dataset.type
this.setData({
statType: type,
})
this.getPatientChart()
},
// 日期选择变化
onDateChange(e: WechatMiniprogram.CustomEvent) {
const { field } = e.currentTarget.dataset
this.setData({
[field]: e.detail.value,
})
// 重新加载图表数据
this.getPatientChart()
},
initChartBar(list: any[]) { initChartBar(list: any[]) {
return new Promise((reslove) => { return new Promise((reslove) => {
this.ecDataTrendComponent1_1 = this.selectComponent('#chart1_1') this.ecDataTrendComponent1_1 = this.selectComponent('#chart1_1')
@ -30,14 +142,14 @@ Page({
const chart = echarts.init(canvas, null, { const chart = echarts.init(canvas, null, {
width, width,
height, height,
devicePixelRatio: dpr, // new devicePixelRatio: dpr,
}) })
canvas.setChart(chart) canvas.setChart(chart)
const x: string[] = [] const x: string[] = []
const y1: string[] = [] const y1: string[] = []
list.forEach((item) => { list.forEach((item) => {
x.push(item.StatMonth) x.push(item.date || item.StatMonth)
y1.push(item.MonthInvitePCount) y1.push(item.count || item.MonthInvitePCount)
}) })
const option = { const option = {
@ -124,7 +236,7 @@ Page({
}, },
], ],
dataZoom: { dataZoom: {
type: 'inside', // 有type这个属性,滚动条在最下面,也可以不行,写y:36,这表示距离顶端36px,一般就是在图上面。 type: 'inside',
startValue: x.length - 6, startValue: x.length - 6,
endValue: x.length - 1, endValue: x.length - 1,
filterMode: 'none', filterMode: 'none',
@ -137,16 +249,19 @@ Page({
}) })
}) })
}, },
handleInvite() { handleInvite() {
wx.navigateTo({ wx.navigateTo({
url: '/doctor/pages/invite/index', url: '/doctor/pages/invite/index',
}) })
}, },
handleStat() { handleStat() {
wx.navigateTo({ wx.navigateTo({
url: '/doctor/pages/stat/index', url: '/doctor/pages/stat/index',
}) })
}, },
handleFold(e) { handleFold(e) {
const { key } = e.currentTarget.dataset const { key } = e.currentTarget.dataset
this.setData({ this.setData({

9
src/doctor/pages/invite/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 药店端邀约页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

23
src/doctor/pages/login/index.ts

@ -37,9 +37,10 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/login/send-verify-code', url: '/app/common/common/send-code',
data: { data: {
mobile, phone: mobile,
type: 1,
}, },
}).then((_res) => { }).then((_res) => {
wx.showToast({ wx.showToast({
@ -86,12 +87,20 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/doctor/login/reg-login', url: '/app/pharmacist/pharmacist/sms-login',
data: { data: {
mobile: this.data.mobile, phone: this.data.mobile,
code: this.data.code, code: this.data.code,
}, },
}).then((_res) => { }).then((res) => {
const app = getApp<IAppOption>()
app.globalData.loginState = res.token
app.globalData.initLoginInfo = {
loginType: 4,
isLogin: 1,
isReg: 1,
...res,
}
this.submitCallback() this.submitCallback()
}) })
}, },
@ -122,10 +131,8 @@ Page({
} }
}, },
submitCallback() { submitCallback() {
app.globalData.loginType = 2
app.globalData.isLogin = true
wx.reLaunch({ wx.reLaunch({
url: '/doctor/pages/d_home/index', url: '/doctor/pages/home/index',
}) })
}, },
handlePatient() { handlePatient() {

39
src/doctor/pages/loginForm/index.ts

@ -12,11 +12,14 @@ Page({
show: false, show: false,
}, },
onLoad(option) { onLoad(option) {
if (option.back) { // 登录表单页面,允许游客访问
this.setData({ app.waitLogin({ types: [1] }).then(() => {
back: true, if (option.back) {
}) this.setData({
} back: true,
})
}
})
}, },
getCode() { getCode() {
if (timer) return if (timer) return
@ -29,7 +32,7 @@ Page({
return return
} }
// 验证手机号 // 验证手机号
if (!/^1[3-9,]\d{9}$/.test(mobile)) { if (!/^1[3-9]\d{9}$/.test(mobile)) {
wx.showToast({ wx.showToast({
title: '手机号格式不正确', title: '手机号格式不正确',
icon: 'none', icon: 'none',
@ -38,9 +41,10 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/login/send-verify-code', url: '/app/common/common/send-code',
data: { data: {
mobile, phone: mobile,
type: 1,
}, },
}).then((_res) => { }).then((_res) => {
wx.showToast({ wx.showToast({
@ -87,12 +91,19 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/doctor/login/reg-login', url: '/app/pharmacist/pharmacist/sms-login',
data: { data: {
mobile: this.data.mobile, phone: this.data.mobile,
code: this.data.code, code: this.data.code,
}, },
}).then((_res) => { }).then((res: any) => {
app.globalData.loginState = res.token
app.globalData.initLoginInfo = {
loginType: 4,
isLogin: 1,
isReg: 1,
...res,
}
this.submitCallback() this.submitCallback()
}) })
}, },
@ -123,15 +134,13 @@ Page({
} }
}, },
submitCallback() { submitCallback() {
app.globalData.loginType = 2
app.globalData.isLogin = true
wx.reLaunch({ wx.reLaunch({
url: '/doctor/pages/d_home/index', url: '/doctor/pages/home/index',
}) })
}, },
handlePatient() { handlePatient() {
wx.redirectTo({ wx.redirectTo({
url: '/pages/login/index', url: '/pages/index/index',
}) })
}, },
handleTelCode() { handleTelCode() {

9
src/doctor/pages/my/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 药店端我的页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
},
handleNickname() { handleNickname() {
wx.navigateTo({ wx.navigateTo({
url: '/doctor/pages/changeNickname/index', url: '/doctor/pages/changeNickname/index',

46
src/doctor/pages/patientList/index.ts

@ -1,26 +1,38 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: { data: {
popupShow: false, names: [
popupType: 'popup1', '张吉惟',
popupParams: {}, '林国瑞',
'林玟书',
'林雅南',
'江奕云',
'刘柏宏',
'阮建安',
'林子帆',
'夏志豪',
'吉茹定',
'李中冰',
'黄文隆',
'谢彦文',
'傅智翔',
'洪振霞',
'刘姿婷',
'荣姿康',
'吕致盈',
'方一强',
],
}, },
onLoad() {}, onLoad() {
handleUpload() { // 药店端患者列表页面,仅允许药店人员访问
this.setData({ app.waitLogin({ types: [4] }).then(() => {
popupShow: true, // 页面加载完成
popupType: 'popup1',
}) })
}, },
handlePopupOk() { handleInfo() {
this.setData({ wx.navigateTo({
popupShow: false, url: '/doctor/pages/stat/index',
})
},
handlePopupCancel() {
this.setData({
popupShow: false,
}) })
}, },
}) })

9
src/doctor/pages/stat/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 药店端统计页面,仅允许药店人员访问
app.waitLogin({ types: [4] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

9
src/ground/pages/changeNickname/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 地推端修改昵称页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

84
src/ground/pages/changeTel/index.ts

@ -1,78 +1,26 @@
const app = getApp<IAppOption>(); const app = getApp<IAppOption>()
let timer = null as null | number;
Page({ Page({
data: { data: {
mobile: "", mobile: '',
code: "", code: '',
codeText: '发送验证码',
codeText: "发送验证码", },
onLoad() {
// 地推端修改手机号页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
}, },
onLoad() {},
getCode() { getCode() {
if (timer) return; // TODO: 需要更新为新的接口
const mobile = this.data.mobile;
if (!mobile) {
wx.showToast({
title: "手机号不能为空",
icon: "none",
});
return;
}
// 验证手机号
if (!/^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$/.test(mobile)) {
wx.showToast({
title: "手机号格式不正确",
icon: "none",
});
return;
}
wx.ajax({
method: "POST",
url: "?r=zd/login/send-verify-code",
data: {
mobile,
},
}).then((res) => {
console.log(res);
wx.showToast({
icon: "none",
title: "验证码已发送~",
});
let time = 60;
timer = setInterval(() => {
time--;
this.setData({
codeText: time + "s后重新发送",
});
if (time <= 0) {
clearInterval(timer as number);
timer = null;
this.setData({
codeText: "发送验证码",
});
}
}, 1000);
});
}, },
handleSubmit() { handleSubmit() {
const { mobile, code } = this.data; // TODO: 需要更新为新的接口
const { registrationSource, registChannel, regBusinessId } = app.globalData;
wx.ajax({
method: "POST",
url: "?r=zd/account/update-telephone",
data: {
mobile,
code,
registrationSource,
registChannel,
regBusinessId,
},
}).then((_res) => {
wx.navigateBack();
});
}, },
handleBack() { handleBack() {
wx.navigateBack(); wx.navigateBack()
}, },
}); })
export {}

193
src/ground/pages/home/index.ts

@ -4,29 +4,170 @@ Page({
data: { data: {
fold1: true, fold1: true,
fold2: 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, ecDataTrendComponent1_1: null as any,
ecDataTrendComponent2_1: null as any, ecDataTrendComponent2_1: null as any,
ecDataTrendComponent3_1: null as any, ecDataTrendComponent3_1: null as any,
async onLoad() { async onLoad() {
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
app.waitLogin().then(() => {}) // 地推端页面,仅允许地推人员(3)访问
const list = [ app.waitLogin({ types: [3] }).then(() => {
{ StatMonth: '2026-01', MonthInvitePCount: 1 }, this.getUserInfo()
{ StatMonth: '2026-02', MonthInvitePCount: 2 }, this.getStatistics()
{ StatMonth: '2026-03', MonthInvitePCount: 3 }, this.getPatientChart()
{ StatMonth: '2026-04', MonthInvitePCount: 2 }, this.getPharmacistChart()
{ StatMonth: '2026-05', MonthInvitePCount: 5 }, this.getPharmacyChart()
{ StatMonth: '2026-06', MonthInvitePCount: 7 }, })
{ StatMonth: '2026-07', MonthInvitePCount: 5 },
{ StatMonth: '2026-08', MonthInvitePCount: 3 }, // 初始化日期范围为最近30天
{ StatMonth: '2026-09', MonthInvitePCount: 8 }, const endDate = this.formatDate(new Date())
{ StatMonth: '2026-10', MonthInvitePCount: 10 }, const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000))
] this.setData({
this.initChartBar(list) startDate,
this.initChartLine(list, '#chart2_1', this.ecDataTrendComponent2_1) endDate,
this.initChartLine(list, '#chart3_1', this.ecDataTrendComponent3_1) })
},
// 格式化日期
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[]) { initChartBar(list: any[]) {
return new Promise((reslove) => { return new Promise((reslove) => {
this.ecDataTrendComponent1_1 = this.selectComponent('#chart1_1') this.ecDataTrendComponent1_1 = this.selectComponent('#chart1_1')
@ -34,14 +175,14 @@ Page({
const chart = echarts.init(canvas, null, { const chart = echarts.init(canvas, null, {
width, width,
height, height,
devicePixelRatio: dpr, // new devicePixelRatio: dpr,
}) })
canvas.setChart(chart) canvas.setChart(chart)
const x: string[] = [] const x: string[] = []
const y1: string[] = [] const y1: string[] = []
list.forEach((item) => { list.forEach((item) => {
x.push(item.StatMonth) x.push(item.date || item.StatMonth)
y1.push(item.MonthInvitePCount) y1.push(item.count || item.MonthInvitePCount)
}) })
const option = { const option = {
@ -128,7 +269,7 @@ Page({
}, },
], ],
dataZoom: { dataZoom: {
type: 'inside', // 有type这个属性,滚动条在最下面,也可以不行,写y:36,这表示距离顶端36px,一般就是在图上面。 type: 'inside',
startValue: x.length - 6, startValue: x.length - 6,
endValue: x.length - 1, endValue: x.length - 1,
filterMode: 'none', filterMode: 'none',
@ -141,6 +282,7 @@ Page({
}) })
}) })
}, },
initChartLine(list: any[], name: string, componentName: string) { initChartLine(list: any[], name: string, componentName: string) {
return new Promise((reslove) => { return new Promise((reslove) => {
this[componentName] = this.selectComponent(name) this[componentName] = this.selectComponent(name)
@ -148,14 +290,14 @@ Page({
const chart = echarts.init(canvas, null, { const chart = echarts.init(canvas, null, {
width, width,
height, height,
devicePixelRatio: dpr, // new devicePixelRatio: dpr,
}) })
canvas.setChart(chart) canvas.setChart(chart)
const x: string[] = [] const x: string[] = []
const y1: string[] = [] const y1: string[] = []
list.forEach((item) => { list.forEach((item) => {
x.push(item.StatMonth) x.push(item.date || item.StatMonth)
y1.push(item.MonthInvitePCount) y1.push(item.count || item.MonthInvitePCount)
}) })
const option = { const option = {
@ -234,7 +376,7 @@ Page({
}, },
], ],
dataZoom: { dataZoom: {
type: 'inside', // 有type这个属性,滚动条在最下面,也可以不行,写y:36,这表示距离顶端36px,一般就是在图上面。 type: 'inside',
startValue: x.length - 6, startValue: x.length - 6,
endValue: x.length - 1, endValue: x.length - 1,
filterMode: 'none', filterMode: 'none',
@ -247,16 +389,19 @@ Page({
}) })
}) })
}, },
handleInvite() { handleInvite() {
wx.navigateTo({ wx.navigateTo({
url: '/ground/pages/invite/index', url: '/ground/pages/invite/index',
}) })
}, },
handleInfo() { handleInfo() {
wx.navigateTo({ wx.navigateTo({
url: '/ground/pages/stat/index', url: '/ground/pages/stat/index',
}) })
}, },
handleFold(e) { handleFold(e) {
const { key } = e.currentTarget.dataset const { key } = e.currentTarget.dataset
this.setData({ this.setData({

9
src/ground/pages/invite/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 地推端邀约页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

24
src/ground/pages/login/index.ts

@ -1,4 +1,3 @@
const app = getApp<IAppOption>()
let timer = null as null | number let timer = null as null | number
Page({ Page({
@ -37,9 +36,10 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/login/send-verify-code', url: '/app/common/common/send-code',
data: { data: {
mobile, phone: mobile,
type: 1,
}, },
}).then((_res) => { }).then((_res) => {
wx.showToast({ wx.showToast({
@ -86,12 +86,20 @@ Page({
} }
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/doctor/login/reg-login', url: '/app/promoter/promoter/sms-login',
data: { data: {
mobile: this.data.mobile, phone: this.data.mobile,
code: this.data.code, code: this.data.code,
}, },
}).then((_res) => { }).then((res) => {
const app = getApp<IAppOption>()
app.globalData.loginState = res.token
app.globalData.initLoginInfo = {
loginType: 3,
isLogin: 1,
isReg: 1,
...res,
}
this.submitCallback() this.submitCallback()
}) })
}, },
@ -122,10 +130,8 @@ Page({
} }
}, },
submitCallback() { submitCallback() {
app.globalData.loginType = 2
app.globalData.isLogin = true
wx.reLaunch({ wx.reLaunch({
url: '/doctor/pages/d_home/index', url: '/ground/pages/home/index',
}) })
}, },
handlePatient() { handlePatient() {

9
src/ground/pages/my/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 地推端我的页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
},
handleNickname() { handleNickname() {
wx.navigateTo({ wx.navigateTo({
url: '/ground/pages/changeNickname/index', url: '/ground/pages/changeNickname/index',

9
src/ground/pages/pharmacist/index.ts

@ -1,4 +1,4 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: { data: {
@ -24,7 +24,12 @@ Page({
'方一强', '方一强',
], ],
}, },
onLoad() {}, onLoad() {
// 地推端药师页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
},
handleInfo() { handleInfo() {
wx.navigateTo({ wx.navigateTo({
url: '/ground/pages/stat/index', url: '/ground/pages/stat/index',

9
src/ground/pages/stat/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 地推端统计页面,仅允许地推人员访问
app.waitLogin({ types: [3] }).then(() => {
// 页面加载完成
})
},
handleBack() { handleBack() {
wx.navigateBack() wx.navigateBack()
}, },

142
src/pages/index/index.ts

@ -1,67 +1,160 @@
Page({ Page({
data: { data: {
// 导航栏背景
background: 'transparent', background: 'transparent',
// 图片URL
imageUrl: '', imageUrl: '',
// 时间戳,用于图片缓存
Timestamp: Date.now(), Timestamp: Date.now(),
// 弹窗控制
popupShow: false, popupShow: false,
popupType: '', popupType: '',
popupParams: {}, popupParams: {},
// 适应症选项 options: [] as Array<{ indicationId: number; indicationName: string; active: boolean }>,
options: [
{ id: 1, name: '斑块状银屑病', active: false },
{ id: 2, name: '克罗恩病', active: false },
{ id: 3, name: '溃疡性结肠炎', active: false },
],
// 协议勾选状态
agreementChecked: true, agreementChecked: true,
projectId: 0,
projectName: '',
isLogin: 0,
isPatient: 0,
bannerList: [] as any[],
}, },
// 生命周期函数:页面加载
onLoad() { onLoad() {
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
app.waitLogin().then(() => { app.waitLogin({ types: [1, 2] }).then(() => {
// 登录后调用页面所需的接口 this.getBanner()
this.checkStatus()
})
},
getBanner() {
wx.ajax({
method: 'GET',
url: '/app/patient/patient/banner-list',
data: {
projectId: this.data.projectId,
},
}).then((res: any) => {
this.setData({
bannerList: res,
})
})
},
checkStatus() {
wx.ajax({
method: 'GET',
url: '/app/patient/patient/check-status',
}).then((res: any) => {
this.setData({
isLogin: res.isLogin,
isPatient: res.isPatient,
projectId: res.projectId,
projectName: res.projectName,
})
if (res.isLogin === 1 && res.isPatient === 1 && res.projectId) {
this.setData({
options: [
{
indicationId: res.indicationId,
indicationName: res.indicationName,
active: true,
},
],
})
} else {
this.getProjectInfo()
}
})
},
getProjectInfo() {
wx.ajax({
method: 'GET',
url: '/app/patient/patient/project-info',
}).then((res: any) => {
this.setData({
projectId: res.projectId,
projectName: res.projectName,
options: res.indications.map((item: any) => ({
indicationId: item.indicationId,
indicationName: item.indicationName,
active: false,
})),
})
}) })
}, },
// 弹窗确认操作
handlePopupOk() { handlePopupOk() {
this.setData({ this.setData({
popupShow: false, popupShow: false,
}) })
}, },
// 弹窗取消操作
handlePopupCancel() { handlePopupCancel() {
this.setData({ this.setData({
popupShow: false, popupShow: false,
}) })
}, },
// 选择适应症
selectOption(e) { selectOption(e) {
const id = e.currentTarget.dataset.id as number const indicationId = e.currentTarget.dataset.id as number
const newOptions = this.data.options.map((option) => ({ const newOptions = this.data.options.map((option) => ({
...option, ...option,
active: option.id === id, active: option.indicationId === indicationId,
})) }))
this.setData({ this.setData({
options: newOptions, options: newOptions,
}) })
}, },
handleWxSubmit() {
wx.navigateToMiniProgram({ handleWxSubmit(e: WechatMiniprogram.CustomEvent) {
appId: 'wx05551c5ee1fd1c12', if (!this.data.agreementChecked) {
}) wx.showToast({
icon: 'none',
title: '请同意用户协议',
})
return
}
const selectedOption = this.data.options.find((item) => item.active)
if (!selectedOption) {
wx.showToast({
icon: 'none',
title: '请选择适应症',
})
return
}
const { iv, encryptedData } = e.detail
if (iv && encryptedData) {
wx.login({
success: (loginRes) => {
wx.ajax({
method: 'POST',
url: '/app/common/common/wx-login',
data: {
code: loginRes.code,
},
}).then(() => {
wx.ajax({
method: 'POST',
url: '/app/patient/patient/select-indication',
data: {
projectId: this.data.projectId,
indicationId: selectedOption.indicationId,
},
}).then((res: any) => {
wx.navigateToMiniProgram({
appId: 'wx05551c5ee1fd1c12',
path: res.jumpUrl,
})
})
})
},
})
}
}, },
// 切换协议勾选状态
toggleAgreement() { toggleAgreement() {
this.setData({ this.setData({
agreementChecked: !this.data.agreementChecked, agreementChecked: !this.data.agreementChecked,
@ -74,7 +167,6 @@ Page({
}) })
}, },
// 用户点击右上角分享
onShareAppMessage() { onShareAppMessage() {
return { return {
title: '华观健康', title: '华观健康',

4
src/pages/index/index.wxml

@ -6,9 +6,9 @@
class="page" class="page"
style="background: url('{{imageUrl}}bg2.png?t={{Timestamp}}') no-repeat top center/100% 558rpx;padding-top: {{pageTop+24}}px;" style="background: url('{{imageUrl}}bg2.png?t={{Timestamp}}') no-repeat top center/100% 558rpx;padding-top: {{pageTop+24}}px;"
> >
<swiper class="banner"> <swiper class="banner" wx:if="{{bannerList.length > 0}}">
<swiper-item class="b-item"> <swiper-item class="b-item">
<image class="b-img" src="{{imageUrl}}cache/bg1.png?t={{Timestamp}}"></image> <image class="b-img" wx:for="{{bannerList}}" wx:key="id" src="{{item.imageUrl}}"></image>
</swiper-item> </swiper-item>
</swiper> </swiper>
<view class="blur"></view> <view class="blur"></view>

9
src/pages/work/index.ts

@ -1,8 +1,13 @@
const _app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad() {}, onLoad() {
// 工作入口页面,允许所有身份访问
app.waitLogin({ types: [] }).then(() => {
// 页面加载完成
})
},
handleGround() { handleGround() {
wx.navigateTo({ wx.navigateTo({
url: '/ground/pages/login/index', url: '/ground/pages/login/index',

10
typings/index.d.ts vendored

@ -38,16 +38,18 @@ interface IAppOption {
initLoginInfo: Partial<{ initLoginInfo: Partial<{
isLogin: 0 | 1 isLogin: 0 | 1
isReg: 0 | 1 isReg: 0 | 1
loginType: 1 | 2 // 1-游客,2-患者端,3-地推人员端,4-药店人员端
loginType: 1 | 2 | 3 | 4
guestPrivacyAgree: boolean guestPrivacyAgree: boolean
}> }>
[propName: string]: any [propName: string]: any
} }
getUserInfo: (type?: 0 | 1 | 2) => Promise<any> getUserInfo: () => Promise<any>
startLogin: (callback?: () => void) => void startLogin: (callback?: () => void) => void
waitLogin: (params?: { type?: 0 | 1 | 2 | 'any' }) => Promise<void> // types: 身份类型数组,如 [2, 3] 表示患者端和地推人员端都可以访问
checkLoginType: (type: 0 | 1 | 2 | 'any') => boolean waitLogin: (params?: { types?: number[] }) => Promise<void>
checkLoginTypes: (types: number[]) => boolean
mpBehavior: (data: { PageName: string; type?: 0 | 1 | 2 | 3 }) => void mpBehavior: (data: { PageName: string; type?: 0 | 1 | 2 | 3 }) => void
globalSystemInfo?: globalSystemInfo globalSystemInfo?: globalSystemInfo
[propName: string]: any [propName: string]: any

Loading…
Cancel
Save