Browse Source

feat(privacy): 添加个人信息及隐私保护政策页面

refactor(api): 更新用户信息接口路径从/common/common到各模块专用路径
style(home): 优化图表空数据状态显示
fix(logout): 完善退出登录逻辑,调用对应模块的logout接口
docs(login): 更新隐私政策链接指向新页面
chore: 移除无用代码和注释
master
kola-web 1 week ago
parent
commit
3e78310097
  1. 4
      src/app.json
  2. 21
      src/app.ts
  3. 6
      src/doc/pages/doc1/index.json
  4. 3
      src/doc/pages/doc1/index.scss
  5. 10
      src/doc/pages/doc1/index.ts
  6. 3
      src/doc/pages/doc1/index.wxml
  7. 4
      src/doctor/pages/changeTel/index.ts
  8. 16
      src/doctor/pages/invite/index.ts
  9. 33
      src/doctor/pages/login/index.ts
  10. 110
      src/doctor/pages/loginForm/index.ts
  11. 15
      src/doctor/pages/my/index.ts
  12. 2
      src/doctor/pages/my/index.wxml
  13. 5
      src/ground/pages/changeNickname/index.ts
  14. 4
      src/ground/pages/home/index.scss
  15. 221
      src/ground/pages/home/index.ts
  16. 21
      src/ground/pages/home/index.wxml
  17. 33
      src/ground/pages/invite/index.ts
  18. 34
      src/ground/pages/login/index.ts
  19. 23
      src/ground/pages/my/index.ts
  20. 1
      src/ground/pages/pharmacist/index.wxml
  21. 3
      src/ground/pages/stat/index.json
  22. 17
      src/ground/pages/stat/index.ts
  23. 21
      src/pages/index/index.ts
  24. 10
      src/pages/start/index.ts
  25. 32
      src/pages/tourists/index.ts
  26. 4
      src/pages/tourists/index.wxml
  27. 2
      src/pages/work/index.ts
  28. 7
      src/privacy/pages/policy/index.json
  29. 64
      src/privacy/pages/policy/index.scss
  30. 109
      src/privacy/pages/policy/index.ts
  31. 7
      src/privacy/pages/policy/index.wxml
  32. 1
      typings/index.d.ts

4
src/app.json

