9.5上午更新

This commit is contained in:
zoujiandong
2025-09-05 10:19:10 +08:00
parent 9a26193ea4
commit 397cf0c88e
13 changed files with 3146 additions and 222 deletions
+262 -21
View File
@@ -2,8 +2,8 @@
<view class="zhinan-list-page">
<!-- 头部导航栏 -->
<uni-nav-bar
left-icon="left"
title="诊疗指南"
left-icon="left"
:title="title"
@clickLeft="goBack"
fixed
color="#8B2316"
@@ -12,12 +12,26 @@
backgroundColor="#eeeeee"
>
<template v-slot:right>
<view class="nav-right" @click="testLoadMore">
<text style="font-size: 24rpx; color: #8B2316;">测试加载</text>
<view class="nav-right" @click="goGot">
<up-image :src="hotImg" width="40rpx" height="40rpx" ></up-image>
</view>
</template>
</uni-nav-bar>
<!-- 固定搜索栏 -->
<view class="search-container-fixed filter-bar">
<view class="search-box" @click="goToSearch">
<uni-icons type="search" size="16" color="#999"></uni-icons>
<text class="search-text">搜索</text>
</view>
<view class="divider"></view>
<view class="current-sort" @click="toggleInnerSort">
<text class="sort-text">{{ innerSortTitle }}</text>
<view class="imgbox">
<up-image :src="upImg" width="26rpx" height="26rpx" ></up-image>
</view>
</view>
</view>
<!-- 使用scroll-view实现列表 -->
<scroll-view
class="guidelines-scroll-view"
@@ -34,6 +48,7 @@
class="guideline-item"
v-for="(item, index) in guidelinesList"
:key="item.uuid || index"
@click="viewGuideline(item)"
>
<!-- 指南信息 -->
<view class="item-content">
@@ -43,19 +58,18 @@
<!-- 操作按钮 -->
<view class="item-action">
<view
v-if="item.can_download"
class="download-btn"
@click="downloadGuideline(item)"
@click.stop="viewGuideline(item)"
>
<up-icon name="download" color="#8D2316" size="28"></up-icon>
</view>
<view
<!-- <view
v-else
class="view-btn"
@click="viewGuideline(item)"
@click.stop="viewGuideline(item)"
>
查看
</view>
</view> -->
</view>
</view>
</view>
@@ -83,13 +97,32 @@
</view>
</scroll-view>
</view>
<!-- 组内排序弹窗 -->
<view v-if="showInnerSort" class="popup-panel">
<view class="popup-item" :class="{ active:sort==1 }" @click.stop="chooseInnerSort(1)">
<text class="item-text">下载量</text>
<uni-icons v-if="sort==1" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
</view>
<view class="popup-divider"></view>
<view class="popup-item" :class="{ active:sort==2 }" @click.stop="chooseInnerSort(2)">
<text class="item-text">上传时间</text>
<uni-icons v-if="sort==2" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
</view>
<view class="popup-divider"></view>
<view class="popup-item" :class="{ active:sort==3 }" @click.stop="chooseInnerSort(3)">
<text class="item-text">标题</text>
<uni-icons v-if="sort==3" type="checkmarkempty" color="#8B2316" size="22"></uni-icons>
</view>
</view>
</template>
<script setup>
import { ref, onMounted} from 'vue'
import api from '@/api/api.js'
import { onShow,onLoad } from "@dcloudio/uni-app";
import docUrl from "@/utils/docUrl.js"
import navTo from "@/utils/navTo.js"
import hotImg from "@/static/hot_booklist.png"
// 响应式数据
const guidelinesList = ref([])
const isLoading = ref(false)
@@ -98,14 +131,48 @@ const currentPage = ref(1)
const pageSize = ref(10)
const isRefreshing = ref(false)
const keywords=ref('');
import upImg from "@/static/triangle_green_theme.png"
import downImg from "@/static/triangle_normal.png"
const loadMoreStatus = ref('more') // 'loading', 'more', 'noMore'
const typeUuid=ref('');
const title=ref('');
const sort=ref(2);
const showInnerSort=ref(false);
const innerSortTitle=ref('上传时间');
const chooseInnerSort=(index)=>{
sort.value=index;
if(index==1){
innerSortTitle.value='下载量';
}else if(index==2){
innerSortTitle.value='上传时间';
}else if(index==3){
innerSortTitle.value='标题';
}
showInnerSort.value=false;
loadGuidelinesList(true);
}
onLoad((options)=>{
console.log(options)
keywords.value=decodeURIComponent(options.keywords);
console.log(keywords.value);
if(options.typeUuid){
typeUuid.value=options.typeUuid;
}
if(options.title){
title.value=options.title;
}
if(options.keywords){
keywords.value=decodeURIComponent(options.keywords);
title.value=decodeURIComponent(options.title);
}
})
const goGot=()=>{
navTo({
url:'/pages_app/hot/hot?from=hot&typeUuid='+typeUuid.value
})
}
const toggleInnerSort=()=>{
showInnerSort.value=!showInnerSort.value;
}
onShow(() => {
// 页面显示时,如果列表为空则加载数据
if (guidelinesList.value.length === 0) {
@@ -113,6 +180,16 @@ onShow(() => {
}
})
// 跳转到搜索页
const goToSearch = () => {
const q = keywords.value ? encodeURIComponent(keywords.value) : ''
const t = title.value ? encodeURIComponent(title.value) : ''
const type = typeUuid.value ? `&typeUuid=${encodeURIComponent(typeUuid.value)}` : ''
uni.navigateTo({
url: `/pages_app/search/search?keywords=${q}&title=${t}${type}`
})
}
// scroll-view 下拉刷新
const onRefresh = async () => {
console.log('scroll-view 下拉刷新触发');
@@ -183,6 +260,7 @@ const loadGuidelinesList = async (isRefresh = false) => {
pageSize: pageSize.value,
type: 1, // 诊疗指南类型
sort:2,
typeUuid:typeUuid.value,
keywords:keywords.value
}
@@ -289,13 +367,66 @@ const downloadGuideline = (item) => {
}
}
// 查看指南
// 查看指南(支持常用文档直链:pdf/doc/docx/xls/xlsx/ppt/pptx/txt
const viewGuideline = (item) => {
console.log('查看指南:', item)
// 跳转到指南详情页或预览页
uni.navigateTo({
url: `/pages_app/zhinanDetail/zhinanDetail?uuid=${item.uuid}&title=${encodeURIComponent(item.title)}`
})
const url = docUrl+item.path
if (url) {
const isPDF = /\.(pdf)(\?|$)/i.test(url)
const isOffice = /\.(docx?|xlsx?|pptx?)(\?|$)/i.test(url)
const isText = /\.(txt)(\?|$)/i.test(url)
// H5 端
// #ifdef H5
if (isPDF) {
try { window.open(url, '_blank') } catch (e) {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
}
return
}
if (isOffice) {
const officeUrl = `https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`
try { window.open(officeUrl, '_blank') } catch (e) {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(officeUrl)}` })
}
return
}
if (isText) {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
return
}
// 其他格式统一用 webview 打开
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
return
// #endif
// 非 H5 端:下载后尝试用 openDocument,失败回退 webview
// #ifndef H5
uni.showToast({ title: '正在打开...', icon: 'none' })
uni.downloadFile({
url,
success: (res) => {
if (res.statusCode === 200 && res.tempFilePath) {
uni.openDocument({
filePath: res.tempFilePath,
showMenu: true,
success: () => {},
fail: () => {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
}
})
} else {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
}
},
fail: () => {
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encodeURIComponent(url)}` })
}
})
return
// #endif
}
// 无直链,回退到详情页
}
// 返回上一页
@@ -350,16 +481,126 @@ $text-light: #999;
$border-color: #e0e0e0;
$bg-color: #f6f6f6;
$white: #ffffff;
.imgbox{
width: 32rpx;
margin-top: -10rpx;
}
.popup-panel {
position: fixed;
top: 256rpx; /* 紧贴筛选栏 */
left: 0;
right: 0;
background: #fff;
z-index: 100;
box-shadow: 0 6rpx 20rpx rgba(0,0,0,0.08);
}
.popup-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 28rpx 30rpx;
font-size: 30rpx;
color: #333;
}
.popup-divider {
height: 2rpx;
background: #eaeaea;
}
.popup-item.active .item-text {
color: #8B2316;
}
.current-sort {
display: flex;
align-items: center;
gap: 10rpx;
.sort-text {
font-size: 28rpx;
color: #333;
}
.sort-icon.up {
width: 0;
height: 0;
border-left: 8rpx solid transparent;
border-right: 8rpx solid transparent;
border-bottom: 12rpx solid #999;
&.active {
border-bottom-color: #ff0000;
}
}
}
.zhinan-list-page {
background-color: $bg-color;
height: 100vh;
}
.guidelines-scroll-view {
position: fixed;
top: 242rpx;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
height: calc(100vh - 140rpx);
background-color: $bg-color;
}
// 固定搜索容器
.search-container-fixed {
position: fixed;
top: 140rpx; // 导航栏高度
left: 0;
right: 0;
z-index: 90;
display: flex;
align-items: center;
justify-content: center;
padding: 30rpx 30rpx;
background-color: $white;
gap: 20rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
// 筛选栏
.filter-bar {
background-color: $white;
display: flex;
align-items: center;
border-bottom: 2px solid #eee;
.search-box {
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
.search-text {
font-size: 14px;
color:#999;
}
}
.divider {
width: 1px;
height: 16px;
background-color: #999;
margin: 0 60rpx;
}
.filter-item {
flex:1;
display: flex;
align-items: center;
justify-content: center;
gap: 3px;
font-size: 14px;
color: #999;
}
}
// 指南列表
.guidelines-list {