diff --git a/project.private.config.json b/project.private.config.json index f6fd786..9beba44 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -23,13 +23,20 @@ "miniprogram": { "list": [ { - "name": "修改手机号", - "pathName": "pages/changeTel/index", + "name": "随行包", + "pathName": "pages/bag/index", "query": "", "scene": null, "launchMode": "default" }, { + "name": "修改手机号", + "pathName": "pages/changeTel/index", + "query": "", + "launchMode": "default", + "scene": null + }, + { "name": "隐私协议", "pathName": "doc/pages/doc/index", "query": "", diff --git a/src/api/request.ts b/src/api/request.ts index 0eaa79a..92fce7c 100644 --- a/src/api/request.ts +++ b/src/api/request.ts @@ -78,5 +78,5 @@ function errPicker(err) { if (typeof err === 'string') { return err } - return err.data || err.msg || err.errMsg || (err.detail && err.detail.errMsg) || '未知错误' + return err.data || err.msg || err.message || err.errMsg || (err.detail && err.detail.errMsg) || '未知错误' } diff --git a/src/app.json b/src/app.json index 6e9c517..c402805 100644 --- a/src/app.json +++ b/src/app.json @@ -26,7 +26,9 @@ "pages/myComment/index", "pages/myCollection/index", "pages/userInfo/index", - "pages/changeTel/index" + "pages/changeTel/index", + "pages/bag/index", + "pages/chat/index" ], "subPackages": [ { diff --git a/src/app.ts b/src/app.ts index fed6f6e..903a3d8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -62,7 +62,6 @@ App({ }, onShow(options) { console.log('DEBUGPRINT[316]: app.ts:63: options=', JSON.stringify(options)) - // {"path":"pages/start/index","query":{"scene":"cid%3D3"},"scene":1047,"referrerInfo":{},"mode":"default","apiCategory":"default"} let sceneData: any = {} if (options.query.scene) { sceneData = parseScene(options.query.scene) || {} @@ -74,21 +73,7 @@ App({ } this.globalData.scene = sceneData - this.startLogin(() => { - // 已登录用户扫码,调用渠道码扫码记录接口 - if (channelId) { - const { isLogin, isReg } = this.globalData.initLoginInfo - if (isLogin && isReg) { - wx.ajax({ - method: 'POST', - url: '?r=psvt/channel/scan-channel', - data: { channelId: Number(channelId) }, - loading: false, - showMsg: false, - }) - } - } - }) + this.startLogin() }, startLogin(callback?: () => void) { wx.login({ @@ -115,9 +100,7 @@ App({ return new Promise((resolve) => { const checkLogin = () => { if (this.globalData.loginState) { - if (this.checkLoginType(type, false)) { - resolve() - } + resolve(this.checkLoginType(type, false)) return } setTimeout(() => { @@ -176,6 +159,7 @@ App({ wx.reLaunch({ url: path, }) + return }, mpBehavior(data: { PageName: string }) { const url = '?r=wtx/mp-behavior/add' diff --git a/src/components/pickerArea/index.ts b/src/components/pickerArea/index.ts index db3f450..7d49101 100644 --- a/src/components/pickerArea/index.ts +++ b/src/components/pickerArea/index.ts @@ -257,28 +257,31 @@ Component({ }) }, handleShare() { - const { ProvinceName, ProvinceId, CityName, CityId } = this.data + const { ProvinceName, ProvinceId, CityName, CityId, range } = this.data if (!ProvinceId) { wx.showToast({ title: '请选择省份', icon: 'none' }) return } - if (!CityId) { + if (range && range.length && !CityId) { wx.showToast({ title: '请选择城市', icon: 'none' }) return } this.setData({ show: false, }) - this.triggerEvent('change', [ + const result: any = [ { label: ProvinceName, value: ProvinceId, }, - { + ] + if (CityId) { + result.push({ label: CityName, value: CityId, - }, - ]) + }) + } + this.triggerEvent('change', result) }, handleSelect(e) { const { id } = e.currentTarget.dataset @@ -290,7 +293,12 @@ Component({ getRangeList() { const { area, ProvinceId } = this.data if (!ProvinceId) return - const range = area.filter((item: any) => item.value == ProvinceId)[0].children + const province = area.filter((item: any) => item.value == ProvinceId)[0] + const range = province?.children || [] + if (range.length === 0) { + this.setData({ range, active: 0 }) + return + } this.setData({ range, active: 1, diff --git a/src/components/popup/index.scss b/src/components/popup/index.scss index b71d6ef..2940fa7 100644 --- a/src/components/popup/index.scss +++ b/src/components/popup/index.scss @@ -117,6 +117,71 @@ } } +.popup4 { + .popup-container { + .badge { + position: relative; + z-index: 1; + display: block; + margin: 0 auto; + width: 647rpx; + height: 340rpx; + } + .container { + margin-top: -126rpx; + width: 690rpx; + height: 850rpx; + border-radius: 42rpx; + .title { + padding-top: 158rpx; + text-align: center; + font-size: 48rpx; + color: rgba(30, 41, 59, 1); + font-weight: bold; + line-height: 56rpx; + } + .content { + margin-top: 16rpx; + font-size: 32rpx; + color: rgba(71, 85, 105, 1); + line-height: 48rpx; + text-align: center; + } + .code { + margin: 52rpx auto 0; + display: block; + width: 348rpx; + height: 348rpx; + } + } + } +} + +.popup5 { + .popup-container { + .container { + padding-top: 572rpx; + width: 690rpx; + height: 720rpx; + border-radius: 42rpx; + box-sizing: border-box; + .btn { + display: block; + margin: 0 auto; + width: 626rpx; + height: 96rpx; + font-size: 40rpx; + color: rgba(255, 255, 255, 1); + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + border-radius: 24rpx 24rpx 24rpx 24rpx; + } + } + } +} + .close { margin: 32rpx auto 0; display: block; diff --git a/src/components/popup/index.wxml b/src/components/popup/index.wxml index cf6ac54..77cbcdb 100644 --- a/src/components/popup/index.wxml +++ b/src/components/popup/index.wxml @@ -11,7 +11,10 @@ > - + 关注“星动守护” 我们将在每周五下午7点提醒您记录 @@ -23,7 +26,10 @@ 保存复诊记录成功! - + @@ -40,7 +46,10 @@ 保存复诊记录成功! - + @@ -51,6 +60,30 @@ + + + + + + 安心随行大礼包申请成功! + 请您添加助手获得审批结果 + + + + + + + + + 免费领取> + + + - + diff --git a/src/custom-tab-bar/index.ts b/src/custom-tab-bar/index.ts index ff7e852..ff06450 100644 --- a/src/custom-tab-bar/index.ts +++ b/src/custom-tab-bar/index.ts @@ -23,7 +23,7 @@ Component({ iconActive: 'tabbar1-2-active', }, { - pagePath: '', + pagePath: '/pages/chat/index', custom: true, }, { @@ -45,21 +45,48 @@ Component({ ready() { const pagePath = getCurrentPageUrl() const active = this.data.list.findIndex((item) => item.pagePath === pagePath) - this.setData({ - active, - anyWhere: app.globalData.anyWhere, - }) + const wallConfig = app.globalData.wallConfig + if (wallConfig) { + const list: any[] = [...this.data.list] + const wallIndex = list.findIndex((item: any) => item.pagePath === '/pages/wall/index') + if (wallIndex > -1) { + list[wallIndex] = { ...list[wallIndex], text: wallConfig.navName || '交流墙' } + } + this.setData({ active, list, anyWhere: app.globalData.anyWhere }) + } else { + this.setData({ active, anyWhere: app.globalData.anyWhere }) + app.waitLogin?.({ type: 1 }).then(() => { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/get-config', + loading: false, + showMsg: false, + }).then((res: any) => { + const config = res || {} + app.globalData.wallConfig = config + this.updateWallName(config.navName || '交流墙') + }) + }) + } }, }, methods: { + updateWallName(name: string) { + const list: any[] = [...this.data.list] + const wallIndex = list.findIndex((item: any) => item.pagePath === '/pages/wall/index') + if (wallIndex > -1) { + list[wallIndex] = { ...list[wallIndex], text: name } + this.setData({ list }) + } + }, handleNav(e) { const { index } = e.currentTarget.dataset const { list } = this.data const pagePath = list[index].pagePath - if (!pagePath) { - wx.showToast({ - title: '功能开发中,敬请期待', - icon: 'none', + const custom = list[index].custom + if (custom) { + wx.navigateTo({ + url: '/pages/chat/index', }) } wx.switchTab({ diff --git a/src/images/badge3.png b/src/images/badge3.png new file mode 100644 index 0000000..989be2d Binary files /dev/null and b/src/images/badge3.png differ diff --git a/src/images/bag/bag-decor.png b/src/images/bag/bag-decor.png new file mode 100644 index 0000000..ff56af2 Binary files /dev/null and b/src/images/bag/bag-decor.png differ diff --git a/src/images/bg18.png b/src/images/bg18.png new file mode 100644 index 0000000..b2f867f Binary files /dev/null and b/src/images/bg18.png differ diff --git a/src/images/bg19.png b/src/images/bg19.png new file mode 100644 index 0000000..ff56af2 Binary files /dev/null and b/src/images/bg19.png differ diff --git a/src/images/bg20.png b/src/images/bg20.png new file mode 100644 index 0000000..86bfc4f Binary files /dev/null and b/src/images/bg20.png differ diff --git a/src/images/bg21.png b/src/images/bg21.png new file mode 100644 index 0000000..2694203 Binary files /dev/null and b/src/images/bg21.png differ diff --git a/src/images/bg7.png b/src/images/bg7.png index 588f949..9bc5ed3 100644 Binary files a/src/images/bg7.png and b/src/images/bg7.png differ diff --git a/src/images/chat/chat-bg.svg b/src/images/chat/chat-bg.svg new file mode 100644 index 0000000..0729eea --- /dev/null +++ b/src/images/chat/chat-bg.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/images/chat/chat-btn-bg.svg b/src/images/chat/chat-btn-bg.svg new file mode 100644 index 0000000..ab05a51 --- /dev/null +++ b/src/images/chat/chat-btn-bg.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/images/chat/chat-logo.svg b/src/images/chat/chat-logo.svg new file mode 100644 index 0000000..008d683 --- /dev/null +++ b/src/images/chat/chat-logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/images/chat/chat-mascot.png b/src/images/chat/chat-mascot.png new file mode 100644 index 0000000..88544e1 Binary files /dev/null and b/src/images/chat/chat-mascot.png differ diff --git a/src/images/chat/icon-what.svg b/src/images/chat/icon-what.svg new file mode 100644 index 0000000..a4c1d57 --- /dev/null +++ b/src/images/chat/icon-what.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/chat/icon-who.svg b/src/images/chat/icon-who.svg new file mode 100644 index 0000000..a4c1d57 --- /dev/null +++ b/src/images/chat/icon-who.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/images/icon21-active.png b/src/images/icon21-active.png new file mode 100644 index 0000000..6807388 Binary files /dev/null and b/src/images/icon21-active.png differ diff --git a/src/images/icon21.png b/src/images/icon21.png index 6807388..b9828c7 100644 Binary files a/src/images/icon21.png and b/src/images/icon21.png differ diff --git a/src/images/icon22-active.png b/src/images/icon22-active.png new file mode 100644 index 0000000..39f1641 Binary files /dev/null and b/src/images/icon22-active.png differ diff --git a/src/images/icon22.png b/src/images/icon22.png index 3c56708..3bd25c6 100644 Binary files a/src/images/icon22.png and b/src/images/icon22.png differ diff --git a/src/images/icon44.png b/src/images/icon44.png new file mode 100644 index 0000000..b9c119f Binary files /dev/null and b/src/images/icon44.png differ diff --git a/src/images/icon45.png b/src/images/icon45.png new file mode 100644 index 0000000..e700fb1 Binary files /dev/null and b/src/images/icon45.png differ diff --git a/src/images/icon46.png b/src/images/icon46.png new file mode 100644 index 0000000..d3c3ffe Binary files /dev/null and b/src/images/icon46.png differ diff --git a/src/images/share-img1.png b/src/images/share-img1.png new file mode 100644 index 0000000..789e0f9 Binary files /dev/null and b/src/images/share-img1.png differ diff --git a/src/images/title1.png b/src/images/title1.png new file mode 100644 index 0000000..981e79e Binary files /dev/null and b/src/images/title1.png differ diff --git a/src/images/title2.png b/src/images/title2.png new file mode 100644 index 0000000..4be90cb Binary files /dev/null and b/src/images/title2.png differ diff --git a/src/pages/articleDetail/index.wxml b/src/pages/articleDetail/index.wxml index 2659652..96427f4 100644 --- a/src/pages/articleDetail/index.wxml +++ b/src/pages/articleDetail/index.wxml @@ -19,7 +19,13 @@ 相关推荐 - + 图文 @@ -51,12 +57,18 @@ - + {{detail.ComplimentNum || 0}} - + {{detail.CollectionPeopleNum || 0}} @@ -69,6 +81,7 @@ 下一篇 + diff --git a/src/pages/bag/index.json b/src/pages/bag/index.json new file mode 100644 index 0000000..d9fc6a9 --- /dev/null +++ b/src/pages/bag/index.json @@ -0,0 +1,9 @@ +{ + "navigationStyle": "custom", + "usingComponents": { + "popup": "/components/popup/index", + "navbar": "/components/navbar/index", + "van-popup": "@vant/weapp/popup/index", + "van-icon": "@vant/weapp/icon/index" + } +} diff --git a/src/pages/bag/index.scss b/src/pages/bag/index.scss new file mode 100644 index 0000000..8f1e9ef --- /dev/null +++ b/src/pages/bag/index.scss @@ -0,0 +1,354 @@ +page { + background-color: #f7fafc; +} + +.page-title { + font-size: 36rpx; + color: rgba(51, 51, 51, 1); + padding-right: 100rpx; +} + +.page { + padding-bottom: 260rpx; + .hero { + padding: 0 40rpx; + display: flex; + align-items: flex-start; + justify-content: space-between; + + .hero-text { + padding-top: 78rpx; + .hero-title1 { + display: block; + width: 233rpx; + } + + .hero-title2 { + margin-top: 20rpx; + display: block; + width: 353rpx; + height: 56rpx; + } + + .hero-sub { + margin-top: 24rpx; + font-size: 28rpx; + font-weight: 400; + color: #64748b; + line-height: 40rpx; + } + } + + .hero-decor { + margin-top: 48rpx; + width: 356rpx; + height: 356rpx; + flex-shrink: 0; + } + } + + .card { + margin: 30rpx; + padding: 0; + border-radius: 32rpx; + border: 2rpx solid #fff; + background: rgba(255, 255, 255, 0.7); + box-shadow: 0 8rpx 64rpx 0 rgba(0, 99, 132, 0.08); + backdrop-filter: blur(10rpx); + overflow: hidden; + } + + .step { + display: flex; + align-items: center; + gap: 24rpx; + padding: 24rpx 32rpx; + background: rgba(47, 130, 169, 0.08); + border: 2rpx solid #fff; + border-radius: 24rpx; + margin: 32rpx 32rpx 0; + + .step-badge { + width: 64rpx; + height: 64rpx; + border-radius: 50%; + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + display: flex; + align-items: center; + justify-content: center; + color: #fff; + font-size: 29rpx; + font-weight: 700; + line-height: 44rpx; + flex-shrink: 0; + } + + .step-title { + font-size: 36rpx; + font-weight: 500; + color: #2f82a9; + line-height: 44rpx; + } + } + + .card-body { + padding: 48rpx 32rpx 54rpx; + + .card-desc { + padding-left: 12rpx; + width: 400rpx; + font-size: 28rpx; + color: #64748b; + line-height: 38rpx; + padding-right: 20rpx; + white-space: pre-line; + } + .upload-grid { + margin-top: 53rpx; + } + + .rejected { + margin-top: 24rpx; + padding: 16rpx 24rpx; + border-radius: 16rpx; + background: rgba(186, 26, 26, 0.08); + box-sizing: border-box; + font-size: 28rpx; + color: rgba(186, 26, 26, 1); + line-height: 40rpx; + display: flex; + .icon { + margin-top: 4rpx; + display: inline-block; + flex-shrink: 0; + margin-right: 16rpx; + width: 32rpx; + height: 32rpx; + vertical-align: -4rpx; + } + .blod { + display: inline-block; + font-weight: bold; + } + } + } + .upload-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24rpx; + .upload-item { + aspect-ratio: 1 / 1; + .upload-empty { + width: 100%; + height: 100%; + border-radius: 24rpx; + background: #f7fafc; + border: 2rpx dashed rgba(148, 163, 184, 0.26); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16rpx; + box-sizing: border-box; + + .upload-icon { + width: 56rpx; + height: 56rpx; + } + + .upload-placeholder { + font-size: 28rpx; + color: rgba(148, 163, 184, 0.51); + } + } + .upload { + position: relative; + width: 100%; + height: 100%; + border-radius: 24rpx; + overflow: hidden; + .u-img { + display: block; + width: 100%; + height: 100%; + } + .mask { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.29); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + .icon { + width: 44rpx; + height: 44rpx; + } + .status { + margin-top: 12rpx; + font-size: 28rpx; + color: rgba(255, 255, 255, 1); + } + } + .del { + position: absolute; + right: 0; + top: 0; + width: 40rpx; + height: 40rpx; + z-index: 9; + background-color: rgba(4, 4, 4, 0.31); + border-radius: 0 16rpx; + color: #fff; + font-size: 28rpx; + display: flex; + align-items: center; + justify-content: center; + } + } + } + } + + .card-body2 { + padding: 36rpx 32rpx 32rpx; + .c-item { + display: flex; + gap: 20rpx; + &.c-item2 { + margin-top: 50rpx; + } + .aside { + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: center; + gap: 16rpx; + padding-bottom: 23rpx; + .order { + width: 40rpx; + height: 40rpx; + border-radius: 50%; + font-size: 24rpx; + color: rgba(255, 255, 255, 1); + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + display: flex; + align-items: center; + justify-content: center; + } + .line { + flex: 1; + border-right: 1px dashed rgba(47, 130, 169, 0.38); + } + } + .container { + flex: 1; + .title { + font-size: 32rpx; + color: rgba(30, 41, 59, 1); + font-weight: bold; + } + .content { + width: 338rpx; + margin-top: 12rpx; + font-size: 28rpx; + line-height: 40rpx; + color: rgba(100, 116, 139, 1); + .high { + display: inline; + color: rgba(47, 130, 169, 1); + } + } + .share { + margin-top: 24rpx; + display: flex; + align-items: center; + gap: 34rpx; + .share-img { + width: 212rpx; + height: 318rpx; + border-radius: 32rpx; + } + .btn { + padding: 8rpx 16rpx; + font-size: 32rpx; + color: rgba(47, 130, 169, 1); + line-height: 48rpx; + border-radius: 12rpx; + border: 1px solid rgba(47, 130, 169, 0.16); + box-sizing: border-box; + } + } + .upload-grid { + margin-top: 24rpx; + gap: 22rpx; + } + } + } + } + + .consent { + margin: 32rpx 30rpx; + font-size: 26rpx; + color: rgba(148, 163, 184, 1); + line-height: 40rpx; + .check-content { + padding-top: 4rpx; + display: inline-block; + } + .wx-checkbox-input { + width: 32rpx; + height: 32rpx; + border-radius: 8rpx; + &.wx-checkbox-input-checked { + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + border-color: transparent; + &::before { + font-size: 28rpx; + color: #fff; + } + } + } + } + + .footer { + display: flex; + gap: 24rpx; + padding: 24rpx 30rpx calc(env(safe-area-inset-bottom) + 24rpx); + box-sizing: border-box; + + .btn { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 24rpx 0; + border-radius: 24rpx; + + .btn-title { + font-size: 32rpx; + font-weight: 700; + color: #fff; + line-height: 44rpx; + } + + .btn-sub { + font-size: 28rpx; + font-weight: 400; + color: #fff; + line-height: 40rpx; + } + } + + .btn-disabled { + background: rgba(148, 163, 184, 0.5); + } + + .btn-primary { + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + } + } +} diff --git a/src/pages/bag/index.ts b/src/pages/bag/index.ts new file mode 100644 index 0000000..bc426bd --- /dev/null +++ b/src/pages/bag/index.ts @@ -0,0 +1,139 @@ +type UploadStatus = 'reviewing' | 'approved' | 'rejected' + +interface UploadItem { + url: string + status: UploadStatus + rejectReason?: string +} + +const app = getApp() + +Page({ + data: { + popupShow: false, + popupType: 'popup4', + popupParams: { + position: 'center', + close: true, + } as any, + + id: '', + detail: {} as any, + + // 上传列表(已上传项),null 表示空位待上传 + step1Slots: [null, null, null] as (UploadItem | null)[], + step2Slots: [null, null, null] as (UploadItem | null)[], + agreed: false, + }, + onLoad() {}, + onShow() {}, + handleBack() { + wx.navigateBack() + }, + + // 选择并上传图片 + handleChooseMedia(e: any) { + const { step, index } = e.currentTarget.dataset + const key = step === 1 ? 'step1Slots' : 'step2Slots' + const slots = [...this.data[key]] + + wx.chooseMedia({ + count: 1, + mediaType: ['image'], + sourceType: ['album', 'camera'], + sizeType: ['original', 'compressed'], + success: (res) => { + const tempFile = res.tempFiles[0] + this.uploadImage(tempFile.tempFilePath, key, index, slots) + }, + }) + }, + + // 上传图片到服务器 + uploadImage(filePath: string, key: string, index: number, slots: (UploadItem | null)[]) { + wx.showLoading({ title: '正在上传' }) + const url = `${app.globalData.upFileUrl}?r=file-service/upload-img` + wx.uploadFile({ + filePath, + name: 'file', + url, + success: (res) => { + const data = JSON.parse(res.data) + const imgUrl = data.data.Url + // 新上传默认为审核中状态 + slots[index] = { url: imgUrl, status: 'reviewing' } + this.setData({ [key]: [...slots] }) + }, + fail: () => { + wx.showToast({ title: '上传失败', icon: 'error' }) + }, + complete: () => { + wx.hideLoading() + }, + }) + }, + + // 预览图片 + handlePreviewImage(e: any) { + const { step, index } = e.currentTarget.dataset + const key = step === 1 ? 'step1Slots' : 'step2Slots' + const slots = this.data[key] as (UploadItem | null)[] + const urls = slots.filter((item): item is UploadItem => !!item).map((item) => item.url) + wx.previewImage({ current: urls[index] || urls[0], urls }) + }, + + // 删除上传项(仅审核中、驳回可删) + handleDeleteUpload(e: any) { + const { step, index } = e.currentTarget.dataset + const key = step === 1 ? 'step1Slots' : 'step2Slots' + const slots = [...this.data[key]] + slots[index] = null + this.setData({ [key]: [...slots] }) + }, + + toggleAgree() { + this.setData({ agreed: !this.data.agreed }) + }, + + handleDownloadPoster() { + wx.showToast({ title: '海报下载开发中', icon: 'none' }) + }, + + // 获取已上传(非驳回)的图片 URL 列表 + getValidImages(slots: (UploadItem | null)[]): string[] { + return slots + .filter((item): item is UploadItem => !!item && item.status !== 'rejected') + .map((item) => item.url) + }, + + handleStep1Submit() { + const { step1Slots, agreed } = this.data + const validImages = this.getValidImages(step1Slots as (UploadItem | null)[]) + if (!validImages.length) { + wx.showToast({ title: '请先上传病例', icon: 'none' }) + return + } + if (!agreed) { + wx.showToast({ title: '请先勾选确认', icon: 'none' }) + return + } + wx.showToast({ title: '提交开发中', icon: 'none' }) + }, + + handleAllSubmit() { + const { step1Slots, step2Slots, agreed } = this.data + const valid1 = this.getValidImages(step1Slots as (UploadItem | null)[]) + const valid2 = this.getValidImages(step2Slots as (UploadItem | null)[]) + if (!valid1.length || !valid2.length) { + wx.showToast({ title: '请完成全部任务', icon: 'none' }) + return + } + if (!agreed) { + wx.showToast({ title: '请先勾选确认', icon: 'none' }) + return + } + wx.showToast({ title: '提交开发中', icon: 'none' }) + }, +}) + +export {} diff --git a/src/pages/bag/index.wxml b/src/pages/bag/index.wxml new file mode 100644 index 0000000..76b7139 --- /dev/null +++ b/src/pages/bag/index.wxml @@ -0,0 +1,144 @@ + + + + + + + + + + + + + 上传病例并完成任务,领取 + + 安心随行礼包 + + + + + + + + 1 + 上传病例,获得随行小礼 + + + 上传您的病例即可获得专属随行小礼哦~病历,诊断证明,心电图照片 任意一项 + + + + + 待上传 + + + + + + 审核中 + + + + + + + + + + + + + + + 驳回原因: + 驳回原因:清上传病例、诊断证明心点图照片确诊信息 + + + + + + + + 2 + 分享星动守护 解锁安心随行礼 + + + + + 1 + + + + 发布到小红书 + + 推荐星动守护平台分享到小红书,带上话题: + #星动守护PSVT小助手 + + + + + + + 2 + + + 上传发布截图 + 用于确认任务是否完成 + + + + + 待上传 + + + + + + + + + + + 我已确认上传内容真实有效,并同意用于活动资格审核。 + + + + + + + 完成第1步任务 + 领取随心小礼> + + + 完成全部任务 + 领取随行大礼包> + + + + 添加客服,获得审批结果> + + + 重新提交 + + + + + diff --git a/src/pages/chat/index.json b/src/pages/chat/index.json new file mode 100644 index 0000000..20331ca --- /dev/null +++ b/src/pages/chat/index.json @@ -0,0 +1,7 @@ +{ + "navigationStyle": "custom", + "usingComponents": { + "navbar": "/components/navbar/index", + "van-icon": "@vant/weapp/icon/index" + } +} diff --git a/src/pages/chat/index.scss b/src/pages/chat/index.scss new file mode 100644 index 0000000..6669a77 --- /dev/null +++ b/src/pages/chat/index.scss @@ -0,0 +1,154 @@ +page { + background-color: #f7fafc; +} + +.page-title { + font-size: 36rpx; + color: rgba(51, 51, 51, 1); + padding-right: 100rpx; +} + +.page { + position: relative; + min-height: 100vh; + padding-bottom: 60rpx; +} + +.bg-pattern { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 692rpx; + opacity: 0.68; + pointer-events: none; +} + +// 吉祥物区域 +.mascot-wrap { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 32rpx; + position: relative; +} + +.greeting-bubble { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 304rpx; + height: 98rpx; + + .greeting-bg { + position: absolute; + width: 100%; + height: 100%; + } + + .greeting-text { + position: relative; + z-index: 1; + font-size: 32rpx; + font-weight: 700; + color: #fff; + line-height: 48rpx; + } +} + +.mascot { + width: 302rpx; + height: 384rpx; + margin-top: 12rpx; +} + +// 信息卡片 +.info-card { + margin: 24rpx 30rpx 0; + padding: 32rpx; + background: #fff; + border-radius: 32rpx; +} + +.card-header { + display: flex; + align-items: center; + gap: 14rpx; + margin-bottom: 24rpx; + + .card-icon { + width: 40rpx; + height: 40rpx; + flex-shrink: 0; + } + + .card-title { + font-size: 32rpx; + font-weight: 700; + color: #2f82a9; + line-height: 48rpx; + } +} + +.card-desc { + font-size: 28rpx; + font-weight: 400; + color: #475569; + line-height: 48rpx; +} + +// 升级按钮 +.upgrade-btn { + margin: 48rpx auto 0; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 434rpx; + padding: 16rpx 0; + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + border-radius: 32rpx; + + .upgrade-line1 { + font-size: 28rpx; + font-weight: 700; + color: #fff; + line-height: 42rpx; + } + + .upgrade-line2 { + font-size: 28rpx; + font-weight: 400; + color: #fff; + line-height: 42rpx; + } +} + +// 通知勾选 +.notify { + margin: 32rpx 30rpx; + font-size: 26rpx; + color: rgba(148, 163, 184, 1); + line-height: 40rpx; + display: flex; + align-items: center; + justify-content: center; + .check-content { + padding-top: 4rpx; + display: inline-block; + } + .wx-checkbox-input { + width: 32rpx; + height: 32rpx; + border-radius: 8rpx; + &.wx-checkbox-input-checked { + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + border-color: transparent; + &::before { + font-size: 28rpx; + color: #fff; + } + } + } +} diff --git a/src/pages/chat/index.ts b/src/pages/chat/index.ts new file mode 100644 index 0000000..8319480 --- /dev/null +++ b/src/pages/chat/index.ts @@ -0,0 +1,25 @@ +Page({ + data: { + notifyChecked: false, + }, + onLoad() {}, + onShow() {}, + handleBack() { + wx.navigateBack() + }, + toggleNotify() { + const notifyChecked = !this.data.notifyChecked + this.setData({ notifyChecked }) + if (notifyChecked) { + wx.showToast({ title: '已开启上线通知', icon: 'none' }) + } + }, + handleNotify() { + if (!this.data.notifyChecked) { + this.setData({ notifyChecked: true }) + wx.showToast({ title: '已开启上线通知', icon: 'none' }) + } + }, +}) + +export {} diff --git a/src/pages/chat/index.wxml b/src/pages/chat/index.wxml new file mode 100644 index 0000000..d474a41 --- /dev/null +++ b/src/pages/chat/index.wxml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + Hello,我是小豚 + + + + + + + + + 我是谁 + + hello,我是你的智能助手小豚,为你提供阵发性 室上速健康科普与慢病管理服务。 + + + + + + + 我能干嘛 + + + 作为阵发性室上速(PSVT)智能助手,我将为你 提供解答疾病问题、指导急性发作处理、提醒定 + 期复诊等全周期健康管理服务,你有任何关于 PSVT的问题都可随时咨询我。往后日常生活里, + 我将长久相伴,全程守护你的健康。 + + + + + + 我在努力学习升级中, + 很快就和您见面啦! + + + + + 上线时通知我 + + diff --git a/src/pages/confirmInfo/index.ts b/src/pages/confirmInfo/index.ts index 8489296..58809e5 100644 --- a/src/pages/confirmInfo/index.ts +++ b/src/pages/confirmInfo/index.ts @@ -39,7 +39,9 @@ Page({ menuTop: menuRes.top, currentMonth, }) - this.getBaseData() + app.waitLogin({ type: 'any' }).then(() => { + this.getBaseData() + }) }, getBaseData() { wx.ajax({ @@ -77,12 +79,14 @@ Page({ }, handleAreaChange(e: any) { const [province, city] = e.detail + const cityId = city?.value || '' + const cityName = city?.label || '' this.setData({ provinceId: province.value, provinceName: province.label, - cityId: city.value, - cityName: city.label, - regionText: [province.label, city.label].filter(Boolean).join(' '), + cityId, + cityName, + regionText: [province.label, cityName].filter(Boolean).join(' '), }) }, handleDiagnosisTimeChange(e: WechatMiniprogram.PickerChange) { @@ -106,12 +110,16 @@ Page({ this.setData({ step: 1 }) }, handleSubmit() { - const { diagnosisStatus, surgeryStatus } = this.data + const { diagnosisStatus, diagnosisTime, surgeryStatus } = this.data if (!diagnosisStatus) { wx.showToast({ title: '请选择确诊状态', icon: 'none' }) return } - if (!surgeryStatus) { + if (diagnosisStatus === 2 && !diagnosisTime) { + wx.showToast({ title: '请选择确诊时间', icon: 'none' }) + return + } + if (diagnosisStatus === 2 && !surgeryStatus) { wx.showToast({ title: '请选择手术状态', icon: 'none' }) return } @@ -124,7 +132,6 @@ Page({ cityId, cityName, diagnosisStatus: ds, - diagnosisTime, surgeryStatus: ss, } = this.data const channelId = app.globalData.scene?.channelId || '' diff --git a/src/pages/confirmInfo/index.wxml b/src/pages/confirmInfo/index.wxml index b7ac778..79090a4 100644 --- a/src/pages/confirmInfo/index.wxml +++ b/src/pages/confirmInfo/index.wxml @@ -17,7 +17,7 @@ - 这些信息将用于优化内容推荐与服务提醒,不作为诊断或 治疗建议依据。 + 这些信息将用于优化内容推荐与服务提醒,不作为诊断或治疗建议依据。 @@ -99,7 +99,7 @@ - + 是否接受过相关手术治疗 - {{item.isUpdatePrescription ? '已更新处方' : '未更新处方'}};{{isUpdateSurgery ? '已更新手术诊断' : '未手术诊断'}} + {{item.isUpdatePrescription ? '已更新处方' : '未更新处方'}};{{isUpdateSurgery ? '已更新手术诊断' : '未手术诊断'}} {{item.remark}} diff --git a/src/pages/heartDetail/index.scss b/src/pages/heartDetail/index.scss index f9f7dd2..0fafdc0 100644 --- a/src/pages/heartDetail/index.scss +++ b/src/pages/heartDetail/index.scss @@ -119,6 +119,7 @@ page { background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); border-color: transparent; &::before { + font-size: 28rpx; color: #fff; } } diff --git a/src/pages/heartForm/index.scss b/src/pages/heartForm/index.scss index 2bd8d65..390214a 100644 --- a/src/pages/heartForm/index.scss +++ b/src/pages/heartForm/index.scss @@ -123,6 +123,7 @@ page { background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); border-color: transparent; &::before { + font-size: 28rpx; color: #fff; } } diff --git a/src/pages/hotTopic/index.json b/src/pages/hotTopic/index.json index e3ceeb9..5120472 100644 --- a/src/pages/hotTopic/index.json +++ b/src/pages/hotTopic/index.json @@ -2,6 +2,7 @@ "navigationStyle": "custom", "usingComponents": { "popup": "/components/popup/index", - "navbar": "/components/navbar/index" + "navbar": "/components/navbar/index", + "pagination": "/components/pagination/index" } } diff --git a/src/pages/hotTopic/index.scss b/src/pages/hotTopic/index.scss index 460bbc7..952fdd7 100644 --- a/src/pages/hotTopic/index.scss +++ b/src/pages/hotTopic/index.scss @@ -5,6 +5,7 @@ page { .page-title { font-size: 36rpx; color: #fff; + padding-right: 100rpx; } .page { diff --git a/src/pages/hotTopic/index.ts b/src/pages/hotTopic/index.ts index 951d35e..e12fdd7 100644 --- a/src/pages/hotTopic/index.ts +++ b/src/pages/hotTopic/index.ts @@ -7,10 +7,51 @@ Page({ popupParams: { position: 'bottom', } as any, + topicList: [] as Array, + topicPagination: { + page: 1, + pages: 1, + count: 0, + }, }, onLoad() { app.waitLogin({ type: 1 }).then(() => {}) }, + onShow() { + this.getTopicList() + }, + getTopicList(page = 1, append = false) { + wx.ajax({ + method: 'GET', + url: '?r=psvt/topic/list', + data: { + page, + count: 10, + }, + }).then((res: any) => { + const list = res.list || [] + this.setData({ + topicList: append ? this.data.topicList.concat(list) : list, + topicPagination: { + page: res.page || 1, + pages: res.pages || 1, + count: Number(res.count) || 0, + }, + }) + }) + }, + onReachBottom() { + const { topicPagination } = this.data + if (topicPagination.page < topicPagination.pages) { + this.getTopicList(topicPagination.page + 1, true) + } + }, + handleTopicTap(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/hotTopicDetail/index?id=${id}`, + }) + }, handlePopupOk() { const { popupType } = this.data if (popupType === 'argument') { @@ -74,6 +115,9 @@ Page({ url: '/pages/wechatWork/index', }) }, + handleBack() { + wx.navigateBack() + }, }) export {} diff --git a/src/pages/hotTopic/index.wxml b/src/pages/hotTopic/index.wxml index 82d25c0..647bea2 100644 --- a/src/pages/hotTopic/index.wxml +++ b/src/pages/hotTopic/index.wxml @@ -1,5 +1,5 @@ - + @@ -10,11 +10,12 @@ > - + {{index+1}} - # 我的心悸经历 - 230篇帖子 + # {{item.topicName}} + {{item.postCount}}篇帖子 + diff --git a/src/pages/hotTopicDetail/index.json b/src/pages/hotTopicDetail/index.json index e3ceeb9..5120472 100644 --- a/src/pages/hotTopicDetail/index.json +++ b/src/pages/hotTopicDetail/index.json @@ -2,6 +2,7 @@ "navigationStyle": "custom", "usingComponents": { "popup": "/components/popup/index", - "navbar": "/components/navbar/index" + "navbar": "/components/navbar/index", + "pagination": "/components/pagination/index" } } diff --git a/src/pages/hotTopicDetail/index.scss b/src/pages/hotTopicDetail/index.scss index c33ab5b..f44c06c 100644 --- a/src/pages/hotTopicDetail/index.scss +++ b/src/pages/hotTopicDetail/index.scss @@ -5,6 +5,7 @@ page { .page-title { font-size: 36rpx; color: #fff; + padding-right: 100rpx; } .page { @@ -143,6 +144,24 @@ page { height: 352rpx; border-radius: 24rpx; } + .video-cover { + position: relative; + overflow: hidden; + .p-img { + width: 100%; + height: 100%; + border-radius: 24rpx; + } + } + .play-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 80rpx; + height: 80rpx; + z-index: 1; + } .photo9 { margin-top: 24rpx; display: grid; @@ -151,11 +170,17 @@ page { .p-item { width: 100%; aspect-ratio: 1 / 1; + position: relative; + overflow: hidden; .p-img { width: 100%; height: 100%; border-radius: 24rpx; } + .play-icon { + width: 56rpx; + height: 56rpx; + } } } .comment { diff --git a/src/pages/hotTopicDetail/index.ts b/src/pages/hotTopicDetail/index.ts index 951d35e..a6776b4 100644 --- a/src/pages/hotTopicDetail/index.ts +++ b/src/pages/hotTopicDetail/index.ts @@ -7,9 +7,100 @@ Page({ popupParams: { position: 'bottom', } as any, + topicId: '', + topic: {} as any, + postList: [] as Array, + postPagination: { + page: 1, + pages: 1, + count: 0, + }, + sortOrder: 'latest', }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + onLoad(options: any) { + const topicId = options.id || '' + this.setData({ topicId }) + app.waitLogin({ type: 1 }).then(() => { + this.getTopicDetail() + this.getPostList() + }) + }, + getTopicDetail() { + const { topicId } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/topic/detail', + data: { topicId }, + }).then((res: any) => { + this.setData({ topic: res.topic || {} }) + }) + }, + getPostList(page = 1, append = false) { + const { topicId, sortOrder } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/post/list', + data: { + topicId, + page, + count: 10, + sortOrder, + }, + }).then((res: any) => { + const list = res?.list || [] + this.setData({ + postList: append ? this.data.postList.concat(list) : list, + postPagination: { + page: res?.page || 1, + pages: res?.pages || 1, + count: Number(res?.count) || 0, + }, + }) + }) + }, + onReachBottom() { + const { postPagination } = this.data + if (postPagination.page < postPagination.pages) { + this.getPostList(postPagination.page + 1, true) + } + }, + onChangeSort(e: any) { + const { sort } = e.currentTarget.dataset + if (sort === this.data.sortOrder) return + this.setData({ + sortOrder: sort, + postList: [], + postPagination: { + page: 1, + pages: 1, + count: 0, + }, + }) + this.getPostList() + }, + handleDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/wallDetail/index?id=${id}`, + }) + }, + handleAdd() { + wx.navigateTo({ + url: '/pages/wallForm/index', + }) + }, + handlePreviewMedia(e: any) { + const { index, attachments } = e.currentTarget.dataset + const sources = (attachments || []).map((att: any) => { + if (att.attachmentType == 2) { + return { url: att.attachmentUrl, type: 'video', poster: att.videoCoverUrl } + } + return { url: att.attachmentUrl, type: 'image' } + }) + wx.previewMedia({ + current: Number(index) || 0, + sources, + }) }, handlePopupOk() { const { popupType } = this.data @@ -74,6 +165,9 @@ Page({ url: '/pages/wechatWork/index', }) }, + handleBack() { + wx.navigateBack() + }, }) export {} diff --git a/src/pages/hotTopicDetail/index.wxml b/src/pages/hotTopicDetail/index.wxml index 09df5de..03a5080 100644 --- a/src/pages/hotTopicDetail/index.wxml +++ b/src/pages/hotTopicDetail/index.wxml @@ -1,5 +1,5 @@ - + @@ -11,64 +11,83 @@ - 我的心悸经历 + {{topic.topicName}} - 1200人浏览 | 300篇帖子 + {{topic.postCount}}篇帖子 - 最新 - 最热 + 最新 + 最热 - + - + - @林间心跳 - 2026年7月1日 13:09 + @{{item.nickName}} + {{item.publishTime}} - 热门推荐 + 热门推荐 - #我的心悸经历 - #PSVT急救常识 - 今天去复诊,把最近的发作记录都给医生看了,沟通效率高了很多,也更安心。原来平时记下时间和感受真的很有用。 + #{{topic.topicName}} + {{item.content}} - - 患者故事 + + {{cate.categoryName}} - - - - - - + + + + + - - 最新评论: - 我也是,复诊前先整理记录,医生会更容易判断~ + + + + + + - 126 + {{item.likeCount}} - 126 + {{item.viewCount}} - 126 + {{item.commentCount}} + - + diff --git a/src/pages/index/index.ts b/src/pages/index/index.ts index c3d0220..86aea8c 100644 --- a/src/pages/index/index.ts +++ b/src/pages/index/index.ts @@ -3,10 +3,12 @@ const app = getApp() Page({ data: { popupShow: false, - popupType: '', + popupType: 'popup5', popupParams: { - position: 'bottom', + position: 'center', + close: true, } as any, + userInfo: {} as any, days: 0, cateList: [] as Array<{ CateId: string; CateName: string }>, diff --git a/src/pages/index/index.wxml b/src/pages/index/index.wxml index c4167d3..5b3f440 100644 --- a/src/pages/index/index.wxml +++ b/src/pages/index/index.wxml @@ -175,3 +175,11 @@ 健康助理 + + diff --git a/src/pages/login/index.scss b/src/pages/login/index.scss index 10ba47f..488d45e 100644 --- a/src/pages/login/index.scss +++ b/src/pages/login/index.scss @@ -110,6 +110,7 @@ background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); border-color: transparent; &::before { + font-size: 28rpx; color: #fff; } } diff --git a/src/pages/my/index.wxml b/src/pages/my/index.wxml index c1c62ab..7ec1b83 100644 --- a/src/pages/my/index.wxml +++ b/src/pages/my/index.wxml @@ -18,7 +18,7 @@ - + 我的帖子 diff --git a/src/pages/myComment/index.json b/src/pages/myComment/index.json index d3c67a1..ef32765 100644 --- a/src/pages/myComment/index.json +++ b/src/pages/myComment/index.json @@ -4,7 +4,7 @@ "usingComponents": { "popup": "/components/popup/index", "navbar": "/components/navbar/index", - "uploadFile": "/components/uploadFile/index", + "pagination": "/components/pagination/index", "van-popup": "@vant/weapp/popup/index" } } diff --git a/src/pages/myComment/index.scss b/src/pages/myComment/index.scss index d9b3cb7..024b1f5 100644 --- a/src/pages/myComment/index.scss +++ b/src/pages/myComment/index.scss @@ -88,6 +88,7 @@ page { height: 96rpx; background: #e2e8f0; border-radius: 16rpx; + flex-shrink: 0; } .post-desc { diff --git a/src/pages/myComment/index.ts b/src/pages/myComment/index.ts index f70504d..c750ce8 100644 --- a/src/pages/myComment/index.ts +++ b/src/pages/myComment/index.ts @@ -1,5 +1,13 @@ const app = getApp() +const PAGE_SIZE = 10 + +const statusClassMap: Record = { + 1: 'status1', + 2: 'status2', + 3: 'status3', +} + Page({ data: { popupShow: false, @@ -8,13 +16,72 @@ Page({ position: 'bottom', } as any, - topicShow: false, - replayShow: true, - - fileList: [] as any[], + commentList: [] as any[], + commentPagination: { + page: 1, + pages: 1, + count: 0, + }, + }, + onShow() { + app.waitLogin({ type: 1 }).then(() => { + this.getMyCommentList() + }) + }, + getMyCommentList(page = 1, append = false) { + wx.ajax({ + method: 'GET', + url: '?r=psvt/my-comment/list', + data: { + page, + count: PAGE_SIZE, + }, + }).then((res: any) => { + const list = (res.list || []).map((item: any) => ({ + ...item, + statusClass: statusClassMap[item.commentStatus] || 'status1', + statusText: item.commentStatusDesc || '', + dateText: item.commentTime || item.submitTime || item.createTime || '', + })) + this.setData({ + commentList: append ? this.data.commentList.concat(list) : list, + commentPagination: { + page: res.page || 1, + pages: res.pages || 1, + count: Number(res.count) || 0, + }, + }) + }) + }, + onReachBottom() { + const { commentPagination } = this.data + if (commentPagination.page < commentPagination.pages) { + this.getMyCommentList(commentPagination.page + 1, true) + } + }, + handleDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/wallDetail/index?id=${id}`, + }) }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + handleDelete(e: any) { + const { id } = e.currentTarget.dataset + wx.showModal({ + title: '提示', + content: '确定删除该评论吗?', + success: (res) => { + if (!res.confirm) return + wx.ajax({ + method: 'POST', + url: '?r=psvt/my-comment/delete', + data: { commentId: Number(id) }, + }).then(() => { + wx.showToast({ title: '删除成功', icon: 'success' }) + this.getMyCommentList() + }) + }, + }) }, handlePopupOk() { const { popupType } = this.data @@ -74,29 +141,6 @@ Page({ }) } }, - handleWechatWork() { - wx.navigateTo({ - url: '/pages/wechatWork/index', - }) - }, - handleSetData(e) { - const { fileList } = this.data - this.setData({ - fileList: [...fileList, ...e.detail], - }) - }, - handleDeleteFile(e) { - const { index } = e.detail - const { fileList } = this.data - this.setData({ - fileList: fileList.filter((_, i) => i !== index), - }) - }, - topicClose() { - this.setData({ - topicShow: false, - }) - }, handleBack() { wx.navigateBack() }, diff --git a/src/pages/myComment/index.wxml b/src/pages/myComment/index.wxml index c311eaf..dc0d022 100644 --- a/src/pages/myComment/index.wxml +++ b/src/pages/myComment/index.wxml @@ -9,37 +9,33 @@ class="page" style="background: url('{{imageUrl}}bg6.png?t={{Timestamp}}') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" > - - + + - - 待审核 - 2026-01-01 13:00:09 + {{item.statusText}} + {{item.dateText}} - 记录发作时间真的很重要,尤其是频率和持续时长 - - - # 我的心悸经历 - # PSVT急救常识 - + {{item.content}} + - - 今天把近期的状态、复诊资料和生活节奏整理了一下,也想记录一下最 + + + {{item.postTitle}} - + 评论正在审核中,预计1-2个工作日内完成审核。 - + 驳回原因: - 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 - 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 + {{item.rejectReason}} - 删除 + 删除 + diff --git a/src/pages/myWall/index.json b/src/pages/myWall/index.json index 5c0f8d9..1e1a503 100644 --- a/src/pages/myWall/index.json +++ b/src/pages/myWall/index.json @@ -4,6 +4,7 @@ "popup": "/components/popup/index", "navbar": "/components/navbar/index", "uploadFile": "/components/uploadFile/index", - "van-popup": "@vant/weapp/popup/index" + "van-popup": "@vant/weapp/popup/index", + "pagination": "/components/pagination/index" } } diff --git a/src/pages/myWall/index.scss b/src/pages/myWall/index.scss index 8000f89..4b75836 100644 --- a/src/pages/myWall/index.scss +++ b/src/pages/myWall/index.scss @@ -5,10 +5,40 @@ page { .page-title { font-size: 36rpx; color: rgba(51, 51, 51, 1); + padding-right: 100rpx; } .page { padding-bottom: 260rpx; + .type-navbar { + position: sticky; + top: 0; + left: 0; + padding: 48rpx 0 24rpx 30rpx; + display: flex; + flex-wrap: nowrap; + gap: 12rpx; + overflow-x: auto; + overflow-y: hidden; + background-color: #f7fafc; + &::-webkit-scrollbar { + display: none; + } + .type { + flex-shrink: 0; + padding: 12rpx 32rpx; + font-size: 28rpx; + color: rgba(71, 85, 105, 1); + background-color: #fff; + border: 1px solid rgba(241, 245, 249, 1); + border-radius: 16rpx; + line-height: 40rpx; + &.active { + color: #fff; + background: linear-gradient(270deg, #439fc7 0%, #2f82a9 100%); + } + } + } .list { padding: 0 30rpx; .list-card { @@ -44,6 +74,13 @@ page { background-color: rgba(45, 190, 141, 0.08); } } + .c-title { + margin-top: 32rpx; + font-size: 32rpx; + font-weight: bold; + color: rgba(24, 28, 30, 1); + line-height: 52rpx; + } .content { margin-top: 32rpx; font-size: 32rpx; diff --git a/src/pages/myWall/index.ts b/src/pages/myWall/index.ts index 163a4fe..7363e61 100644 --- a/src/pages/myWall/index.ts +++ b/src/pages/myWall/index.ts @@ -1,5 +1,19 @@ const app = getApp() +const statusClassMap: Record = { + 0: 'status1', + 1: 'status2', + 2: 'status4', + 3: 'status3', +} + +const statusTextMap: Record = { + 0: '草稿', + 1: '待审核', + 2: '已通过', + 3: '已驳回', +} + Page({ data: { popupShow: false, @@ -12,9 +26,97 @@ Page({ replayShow: true, fileList: [] as any[], + + postList: [] as any[], + postPagination: { + page: 1, + pages: 1, + count: 0, + }, + filterStatus: '' as string | number, + filters: [ + { label: '全部', value: '' }, + { label: '草稿', value: 0 }, + { label: '待审核', value: 1 }, + { label: '已通过', value: 2 }, + { label: '已驳回', value: 3 }, + ], + }, + onShow() { + app.waitLogin({ type: 1 }).then(() => { + this.getMyPostList() + }) + }, + getMyPostList(page = 1, append = false) { + const { filterStatus } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/my-post/list', + data: { + page, + count: 10, + ...(filterStatus !== '' ? { postStatus: filterStatus } : {}), + }, + }).then((res: any) => { + const list = (res.list || []).map((item: any) => ({ + ...item, + statusClass: statusClassMap[item.postStatus] || 'status1', + statusText: item.postStatusDesc || statusTextMap[item.postStatus] || '', + dateText: item.publishTime || item.submitTime || item.createTime || '', + imageList: (item.attachments || []).filter((att: any) => att.attachmentType == 1), + })) + this.setData({ + postList: append ? this.data.postList.concat(list) : list, + postPagination: { + page: res.page || 1, + pages: res.pages || 1, + count: Number(res.count) || 0, + }, + }) + }) }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + onReachBottom() { + const { postPagination } = this.data + if (postPagination.page < postPagination.pages) { + this.getMyPostList(postPagination.page + 1, true) + } + }, + handleFilterTap(e: any) { + const { value } = e.currentTarget.dataset + this.setData({ filterStatus: value }, () => { + this.getMyPostList() + }) + }, + handleDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/wallDetail/index?id=${id}`, + }) + }, + handleDelete(e: any) { + const { id } = e.currentTarget.dataset + wx.showModal({ + title: '提示', + content: '确定删除该帖子吗?', + success: (res) => { + if (res.confirm) { + wx.ajax({ + method: 'POST', + url: '?r=psvt/my-post/delete', + data: { postId: Number(id) }, + }).then(() => { + wx.showToast({ title: '删除成功', icon: 'success' }) + this.getMyPostList() + }) + } + }, + }) + }, + handleEdit(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/wallForm/index?id=${id}`, + }) }, handlePopupOk() { const { popupType } = this.data @@ -97,6 +199,9 @@ Page({ topicShow: false, }) }, + handleBack() { + wx.navigateBack() + }, }) export {} diff --git a/src/pages/myWall/index.wxml b/src/pages/myWall/index.wxml index 13ad77b..f7cb6d7 100644 --- a/src/pages/myWall/index.wxml +++ b/src/pages/myWall/index.wxml @@ -1,5 +1,5 @@ - + 我的帖子 @@ -9,43 +9,58 @@ class="page" style="background: url('{{imageUrl}}bg6.png?t={{Timestamp}}') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" > + + + + + + + + + - + - 草稿 + {{item.statusText}} + {{item.title}} - #我的心悸经历 - #PSVT急救常识 - 今天去复诊,把最近的发作记录都给医生看了,沟通效率高了很多,也更安心。原来平时记下时间和感受真的很有用。 + #{{topic.topicName}} + {{item.content}} - - 患者故事 + + {{cat.categoryName}} - + - - - + + + - 2026年7月1日 13:09 - + {{item.dateText}} + 驳回原因: - 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 - 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 语言不当 + {{item.rejectReason}} - - 公开可见 + + {{item.visibility == 1 ? '公开可见' : '仅自己可见'}} - 删除 - 编辑 + 删除 + 编辑 + diff --git a/src/pages/start/index.ts b/src/pages/start/index.ts index e6df1a1..18b84a9 100644 --- a/src/pages/start/index.ts +++ b/src/pages/start/index.ts @@ -8,7 +8,7 @@ Page({ const { doctorId } = parseScene(options.scene) as { doctorId: string } app.globalData.waitBindDoctorId = doctorId } - app.waitLogin().then(() => { + app.waitLogin({ type: 1 }).then(() => { wx.reLaunch({ url: '/pages/index/index', }) diff --git a/src/pages/userInfo/index.scss b/src/pages/userInfo/index.scss index 524c903..4a52231 100644 --- a/src/pages/userInfo/index.scss +++ b/src/pages/userInfo/index.scss @@ -5,6 +5,7 @@ page { .page-title { font-size: 36rpx; color: rgba(51, 51, 51, 1); + padding-right: 100rpx; } .page { diff --git a/src/pages/userInfo/index.ts b/src/pages/userInfo/index.ts index 5921e73..cb42311 100644 --- a/src/pages/userInfo/index.ts +++ b/src/pages/userInfo/index.ts @@ -153,19 +153,20 @@ Page({ handleAreaChange(e: any) { const [province, city] = e.detail const provinceId = province.value ? Number(province.value) : '' - const cityId = city.value ? Number(city.value) : '' + const cityId = city?.value ? Number(city.value) : '' + const cityName = city?.label || '' this.setData({ provinceId, provinceName: province.label, cityId, - cityName: city.label, - regionText: [province.label, city.label].filter(Boolean).join(' '), + cityName, + regionText: [province.label, cityName].filter(Boolean).join(' '), }) this.submitUpdate({ provinceId, provinceName: province.label, cityId, - cityName: city.label, + cityName, }) }, submitUpdate(data: Record) { @@ -206,6 +207,25 @@ Page({ }, }) }, + handleCancellation() { + wx.showModal({ + title: '注销确认', + content: '注销后账号将被永久删除,且不可恢复,确定要注销吗?', + confirmColor: '#ba1a1a', + success: (res) => { + if (res.confirm) { + wx.ajax({ + method: 'POST', + url: '?r=psvt/user/cancellation', + data: {}, + }).then(() => { + wx.showToast({ title: '注销成功', icon: 'success' }) + wx.restartMiniProgram({ path: '/pages/start/index' }) + }) + } + }, + }) + }, }) export {} diff --git a/src/pages/userInfo/index.wxml b/src/pages/userInfo/index.wxml index 15f9a02..ad0e8e6 100644 --- a/src/pages/userInfo/index.wxml +++ b/src/pages/userInfo/index.wxml @@ -55,7 +55,7 @@ > 所在地区 - {{regionText || ''}} + {{regionText || '请选择所在地区'}} @@ -73,6 +73,6 @@ 退出登录 - 注销 + 注销 diff --git a/src/pages/wall/index.json b/src/pages/wall/index.json index e3ceeb9..5120472 100644 --- a/src/pages/wall/index.json +++ b/src/pages/wall/index.json @@ -2,6 +2,7 @@ "navigationStyle": "custom", "usingComponents": { "popup": "/components/popup/index", - "navbar": "/components/navbar/index" + "navbar": "/components/navbar/index", + "pagination": "/components/pagination/index" } } diff --git a/src/pages/wall/index.scss b/src/pages/wall/index.scss index 78427f1..761906d 100644 --- a/src/pages/wall/index.scss +++ b/src/pages/wall/index.scss @@ -178,6 +178,24 @@ page { height: 352rpx; border-radius: 24rpx; } + .video-cover { + position: relative; + overflow: hidden; + .p-img { + width: 100%; + height: 100%; + border-radius: 24rpx; + } + } + .play-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 80rpx; + height: 80rpx; + z-index: 1; + } .photo9 { margin-top: 24rpx; display: grid; @@ -186,11 +204,17 @@ page { .p-item { width: 100%; aspect-ratio: 1 / 1; + position: relative; + overflow: hidden; .p-img { width: 100%; height: 100%; border-radius: 24rpx; } + .play-icon { + width: 56rpx; + height: 56rpx; + } } } .comment { diff --git a/src/pages/wall/index.ts b/src/pages/wall/index.ts index baef5b9..a55ac17 100644 --- a/src/pages/wall/index.ts +++ b/src/pages/wall/index.ts @@ -7,9 +7,149 @@ Page({ popupParams: { position: 'bottom', } as any, + + wallConfig: {} as any, + hotTopics: [] as Array, + categoryList: [] as Array, + activeCategoryId: '', + sortOrder: 'latest', + publishButtonEnabled: true, + + postList: [] as Array, + postPagination: { + page: 1, + pages: 1, + count: 0, + }, + }, + onShow() { + app.waitLogin({ type: 1 }).then(() => { + this.getWallConfig() + this.getHotTopics() + this.getCategoryList() + this.getPostList() + }) + }, + getWallConfig() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/get-config', + }).then((res: any) => { + const config = res || {} + config.inputBoxEnabled = config.inputBoxEnabled == 1 + config.publishButtonEnabled = config.publishButtonEnabled == 1 + this.setData({ + wallConfig: config, + publishButtonEnabled: config.publishButtonEnabled, + }) + app.globalData.wallConfig = config + const tabBar = this.getTabBar?.() as any + if (tabBar && tabBar.updateWallName) { + tabBar.updateWallName(config.navName || '交流墙') + } + }) + }, + getHotTopics() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/index-topic', + }).then((res: any) => { + this.setData({ + hotTopics: res?.list || [], + }) + }) }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + getCategoryList() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/index-category', + }).then((res: any) => { + this.setData({ + categoryList: res?.list || [], + }) + }) + }, + getPostList(page = 1, append = false) { + const { sortOrder, activeCategoryId } = this.data + const params: any = { + page, + count: 10, + sortOrder, + } + if (activeCategoryId) { + params.categoryId = activeCategoryId + } + wx.ajax({ + method: 'GET', + url: '?r=psvt/post/list', + data: params, + }).then((res: any) => { + const list = res?.list || [] + this.setData({ + postList: append ? this.data.postList.concat(list) : list, + postPagination: { + page: res?.page || 1, + pages: res?.pages || 1, + count: Number(res?.count) || 0, + }, + }) + }) + }, + onChangeCategory(e: any) { + const { id } = e.currentTarget.dataset + this.setData({ + activeCategoryId: id || '', + }) + this.getPostList() + }, + onChangeSort(e: any) { + const { sort } = e.currentTarget.dataset + if (sort === this.data.sortOrder) return + this.setData({ + sortOrder: sort, + }) + this.getPostList() + }, + onReachBottom() { + const { postPagination } = this.data + if (postPagination.page < postPagination.pages) { + this.getPostList(postPagination.page + 1, true) + } + }, + handleDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/wallDetail/index?id=${id}`, + }) + }, + handleHotTopicMore() { + wx.navigateTo({ + url: '/pages/hotTopic/index', + }) + }, + handleTopicDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/hotTopicDetail/index?id=${id}`, + }) + }, + handleAdd() { + wx.navigateTo({ + url: '/pages/wallForm/index', + }) + }, + handlePreviewMedia(e: any) { + const { index, attachments } = e.currentTarget.dataset + const sources = (attachments || []).map((att: any) => { + if (att.attachmentType == 2) { + return { url: att.attachmentUrl, type: 'video', poster: att.videoCoverUrl } + } + return { url: att.attachmentUrl, type: 'image' } + }) + wx.previewMedia({ + current: Number(index) || 0, + sources, + }) }, handlePopupOk() { const { popupType } = this.data @@ -69,11 +209,7 @@ Page({ }) } }, - handleDetail() { - wx.navigateTo({ - url: '/pages/wallDetail/index', - }) - }, + }) export {} diff --git a/src/pages/wall/index.wxml b/src/pages/wall/index.wxml index 41b82e7..e5bad4c 100644 --- a/src/pages/wall/index.wxml +++ b/src/pages/wall/index.wxml @@ -12,72 +12,100 @@ - + 热门话题 - + 更多 - + # - 发作时我这样做 + {{item.topicName}} - 最新发布 + 全部 + + {{item.categoryName}} + - + - + - @林间心跳 - 2026年7月1日 13:09 + {{item.nickName}} + {{item.publishTime}} - 热门推荐 + 热门推荐 - #我的心悸经历 - #PSVT急救常识 - 今天去复诊,把最近的发作记录都给医生看了,沟通效率高了很多,也更安心。原来平时记下时间和感受真的很有用。 + #{{topic.topicName}} + {{item.content}} - - 患者故事 + + {{cat.categoryName}} - - - - - - + + + + + - - 最新评论: - 我也是,复诊前先整理记录,医生会更容易判断~ + + + + + + - 126 + {{item.likeCount || 0}} - 126 + {{item.viewCount || 0}} - 126 + {{item.commentCount || 0}} + - + diff --git a/src/pages/wallDetail/index.json b/src/pages/wallDetail/index.json index 13d61b0..cbe33f1 100644 --- a/src/pages/wallDetail/index.json +++ b/src/pages/wallDetail/index.json @@ -3,6 +3,7 @@ "usingComponents": { "popup": "/components/popup/index", "navbar": "/components/navbar/index", + "pagination": "/components/pagination/index", "van-action-sheet": "@vant/weapp/action-sheet/index", "van-popup": "@vant/weapp/popup/index" } diff --git a/src/pages/wallDetail/index.scss b/src/pages/wallDetail/index.scss index 14b8610..b5915ef 100644 --- a/src/pages/wallDetail/index.scss +++ b/src/pages/wallDetail/index.scss @@ -5,19 +5,41 @@ page { .page-title { font-size: 36rpx; color: rgba(51, 51, 51, 1); + padding-right: 100rpx; } .page { padding-bottom: 230rpx; .info-card { margin: 30rpx; - padding: 36rpx 32rpx 36rpx; + padding: 0 32rpx 36rpx; border-radius: 32rpx; border: 2rpx solid #f1f5f9; background: #fff; box-shadow: 0 16rpx 48rpx -8rpx rgba(0, 99, 132, 0.06); box-sizing: border-box; + .auth { + padding: 34rpx 0; + display: flex; + align-items: center; + justify-content: space-between; + border-bottom: 1px solid rgba(241, 245, 249, 1); + .a-status { + display: flex; + align-items: center; + gap: 16rpx; + .icon { + width: 36rpx; + height: 36rpx; + } + } + .a-content { + font-size: 28rpx; + color: rgba(47, 130, 169, 1); + } + } .user { + padding-top: 36rpx; display: flex; gap: 24rpx; .avatar { @@ -71,6 +93,24 @@ page { height: 352rpx; border-radius: 24rpx; } + .video-cover { + position: relative; + overflow: hidden; + .p-img { + width: 100%; + height: 100%; + border-radius: 24rpx; + } + } + .play-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 80rpx; + height: 80rpx; + z-index: 1; + } .photo9 { margin-top: 24rpx; display: grid; @@ -79,11 +119,17 @@ page { .p-item { width: 100%; aspect-ratio: 1 / 1; + position: relative; + overflow: hidden; .p-img { width: 100%; height: 100%; border-radius: 24rpx; } + .play-icon { + width: 56rpx; + height: 56rpx; + } } } .comment { @@ -152,7 +198,6 @@ page { .w-header { display: flex; align-items: center; - justify-content: space-between; gap: 30rpx; flex-wrap: wrap; .name { @@ -456,7 +501,7 @@ page { } } } - .a-close{ + .a-close { padding: 32rpx; font-size: 32rpx; line-height: 48rpx; diff --git a/src/pages/wallDetail/index.ts b/src/pages/wallDetail/index.ts index 645388e..eb36569 100644 --- a/src/pages/wallDetail/index.ts +++ b/src/pages/wallDetail/index.ts @@ -1,5 +1,7 @@ const app = getApp() +const PAGE_SIZE = 10 + Page({ data: { popupShow: false, @@ -11,9 +13,253 @@ Page({ topicShow: false, replayShow: false, actionShow: false, + + postId: '', + post: {} as any, + isMyPost: false, + + commentList: [] as Array, + commentPagination: { + page: 1, + pages: 1, + count: 0, + }, + + predefinedComments: [] as Array, + replyContent: '', + replyToCommentId: 0, + replyToUserName: '', + inputBoxEnabled: true, }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + onLoad(options: any) { + if (options.id) { + this.setData({ postId: options.id }) + } + const wallConfig = app.globalData.wallConfig || {} + this.setData({ inputBoxEnabled: wallConfig.inputBoxEnabled === true || wallConfig.inputBoxEnabled == 1 }) + app.waitLogin({ type: 1 }).then(() => { + this.getPostDetail() + this.getCommentList() + this.viewPost() + }) + }, + getPostDetail() { + const { postId } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/post/detail', + data: { id: Number(postId) }, + }).then((res: any) => { + const post = res || {} + app.getUserInfo().then((userInfo: any) => { + const isMyPost = userInfo?.userId && post.userId && userInfo.userId === post.userId + this.setData({ post, isMyPost }) + }) + }) + }, + getCommentList(page = 1, append = false) { + const { postId } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/comment/list', + data: { postId: Number(postId), page, count: PAGE_SIZE }, + }).then((res: any) => { + const list = res?.list || [] + this.setData({ + commentList: append ? this.data.commentList.concat(list) : list, + commentPagination: { + page: res?.page || 1, + pages: res?.pages || 1, + count: Number(res?.count) || 0, + }, + }) + }) + }, + viewPost() { + const { postId } = this.data + wx.ajax({ + method: 'POST', + url: '?r=psvt/post/view', + data: { postId: Number(postId) }, + loading: false, + showMsg: false, + }) + }, + handleLike() { + if (!app.checkLoginType(1, true)) return + const { post } = this.data + if (post.hasLiked) return + wx.ajax({ + method: 'POST', + url: '?r=psvt/post/like', + data: { targetId: Number(post.id), targetType: 1 }, + }).then(() => { + this.setData({ + 'post.hasLiked': true, + 'post.likeCount': (post.likeCount || 0) + 1, + }) + }) + }, + handleCommentLike(e: any) { + if (!app.checkLoginType(1, true)) return + const { id, index, childIndex } = e.currentTarget.dataset + const { commentList } = this.data + if (childIndex !== undefined) { + const child = commentList[index].childComments[childIndex] + if (child.hasLiked) return + wx.ajax({ + method: 'POST', + url: '?r=psvt/comment/like', + data: { targetId: Number(id) }, + }).then(() => { + this.setData({ + [`commentList[${index}].childComments[${childIndex}].hasLiked`]: true, + [`commentList[${index}].childComments[${childIndex}].likeCount`]: (child.likeCount || 0) + 1, + }) + }) + } else { + const comment = commentList[index] + if (comment.hasLiked) return + wx.ajax({ + method: 'POST', + url: '?r=psvt/comment/like', + data: { targetId: Number(id) }, + }).then(() => { + this.setData({ + [`commentList[${index}].hasLiked`]: true, + [`commentList[${index}].likeCount`]: (comment.likeCount || 0) + 1, + }) + }) + } + }, + showReplay(e: any) { + const { id, nickName } = e.currentTarget.dataset + const data: any = { + replayShow: true, + replyToCommentId: id || 0, + replyToUserName: nickName || '', + replyContent: '', + } + this.setData(data) + this.getPredefinedComments() + }, + getPredefinedComments() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/comment/predefined-list', + loading: false, + showMsg: false, + }).then((res: any) => { + this.setData({ + predefinedComments: res?.list || [], + }) + }) + }, + replayClose() { + this.setData({ + replayShow: false, + replyContent: '', + replyToCommentId: 0, + replyToUserName: '', + }) + }, + onReplyInput(e: any) { + this.setData({ + replyContent: e.detail.value, + }) + }, + handleSendComment() { + const { postId, replyContent, replyToCommentId } = this.data + if (!replyContent.trim()) { + wx.showToast({ title: '请输入评论内容', icon: 'none' }) + return + } + const data: any = { + postId: Number(postId), + content: replyContent, + } + if (replyToCommentId > 0) { + data.replyToCommentId = Number(replyToCommentId) + } + wx.ajax({ + method: 'POST', + url: '?r=psvt/comment/create', + data, + }).then(() => { + wx.showToast({ title: '评论成功', icon: 'success' }) + this.replayClose() + this.getCommentList() + }) + }, + handlePredefinedTap(e: any) { + const { content } = e.currentTarget.dataset + if (!content) return + if (this.data.inputBoxEnabled) { + this.setData({ replyContent: content }) + } else { + const { postId, replyToCommentId } = this.data + const data: any = { + postId: Number(postId), + content, + } + if (replyToCommentId > 0) { + data.replyToCommentId = Number(replyToCommentId) + } + wx.ajax({ + method: 'POST', + url: '?r=psvt/comment/create', + data, + }).then(() => { + wx.showToast({ title: '评论成功', icon: 'success' }) + this.replayClose() + this.getCommentList() + }) + } + }, + showAction() { + this.setData({ actionShow: true }) + }, + actionClose() { + this.setData({ actionShow: false }) + }, + handleEdit() { + const { postId } = this.data + wx.navigateTo({ + url: `/pages/wallForm/index?id=${postId}`, + }) + this.actionClose() + }, + handleDelete() { + const { postId } = this.data + wx.showModal({ + title: '提示', + content: '确定删除该帖子吗?', + success: (res) => { + if (!res.confirm) return + wx.ajax({ + method: 'POST', + url: '?r=psvt/my-post/delete', + data: { postId: Number(postId) }, + }).then(() => { + wx.showToast({ title: '删除成功', icon: 'success' }) + setTimeout(() => { + wx.navigateBack() + }, 1000) + }) + }, + }) + this.actionClose() + }, + onReachBottom() { + const { commentPagination } = this.data + if (commentPagination.page < commentPagination.pages) { + this.getCommentList(commentPagination.page + 1, true) + } + }, + topicClose() { + this.setData({ + topicShow: false, + }) }, handlePopupOk() { const { popupType } = this.data @@ -78,10 +324,26 @@ Page({ url: '/pages/wechatWork/index', }) }, - - topicClose() { - this.setData({ - topicShow: false, + handlePreviewMedia(e: any) { + const { index, attachments } = e.currentTarget.dataset + const sources = (attachments || []).map((att: any) => { + if (att.attachmentType == 2) { + return { url: att.attachmentUrl, type: 'video', poster: att.videoCoverUrl } + } + return { url: att.attachmentUrl, type: 'image' } + }) + wx.previewMedia({ + current: Number(index) || 0, + sources, + }) + }, + handleBack() { + wx.navigateBack() + }, + handleTopicDetail(e: any) { + const { id } = e.currentTarget.dataset + wx.navigateTo({ + url: `/pages/hotTopicDetail/index?id=${id}`, }) }, }) diff --git a/src/pages/wallDetail/index.wxml b/src/pages/wallDetail/index.wxml index 8df5494..8f4c2f2 100644 --- a/src/pages/wallDetail/index.wxml +++ b/src/pages/wallDetail/index.wxml @@ -1,5 +1,5 @@ - + 帖子详情 @@ -10,184 +10,228 @@ style="background: url('{{imageUrl}}bg6.png?t={{Timestamp}}') no-repeat top center/100% 478rpx;padding-top: {{pageTop}}px;" > + + + + {{post.visibility===2 ? '仅自己可见' : '公开可见'}} + + + 编辑和设置权限 + + + - + - @林间心跳 - 2026年7月1日 13:09 + {{post.nickName}} + {{post.publishTime}} - #我的心悸经历 - #PSVT急救常识 - 今天去复诊,把最近的发作记录都给医生看了,沟通效率高了很多,也更安心。原来平时记下时间和感受真的很有用。 + + #{{topic.topicName}} + + {{post.content}} - - 患者故事 + + {{cat.categoryName}} - - - - - - + + + + + - - 最新评论: - 我也是,复诊前先整理记录,医生会更容易判断~ + + + + + + 精彩评论 - 20 + {{commentPagination.count}} - + - + - 小鹿 - 2026-01-01 12:00:00 + {{item.nickName}} + {{item.commentTime}} - 我也是,复诊前先整理记录,医生会更容易 + {{item.content}} - - - 126 + + + {{item.likeCount || 0}} - + - 126 + 回复 - - - + + + - 小鹿 - 2026-01-01 12:00:00 + {{childItem.nickName}} + {{childItem.commentTime}} - 回复小红: - 我也是,复诊前先整理记录,医生会更容易 + + 回复{{childItem.replyToUserName}}: + + {{childItem.content}} - - - 126 + + + {{childItem.likeCount || 0}} - + - 126 + 回复 - - - 收起 - - + - - - - 公开可见 - - 编辑和设置权限 - - - - - - - - 仅自己可见 - - 编辑和设置权限 - - - - - 我要评论 + 我要评论 - - - 126 + + + {{post.likeCount || 0}} - 126 + {{post.viewCount || 0}} - 126 + {{post.commentCount || 0}} - - - - 热门话题 - - - - - {{index+1}} - # 我的心悸经历 - 230篇帖子 - - - - - - 我要评论 + 回复 + 我要评论 - 加油,你真棒! - 相同的经历,感同身受 + + {{item.content}} + - 取消 - 发送 + 取消 + 发送 - + - + 编辑 - + 删除 - 取消 + 取消 diff --git a/src/pages/wallForm/index.scss b/src/pages/wallForm/index.scss index d1a1fe9..5607a14 100644 --- a/src/pages/wallForm/index.scss +++ b/src/pages/wallForm/index.scss @@ -5,6 +5,7 @@ page { .page-title { font-size: 36rpx; color: rgba(51, 51, 51, 1); + padding-right: 100rpx; } .page { @@ -42,6 +43,20 @@ page { .title-place { color: rgba(148, 163, 184, 1); } + .selected-topics { + display: flex; + flex-wrap: wrap; + gap: 16rpx; + padding-top: 16rpx; + .s-item { + height: 52rpx; + line-height: 52rpx; + border-radius: 14rpx; + font-size: 32rpx; + color: rgba(47, 130, 169, 1); + box-sizing: border-box; + } + } .txa { padding: 32rpx 0; font-size: 32rpx; @@ -76,6 +91,10 @@ page { width: 32rpx; height: 32rpx; } + &.active { + background: rgba(47, 130, 169, 0.08); + border-color: rgba(47, 130, 169, 1); + } } } .wrap { @@ -238,3 +257,82 @@ page { } } } + +.topic-popup { + .tp-header { + margin: 40rpx; + display: flex; + align-items: center; + justify-content: space-between; + .title { + font-size: 44rpx; + color: rgba(30, 41, 59, 1); + font-weight: bold; + } + .cross { + font-size: 44rpx; + color: rgba(148, 163, 184, 1); + } + } + .tp-list { + max-height: 928rpx; + overflow-y: auto; + overflow-x: hidden; + padding: 0 40rpx; + &::-webkit-scrollbar { + display: none; + } + .li { + padding: 32rpx 0; + display: flex; + gap: 40rpx; + border-bottom: 1px solid #f8fafc; + .num { + flex-shrink: 0; + width: 56rpx; + height: 56rpx; + display: flex; + align-items: center; + justify-content: center; + background-color: #f7fafc; + border-radius: 14rpx; + } + .content { + padding-top: 4rpx; + flex: 1; + font-size: 36rpx; + color: rgba(30, 41, 59, 1); + line-height: 48rpx; + } + .total { + padding-top: 8rpx; + font-size: 32rpx; + color: rgba(148, 163, 184, 1); + line-height: 40rpx; + } + } + .li.active { + .content { + color: rgba(47, 130, 169, 1); + } + } + .li:nth-of-type(1) { + .num { + background-color: rgba(255, 107, 34, 1); + color: #fff; + } + } + .li:nth-of-type(2) { + .num { + background-color: rgba(255, 143, 51, 1); + color: #fff; + } + } + .li:nth-of-type(3) { + .num { + background-color: rgba(47, 130, 169, 1); + color: #fff; + } + } + } +} diff --git a/src/pages/wallForm/index.ts b/src/pages/wallForm/index.ts index 0ee110e..58aea80 100644 --- a/src/pages/wallForm/index.ts +++ b/src/pages/wallForm/index.ts @@ -12,9 +12,189 @@ Page({ replayShow: false, fileList: [] as any[], + + topicList: [] as any[], + categoryList: [] as any[], + selectedTopicIds: [] as number[], + selectedTopics: [] as any[], + selectedCategoryIds: [] as number[], + title: '', + content: '', + visibility: 1, + isEdit: false, + editPostId: '', + }, + onLoad(options: any) { + if (options && options.id) { + this.setData({ isEdit: true, editPostId: options.id }) + } + app.waitLogin({ type: 1 }).then(() => { + this.getTopicList() + this.getCategoryList() + if (this.data.isEdit) { + this.getPostDetail() + } + }) + }, + getTopicList() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/topic/top-list', + }).then((res: any) => { + this.setData({ + topicList: res.list || [], + selectedTopics: this.computeSelectedTopics(this.data.selectedTopicIds, res.list || []), + }) + }) }, - onLoad() { - app.waitLogin({ type: 1 }).then(() => {}) + getCategoryList() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/index-category', + }).then((res: any) => { + this.setData({ + categoryList: res.list || [], + }) + }) + }, + getPostDetail() { + const { editPostId } = this.data + wx.ajax({ + method: 'GET', + url: '?r=psvt/post/detail', + data: { id: editPostId }, + }).then((res: any) => { + if (!res) return + const fileList = (res.attachments || []).map((item: any) => { + if (item.attachmentType == 2) { + return { + fileType: 'video', + url: item.videoCoverUrl || '', + videoUrl: item.attachmentUrl || '', + } + } + return { + fileType: 'image', + url: item.attachmentUrl || '', + } + }) + this.setData({ + title: res.title || '', + content: res.content || '', + visibility: res.visibility || 1, + selectedTopicIds: (res.topics || []).map((t: any) => t.topicId), + selectedTopics: this.computeSelectedTopics( + (res.topics || []).map((t: any) => t.topicId), + this.data.topicList, + ), + selectedCategoryIds: (res.categories || []).map((c: any) => c.categoryId), + fileList, + }) + }) + }, + onTitleInput(e: any) { + this.setData({ title: e.detail.value }) + }, + onContentInput(e: any) { + this.setData({ content: e.detail.value }) + }, + handleTopicTap(e: any) { + const id = Number(e.currentTarget.dataset.id) + const selectedTopicIds = [...this.data.selectedTopicIds] + const index = selectedTopicIds.indexOf(id) + if (index > -1) { + selectedTopicIds.splice(index, 1) + } else { + selectedTopicIds.push(id) + } + this.setData({ + selectedTopicIds, + selectedTopics: this.computeSelectedTopics(selectedTopicIds, this.data.topicList), + }) + }, + handleRemoveTopic(e: any) { + const id = Number(e.currentTarget.dataset.id) + const selectedTopicIds = this.data.selectedTopicIds.filter((tid) => tid !== id) + this.setData({ + selectedTopicIds, + selectedTopics: this.computeSelectedTopics(selectedTopicIds, this.data.topicList), + }) + }, + computeSelectedTopics(ids: number[], list: any[]) { + return ids.map((id) => list.find((t) => String(t.id) === String(id))).filter((t) => t) + }, + showTopicPopup() { + this.setData({ topicShow: true }) + }, + topicPopupClose() { + this.setData({ topicShow: false }) + }, + handleCategoryTap(e: any) { + const id = Number(e.currentTarget.dataset.id) + const selectedCategoryIds = [...this.data.selectedCategoryIds] + const index = selectedCategoryIds.indexOf(id) + if (index > -1) { + selectedCategoryIds.splice(index, 1) + } else { + selectedCategoryIds.push(id) + } + this.setData({ selectedCategoryIds }) + }, + handleVisibilityChange(e: any) { + this.setData({ visibility: Number(e.currentTarget.dataset.value) }) + }, + buildAttachments() { + const { fileList } = this.data + return fileList.map((item: any, index: number) => { + const isVideo = item.fileType === 'video' + const attachment: any = { + attachmentType: isVideo ? 2 : 1, + attachmentUrl: isVideo ? item.videoUrl : item.url, + sortOrder: index, + } + if (isVideo) { + attachment.videoCoverUrl = item.url + } + return attachment + }) + }, + handleSaveDraft() { + this.submitPost(0) + }, + handleSubmit() { + this.submitPost(1) + }, + submitPost(postStatus: number) { + const { title, content, visibility, selectedTopicIds, selectedCategoryIds, isEdit, editPostId } = this.data + if (!title.trim()) { + wx.showToast({ title: '请添加标题', icon: 'none' }) + return + } + const data: any = { + title, + content, + postStatus, + visibility, + topicIds: selectedTopicIds, + categoryIds: selectedCategoryIds, + attachments: this.buildAttachments(), + } + if (isEdit) { + data.postId = Number(editPostId) + } + wx.ajax({ + method: 'POST', + url: isEdit ? '?r=psvt/my-post/update' : '?r=psvt/post/create', + data, + }).then(() => { + wx.showToast({ + title: postStatus === 0 ? '草稿已保存' : '发布成功', + icon: 'success', + }) + setTimeout(() => { + wx.navigateBack() + }, 1000) + }) }, handlePopupOk() { const { popupType } = this.data @@ -92,6 +272,9 @@ Page({ fileList: fileList.filter((_, i) => i !== index), }) }, + handleBack() { + wx.navigateBack() + }, }) export {} diff --git a/src/pages/wallForm/index.wxml b/src/pages/wallForm/index.wxml index 168f32e..bb95196 100644 --- a/src/pages/wallForm/index.wxml +++ b/src/pages/wallForm/index.wxml @@ -1,5 +1,7 @@ + + - + 发布帖子 @@ -11,27 +13,34 @@ > - + + + + + + #{{item.topicName}} + - - + - 我的心悸经历 + {{item.topicName}} - + 话题 - 0/2000 + {{content.length || 0}}/2000 @@ -40,7 +49,7 @@ 内容标签 - 疾病知识 + {{item.categoryName}} @@ -49,15 +58,15 @@ 谁可以看 - - + + 公开 所有用户可见 - - + + 私密 仅自己可见 @@ -66,13 +75,28 @@ - + 存草稿 - + 发布 + + + + + 热门话题 + + + + + {{index+1}} + # {{item.topicName}} + + + + diff --git a/src/pages/wechatWork/index.scss b/src/pages/wechatWork/index.scss index 0eef1a7..f46ee39 100644 --- a/src/pages/wechatWork/index.scss +++ b/src/pages/wechatWork/index.scss @@ -4,56 +4,58 @@ page { .page-title { font-size: 36rpx; color: rgba(51, 51, 51, 1); + padding-right: 100rpx; } .page { .container { - margin: 240rpx 30rpx 0; - height: 1018rpx; - padding-top: 106rpx; + margin: 120rpx 30rpx 0; + height: 1310rpx; + padding-top: 300rpx; box-sizing: border-box; .title { - margin-top: 236rpx; - font-size: 40rpx; - color: rgba(30, 41, 59, 1); - font-weight: bold; + margin: 0 32rpx; display: flex; align-items: center; - justify-content: center; - gap: 12rpx; - .icon1, - .icon2 { - flex-shrink: 0; - width: 94rpx; - height: 12rpx; + gap: 24rpx; + .avatar { + width: 100rpx; + height: 100rpx; + border-radius: 50%; } - .icon1 { - transform: rotate(180deg); + .name { + font-size: 36rpx; + color: rgba(30, 41, 59, 1); } } - .code-wrap { - margin: 30rpx auto 0; + .code { + margin: 120rpx auto 0; display: block; - width: 376rpx; - height: 376rpx; - display: flex; - align-items: center; - justify-content: center; - .code { - width: 340rpx; - height: 340rpx; - } + width: 340rpx; + height: 340rpx; } - .btn { - display: block; - margin: 20rpx auto 0; - padding-top: 26rpx; - text-align: center; - font-size: 36rpx; - color: rgba(255, 255, 255, 1); - width: 332rpx; - height: 88rpx; - box-sizing: border-box; + .guide { + margin: 188rpx 32rpx 0; + padding: 32rpx; + border-radius: 24rpx; + background: #f7fafc; + .row { + display: flex; + gap: 14rpx; + .aside { + margin-top: 20rpx; + flex-shrink: 0; + width: 18rpx; + height: 18rpx; + border-radius: 50%; + background-color: rgba(47, 130, 169, 1); + } + .content { + font-size: 32rpx; + color: rgba(30, 41, 59, 1); + line-height: 56rpx; + } + } } } } diff --git a/src/pages/wechatWork/index.ts b/src/pages/wechatWork/index.ts index c563ebc..07effe5 100644 --- a/src/pages/wechatWork/index.ts +++ b/src/pages/wechatWork/index.ts @@ -1,8 +1,32 @@ -const _app = getApp() +const app = getApp() Page({ - data: {}, - onLoad() {}, + data: { + avatar: '', + wecomName: '', + qrCode: '', + textList: [] as string[], + }, + onLoad() { + app.waitLogin({ type: 1 }).then(() => { + this.getWecomConfig() + }) + }, + getWecomConfig() { + wx.ajax({ + method: 'GET', + url: '?r=psvt/wall/get-wecom-config', + }).then((res: any) => { + const config = res || {} + const textList = [config.text1, config.text2, config.text3, config.text4, config.text5].filter(Boolean) + this.setData({ + avatar: config.avatar || '', + wecomName: config.wecomName || '', + qrCode: config.qrCode || '', + textList, + }) + }) + }, handleBack() { wx.navigateBack() }, diff --git a/src/pages/wechatWork/index.wxml b/src/pages/wechatWork/index.wxml index e990205..0755147 100644 --- a/src/pages/wechatWork/index.wxml +++ b/src/pages/wechatWork/index.wxml @@ -4,16 +4,21 @@ - + - - 添加你的专属客服 - + + {{wecomName}} - - + + + + + {{item}} + - 长按识别二维码 diff --git a/src/utils/tools.wxs b/src/utils/tools.wxs index fe90f39..e230699 100644 --- a/src/utils/tools.wxs +++ b/src/utils/tools.wxs @@ -1,6 +1,6 @@ function include(value, arr) { for (var i = 0; i < arr.length; i++) { - if (arr[i] === value) { + if (arr[i] == value) { return true } } @@ -9,4 +9,5 @@ function include(value, arr) { module.exports = { include: include, + inArray: include, } diff --git a/typings/index.d.ts b/typings/index.d.ts index ab5985b..454009f 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -45,7 +45,7 @@ interface IAppOption { } getUserInfo: (type?: 0 | 1 | 2) => Promise startLogin: (callback?: () => void) => void - waitLogin: (params?: { type?: 1 | 'any' }) => Promise + waitLogin: (params?: { type?: 1 | 'any' }) => Promise checkLoginType: (type: 1 | 'any', confirm: boolean) => boolean mpBehavior: (data: { PageName: string; type?: 0 | 1 | 2 | 3 }) => void globalSystemInfo?: globalSystemInfo