@ -32,8 +32,8 @@
] ]
}, },
{ {
"root": "doc", "root": "privacy",
"pages": ["pages/doc1/index"] "pages": ["pages/policy/index"]
} }
], ],
"window": { "window": {

21
src/app.ts

@ -82,18 +82,6 @@ App<IAppOption>({
}, },
}) })
}, },
updateLoginInfo(callback?: () => void) {
wx.ajax({
method: 'GET',
url: '/app/common/common/user-info',
data: {},
}).then((res) => {
this.globalData.initLoginInfo = res
if (callback) {
callback()
}
})
},
waitLogin({ types = [] as number[] } = {}) { waitLogin({ types = [] as number[] } = {}) {
return new Promise((resolve) => { return new Promise((resolve) => {
const checkLogin = () => { const checkLogin = () => {
@ -111,14 +99,13 @@ App<IAppOption>({
}) })
}, },
checkLoginTypes(types: number[]) { checkLoginTypes(types: number[]) {
console.log('types: ', types)
const { loginIdentity, isLogin } = this.globalData.initLoginInfo const { loginIdentity, isLogin } = this.globalData.initLoginInfo
if (!types || types.length === 0) { if (!types || types.length === 0) {
return true return true
} }
if (types.includes(loginIdentity) && loginIdentity === 1) { if (loginIdentity && types.includes(loginIdentity) && loginIdentity === 1) {
return true return true
} }
@ -167,12 +154,6 @@ App<IAppOption>({
}) })
}, },
getUserInfo() {
return wx.ajax({
method: 'GET',
url: '/app/common/common/user-info',
})
},
autoUpdate: function () { autoUpdate: function () {
var self = this var self = this
if (wx.canIUse('getUpdateManager')) { if (wx.canIUse('getUpdateManager')) {

6
src/doc/pages/doc1/index.json

@ -1,6 +0,0 @@
{
"navigationBarTitleText": "个人信息及隐私政策",
"usingComponents": {
"mp-html": "mp-html"
}
}

3
src/doc/pages/doc1/index.scss

@ -1,3 +0,0 @@
.page{
padding: 0 40rpx;
}

10
src/doc/pages/doc1/index.ts

@ -1,10 +0,0 @@
const _app = getApp<IAppOption>();
Page({
data: {
doc:`当前为体验版本`
},
onLoad() {},
});
export {}

3
src/doc/pages/doc1/index.wxml

@ -1,3 +0,0 @@
<view class="page">
<mp-html content="{{doc}}"></mp-html>
</view>

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

@ -43,10 +43,10 @@ Page({
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/common/common/send-sms', url: '/app/common/common/send-code',
data: { data: {
phone: mobile, phone: mobile,
type: 3, // 3-修改手机号 type: 2, // 2-绑定手机号
}, },
}).then(() => { }).then(() => {
wx.showToast({ wx.showToast({

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

@ -37,10 +37,10 @@ Page({
}, },
// 生成药店邀约小程序码 // 生成药店邀约小程序码
generateQrCode() { generateQrCode() {
const { pharmacistId } = this.data const { projectId } = this.data
if (!pharmacistId) { if (!projectId) {
wx.showToast({ wx.showToast({
title: '获取药店人员信息失败', title: '获取项目信息失败',
icon: 'none', icon: 'none',
}) })
return return
@ -48,16 +48,16 @@ Page({
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/common/common/wxacode', url: '/app/pharmacist/pharmacist/generate-code',
data: { data: {
scene: `pharmacistId=${pharmacistId}`, projectId: parseInt(projectId),
page: 'pages/invite/patient',
width: 430,
type: 2, // 2-药店人员邀约码
}, },
}).then((res: any) => { }).then((res: any) => {
this.setData({ this.setData({
qrCodeUrl: res.imageUrl || '', qrCodeUrl: res.imageUrl || '',
projectName: res.projectName || '',
pharmacistName: res.pharmacistName || '',
pharmacistAvatar: res.pharmacistAvatar || '',
}) })
}).catch(() => { }).catch(() => {
wx.showToast({ wx.showToast({

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

@ -92,13 +92,12 @@ Page({
phone: this.data.mobile, phone: this.data.mobile,
code: this.data.code, code: this.data.code,
}, },
}).then((res) => { }).then((res: any) => {
const app = getApp<IAppOption>()
app.globalData.initLoginInfo = { app.globalData.initLoginInfo = {
loginType: 4, ...app.globalData.initLoginInfo,
isLogin: 1, isLogin: 1,
isReg: 1, loginIdentity: 4,
...res, userId: res.userId,
} }
this.submitCallback() this.submitCallback()
}) })
@ -113,14 +112,24 @@ Page({
} }
const { iv, encryptedData } = e.detail const { iv, encryptedData } = e.detail
if (iv && encryptedData) { if (iv && encryptedData) {
const sessionKey = app.globalData.initLoginInfo?.sessionKey || ''
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/doctor/login/wx-reg-login', url: '/app/pharmacist/pharmacist/wx-login',
data: { data: {
iv: encodeURIComponent(iv), sessionKey,
encryptedData: encodeURIComponent(encryptedData), encryptedData,
iv,
}, },
}).then((_res) => { }).then((res: any) => {
// 更新登录信息
app.globalData.initLoginInfo = {
...app.globalData.initLoginInfo,
isLogin: 1,
loginIdentity: 4,
userId: res.userId,
}
this.submitCallback() this.submitCallback()
}) })
} }
@ -141,9 +150,9 @@ Page({
}) })
}, },
handleLink() { handleLink() {
// wx.navigateTo({ wx.navigateTo({
// url: '/doc/pages/doc1/index', url: '/privacy/pages/policy/index',
// }) })
}, },
handleCheck() { handleCheck() {
this.setData({ this.setData({

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

@ -39,26 +39,10 @@ Page({
pages: 0, pages: 0,
}, },
}, },
onLoad(option: { promoterId?: string; projectId?: string; scene?: string }) { onLoad(options) {
// 解析扫码参数 // 解析扫码参数
let promoterId = option.promoterId || '' const promoterId = app.globalData.promoterId || ''
let projectId = option.projectId || '' const projectId = app.globalData.projectId || ''
// 如果是扫码进入,解析 scene 参数
if (option.scene) {
const scene = decodeURIComponent(option.scene)
const params = this.parseScene(scene)
promoterId = params.promoterId || ''
projectId = params.projectId || ''
}
if (!promoterId || !projectId) {
wx.showToast({
title: '缺少必要参数',
icon: 'none',
})
return
}
this.setData({ this.setData({
promoterId, promoterId,
@ -123,26 +107,28 @@ Page({
page: this.data.page, page: this.data.page,
pageSize: this.data.pageSize, pageSize: this.data.pageSize,
}, },
}).then((res: any) => {
const list = res.list || []
const currentPage = this.data.page
const total = res.total || 0
const pages = Math.ceil(total / this.data.pageSize)
this.setData({
pharmacyList: [...this.data.pharmacyList, ...list],
total,
page: currentPage + 1,
hasMore: currentPage < pages,
loading: false,
pagination: {
count: total,
page: currentPage,
pages,
},
})
}).catch(() => {
this.setData({ loading: false })
}) })
.then((res: any) => {
const list = res.list || []
const currentPage = this.data.page
const total = res.total || 0
const pages = Math.ceil(total / this.data.pageSize)
this.setData({
pharmacyList: [...this.data.pharmacyList, ...list],
total,
page: currentPage + 1,
hasMore: currentPage < pages,
loading: false,
pagination: {
count: total,
page: currentPage,
pages,
},
})
})
.catch(() => {
this.setData({ loading: false })
})
}, },
// 省市区选择变化 // 省市区选择变化
handleChange(e: WechatMiniprogram.CustomEvent) { handleChange(e: WechatMiniprogram.CustomEvent) {
@ -224,32 +210,34 @@ Page({
name: name.trim(), name: name.trim(),
pharmacyId, pharmacyId,
}, },
}).then((res: any) => { })
wx.hideLoading() .then((res: any) => {
// 保存登录信息 wx.hideLoading()
app.globalData.initLoginInfo = { // 保存登录信息
loginType: 4, app.globalData.initLoginInfo = {
isLogin: 1, loginType: 4,
isReg: 1, isLogin: 1,
...res, isReg: 1,
} ...res,
wx.showToast({ }
title: '绑定成功', wx.showToast({
icon: 'success', title: '绑定成功',
icon: 'success',
})
// 跳转到药店端首页
setTimeout(() => {
wx.reLaunch({
url: '/doctor/pages/home/index',
})
}, 1500)
}) })
// 跳转到药店端首页 .catch(() => {
setTimeout(() => { wx.hideLoading()
wx.reLaunch({ wx.showToast({
url: '/doctor/pages/home/index', title: '绑定失败',
icon: 'none',
}) })
}, 1500)
}).catch(() => {
wx.hideLoading()
wx.showToast({
title: '绑定失败',
icon: 'none',
}) })
})
}, },
}) })

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

@ -161,11 +161,16 @@ Page({
content: '确定要退出登录吗?', content: '确定要退出登录吗?',
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
// 清除登录信息 // 调用退出登录接口
app.globalData.initLoginInfo = null wx.ajax({
app.globalData.loginState = '' method: 'POST',
wx.redirectTo({ url: '/app/pharmacist/pharmacist/logout',
url: '/pages/work/index', }).finally(() => {
// 清除登录信息
app.globalData.initLoginInfo = {}
wx.reLaunch({
url: '/pages/work/index',
})
}) })
} }
}, },

2
src/doctor/pages/my/index.wxml

@ -38,4 +38,4 @@
<view class="exit" bind:tap="handleExit">退出登录</view> <view class="exit" bind:tap="handleExit">退出登录</view>
</view> </view>
<doctor-tab-bar active="{{ 2 }}"></doctor-tab-bar> <doctor-tab-bar active="{{ 3 }}"></doctor-tab-bar>

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

@ -16,11 +16,10 @@ Page({
getCurrentName() { getCurrentName() {
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/common/common/user-info', url: '/app/promoter/promoter/profile',
}).then((res: any) => { }).then((res: any) => {
const promoterInfo = res.promoterInfo || {}
this.setData({ this.setData({
name: promoterInfo.name || '', name: res.name || '',
}) })
}) })
}, },

