| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- <template>
- <view class="content">
- <view class="page-section-spacing">
- <image src="/static/poster-bg-new.png" mode="scaleToFill" style="width: 100%; height: 100%"></image>
- </view>
- <view class="notice-box" style="width:90%;margin-top: 50rpx;">
- <view class="notice-title-box" style="margin: 0 auto;">
- <view class="notice-font margin-right-30">初诊/复诊问卷</view>
- <view class="notice-more-font">
- <image
- src="/static/dot.svg"
- mode="aspectFill"
- class="margin-right-10"
- style="width: 16rpx; height: 16rpx"
- ></image>
- <view class="dot-line margin-right-30"></view>
- <view class="margin-right-10" style="font-size: 20rpx;color: #70b62b;">已完成</view>
- <view style="font-size: 30rpx;color: #70b62b;">{{ totalFinish }}项</view>
- </view>
- </view>
- </view>
- <view class="page-nav-box">
- <view v-for="(item, index) in navList" :key="index" class="nav-content" @click="goDetailPage(item)">
- <view class="nav-badge" :style="{ background: badgeOf(item.task_name).color }">{{ badgeOf(item.task_name).label }}</view>
- <view class="nav-task-name">{{ item.task_name }}</view>
- <view v-if="item.finish_flag" style="color: #ff7356;font-size: 22rpx;">已完成</view>
- <view v-else style="color: #d9001b;font-size: 22rpx;">未完成</view>
- </view>
- </view>
- <view class="notice-box" style="width:90%;margin-top: 30rpx;" v-if="showCaseShare">
- <view class="notice-title-box" style="margin: 0 auto;">
- <view class="notice-font margin-right-30">病例分析分享</view>
- </view>
- <scroll-view scroll-y class="article-scroll" @scrolltolower="loadMoreCaseShare">
- <view class="article-item" v-for="item in caseShareList" :key="item.id" @click="goArticleDetail(item, 'case_share')">
- <view class="article-item-text">
- <view class="article-item-title">{{ item.title }}</view>
- <view class="article-item-sub">{{ item.hospital }} {{ item.doctor }}</view>
- <view class="article-item-date">{{ item.date }}</view>
- </view>
- <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
- </view>
- <view class="scroll-end-tip" v-if="!caseShareHasMore && caseShareList.length">没有更多了</view>
- </scroll-view>
- </view>
- <view class="notice-box" style="width:90%;margin-top: 30rpx;">
- <view class="notice-title-box" style="margin: 0 auto;">
- <view class="notice-font margin-right-30">用嗓科普</view>
- </view>
- <scroll-view scroll-y class="article-scroll" @scrolltolower="loadMoreVoiceScience">
- <view class="article-item" v-for="item in voiceScienceList" :key="item.id" @click="goArticleDetail(item, 'voice_science')">
- <view class="article-item-text">
- <view class="article-item-title">{{ item.title }}</view>
- <view class="article-item-sub">{{ item.hospital }} {{ item.doctor }}</view>
- <view class="article-item-date">{{ item.date }}</view>
- </view>
- <image class="article-item-img" :src="item.cover" mode="aspectFill"></image>
- </view>
- <view class="scroll-end-tip" v-if="!voiceScienceHasMore && voiceScienceList.length">没有更多了</view>
- </scroll-view>
- </view>
- </view>
- </template>
- <script>
- import { request, currentOpenId } from '@/utils/request.js'
- // 量表名称 -> 徽标文案/颜色,未命中时回退为取名称前两个字 + 按序号轮换配色
- const SCALE_BADGE_MAP = {
- '病史信息': { label: '病史', color: '#ff7356' },
- '疲劳量表': { label: 'Zzz', color: '#19be6b' },
- 'SAS量表': { label: 'SAS', color: '#5b9bf5' },
- 'SDS量表': { label: 'SDS', color: '#8f8fe0' },
- '反流量表': { label: 'RSI', color: '#5b6b8c' },
- 'VHI量表': { label: 'VHI', color: '#f2a93b' },
- }
- const FALLBACK_COLORS = ['#ff7356', '#19be6b', '#5b9bf5', '#8f8fe0', '#5b6b8c', '#f2a93b']
- export default {
- data() {
- return {
- navList: [],
- totalFinish: 0,
- // 病例分析分享是否可见依赖用户角色(普通用户不可见),判断依据是 info_by_openid 接口返回的 is_doctor 字段
- showCaseShare: false,
- caseShareList: [],
- caseSharePage: 1,
- caseShareHasMore: false,
- caseShareLoading: false,
- voiceScienceList: [],
- voiceSciencePage: 1,
- voiceScienceHasMore: false,
- voiceScienceLoading: false,
- articlePageSize: 10,
- };
- },
- async onShow() {
- await this.$onLaunched;
- this.getUserTask();
- this.getUserRole();
- this.getArticleList('case_share');
- this.getArticleList('voice_science');
- },
- onShareAppMessage() {
- return {
- title: '耳鸣测试',
- path: '/pages/index/index',
- imageUrl: '/static/shareImg2.png',
- }
- },
- methods: {
- badgeOf(name) {
- if (SCALE_BADGE_MAP[name]) return SCALE_BADGE_MAP[name]
- const idx = this.navList.findIndex(item => item.task_name === name)
- return { label: (name || '').slice(0, 2), color: FALLBACK_COLORS[idx % FALLBACK_COLORS.length] }
- },
- async getUserTask() {
- const res = await request('user', 'task', { openId: currentOpenId() })
- if (res.code === 200) {
- const result = res.data
- let total = 0
- result.forEach((item) => {
- item.finish_flag = Number(item.finish_flag)
- total += item.finish_flag
- })
- this.navList = result
- this.totalFinish = total
- }
- },
- async getUserRole() {
- // 普通用户看不到"病例分析分享",判断依据沿用1.0"我的"模块里的 is_doctor 字段
- const res = await request('user', 'info_by_openid', { openId: currentOpenId() })
- if (res.code === 200) {
- this.showCaseShare = Number(res.data.is_doctor) === 1
- }
- },
- async getArticleList(category, loadMore = false) {
- const categoryId = category === 'case_share' ? 1 : 2
- const pageKey = category === 'case_share' ? 'caseSharePage' : 'voiceSciencePage'
- const hasMoreKey = category === 'case_share' ? 'caseShareHasMore' : 'voiceScienceHasMore'
- const listKey = category === 'case_share' ? 'caseShareList' : 'voiceScienceList'
- const loadingKey = category === 'case_share' ? 'caseShareLoading' : 'voiceScienceLoading'
- if (this[loadingKey]) return
- if (loadMore && !this[hasMoreKey]) return
- this[loadingKey] = true
- const page = loadMore ? this[pageKey] + 1 : 1
- const res = await request('article', 'list', { category_id: categoryId, page, page_size: this.articlePageSize })
- this[loadingKey] = false
- if (res.code === 200) {
- const rawList = (res.data && res.data.list) || []
- const list = rawList.map(item => ({
- id: item.id,
- title: item.title,
- hospital: item.hospital_name,
- doctor: item.doctor_name,
- date: this.formatDate(item.create_time),
- cover: item.pic_url ? (getApp().globalData.shareUrl + item.pic_url) : '',
- }))
- this[listKey] = loadMore ? this[listKey].concat(list) : list
- this[pageKey] = page
- const pageCount = Number(res.data && res.data.page_count) || 1
- this[hasMoreKey] = page < pageCount
- } else {
- console.error('getArticleList failed', category, res)
- }
- },
- formatDate(ts) {
- if (!ts) return ''
- const d = new Date(Number(ts) * 1000)
- const y = d.getFullYear()
- const m = String(d.getMonth() + 1).padStart(2, '0')
- const day = String(d.getDate()).padStart(2, '0')
- return `${y}-${m}-${day}`
- },
- loadMoreCaseShare() {
- this.getArticleList('case_share', true)
- },
- loadMoreVoiceScience() {
- this.getArticleList('voice_science', true)
- },
- goArticleDetail(item, category) {
- uni.navigateTo({
- url: `/pages/index/articleDetail?id=${item.id}&category=${category}`
- })
- },
- goDetailPage(item) {
- item.category_id == 1 ? uni.navigateTo({
- url: "/pages/sickForm/history?finish=" + item.finish_flag
- }) :
- uni.navigateTo({
- url: "/pages/sickForm/blurb?id=" + item.category_id + '&name=' + item.task_name + '&finish=' + item.finish_flag
- })
- },
- },
- };
- </script>
- <style>
- .content {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- position: relative;
- }
- .page-section-spacing{
- width: 100%;
- height: 400rpx;
- }
- .page-nav-box {
- width: 98%;
- display: flex;
- flex-wrap: wrap;
- align-items: flex-start;
- padding: 20rpx 10rpx 30rpx 10rpx;
- border-radius: 16rpx;
- background-color: #fff;
- }
- .nav-content {
- width: 25%;
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-top: 40rpx;
- padding: 0 6rpx;
- font-size: 28rpx;
- letter-spacing: 0.02em;
- color: #0d1937;
- font-family: PingFang SC;
- font-style: normal;
- box-sizing: border-box;
- }
- .nav-badge {
- width: 80px;
- height: 80px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- color: #fff;
- font-weight: bold;
- font-size: 26rpx;
- margin-bottom: 20rpx;
- }
- .nav-task-name {
- height: 76rpx;
- line-height: 38rpx;
- text-align: center;
- overflow: hidden;
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-line-clamp: 2;
- margin-bottom: 2rpx;
- }
- .notice-box {
- width: 90%;
- margin-bottom: 20rpx;
- }
- .notice-title-box {
- width: 100%;
- display: flex;
- align-items: center;
- margin-bottom: 40rpx;
- }
- .notice-font {
- font-family: PingFang SC;
- font-style: normal;
- font-weight: bold;
- font-size: 38rpx;
- letter-spacing: 0.02em;
- color: #0d1937;
- }
- .notice-more-font {
- font-size: 28rpx;
- color: #146afb;
- display: flex;
- align-items: center;
- }
- .dot-line {
- width: 50rpx;
- height: 2rpx;
- background-color: #bfbfbf;
- }
- .margin-right-10 {
- margin-right: 10rpx;
- }
- .margin-right-30 {
- margin-right: 30rpx;
- }
- .article-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- background: #fff;
- border-radius: 12rpx;
- padding: 24rpx;
- margin-bottom: 20rpx;
- }
- .article-item-text {
- flex: 1;
- margin-right: 20rpx;
- }
- .article-item-title {
- font-size: 28rpx;
- color: #0d1937;
- font-weight: bold;
- line-height: 40rpx;
- }
- .article-item-sub {
- font-size: 24rpx;
- color: #5f5f5f;
- margin-top: 12rpx;
- }
- .article-item-date {
- font-size: 22rpx;
- color: #a7adba;
- margin-top: 6rpx;
- }
- .article-item-img {
- width: 140rpx;
- height: 140rpx;
- border-radius: 8rpx;
- flex-shrink: 0;
- }
- .article-scroll {
- max-height: 700rpx;
- }
- .scroll-end-tip {
- text-align: center;
- font-size: 24rpx;
- color: #a7adba;
- padding: 16rpx 0;
- }
- </style>
|