4
src/ground/pages/home/index.scss

@ -367,6 +367,10 @@ page {
width: 100%; width: 100%;
height: 546rpx; height: 546rpx;
box-sizing: border-box; box-sizing: border-box;
position: relative;
.hide {
display: none;
}
} }
.more { .more {
padding: 20rpx 0 0; padding: 20rpx 0 0;

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

@ -26,13 +26,22 @@ Page({
// 图表数据 // 图表数据
chartData: [] as Array<{ date: string, count: number }>, chartData: [] as Array<{ date: string, count: number }>,
pharmacistChartData: [] as Array<{ date: string, count: number }>,
pharmacyChartData: [] as Array<{ date: string, count: number }>,
// 日期范围 // 日期范围
startDate: '', startDate: '',
endDate: '', endDate: '',
today: '',
// 统计类型: day-日统计, month-月统计 // 统计类型: day-日统计, month-月统计
statType: 'day', statType: 'day',
// 项目列表
projectList: [] as Array<{ projectId: number; projectName: string; projectDescription: string }>,
currentProjectId: 0,
currentProjectName: '特诺雅',
projectIndex: 0,
}, },
ecDataTrendComponent1_1: null as any, ecDataTrendComponent1_1: null as any,
@ -44,16 +53,15 @@ Page({
// 地推端页面,仅允许地推人员(3)访问 // 地推端页面,仅允许地推人员(3)访问
app.waitLogin({ types: [3] }).then(() => { app.waitLogin({ types: [3] }).then(() => {
this.getUserInfo() this.getUserInfo()
this.getStatistics() this.getProjectList()
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
}) })
// 初始化日期范围为最近30天 // 初始化日期范围为最近30天
const endDate = this.formatDate(new Date()) const today = this.formatDate(new Date())
const endDate = today
const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)) const startDate = this.formatDate(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000))
this.setData({ this.setData({
today,
startDate, startDate,
endDate, endDate,
}) })
@ -67,11 +75,11 @@ Page({
return `${year}-${month}-${day}` return `${year}-${month}-${day}`
}, },
// 获取用户信息 // 获取个人信息
getUserInfo() { getUserInfo() {
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/promoter/promoter/info', url: '/app/promoter/promoter/profile',
}).then((res: any) => { }).then((res: any) => {
this.setData({ this.setData({
promoterName: res.name, promoterName: res.name,
@ -80,11 +88,60 @@ Page({
}) })
}, },
// 获取项目列表
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.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) {
this.setData({
currentProjectId: project.projectId,
currentProjectName: project.projectName,
projectIndex: index,
})
// 重新加载数据
this.getStatistics()
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
}
},
// 获取统计数据看板 // 获取统计数据看板
getStatistics() { getStatistics() {
const data: any = {}
if (this.data.currentProjectId) {
data.projectId = this.data.currentProjectId
}
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/promoter/promoter/statistics', url: '/app/promoter/promoter/statistics',
data,
}).then((res: any) => { }).then((res: any) => {
this.setData({ this.setData({
invitePharmacyCount: res.invitePharmacyCount || 0, invitePharmacyCount: res.invitePharmacyCount || 0,
@ -94,108 +151,74 @@ Page({
enrollPatientCount: res.enrollPatientCount || 0, enrollPatientCount: res.enrollPatientCount || 0,
indicationStats: res.indicationStats || [], indicationStats: res.indicationStats || [],
}) })
}).catch(() => {
// 接口失败时使用模拟数据
this.setData({
invitePharmacyCount: 45,
invitePharmacistCount: 128,
invitePatientCount: 356,
jumpPatientCount: 289,
enrollPatientCount: 156,
indicationStats: [
{ indicationId: 1, indicationName: '斑块状银屑病', invitePatientCount: 150, jumpPatientCount: 120, enrollPatientCount: 65 },
{ indicationId: 2, indicationName: '溃疡性结肠炎', invitePatientCount: 120, jumpPatientCount: 98, enrollPatientCount: 52 },
{ indicationId: 3, indicationName: '克罗恩病', invitePatientCount: 86, jumpPatientCount: 71, enrollPatientCount: 39 },
],
})
}) })
}, },
// 获取邀约患者统计图表 // 获取邀约患者统计图表
getPatientChart() { getPatientChart() {
const data: any = {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
}
if (this.data.currentProjectId) {
data.projectId = this.data.currentProjectId
}
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/promoter/promoter/patient-chart', url: '/app/promoter/promoter/patient-chart',
data: { data,
type: this.data.statType, }).then((list: any) => {
startDate: this.data.startDate,
endDate: this.data.endDate,
},
}).then((res: any) => {
const list = res.list || []
this.setData({
chartData: list,
})
this.initChartBar(list)
}).catch(() => {
// 接口失败时使用模拟数据
const mockData = this.generateMockChartData()
this.setData({ this.setData({
chartData: mockData, chartData: list || [],
}) })
this.initChartBar(mockData) this.initChartBar(list || [])
}) })
}, },
// 获取邀约药师统计图表 // 获取邀约药师统计图表
getPharmacistChart() { getPharmacistChart() {
const data: any = {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
}
if (this.data.currentProjectId) {
data.projectId = this.data.currentProjectId
}
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/promoter/promoter/pharmacist-chart', url: '/app/promoter/promoter/pharmacist-chart',
data: { data,
type: this.data.statType, }).then((list: any) => {
startDate: this.data.startDate, this.setData({
endDate: this.data.endDate, pharmacistChartData: list || [],
}, })
}).then((res: any) => { this.initChartLine(list || [], '#chart2_1', 'ecDataTrendComponent2_1')
this.initChartLine(res.list || [], '#chart2_1', 'ecDataTrendComponent2_1')
}).catch(() => {
// 接口失败时使用模拟数据
const mockData = this.generateMockChartData()
this.initChartLine(mockData, '#chart2_1', 'ecDataTrendComponent2_1')
}) })
}, },
// 获取邀约药店统计图表 // 获取邀约药店统计图表
getPharmacyChart() { getPharmacyChart() {
const data: any = {
type: this.data.statType,
startDate: this.data.startDate,
endDate: this.data.endDate,
}
if (this.data.currentProjectId) {
data.projectId = this.data.currentProjectId
}
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/promoter/promoter/pharmacy-chart', url: '/app/promoter/promoter/pharmacy-chart',
data: { data,
type: this.data.statType, }).then((list: any) => {
startDate: this.data.startDate, this.setData({
endDate: this.data.endDate, pharmacyChartData: list || [],
}, })
}).then((res: any) => { this.initChartLine(list || [], '#chart3_1', 'ecDataTrendComponent3_1')
this.initChartLine(res.list || [], '#chart3_1', 'ecDataTrendComponent3_1')
}).catch(() => {
// 接口失败时使用模拟数据
const mockData = this.generateMockChartData()
this.initChartLine(mockData, '#chart3_1', 'ecDataTrendComponent3_1')
}) })
}, },
// 生成模拟图表数据
generateMockChartData() {
const list: any[] = []
const days = this.data.statType === 'day' ? 30 : 12
for (let i = 0; i < days; i++) {
const date = new Date()
if (this.data.statType === 'day') {
date.setDate(date.getDate() - (days - 1 - i))
list.push({
date: this.formatDate(date),
count: Math.floor(Math.random() * 50) + 10,
})
} else {
date.setMonth(date.getMonth() - (days - 1 - i))
list.push({
date: `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`,
count: Math.floor(Math.random() * 500) + 100,
})
}
}
return list
},
// 切换统计类型 // 切换统计类型
switchStatType(e: WechatMiniprogram.CustomEvent) { switchStatType(e: WechatMiniprogram.CustomEvent) {
@ -238,6 +261,42 @@ Page({
this.getPharmacyChart() 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)
this.setData({ startDate })
// 重新加载图表数据
this.getPatientChart()
this.getPharmacistChart()
this.getPharmacyChart()
},
// 切换到下一天
nextDate() {
const currentDate = new Date(this.data.startDate)
const newDate = new Date(currentDate.getTime() + 24 * 60 * 60 * 1000)
const today = new Date()
// 最大日期不能大于当前日期
if (newDate > today) {
wx.showToast({
title: '不能选择未来日期',
icon: 'none',
})
return
}
const startDate = this.formatDate(newDate)
this.setData({ startDate })
// 重新加载图表数据
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')

21
src/ground/pages/home/index.wxml

@ -1,9 +1,9 @@
<navbar fixed custom-style="background: {{background}};"> <navbar fixed custom-style="background: {{background}};">
<view class="page-switch" slot="left" style="color: {{background=='transparent'?'#fff':'#4A8DFF'}};"> <picker class="page-switch" slot="left" mode="selector" range="{{projectList}}" range-key="projectName" value="{{projectIndex}}" bindchange="onProjectChange" style="color: {{background=='transparent'?'#fff':'#4A8DFF'}};">
特诺雅 {{currentProjectName}}
<text style="font-size: 0.5em; vertical-align: super">®</text> <text style="font-size: 0.5em; vertical-align: super">®</text>
<van-icon class="arrow" name="arrow-down" /> <van-icon class="arrow" name="arrow-down" />
</view> </picker>
</navbar> </navbar>
<view <view
@ -95,11 +95,11 @@
<van-icon class="icon" name="arrow-down" /> <van-icon class="icon" name="arrow-down" />
</view> </view>
</view> </view>
<picker class="picker" mode="date" value="{{startDate}}" bindchange="onDateChange" data-field="startDate"> <picker class="picker" mode="date" value="{{startDate}}" end="{{today}}" bindchange="onDateChange" data-field="startDate">
<view class="p-content"> <view class="p-content">
<van-icon class="icon" name="arrow-left" /> <van-icon class="icon" name="arrow-left" catchtap="prevDate" />
<view class="content">{{startDate}}</view> <view class="content">{{startDate}}</view>
<van-icon class="icon" name="arrow" /> <van-icon class="icon" name="arrow" catchtap="nextDate" />
</view> </view>
</picker> </picker>
</view> </view>
@ -155,7 +155,8 @@
</picker> </picker>
</view> </view>
<view class="chart-container"> <view class="chart-container">
<ec-canvas id="chart1_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas> <ec-canvas class="{{chartData.length === 0 ? 'hide' : ''}}" id="chart1_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
<van-empty class="{{chartData.length > 0 ? 'hide' : ''}}" description="暂无数据" />
</view> </view>
<view class="more" bind:tap="handleInfo"> <view class="more" bind:tap="handleInfo">
查看明细 查看明细
@ -182,7 +183,8 @@
</picker> </picker>
</view> </view>
<view class="chart-container"> <view class="chart-container">
<ec-canvas id="chart2_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas> <ec-canvas class="{{pharmacistChartData.length === 0 ? 'hide' : ''}}" id="chart2_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
<van-empty class="{{pharmacistChartData.length > 0 ? 'hide' : ''}}" description="暂无数据" />
</view> </view>
</view> </view>
<view class="chat-data"> <view class="chat-data">
@ -205,7 +207,8 @@
</picker> </picker>
</view> </view>
<view class="chart-container"> <view class="chart-container">
<ec-canvas id="chart3_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas> <ec-canvas class="{{pharmacyChartData.length === 0 ? 'hide' : ''}}" id="chart3_1" canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>
<van-empty class="{{pharmacyChartData.length > 0 ? 'hide' : ''}}" description="暂无数据" />
</view> </view>
</view> </view>
</view> </view>

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

@ -24,13 +24,12 @@ Page({
getUserInfo() { getUserInfo() {
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/common/common/user-info', url: '/app/promoter/promoter/profile',
}).then((res: any) => { }).then((data: any) => {
const promoterInfo = res.promoterInfo || {}
this.setData({ this.setData({
promoterName: promoterInfo.name || '', promoterName: data.name || '',
promoterAvatar: promoterInfo.avatar || '', promoterAvatar: data.avatar || '',
promoterId: promoterInfo.id || '', promoterId: data.id || '',
}) })
// 获取小程序码 // 获取小程序码
this.generateQrCode() this.generateQrCode()
@ -38,27 +37,17 @@ Page({
}, },
// 生成地推邀约小程序码 // 生成地推邀约小程序码
generateQrCode() { generateQrCode() {
const { promoterId } = this.data
if (!promoterId) {
wx.showToast({
title: '获取地推人员信息失败',
icon: 'none',
})
return
}
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/common/common/wxacode', url: '/app/promoter/promoter/generate-code',
data: { data: {
scene: `promoterId=${promoterId}`,
page: 'pages/invite/pharmacist',
width: 430,
type: 1, // 1-地推邀约码
}, },
}).then((res: any) => { }).then((data: any) => {
this.setData({ this.setData({
qrCodeUrl: res.imageUrl || '', qrCodeUrl: data.imageUrl || '',
projectName: data.projectName || '',
promoterName: data.promoterName || '',
promoterAvatar: data.promoterAvatar || '',
}) })
}).catch(() => { }).catch(() => {
wx.showToast({ wx.showToast({

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

@ -90,15 +90,14 @@ Page({
data: { data: {
phone: this.data.mobile, phone: this.data.mobile,
code: this.data.code, code: this.data.code,
identity: 3,
}, },
}).then((res) => { }).then((res: any) => {
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
app.globalData.initLoginInfo = { app.globalData.initLoginInfo = {
loginType: 3, ...app.globalData.initLoginInfo,
isLogin: 1, isLogin: 1,
isReg: 1, loginIdentity: 3,
...res, userId: res.userId,
} }
this.submitCallback() this.submitCallback()
}) })
@ -113,14 +112,25 @@ Page({
} }
const { iv, encryptedData } = e.detail const { iv, encryptedData } = e.detail
if (iv && encryptedData) { if (iv && encryptedData) {
const app = getApp<IAppOption>()
const sessionKey = app.globalData.initLoginInfo?.sessionKey || ''
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '?r=zd/doctor/login/wx-reg-login', url: '/app/promoter/promoter/wx-login',
data: { data: {
iv: encodeURIComponent(iv), sessionKey,
encryptedData: encodeURIComponent(encryptedData), encryptedData,
iv,
}, },
}).then((_res) => { }).then((res: any) => {
// 更新登录信息
app.globalData.initLoginInfo = {
...app.globalData.initLoginInfo,
isLogin: 1,
loginIdentity: 3,
userId: res.userId,
}
this.submitCallback() this.submitCallback()
}) })
} }
@ -141,9 +151,9 @@ Page({
}) })
}, },
handleLink() { handleLink() {
// wx.navigateTo({ wx.navigateTo({
// url: '/doc/pages/doc1/index', url: '/privacy/pages/policy/index',
// }) })
}, },
handleCheck() { handleCheck() {
this.setData({ this.setData({

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

@ -17,17 +17,16 @@ Page({
// 页面显示时刷新用户信息 // 页面显示时刷新用户信息
this.getUserInfo() this.getUserInfo()
}, },
// 获取用户信息 // 获取个人信息
getUserInfo() { getUserInfo() {
wx.ajax({ wx.ajax({
method: 'GET', method: 'GET',
url: '/app/common/common/user-info', url: '/app/promoter/promoter/profile',
}).then((res: any) => { }).then((res: any) => {
const promoterInfo = res.promoterInfo || {}
this.setData({ this.setData({
promoterName: promoterInfo.name || '', promoterName: res.name || '',
promoterAvatar: promoterInfo.avatar || '', promoterAvatar: res.avatar || '',
promoterPhone: promoterInfo.phone || '', promoterPhone: res.phone || '',
}) })
}) })
}, },
@ -126,8 +125,16 @@ Page({
content: '确定要退出登录吗?', content: '确定要退出登录吗?',
success: (res) => { success: (res) => {
if (res.confirm) { if (res.confirm) {
wx.reLaunch({ // 调用退出登录接口
url: '/pages/work/index', wx.ajax({
method: 'POST',
url: '/app/promoter/promoter/logout',
}).finally(() => {
// 清除登录信息
app.globalData.initLoginInfo = {}
wx.reLaunch({
url: '/pages/work/index',
})
}) })
} }
}, },

1
src/ground/pages/pharmacist/index.wxml

@ -85,7 +85,6 @@
</view> </view>
</view> </view>
<pagination pagination="{{pagination}}" wx:if="{{pharmacistList.length > 0}}" /> <pagination pagination="{{pagination}}" wx:if="{{pharmacistList.length > 0}}" />
<view class="empty" wx:if="{{!loading && pharmacistList.length === 0}}">暂无数据</view>
</view> </view>
</view> </view>

3
src/ground/pages/stat/index.json

@ -2,6 +2,7 @@
"navigationStyle": "custom", "navigationStyle": "custom",
"usingComponents": { "usingComponents": {
"popup": "/components/popup/index", "popup": "/components/popup/index",
"navbar": "/components/navbar/index" "navbar": "/components/navbar/index",
"pagination": "/components/pagination/index"
} }
} }

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

@ -21,6 +21,13 @@ Page({
// 加载状态 // 加载状态
loading: false, loading: false,
// 分页信息
pagination: {
count: 0,
page: 1,
pages: 1,
},
}, },
onLoad(option: { id?: string }) { onLoad(option: { id?: string }) {
// 地推端统计页面,仅允许地推人员访问 // 地推端统计页面,仅允许地推人员访问
@ -97,10 +104,16 @@ Page({
endDate, endDate,
type, type,
}, },
}).then((res: any) => { }).then((data: any) => {
const chartList = data || []
this.setData({ this.setData({
chartList: res.list || res || [], chartList,
loading: false, loading: false,
pagination: {
count: chartList.length,
page: 1,
pages: 1,
},
}) })
}).catch(() => { }).catch(() => {
this.setData({ loading: false }) this.setData({ loading: false })

21
src/pages/index/index.ts

@ -161,15 +161,24 @@ Page({
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
const sessionKey = app.globalData.initLoginInfo?.sessionKey || '' const sessionKey = app.globalData.initLoginInfo?.sessionKey || ''
// 解密手机号 // 患者微信登录/注册
const params: any = {
sessionKey,
encryptedData,
iv,
}
// 如果有扫码参数,传入
if (this.data.pharmacistId) {
params.pharmacistId = Number.parseInt(this.data.pharmacistId)
}
if (this.data.projectId) {
params.projectId = this.data.projectId
}
wx.ajax({ wx.ajax({
method: 'POST', method: 'POST',
url: '/app/patient/patient/wx-login', url: '/app/patient/patient/wx-login',
data: { data: params,
sessionKey,
encryptedData,
iv,
},
}) })
.then(() => { .then(() => {
// 选择适应症 // 选择适应症

10
src/pages/start/index.ts

@ -10,7 +10,6 @@ Page({
if (options.scene) { if (options.scene) {
const sceneData = parseScene(options.scene) as { pharmacistId?: string; projectId?: string } const sceneData = parseScene(options.scene) as { pharmacistId?: string; projectId?: string }
console.log('sceneData: ', sceneData);
pharmacistId = sceneData.pharmacistId || '' pharmacistId = sceneData.pharmacistId || ''
projectId = sceneData.projectId || '' projectId = sceneData.projectId || ''
} }
@ -27,7 +26,7 @@ Page({
const { isLogin, loginIdentity } = app.globalData.initLoginInfo const { isLogin, loginIdentity } = app.globalData.initLoginInfo
// 游客(1)或患者端(2)且有扫码参数,进入患者首页 // 游客(1)或患者端(2)且有扫码参数,进入患者首页
if ((loginIdentity === 1 || loginIdentity === 2) && (pharmacistId && projectId)) { if ((loginIdentity === 1 || loginIdentity === 2) && pharmacistId && projectId) {
wx.reLaunch({ wx.reLaunch({
url: '/pages/index/index', url: '/pages/index/index',
}) })
@ -44,13 +43,8 @@ Page({
// 未注册,根据身份跳转到对应注册页面 // 未注册,根据身份跳转到对应注册页面
if (!isLogin) { if (!isLogin) {
const regPageUrl = {
2: '/pages/index/index',
3: '/ground/pages/login/index',
4: '/doctor/pages/login/index',
}[loginIdentity as 2 | 3 | 4]
wx.reLaunch({ wx.reLaunch({
url: regPageUrl || '/pages/index/index', url: '/pages/tourists/index',
}) })
return return
} }

32
src/pages/tourists/index.ts

@ -1,23 +1,23 @@
import { parseScene } from '@/utils/util'
const app = getApp<IAppOption>() const app = getApp<IAppOption>()
Page({ Page({
data: {}, data: {},
onLoad(options) { onLoad() {
if (options.scene) { app.waitLogin().then(() => {
const { doctorId } = parseScene(options.scene) as { doctorId: string } // 页面加载完成
app.globalData.waitBindDoctorId = doctorId })
} },
// 跳转到药店工作人员登录页
// app.waitLogin().then(() => { goToPharmacist() {
// const initLoginInfo = app.globalData.initLoginInfo || {} wx.navigateTo({
// wx.reLaunch({ url: '/doctor/pages/login/index',
// url: '/pages/index/index', })
// }) },
// }) // 跳转到地推人员登录页
// wx.reLaunch({ goToPromoter() {
// url: '/pages/index/index', wx.navigateTo({
// }) url: '/ground/pages/login/index',
})
}, },
}) })

4
src/pages/tourists/index.wxml

@ -5,7 +5,7 @@
<view class="page" style="background: url('/images/bg11.png') no-repeat top center/100% 1624rpx;padding-top: {{pageTop+24}}px;"> <view class="page" style="background: url('/images/bg11.png') no-repeat top center/100% 1624rpx;padding-top: {{pageTop+24}}px;">
<image class="page-banner" src="/images/start1.png"></image> <image class="page-banner" src="/images/start1.png"></image>
<view class="page-options"> <view class="page-options">
<view class="o-item">我是药店工作人员</view> <view class="o-item" bindtap="goToPharmacist">我是药店工作人员</view>
<view class="o-item">我是地推人员</view> <view class="o-item" bindtap="goToPromoter">我是地推人员</view>
</view> </view>
</view> </view>

2
src/pages/work/index.ts

@ -20,7 +20,7 @@ Page({
}, },
hadlePatient() { hadlePatient() {
wx.navigateTo({ wx.navigateTo({
url: '/pages/index/index', url: '/pages/start/index',
}) })
}, },
}) })

7
src/privacy/pages/policy/index.json

@ -0,0 +1,7 @@
{
"navigationBarTitleText": "个人信息及隐私保护政策",
"usingComponents": {
"navbar": "/components/navbar/index",
"mp-html": "mp-html"
}
}

64
src/privacy/pages/policy/index.scss

@ -0,0 +1,64 @@
.privacy-page {
min-height: 100vh;
background: #f8fafa;
padding: 32rpx;
box-sizing: border-box;
.content {
background: #fff;
border-radius: 16rpx;
padding: 40rpx 32rpx;
font-size: 28rpx;
line-height: 1.8;
color: #333;
rich-text {
display: block;
h2 {
font-size: 36rpx;
font-weight: 600;
color: #333;
margin: 48rpx 0 24rpx;
line-height: 1.4;
&:first-child {
margin-top: 0;
}
}
h3 {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin: 32rpx 0 16rpx;
line-height: 1.4;
}
p {
margin: 16rpx 0;
text-align: justify;
}
ul, ol {
margin: 16rpx 0;
padding-left: 40rpx;
}
li {
margin: 8rpx 0;
}
strong {
font-weight: 600;
color: #333;
}
hr {
border: none;
border-top: 1rpx solid #e5e5e5;
margin: 32rpx 0;
}
}
}
}

109
src/privacy/pages/policy/index.ts

@ -0,0 +1,109 @@
Page({
data: {
content: `
##
###
"本政策"使使
###
#### 2.1
- ****
- ****
- ****
- ****
- **使**使访
#### 2.2
-
- 使
-
### 使
使
-
-
-
-
-
###
-
-
-
-
###
- 使
- 访
-
-
###
- **访**
- ****
- ****
- ****
###
### Cookie和类似技术
使Cookie和类似技术来收集和存储信息使Cookie偏好
###
使
###
###
- 400-XXX-XXXX
- privacy@example.com
- XX省XX市XX区XX路XX号
###
---
**202633**
`,
},
onLoad() {
// 隐私协议页面不需要身份验证
},
// 返回上一页
goBack() {
wx.navigateBack()
},
})

7
src/privacy/pages/policy/index.wxml

@ -0,0 +1,7 @@
<navbar fixed title="个人信息及隐私保护政策" show-back bind:back="goBack" />
<view class="privacy-page" style="padding-top: {{pageTop}}px">
<view class="content">
<mp-html content="{{content}}" />
</view>
</view>

1
typings/index.d.ts vendored

@ -57,7 +57,6 @@ interface IAppOption {
[propName: string]: any [propName: string]: any
} }
getUserInfo: () => Promise<any>
startLogin: (callback?: () => void) => void startLogin: (callback?: () => void) => void
// types: 身份类型数组,如 [2, 3] 表示患者端和地推人员端都可以访问 // types: 身份类型数组,如 [2, 3] 表示患者端和地推人员端都可以访问
waitLogin: (params?: { types?: number[] }) => Promise<void> waitLogin: (params?: { types?: number[] }) => Promise<void>

Loading…
Cancel
Save