first commit

This commit is contained in:
zoujiandong 2025-08-14 17:02:24 +08:00
commit 2903884922
160 changed files with 8678 additions and 0 deletions

34
.gitignore vendored Normal file
View File

@ -0,0 +1,34 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
yarn.lock
node_modules
uni_modules
unpackage
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# node_modules
node_modules
package-lock.json
package-lock.json
components.d.ts

53
App.vue Normal file
View File

@ -0,0 +1,53 @@
<script>
export default {
onLaunch: function() {
console.warn('当前组件仅支持 uni_modules 目录结构 ,请升级 HBuilderX 到 3.1.0 版本以上!')
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style lang="scss">
/*每个页面公共css */
@import '@/uni_modules/uni-scss/index.scss';
/* #ifndef APP-NVUE */
@import '@/static/customicons.css';
//
page {
background-color: #f5f5f5;
}
/* #endif */
.uni-nav-bar-text{
font-weight: bold;
font-size: 34rpx!important;
}
.example-info {
font-size: 14px;
color: #333;
padding: 10px;
}
.twoline{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.oneline{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.uni-navbar .uniui-left{
font-weight: bold;
font-size: 50rpx!important;
}
</style>

27
api/api.js Normal file
View File

@ -0,0 +1,27 @@
import {request} from '@/utils/request.js'
const api = {
wxLogin(data) {
return request('/login/wechat/mobile', data, 'post', true);
},
mobileLogin(data) {
return request('/login/mobile', data, 'post', true);
},
getCode(data) {
return request('/code/phone', data, 'post', true);
},
// 视频相关API
getVideoList(data) {
return request('/video/list', data, 'get', true);
},
getVideoDetail(data) {
return request('/video/detail', data, 'get', true);
},
getBannerVideo(data) {
return request('/video/banner', data, 'get', true);
},
}
export default api

367
compoents/tabBar/tabBar.vue Normal file
View File

@ -0,0 +1,367 @@
<template>
<view class="custom-tabbar">
<view
class="tabbar-item"
v-for="(item, index) in tabList"
:key="index"
@click="switchTab(index, item)"
:class="{ active: currentTab === index }"
>
<!-- 图标容器 -->
<view class="icon-container">
<!-- <uni-icons
:type="currentTab === index ? item.activeIcon : item.icon"
:size="currentTab === index ? 28 : 24"
:color="currentTab === index ? item.activeColor : item.color"
></uni-icons> -->
<image class="img" :src="currentTab === index ? item.activeIcon : item.icon" alt="" />
<!-- 徽章 -->
<view class="badge" v-if="item.badge && item.badge > 0">
<uni-badge
:text="item.badge > 99 ? '99+' : item.badge.toString()"
type="error"
size="small"
></uni-badge>
</view>
<!-- 红点 -->
<view class="red-dot" v-if="item.showRedDot"></view>
</view>
<!-- 文字 -->
<text class="tab-text" :class="{ active: currentTab === index }">
{{ item.text }}
</text>
<!-- 动画效果 -->
<!-- <view class="active-indicator" v-if="currentTab === index"></view> -->
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import home from '@/static/home_nor.png'
import homeOn from '@/static/home_sel.png'
import classroom from "@/static/classroom.png"
import classroomOn from "@/static/classroomOn.png"
import live from "@/static/live.png"
import liveOn from "@/static/liveOn.png"
import education from '@/static/education.png'
import educationOn from '@/static/educationOn.png'
import my from '@/static/my.png'
import myOn from '@/static/myOn.png'
// props
const props = defineProps({
// props
});
// emits
const emit = defineEmits(['tabChange']);
// tab
const currentTab = ref(0);
// tabbar
const tabList = reactive([
{
icon: home,
activeIcon: homeOn,
text: '首页',
color: '#999999',
activeColor: '#007aff',
badge: 0,
showRedDot: false,
pagePath: '/pages/index/index'
},
{
icon: classroom,
activeIcon: classroomOn,
text: '患教学堂',
color: '#999999',
activeColor: '#007aff',
badge: 5,
showRedDot: false,
pagePath: '/pages/education/education'
},
{
icon: live,
activeIcon: liveOn,
text: '会议·直播',
color: '#999999',
activeColor: '#007aff',
badge: 0,
showRedDot: true,
pagePath: '/pages/meeting/meeting'
},
{
icon: education,
activeIcon:educationOn,
text: '继续教育',
color: '#999999',
activeColor: '#007aff',
badge: 12,
showRedDot: false,
pagePath: '/pages/education/continuing'
},
{
icon: my,
activeIcon: myOn,
text: '我的',
color: '#999999',
activeColor: '#007aff',
badge: 0,
showRedDot: false,
pagePath: '/pages/profile/profile'
}
]);
// tab
const switchTab = (index, item) => {
if (currentTab.value === index) return;
// tab
currentTab.value = index;
//
if (item.showRedDot) {
item.showRedDot = false;
}
//
uni.switchTab({
url: item.pagePath,
fail: () => {
// 使navigateTo
uni.navigateTo({
url: item.pagePath,
fail: () => {
uni.showToast({
title: '页面开发中',
icon: 'none'
});
}
});
}
});
//
emit('tabChange', {
index,
item
});
};
//
const setBadge = (index, count) => {
if (index >= 0 && index < tabList.length) {
tabList[index].badge = count;
}
};
//
const showRedDot = (index) => {
if (index >= 0 && index < tabList.length) {
tabList[index].showRedDot = true;
}
};
//
const hideRedDot = (index) => {
if (index >= 0 && index < tabList.length) {
tabList[index].showRedDot = false;
}
};
// tab
const setCurrentTab = (index) => {
if (index >= 0 && index < tabList.length) {
currentTab.value = index;
}
};
// tab
const getCurrentTab = () => {
return {
index: currentTab.value,
item: tabList[currentTab.value]
};
};
// tabbar
const updateTabList = (newTabList) => {
if (Array.isArray(newTabList)) {
tabList.splice(0, tabList.length, ...newTabList);
}
};
//
defineExpose({
setBadge,
showRedDot,
hideRedDot,
setCurrentTab,
getCurrentTab,
updateTabList,
currentTab,
tabList
});
//
onLoad(() => {
nextTick(() => {
const pages = getCurrentPages();
const currentPage = pages[pages.length - 1];
const currentPath = '/' + currentPage.route;
// tab
const tabIndex = tabList.findIndex(item => item.pagePath === currentPath);
if (tabIndex !== -1) {
currentTab.value = tabIndex;
}
});
});
//
onShow(() => {
//
console.log('Tabbar onShow - 当前tab:', currentTab.value);
});
//
onMounted(() => {
console.log('Tabbar组件已挂载');
});
</script>
<style scoped>
.custom-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
overflow-x: hidden;
height: 120rpx;
background-color: #ffffff;
display: flex;
justify-content: space-around;
align-items: center;
border-top: 2rpx solid #f0f0f0;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.1);
z-index: 999;
padding-bottom: env(safe-area-inset-bottom);
}
.tabbar-item {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
height: 100%;
transition: all 0.3s ease;
}
.img{
width: 46rpx;
height: 46rpx;
}
.icon-container {
width:100%;
overflow-x: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 8rpx;
}
.badge {
position: absolute;
top: -8rpx;
right: -8rpx;
z-index: 10;
}
.red-dot {
position: absolute;
top: -4rpx;
right: -4rpx;
width: 16rpx;
height: 16rpx;
background-color: #ff0000;
border-radius: 50%;
border: 2rpx solid #ffffff;
z-index: 10;
}
.tab-text {
font-size: 20rpx;
color: #999999;
transition: all 0.3s ease;
font-weight: 400;
}
.tab-text.active {
color: #8B2316;
font-weight: 600;
transform: scale(1.05);
}
.active-indicator {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 40rpx;
height: 4rpx;
background: linear-gradient(90deg, #007aff, #0056b3);
border-radius: 2rpx;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
width: 0;
opacity: 0;
}
to {
width: 40rpx;
opacity: 1;
}
}
/* 点击效果 */
.tabbar-item:active {
transform: scale(0.95);
}
/* 响应式设计 */
@media (max-width: 750rpx) {
.custom-tabbar {
height: 100rpx;
}
.tab-text {
font-size: 18rpx;
}
}
/* 深色模式支持 */
@media (prefers-color-scheme: dark) {
.custom-tabbar {
background-color: #1c1c1e;
border-top-color: #2c2c2e;
}
.tab-text {
color: #8e8e93;
}
.tab-text.active {
color: #0a84ff;
}
}
</style>

246
echart.html Normal file
View File

@ -0,0 +1,246 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>地图下钻</title>
<style>
:root {
--primary: #1890ff;
--primary-hover: #40a9ff;
--bg: #f4f8fb;
--radius: 18px;
--shadow: 0 4px 24px 0 rgba(24, 144, 255, 0.08);
}
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background: var(--bg);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.center-box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
}
.map-container {
width: 80vw;
max-width: 1200px;
height: 80vh;
min-height: 400px;
background: #fff;
border-radius: var(--radius);
box-shadow: var(--shadow);
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
transition: box-shadow 0.3s;
}
#main {
width: 100%;
height: 70%;
border-radius: var(--radius);
}
.btns {
position: absolute;
top: 32px;
left: 32px;
display: flex;
gap: 24px;
}
.btn {
padding: 10px 28px;
background-color: var(--primary);
color: #fff;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 16px;
font-weight: 500;
box-shadow: 0 2px 8px 0 rgba(24, 144, 255, 0.12);
transition: background 0.2s, transform 0.2s, box-shadow 0.2s;
z-index: 10;
}
.btn:hover {
background-color: var(--primary-hover);
transform: translateY(-2px) scale(1.04);
box-shadow: 0 4px 16px 0 rgba(24, 144, 255, 0.18);
}
@media (max-width: 900px) {
.map-container {
width: 98vw;
height: 70vh;
}
.btn {
top: 16px;
left: 16px;
padding: 8px 18px;
font-size: 14px;
}
}
@media (max-width: 600px) {
.map-container {
width: 100vw;
height: 60vh;
min-height: 220px;
}
.btn {
top: 8px;
left: 8px;
padding: 6px 10px;
font-size: 13px;
}
}
</style>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"
integrity="sha512-XSmbX3mhrD2ix5fXPTRQb2FwK22sRMVQTpBP2ac8hX7Dh/605hA2QDegVWiAvZPiXIxOV0CbkmUjGionDpbCmw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
</head>
<body>
<div class="center-box">
<div class="map-container">
<div id="main"></div>
<div class="btns">
<input
type="button"
class="btn"
onClick="reutrnUp()"
value="返回上一级"
/>
</div>
</div>
</div>
<script>
// 获取echartsDOM元素
const echartDOM = document.getElementById('main')
const chart = echarts.init(echartDOM)
let menus = [
{
adcode: 100000,
name: '全国'
}
]
/**
* @function 获取地区数据
* @param {number} adcode - 地区编码默认为100000全国
* */
const getGeoJson = async (adcode = 100000) => {
try {
const url = `https://geo.datav.aliyun.com/areas_v2/bound/${adcode}_full.json`
const result = await axios.get(url)
return result.data
} catch (err) {
return void 0
}
}
let option = null
const updateEcharts = async (adcode, name) => {
// 默认获取全国行政区数据
const geoJson = await getGeoJson(adcode)
if (!geoJson) {
throw new Error('已经是最后一级了')
}
// 注册地图
echarts.registerMap(name, geoJson)
// 设置地图配置项
option = {
title: {
text: name,
left: 'center'
},
series: [
{
type: 'map',
map: name,
itemStyle: {
areaColor: '#1890ff'
},
data: geoJson['features'].map((item) => {
return {
name: item.properties.name,
value: item.properties.adcode
}
})
}
]
}
}
// 下钻动画
const runAnimation = () => {
// 地图放大然后消失
option['animation'] = true
option['series'][0]['itemStyle']['opacity'] = 0
chart.setOption(option)
setTimeout(() => {
option['animation'] = false
option['series'][0]['zoom'] = 0.1
option['series'][0]['itemStyle']['opacity'] = 1
chart.setOption(option)
}, 300)
setTimeout(() => {
option['animation'] = true
option['series'][0]['zoom'] = 1
chart.setOption(option)
}, 600)
}
// 返回上一级
const reutrnUp = async () => {
if (menus.length > 1) {
menus.pop()
const { adcode, name } = menus[menus.length - 1]
await updateEcharts(adcode, name)
runAnimation()
} else {
menus = [
{
adcode: 100000,
name: '全国'
}
]
await updateEcharts(100000, '全国')
runAnimation()
alert('已经是最开始一级了。')
}
}
;(async () => {
await updateEcharts(100000, '全国')
// 设置图表配置项
chart.setOption(option)
// 点击行政区的时候,重新加载这个行政区的数据
chart.on('click', async (params) => {
const { value, name } = params.data
if (value) {
try {
await updateEcharts(value, name)
runAnimation()
menus.push({
adcode: value,
name
})
} catch (err) {
alert(err.message)
}
}
})
})()
</script>
</body>
</html>

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

34
main.js Normal file
View File

@ -0,0 +1,34 @@
import App from './App'
import uviewPlus, { setConfig } from 'uview-plus'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(uviewPlus, async() => {
return {
options: {
// 修改$u.config对象的属性
config: {
// 修改默认单位为rpx相当于执行 uni.$u.config.unit = 'rpx'
unit: 'rpx'
}
}
}
})
return {
app
}
}
// #endif

66
manifest.json Normal file
View File

@ -0,0 +1,66 @@
{
"name" : "uniapp",
"appid" : "__UNI__34144D0",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
/* 5+App */
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"nvueStyleCompiler" : "uni-app",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {
"OAuth" : {}
},
/* */
"distribute" : {
/* */
"android" : {
/* android */
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
/* ios */
"sdkConfigs" : {
"oauth" : {
"univerify" : {}
}
}
}
},
/* SDK */
"quickapp" : {},
/* */
"mp-weixin" : {
/* */
"appid" : "wx061c1f4e16a5f20f",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"vueVersion" : "3"
}

17
package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "uniapp",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"dev": "cross-env NODE_ENV=development uniapp-cli build --watch",
"test": "cross-env NODE_ENV=test uniapp-cli build",
"prod": "cross-env NODE_ENV=production uniapp-cli build"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"uview-plus": "^3.4.73"
}
}

158
pages.json Normal file
View File

@ -0,0 +1,158 @@
{
"easycom": {
"autoscan": true,
// customhttps://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "@/node_modules/uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "@/node_modules/uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "@/node_modules/uview-plus/components/u-$1/u-$1.vue"
}
},
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"app": {
"bounce": "none"
}
}
},
{
"path": "pages/patientClass/patientClass",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "pages/live/live",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "pages/education/education",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "pages/my/my",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
}
],
"subPackages": [{
"root": "pages_app",
"pages": [
{
"path": "search/search",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "login/login",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "video/video",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "zhinan/zhinan",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "qikan/qikan",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "smsLogin/smsLogin",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "pwdLogin/pwdLogin",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
}
]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"app-plus": {
"background": "#efeff4"
}
},
"condition" : { //
"current": 0, //(list )
"list": [
{
"name": "", //
"path": "pages_app/login/login", //
"query": "" //onLoad
}
]
}
}

View File

@ -0,0 +1,287 @@
<template>
<uni-nav-bar title="继续教育" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="page">
<!-- 课程列表 -->
<view class="course-list">
<!-- 肝胆精品课 -->
<view class="course-item" @click="goToCourse('hepatoBiliary')">
<up-image :src="course" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">肝胆精品课</view>
<view class="course-subtitle">肝胆精品课筑梦·医路成长</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 肝胆视频 -->
<view class="course-item" @click="goToCourse('hepatoBiliaryVideo')">
<up-image :src="videoImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">肝胆视频</view>
<view class="course-subtitle">数千集精彩报告等您来看</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 肝胆课件 -->
<view class="course-item" @click="goToCourse('hepatoBiliaryCourseware')">
<up-image :src="pptImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">肝胆课件</view>
<view class="course-subtitle">国内专业优质肝胆课件共享平台</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 病例讨论 -->
<view class="course-item" @click="goToCourse('caseDiscussion')">
<up-image :src="talkImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">病例讨论</view>
<view class="course-subtitle">互帮互助病例共讨</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 病例荟萃 -->
<view class="course-item" @click="goToCourse('caseCollection')">
<up-image :src="huicuiImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">病例荟萃</view>
<view class="course-subtitle">一线专家临床总结</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 现代肝病学院 -->
<view class="course-item" @click="goToCourse('modernHepatology')">
<up-image :src="xueyuanImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">现代肝病学院</view>
<view class="course-subtitle">一期一关注绝对收获满满</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
<!-- 新手教程 -->
<view class="course-item" @click="goToCourse('tutorial')">
<up-image :src="newerImg" width="94rpx" height="94rpx" ></up-image>
<view class="course-content">
<view class="course-title">新手教程</view>
<view class="course-subtitle">手把手助您用好专家工作室</view>
</view>
<view class="course-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
</view>
</view>
<CustomTabbar></CustomTabbar>
</template>
<script setup>
import CustomTabbar from '@/compoents/tabBar/tabBar.vue';
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import course from "@/static/jingpinkecheng.png"
import videoImg from "@/static/gandanshipin.png"
import pptImg from "@/static/gandankejian.png"
import talkImg from "@/static/bibglijiaoliu.png"
import huicuiImg from "@/static/jingdianbingli.png"
import xueyuanImg from "@/static/ganbingxueyuan.png"
import newerImg from "@/static/xinshoujiaocheng.png"
//
//
const goToCourse = (courseType) => {
console.log('进入课程:', courseType);
//
switch(courseType) {
case 'hepatoBiliary':
uni.showToast({
title: '肝胆精品课功能开发中',
icon: 'none'
});
break;
case 'hepatoBiliaryVideo':
uni.showToast({
title: '肝胆视频功能开发中',
icon: 'none'
});
break;
case 'hepatoBiliaryCourseware':
uni.showToast({
title: '肝胆课件功能开发中',
icon: 'none'
});
break;
case 'caseDiscussion':
uni.showToast({
title: '病例讨论功能开发中',
icon: 'none'
});
break;
case 'caseCollection':
uni.showToast({
title: '病例荟萃功能开发中',
icon: 'none'
});
break;
case 'modernHepatology':
uni.showToast({
title: '现代肝病学院功能开发中',
icon: 'none'
});
break;
case 'tutorial':
uni.showToast({
title: '新手教程功能开发中',
icon: 'none'
});
break;
default:
uni.showToast({
title: '功能开发中',
icon: 'none'
});
}
};
onShow(() => {
console.log('继续教育页面显示');
});
</script>
<style lang="scss" scoped>
//
$primary-color: #ff6b6b;
$theme-color: #8B2316;
$white: #fff;
$gray-bg: #f5f5f5;
$gray-light: #eee;
$gray-medium: #999;
$gray-dark: #666;
$text-color: #333;
//
$green-color: #00D4AA;
$yellow-color: #FFB800;
$orange-color: #FF8C00;
$green-chat-color: #52C41A;
$purple-color: #B37FEB;
$blue-color: #40A9FF;
$orange-tutorial-color: #FF7A45;
//
$border-radius: 8px;
$border-radius-small: 6px;
$padding: 15px;
$padding-small: 10px;
.page {
background-color: $gray-bg;
min-height: calc(100vh - 140rpx);
padding-bottom: 120rpx;
}
//
.course-list {
padding: 20rpx;
.course-item {
background-color: $white;
border-radius: $border-radius;
margin-bottom: 20rpx;
padding: 30rpx;
display: flex;
align-items: center;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
.course-icon {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 30rpx;
&.green {
background-color: $green-color;
}
&.yellow {
background-color: $yellow-color;
}
&.orange {
background-color: $orange-color;
}
&.green-chat {
background-color: $green-chat-color;
}
&.purple {
background-color: $purple-color;
}
&.blue {
background-color: $blue-color;
}
&.orange-tutorial {
background-color: $orange-tutorial-color;
}
}
.course-content {
flex: 1;
margin-left: 20rpx;
display: flex;
flex-direction: column;
gap: 8rpx;
.course-title {
font-size: 32rpx;
color: $text-color;
font-weight: 600;
line-height: 1.3;
}
.course-subtitle {
font-size: 26rpx;
color: $gray-medium;
line-height: 1.4;
}
}
.course-arrow {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
//
&:active {
opacity: 0.8;
transform: scale(0.98);
}
}
}
</style>

1461
pages/index/index.vue Normal file

File diff suppressed because it is too large Load Diff

807
pages/live/live.vue Normal file
View File

@ -0,0 +1,807 @@
<template>
<uni-nav-bar title="肝胆会议" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="page">
<!-- 筛选标签栏 -->
<view class="filter-bar">
<view class="filter-item active" @click="showTimePopup">
<text>会议时间</text>
<up-image :src="select" width="26rpx" height="26rpx" ></up-image>
</view>
<view class="filter-divider"></view>
<view class="filter-item" @click="showLocationPopup">
<text>会议地点</text>
<up-image :src="select" width="26rpx" height="26rpx" ></up-image>
</view>
<view class="filter-divider"></view>
<view class="filter-item">
<text>会议回放</text>
</view>
</view>
<!-- 可滚动内容区域 -->
<scroll-view
ref="scrollView"
class="scroll-content"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
:refresher-threshold="100"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
:lower-threshold="100"
:scroll-top="scrollTop"
:enable-back-to-top="true"
>
<!-- 时间标题 -->
<view class="time-header">2025年08月</view>
<!-- 会议列表 -->
<view class="meeting-list">
<view class="meeting-item" v-for="(item, index) in meetingList" :key="index">
<!-- 左侧日期标识 -->
<view class="date-tag" :style="{backgroundColor: item.tagColor}">
<text class="date-text">{{ item.date }}</text>
</view>
<!-- 会议内容 -->
<view class="meeting-content">
<view class="meeting-title">{{ item.title }}</view>
<view class="meeting-poster" @click="playVideo(item)">
<image :src="item.poster" class="poster-image"></image>
<view class="play-btn">
<up-image :src="playImg" width="108rpx" height="108rpx" ></up-image>
</view>
<view class="preview-tag">预告</view>
</view>
<view class="meeting-info">
<view class="info-item">
<view class="timebox">
<up-image :src="timeImg" width="24rpx" height="24rpx" ></up-image>
</view>
<text class="info-text">{{ item.time }}</text>
</view>
<view class="info-item">
<uni-icons type="location" size="14" color="#999"></uni-icons>
<text class="info-text">{{ item.location }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 加载更多提示 -->
<view class="load-more" v-if="showLoadMore">
<view class="load-more-content" v-if="isLoadingMore">
<uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
<text class="load-more-text">加载中...</text>
</view>
<view class="load-more-content" v-else-if="hasMoreData">
<text class="load-more-text">上拉加载更多</text>
</view>
<view class="load-more-content" v-else>
<text class="load-more-text">没有更多数据了</text>
</view>
</view>
</scroll-view>
<!-- 时间选择弹窗 -->
<view class="time-popup" v-if="isTimePopupShow" @click="hideTimePopup">
<view class="popup-mask"></view>
<view class="time-popup-content" @click.stop>
<view class="time-list">
<view
class="time-item"
v-for="(month, index) in monthList"
:key="index"
:class="{ active: selectedMonth === month.value }"
@click="selectMonth(month)"
>
<text>{{ month.label }}</text>
</view>
</view>
</view>
</view>
<!-- 地区选择弹窗 -->
<view class="location-popup" v-if="isLocationPopupShow" @click="hideLocationPopup">
<view class="popup-mask"></view>
<view class="popup-content" @click.stop>
<view class="location-grid">
<view
class="location-item"
v-for="(province, index) in provinceList"
:key="index"
:class="{ active: selectedProvince === province.code }"
@click="selectProvince(province)"
>
<text>{{ province.name }}</text>
</view>
</view>
</view>
</view>
<!-- 过往会议提示 -->
<view class="history-tip">
<view class="tip-icon">
<up-icon name="clock" color="#00cbc0" size="28"></up-icon>
</view>
<text class="tip-text">过往会议</text>
</view>
<!-- 底部导航栏 -->
<CustomTabbar></CustomTabbar>
</view>
</template>
<script setup>
import { ref,nextTick} from 'vue';
import { onShow } from "@dcloudio/uni-app";
import CustomTabbar from '@/compoents/tabBar/tabBar.vue';
import select from "@/static/triangle_normal.png"
import selectOn from "@/static/triangle_normal.png"
import playImg from "@/static/bofang.png"
import timeImg from "@/static/play_long.png"
//
const isTimePopupShow = ref(false);
const isLocationPopupShow = ref(false);
const selectedMonth = ref('all');
const selectedProvince = ref('');
//
const isRefreshing = ref(false);
const isLoadingMore = ref(false);
const hasMoreData = ref(true);
const showLoadMore = ref(true);
const currentPage = ref(1);
const pageSize = ref(10);
const scrollTop = ref(0);
//
const monthList = ref([
{ value: 'all', label: '所有' },
{ value: '8', label: '8月' },
{ value: '9', label: '9月' },
{ value: '10', label: '10月' },
{ value: '11', label: '11月' },
{ value: '12', label: '12月' },
{ value: '1', label: '1月' },
{ value: '2', label: '2月' },
{ value: '3', label: '3月' },
{ value: '4', label: '4月' },
{ value: '5', label: '5月' },
{ value: '6', label: '6月' },
{ value: '7', label: '7月' }
]);
//
const provinceList = ref([
{ code: 'all', name: '全国' },
{ code: 'beijing', name: '北京市' },
{ code: 'tianjin', name: '天津市' },
{ code: 'hebei', name: '河北省' },
{ code: 'shanxi', name: '山西省' },
{ code: 'neimenggu', name: '内蒙古...' },
{ code: 'liaoning', name: '辽宁省' },
{ code: 'jilin', name: '吉林省' },
{ code: 'heilongjiang', name: '黑龙江省' },
{ code: 'shanghai', name: '上海市' },
{ code: 'jiangsu', name: '江苏省' },
{ code: 'zhejiang', name: '浙江省' },
{ code: 'anhui', name: '安徽省' },
{ code: 'fujian', name: '福建省' },
{ code: 'jiangxi', name: '江西省' },
{ code: 'shandong', name: '山东省' },
{ code: 'henan', name: '河南省' },
{ code: 'hubei', name: '湖北省' },
{ code: 'hunan', name: '湖南省' },
{ code: 'guangdong', name: '广东省' },
{ code: 'guangxi', name: '广西壮...' },
{ code: 'hainan', name: '海南省' },
{ code: 'chongqing', name: '重庆市' },
{ code: 'sichuan', name: '四川省' },
{ code: 'guizhou', name: '贵州省' },
{ code: 'yunnan', name: '云南省' },
{ code: 'xizang', name: '西藏自...' },
{ code: 'shaanxi', name: '陕西省' },
{ code: 'gansu', name: '甘肃省' },
{ code: 'qinghai', name: '青海省' },
{ code: 'ningxia', name: '宁夏回...' },
{ code: 'xinjiang', name: '新疆维...' },
{ code: 'taiwan', name: '台湾省' },
{ code: 'hongkong', name: '香港特...' },
{ code: 'macao', name: '澳门特...' }
]);
//
const meetingList = ref([
{
date: '13',
tagColor: '#FF4444',
title: '"天山论·见"—疑难危重病患维训练营',
poster: '/static/meeting-poster-1.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '13',
tagColor: '#FFA500',
title: '护肝新声大咖谈',
poster: '/static/meeting-poster-2.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '15',
tagColor: '#00BCD4',
title: '小罐医生讲HIV和感染专题二:抗菌药物-抗真菌药物特性解读',
poster: '/static/meeting-poster-3.jpg',
time: '2025.08.15',
location: '线上'
}
]);
//
const showTimePopup = () => {
isTimePopupShow.value = !isTimePopupShow.value;
};
//
const hideTimePopup = () => {
isTimePopupShow.value = false;
};
//
const selectMonth = (month) => {
selectedMonth.value = month.value;
console.log('选择月份:', month.label);
//
hideTimePopup();
};
//
const showLocationPopup = () => {
isLocationPopupShow.value = !isLocationPopupShow.value;
};
//
const hideLocationPopup = () => {
isLocationPopupShow.value = false;
};
//
const selectProvince = (province) => {
selectedProvince.value = province.code;
console.log('选择省份:', province.name);
//
hideLocationPopup();
};
//
const playVideo = (item) => {
console.log('播放视频:', item.title);
//
};
//
const onRefresh = () => {
isRefreshing.value = true;
currentPage.value = 1;
hasMoreData.value = true;
//
setTimeout(() => {
//
meetingList.value = [
{
date: '13',
tagColor: '#FF4444',
title: '"天山论·见"—疑难危重病患维训练营',
poster: '/static/meeting-poster-1.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '13',
tagColor: '#FFA500',
title: '护肝新声大咖谈',
poster: '/static/meeting-poster-2.jpg',
time: '2025.08.13',
location: '线上'
},
{
date: '15',
tagColor: '#00BCD4',
title: '小罐医生讲HIV和感染专题二:抗菌药物-抗真菌药物特性解读',
poster: '/static/meeting-poster-3.jpg',
time: '2025.08.15',
location: '线上'
}
];
isRefreshing.value = false;
uni.showToast({
title: '刷新成功',
icon: 'success',
duration: 1500
});
}, 1500);
};
//
const onLoadMore = () => {
console.log('上拉加载');
if (isLoadingMore.value || !hasMoreData.value) return;
isLoadingMore.value = true;
currentPage.value++;
//
setTimeout(() => {
//
const newMeetings = [
{
date: '16',
tagColor: '#9C27B0',
title: '肝胆外科微创技术研讨会',
poster: '/static/meeting-poster-4.jpg',
time: '2025.08.16',
location: '北京'
},
{
date: '17',
tagColor: '#FF9800',
title: '胆囊疾病诊疗新进展',
poster: '/static/meeting-poster-5.jpg',
time: '2025.08.17',
location: '上海'
},
{
date: '18',
tagColor: '#4CAF50',
title: '肝移植术后管理专题讲座',
poster: '/static/meeting-poster-6.jpg',
time: '2025.08.18',
location: '广州'
}
];
meetingList.value.push(...newMeetings);
// 3
if (currentPage.value >= 3) {
hasMoreData.value = false;
}
isLoadingMore.value = false;
// scroll-view
nextTick(() => {
console.log('数据加载完成,列表长度:', meetingList.value.length);
});
}, 1000);
};
</script>
<style lang="scss" scoped>
//
$primary-color: #D32F2F;
$secondary-color: #8B2316;
$background-color: #f5f5f5;
$white: #ffffff;
$gray-light: #f0f0f0;
$gray: #666;
$gray-dark: #333;
$gray-text: #999;
$border-color: #e0e0e0;
$green-accent: #00D4AA;
$shadow: 0 2px 8px rgba(0,0,0,0.1);
.page {
background-color: $background-color;
min-height: 100vh;
padding-bottom: 120rpx;
}
//
.scroll-content {
position: fixed;
top: 228rpx; // 140rpx + 88rpx
left: 0;
right: 0;
bottom: 120rpx; //
width: 100%;
}
//
.filter-bar {
position:fixed ;
top:140rpx;
width:100%;
z-index:2;
background-color: $white;
height: 88rpx;
display: flex;
align-items: center;
padding: 0 30rpx;
border-bottom: 2rpx solid $gray-light;
.filter-item {
flex:1;
display: flex;
align-items: center;
padding: 0 20rpx;
font-size: 28rpx;
color: $gray;
text{
margin-right: 10rpx;
}
&.active {
color: $gray-dark;
}
}
.filter-divider {
width: 2rpx;
height: 32rpx;
background-color: $border-color;
margin: 0 10rpx;
}
}
//
.time-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
.popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.time-popup-content {
margin-top: 231rpx;
position: relative;
background-color: $white;
width: 100%;
height: calc(100vh - 348rpx);
.time-list {
padding: 0;
height: 100%;
overflow-y: auto;
.time-item {
padding: 25rpx 60rpx;
font-size: 32rpx;
color: #666;
border-bottom: 2rpx solid #f0f0f0;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
&:hover {
background-color: #f8f8f8;
}
&.active {
background-color: #f8f8f8;
color: $primary-color;
text {
font-weight: 500;
}
}
&:last-child {
border-bottom: none;
}
text {
display: block;
width: 100%;
}
}
}
}
}
//
.location-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
.popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.popup-content {
margin-top: 231rpx;
position: relative;
background-color: $white;
width: 100%;
height: calc(100vh - 433rpx);
padding:40rpx;
.popup-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.popup-title {
font-size: 18px;
font-weight: 500;
color: $gray-dark;
}
.close-btn {
width: 30px;
height: 30px;
background-color: $gray-light;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
color: $gray;
cursor: pointer;
}
}
.location-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30rpx;
height: 100%;
overflow-y: auto;
.location-item {
padding: 16rpx;
background-color: $background-color;
border-radius: 16rpx;
text-align: center;
font-size: 28rpx;
color: #999;
border: 2rpx solid #999;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
background-color: lighten($primary-color, 45%);
}
&.active {
background-color: lighten($primary-color, 40%);
border-color: $primary-color;
color: $primary-color;
}
text {
display: block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
}
}
}
}
}
//
.time-header {
text-align: center;
padding: 30rpx 0;
font-size: 32rpx;
color: $gray;
background-color: $background-color;
}
//
.meeting-list {
padding: 0 30rpx;
.meeting-item {
display: flex;
margin-bottom: 30rpx;
background-color: $white;
border-radius: 16rpx;
overflow: hidden;
box-shadow: $shadow;
//
.date-tag {
width: 50rpx;
display: flex;
align-items: center;
justify-content: center;
position:relative;
.date-text {
background: $white;
position:absolute;
top:50%;
color:red;
transform:translateY(-50%);
font-size: 32rpx;
width:40rpx;
display: flex;
justify-content: center;
align-items: center;
left: 35rpx;
height: 40rpx;
border-radius:50%;
}
}
//
.meeting-content {
flex: 1;
padding: 30rpx;
.meeting-title {
font-size: 32rpx;
font-weight: 500;
color: $gray-dark;
margin-bottom: 20rpx;
line-height: 1.4;
}
.meeting-poster {
position: relative;
height: 240rpx;
border-radius: 12rpx;
overflow: hidden;
margin-bottom: 20rpx;
.poster-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.play-btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width:210rpx;
height:210rpx;
opacity: 0.3;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.preview-tag {
position: absolute;
top: 16rpx;
right: 16rpx;
border: 4rpx solid #fff;
color: $white;
font-size: 24rpx;
padding: 4rpx 16rpx;
border-radius: 20rpx;
}
}
.meeting-info {
display: flex;
justify-content: space-between;
.info-item {
display: flex;
align-items: center;
.timebox{
margin-top: -19rpx;
}
.info-text {
font-size: 24rpx;
color: $gray-text;
margin-left: 8rpx;
}
}
}
}
}
}
//
.load-more {
padding: 30rpx;
.load-more-content {
display: flex;
align-items: center;
justify-content: center;
.load-more-text {
font-size: 28rpx;
color: $gray-text;
margin-left: 10rpx;
}
}
}
//
.history-tip {
position: fixed;
bottom:200rpx;
z-index:9;
right:0;
border-radius: 50rpx 0 0 50rpx;
background:#00cbc0;
display: flex;
align-items: center;
justify-content: center;
padding: 10rpx 10rpx;
.tip-icon {
padding:10rpx;
background-color: #fff;
margin-right: 10rpx;
border-radius: 50%;
}
.tip-text {
width: 60rpx;
font-size: 26rpx;
color:#fff;
}
}
//
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 60px;
background-color: $white;
display: flex;
border-top: 1px solid $gray-light;
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 5px 0;
.nav-text {
font-size: 10px;
color: $gray-text;
margin-top: 2px;
&.active {
color: $primary-color;
}
}
}
}
</style>

632
pages/my/my.vue Normal file
View File

@ -0,0 +1,632 @@
<template>
<uni-nav-bar title="我的" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="page">
<!-- 用户信息卡片 -->
<view class="user-card">
<view class="user-info">
<image class="avatar" src="/static/avatar_default.png" mode="aspectFill"></image>
<text class="username">邹建东</text>
</view>
<!-- 统计数据 -->
<view class="stats-section">
<view class="stats-item">
<text class="stats-number">5</text>
<text class="stats-label">随访患者数</text>
</view>
<view class="stats-item">
<text class="stats-number">0</text>
<text class="stats-label">公益咨询数</text>
</view>
<view class="stats-item">
<text class="stats-number">0</text>
<text class="stats-label">患者送花数</text>
</view>
<view class="divder"></view>
<view class="signbox">
<view class="sign">签到</view>
</view>
</view>
</view>
<!-- 随访服务 -->
<view class="section">
<view class="section-title">随访服务</view>
<up-scroll-list indicatorActiveColor="#8B2316" indicatorWidth="40rpx" indicatorBarWidth="20rpx" class="service-grid">
<view class="service-item" @click="goToPage('patientAudit')">
<up-image :src="hzshImg" width="48rpx" height="48rpx" ></up-image>
<text>患者审核</text>
</view>
<view class="service-item" @click="goToPage('patientGroup')">
<up-image :src="hzfzImg" width="48rpx" height="48rpx" ></up-image>
<text>患者分组</text>
</view>
<view class="service-item" @click="goToPage('groupMessage')">
<up-image :src="qfxxImg" width="48rpx" height="48rpx" ></up-image>
<text>群发消息</text>
</view>
<view class="service-item" @click="goToPage('qrcode')">
<up-image :src="sfImg" width="48rpx" height="48rpx" ></up-image>
<text>随访二维码</text>
</view>
<view class="service-item" @click="goToPage('qrcode')">
<up-image :src="czjhImg" width="48rpx" height="48rpx" ></up-image>
<text>出诊计划</text>
</view>
</up-scroll-list>
</view>
<!-- 学习进步 -->
<view class="section">
<view class="section-title">学习进步</view>
<view class="learning-grid">
<view class="learning-item" @click="goToPage('myVideos')">
<up-image :src="wdspImg" width="48rpx" height="48rpx" ></up-image>
<text>我的视频</text>
</view>
<view class="learning-item" @click="goToPage('myCourses')">
<up-image :src="wdkcImg" width="48rpx" height="48rpx" ></up-image>
<text>我的课程</text>
</view>
<view class="learning-item" @click="goToPage('myDownloads')">
<up-image :src="wdxzImg" width="48rpx" height="48rpx" ></up-image>
<text>我的下载</text>
</view>
<view class="learning-item" @click="goToPage('myFavorites')">
<up-image :src="wdscImg" width="48rpx" height="48rpx" ></up-image>
<text>我的收藏</text>
</view>
</view>
</view>
<!-- 账户明细 -->
<view class="section">
<view class="section-title">账户明细</view>
<up-scroll-list indicatorActiveColor="#8B2316" indicatorWidth="40rpx" indicatorBarWidth="20rpx" class="account-grid">
<view class="account-item" @click="goToPage('myAccount')">
<up-image :src="wdzzImg" width="48rpx" height="48rpx" ></up-image>
<text>我的账户</text>
</view>
<view class="account-item" @click="goToPage('myPoints')">
<up-image :src="wdjfImg" width="48rpx" height="48rpx" ></up-image>
<text>我的积分</text>
</view>
<view class="account-item" @click="goToPage('myBenefits')">
<up-image :src="wdflImg" width="48rpx" height="48rpx" ></up-image>
<text>我的福利</text>
</view>
<view class="account-item" @click="goToPage('myReviews')">
<up-image :src="wdxhImg" width="48rpx" height="48rpx" ></up-image>
<text>我的鲜花</text>
</view>
<view class="account-item" @click="goToPage('myReviews')">
<up-image :src="kjmxImg" width="48rpx" height="48rpx" ></up-image>
<text>课件明细</text>
</view>
<view class="account-item" @click="goToPage('myReviews')">
<up-image :src="kcmxImg" width="48rpx" height="48rpx" ></up-image>
<text>课程明细</text>
</view>
<view class="account-item" @click="goToPage('myReviews')">
<up-image :src="sxyImg" width="48rpx" height="48rpx" ></up-image>
<text>送心意</text>
</view>
</up-scroll-list>
</view>
<!-- 常用操作 -->
<view class="section">
<view class="section-title">常用操作</view>
<view class="operation-grid">
<view class="operation-item" @click="goToPage('wechatUnbind')">
<up-image :src="wxjbImg" width="48rpx" height="48rpx" ></up-image>
<text>微信解绑</text>
</view>
<view class="operation-item" @click="goToPage('changePhone')">
<up-image :src="ghsjhImg" width="48rpx" height="48rpx" ></up-image>
<text>更换手机号</text>
</view>
<view class="operation-item" @click="goToPage('notifications')">
<up-image :src="tzykImg" width="48rpx" height="48rpx" ></up-image>
<text>通知已开</text>
</view>
<view class="operation-item" @click="showVersion">
<up-image :src="versionImg" width="48rpx" height="48rpx" ></up-image>
<text>V4.1.4</text>
</view>
</view>
</view>
<view class="setbox">
<!-- 福利卡兑换 -->
<view class="sectioncell benefit-section">
<view class="benefit-item" @click="goToPage('benefitExchange')">
<view class="benefit-icon">
<up-image :src="fulicard" width="48rpx" height="48rpx"></up-image>
</view>
<view class="benefit-content">
<text class="benefit-title">福利卡兑换</text>
</view>
<view class="benefit-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
</view>
<!-- 发票管理 -->
<view class="sectioncell invoice-section">
<view class="invoice-item" @click="goToPage('invoiceManage')">
<view class="invoice-icon">
<up-image :src="fpgl" width="48rpx" height="48rpx"></up-image>
</view>
<view class="invoice-content">
<text class="invoice-title">发票管理</text>
</view>
<view class="invoice-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
</view>
<!-- 常用银行卡 -->
<view class="sectioncell bank-section">
<view class="bank-item" @click="goToPage('bankCard')">
<view class="bank-icon">
<up-image :src="cyyhk" width="48rpx" height="48rpx"></up-image>
</view>
<view class="bank-content">
<text class="bank-title">常用银行卡</text>
</view>
<view class="bank-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
</view>
<!-- 设置与帮助 -->
<view class="sectioncell settings-section">
<view class="settings-item" @click="goToPage('settings')">
<view class="settings-icon">
<up-image :src="settingImg" width="48rpx" height="48rpx"></up-image>
</view>
<view class="settings-content">
<text class="settings-title">设置与帮助</text>
</view>
<view class="settings-arrow">
<uni-icons type="forward" size="16" color="#ccc"></uni-icons>
</view>
</view>
</view>
</view>
<!-- 年度总结悬浮按钮 -->
<view class="year-summary-btn" @click="showYearSummary">
<view class="year-text">2024</view>
<view class="summary-text">年度总结</view>
</view>
<!-- 底部导航栏 -->
<CustomTabbar></CustomTabbar>
</view>
</template>
<script setup>
import CustomTabbar from '@/compoents/tabBar/tabBar.vue';
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import hzshImg from "@/static/hzsh.png"
import hzfzImg from "@/static/hzfz.png"
import qfxxImg from "@/static/qfxz.png"
import sfImg from "@/static/sfewm.png"
import czjhImg from "@/static/czjh.png"
import wdspImg from "@/static/wdsp.png"
import wdkcImg from "@/static/wdkc.png"
import wdxzImg from "@/static/wdxz.png"
import wdscImg from "@/static/wdsc.png"
import wdzzImg from "@/static/wdzh.png"
import wdjfImg from "@/static/wdjf.png"
import wdflImg from "@/static/wdfl.png"
import wdxhImg from "@/static/wdxh.png"
import kjmxImg from "@/static/kjmx.png"
import kcmxImg from "@/static/kcmx.png"
import sxyImg from "@/static/sxy.png"
import wxjbImg from "@/static/wxjb.png"
import ghsjhImg from "@/static/ghsjh.png"
import tzykImg from "@/static/xxtx.png"
import versionImg from "@/static/fxxbb.png"
import fulicard from "@/static/fulicard.png"
import fpgl from "@/static/fpgl.png"
import cyyhk from "@/static/cyhhk.png"
import settingImg from "@/static/setting.png"
//
const isLargeFont = ref(false);
//
const toggleFontSize = () => {
isLargeFont.value = !isLargeFont.value;
console.log('切换字体大小:', isLargeFont.value ? '大字版' : '普通版');
};
const checkin = () => {
console.log('签到');
uni.showToast({
title: '签到成功',
icon: 'success'
});
};
const goToPage = (page) => {
console.log('跳转到页面:', page);
//
switch(page) {
case 'index':
uni.switchTab({
url: '/pages/index/index'
});
break;
case 'patientClass':
uni.switchTab({
url: '/pages_app/patientClass/patientClass'
});
break;
case 'benefitExchange':
uni.showToast({
title: '福利卡兑换功能开发中',
icon: 'none'
});
break;
case 'invoiceManage':
uni.showToast({
title: '发票管理功能开发中',
icon: 'none'
});
break;
case 'bankCard':
uni.showToast({
title: '常用银行卡功能开发中',
icon: 'none'
});
break;
case 'settings':
uni.showToast({
title: '设置与帮助功能开发中',
icon: 'none'
});
break;
default:
uni.showToast({
title: '功能开发中',
icon: 'none'
});
}
};
const showYearSummary = () => {
console.log('显示年度总结');
uni.showToast({
title: '年度总结功能开发中',
icon: 'none'
});
};
const showVersion = () => {
uni.showModal({
title: '版本信息',
content: '当前版本V4.1.4',
showCancel: false
});
};
onShow(() => {
console.log('我的页面显示');
});
</script>
<style lang="scss" scoped>
//
$primary-color: #ff6b6b;
$theme-color: #8B2316;
$cyan-color: #00CED1;
$white: #fff;
$gray-bg: #f5f5f5;
$gray-light: #eee;
$gray-medium: #999;
$gray-dark: #666;
$text-color: #333;
//
$border-radius: 8px;
$border-radius-small: 6px;
$padding: 15px;
$padding-small: 10px;
.page {
background-color: $gray-bg;
height: calc(100vh - 140rpx);
overflow-y: scroll;
padding-bottom: 100rpx;
}
//
.user-card {
background: url('@/static/big_background_my.png') no-repeat 0 0;
height:310rpx;
padding:0 30rpx;
background-size: cover;
position: relative;
margin-bottom: 67rpx;
.user-info {
padding-top: 30rpx;
display: flex;
align-items: center;
gap: 20rpx;
margin-bottom: 40rpx;
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
}
.username {
color: $white;
font-size: 36rpx;
font-weight: bold;
}
}
.stats-section {
position: relative;
background-color: $white;
border-radius: $border-radius;
padding: 30rpx;
display: flex;
justify-content: space-around;
margin-bottom: 20rpx;
.divder{
width:2rpx;
height:50rpx;
margin-top: 32rpx;
margin-left:10rpx;
margin-right: 150rpx;
background-color: #999;
}
.signbox{
position:absolute;
right:0;
top:54rpx;
width:160rpx;
height: 56rpx;
display: flex;
align-items: center;
border-radius:30rpx 0 0 30rpx;
background:#fc564a url("@/static/qd1_bg.9.png")no-repeat 0 0;
background-size:57rpx 56rpx;
.sign{
margin-left: 60rpx;
font-size: 28rpx;
color:#fff;
}
}
.stats-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 10rpx;
.stats-number {
font-size: 48rpx;
color: $text-color;
}
.stats-label {
font-size: 24rpx;
color: $text-color;
}
}
}
.checkin-btn {
position: absolute;
top: 30rpx;
right: 30rpx;
background-color: $theme-color;
color: $white;
padding: 16rpx 24rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
gap: 8rpx;
font-size: 28rpx;
}
}
// section
.section {
background-color: $white;
margin: $padding-small;
border-radius: $border-radius;
padding: 26rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: $text-color;
margin-bottom: 30rpx;
}
}
//
.learning-grid,.operation-grid{
display: flex;
}
.service-item,
.learning-item,
.account-item,
.operation-item {
width: 130rpx;
display: flex;
flex-direction: column;
align-items: center;
gap: 16rpx;
padding: 20rpx;
text{
white-space: nowrap;
font-size: 26rpx;
color: $text-color;
text-align: center;
}
}
.setbox{
margin:0 26rpx;
border-radius:20rpx;
overflow: hidden;
background-color: #fff;
margin-bottom: 30rpx;
}
//
.benefit-section,
.invoice-section,
.bank-section,
.settings-section {
border-radius: $border-radius;
margin-bottom: 0;
padding: 0;
.benefit-item,
.invoice-item,
.bank-item,
.settings-item {
display: flex;
align-items: center;
padding: 14rpx;
background-color: $white;
border-bottom:2rpx solid #efefef;
.benefit-icon,
.invoice-icon,
.bank-icon,
.settings-icon {
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.benefit-content,
.invoice-content,
.bank-content,
.settings-content {
flex: 1;
.benefit-title,
.invoice-title,
.bank-title,
.settings-title {
font-size: 26rpx;
color: $text-color;
font-weight: 500;
}
}
.benefit-arrow,
.invoice-arrow,
.bank-arrow,
.settings-arrow {
width: 30rpx;
height: 30rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
}
//
.year-summary-btn {
position: fixed;
bottom: 200rpx;
right: 0rpx;
width: 150rpx;
height: 80rpx;
background: linear-gradient(135deg, $cyan-color 0%, #20B2AA 100%);
border-radius: 60rpx 0 0 60rpx;
justify-content: flex-start;
align-items: center;
color: $white;
display: flex;
box-shadow: 0 8rpx 24rpx rgba(0, 206, 209, 0.3);
z-index: 999;
.year-text {
font-size: 24rpx;
font-weight: bold;
width:70rpx;
height:70rpx;
display: flex;
margin-left: 5rpx;
justify-content: center;
align-items: center;
color:#3cc7c0;
border-radius: 50%;
background-color: #fff;
}
.summary-text {
font-weight: bold;
width:50rpx;
margin-left: 10rpx;
font-size: 20rpx;
}
}
//
.bottom-nav {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: $white;
display: flex;
border-top: 1px solid $gray-light;
padding: 16rpx 0;
z-index: 1000;
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 8rpx;
font-size: 20rpx;
color: $gray-medium;
&.active {
color: $theme-color;
}
}
}
</style>

View File

@ -0,0 +1,561 @@
<template>
<uni-nav-bar title="患教学堂" fixed color="#8B2316" height="140rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="page">
<!-- 顶部标题栏 -->
<view class="top">
<!-- 选项卡 -->
<view class="tabs">
<view class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">
患教文库
</view>
<view class="tab-item" :class="{ active: activeTab === 1 }" @click="switchTab(1)">
患教视频
</view>
<view class="tab-item" :class="{ active: activeTab === 2 }" @click="switchTab(2)">
常见问题
</view>
</view>
<!-- 筛选栏 -->
<view class="filter-bar">
<view class="search-box">
<uni-icons type="search" size="16" color="#999"></uni-icons>
<text class="search-text">搜索</text>
</view>
<view class="divider"></view>
<view class="filter-item">
<text>最新</text>
<up-image :src="upImg" width="20rpx" height="26rpx" ></up-image>
</view>
<view class="divider"></view>
<view class="filter-item" @click="showFilterPopup">
<text>筛选</text>
<up-image :src="isFilterActive ? filterOn : filter" width="30rpx" height="30rpx" ></up-image>
</view>
</view>
</view>
<!-- 筛选弹窗 -->
<view class="filter-popup" v-if="showFilter" @click="hideFilterPopup">
<view class="filter-content" @click.stop>
<!-- 筛选标签网格 -->
<view class="filter-tags">
<view
class="tag-item"
v-for="(tag, index) in filterTags"
:key="index"
:class="{ active: tag.selected }"
@click="toggleTag(index)"
>
{{ tag.name }}
</view>
</view>
<!-- 底部按钮 -->
<view class="filter-buttons">
<view class="btn-reset" @click="resetFilter">重置</view>
<view class="btn-confirm" @click="confirmFilter">确定</view>
</view>
</view>
</view>
<!-- 文章列表 -->
<scroll-view class="article-list" scroll-y>
<view class="article-item" v-for="(article, index) in articleList" :key="index" @click="goToDetail(article)">
<image class="article-image" :src="article.image" mode="aspectFill"></image>
<view class="article-content">
<view class="article-title">{{ article.title }}</view>
<view class="article-meta">
<view class="date-tag" v-if="article.isToday">今日</view>
<view class="date" v-else>{{ article.date }}</view>
<view class="stats">
<view class="stat-item">
<uni-icons type="eye" size="12" color="#999"></uni-icons>
<text>{{ article.views }}</text>
</view>
<view class="stat-item">
<uni-icons type="heart" size="12" color="#999"></uni-icons>
<text>{{ article.likes }}</text>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
<!-- 底部导航栏 -->
</view>
<CustomTabbar></CustomTabbar>
</template>
<script setup>
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import CustomTabbar from '@/compoents/tabBar/tabBar.vue';
import upImg from "@/static/cb_up.png"
import downImg from "@/static/cb_up.png"
import filter from "@/static/cb_screen_no.png"
import filterOn from "@/static/cb_screen_yes.png"
//
const activeTab = ref(0);
const showFilter = ref(false);
const isFilterActive = ref(false);
//
const filterTags = ref([
{ name: '甲型肝炎', selected: false },
{ name: '乙型肝炎', selected: false },
{ name: '丙型肝炎', selected: false },
{ name: '药物肝', selected: false },
{ name: '自免肝', selected: false },
{ name: '酒精肝', selected: false },
{ name: '脂肪肝', selected: false },
{ name: '肝纤维化', selected: false },
{ name: '肝硬化', selected: false },
{ name: '肝癌', selected: false },
{ name: '肝囊虫', selected: false },
{ name: '肝移植', selected: false },
{ name: '胆结石', selected: false },
{ name: '胆囊炎', selected: false },
{ name: '其他疾病', selected: false },
{ name: '肝脏检查', selected: false },
{ name: '乙肝五项', selected: false },
{ name: '肝功能', selected: false },
{ name: '报告解读', selected: false },
{ name: '肝炎病毒', selected: false },
{ name: '传播途径', selected: false },
{ name: '症状表现', selected: false },
{ name: '疫苗接种', selected: false },
{ name: '诊断治疗', selected: false },
{ name: '抗病毒', selected: false },
{ name: '干扰素', selected: false },
{ name: '用药', selected: false },
{ name: '耐药', selected: false },
{ name: '保肝降酶', selected: false },
{ name: '毒副反应', selected: false },
{ name: '治愈停药', selected: false },
{ name: '肝炎复发', selected: false },
{ name: '预后预防', selected: false },
{ name: '日常生活', selected: false },
{ name: '饮食营养', selected: false },
{ name: '养肝护肝', selected: false },
{ name: '一图读懂', selected: false },
{ name: '误区辟谣', selected: false },
{ name: '生儿育女', selected: false },
{ name: '医保报销', selected: false },
{ name: '肝胆相照', selected: false },
{ name: '精华好文', selected: false },
{ name: '肝病故事', selected: false },
{ name: '名医科普', selected: false },
{ name: '肝病现状', selected: false },
{ name: '中医中药', selected: false }
]);
//
const articleList = ref([
{
id: 1,
image: '/static/liver_knowledge.png',
title: '甩掉"乙肝大国"的帽子后,中国第一大肝病变成了它,正在侵...',
date: '今日',
isToday: true,
views: 185,
likes: 0
},
{
id: 2,
image: '/static/doctor_liver.png',
title: '从你我做起,让肝炎止步',
date: '08-01',
isToday: false,
views: 315,
likes: 0
},
{
id: 3,
image: '/static/liver_health.png',
title: '这6个指标正常说明你肝脏健康',
date: '07-25',
isToday: false,
views: 1033,
likes: 0
},
{
id: 4,
image: '/static/diet_liver.png',
title: '无需节食吃饭一个改变脂肪肝好转了4个月肝脏脂肪减...',
date: '07-18',
isToday: false,
views: 1829,
likes: 1
},
{
id: 5,
image: '/static/cooking_spices.png',
title: '这种家家都有的调料,吃太多会增加肝癌风险?很多人已超标!',
date: '07-11',
isToday: false,
views: 2992,
likes: 0
},
{
id: 6,
image: '/static/liver_protection.png',
title: '肝炎拖成肝硬化下一步就是肝癌养肝护肝记住这3点',
date: '07-04',
isToday: false,
views: 1993,
likes: 1
}
]);
//
const switchTab = (index) => {
activeTab.value = index;
};
const goToDetail = (article) => {
console.log('查看文章详情:', article);
//
};
const goToPage = (page) => {
console.log('跳转到页面:', page);
//
if (page === 'index') {
uni.switchTab({
url: '/pages/index/index'
});
}
};
//
const showFilterPopup = () => {
showFilter.value = true;
};
const hideFilterPopup = () => {
showFilter.value = false;
};
const toggleTag = (index) => {
filterTags.value[index].selected = !filterTags.value[index].selected;
};
const resetFilter = () => {
filterTags.value.forEach(tag => {
tag.selected = false;
});
isFilterActive.value = false;
};
const confirmFilter = () => {
//
const hasSelected = filterTags.value.some(tag => tag.selected);
isFilterActive.value = hasSelected;
//
if (hasSelected) {
const selectedTags = filterTags.value.filter(tag => tag.selected).map(tag => tag.name);
console.log('选中的标签:', selectedTags);
//
}
showFilter.value = false;
};
onShow(() => {
console.log('患教学堂页面显示');
});
</script>
<style lang="scss" scoped>
//
$primary-color: #ff6b6b;
$theme-color: #8B2316;
$white: #fff;
$gray-bg: #f5f5f5;
$gray-light: #eee;
$gray-medium: #999;
$gray-dark: #666;
$text-color: #333;
//
$border-radius: 8px;
$border-radius-small: 6px;
$padding: 15px;
$padding-small: 10px;
.page {
background-color: $gray-bg;
height: calc(100vh - 140rpx);
display: flex;
overflow-y: hidden;
flex-direction: column;
//
}
.top{
width:100%;
position: fixed;
top:140rpx;
}
//
.tabs {
background-color: $white;
display: flex;
border-bottom: 1px solid $gray-light;
.tab-item {
flex: 1;
text-align: center;
padding: $padding 0;
font-size: 16px;
color: $gray-dark;
position: relative;
&.active {
color: $theme-color;
&::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 2px;
}
}
}
}
//
.filter-bar {
background-color: $white;
padding: $padding-small $padding;
display: flex;
align-items: center;
border-bottom: 1px solid $gray-light;
.search-box {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
.search-text {
font-size: 14px;
color: $gray-medium;
}
}
.divider {
width: 1px;
height: 16px;
background-color: $gray-medium;
margin: 0 $padding;
}
.filter-item {
flex:1;
display: flex;
align-items: center;
justify-content: center;
gap: 3px;
font-size: 14px;
color: #999;
}
}
//
.article-list {
position: fixed;
height:calc(100vh - 450rpx);
top: 342rpx;
padding-bottom: 130rpx;
.article-item {
background-color: $white;
margin-bottom: $padding-small;
border-radius: $border-radius;
padding: $padding;
display: flex;
gap: 12px;
.article-image {
width: 80px;
height: 80px;
border-radius: $border-radius-small;
flex-shrink: 0;
}
.article-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.article-title {
font-size: 16px;
color: $text-color;
line-height: 1.4;
margin-bottom: $padding-small;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
}
.article-meta {
display: flex;
justify-content: space-between;
align-items: center;
.date-tag {
background-color: $primary-color;
color: $white;
font-size: 12px;
padding: 2px 6px;
border-radius: 3px;
}
.date {
font-size: 12px;
color: $gray-medium;
}
.stats {
display: flex;
gap: $padding;
.stat-item {
display: flex;
align-items: center;
gap: 3px;
font-size: 12px;
color: $gray-medium;
}
}
}
}
}
}
//
.bottom-nav {
background-color: $white;
display: flex;
border-top: 1px solid $gray-light;
padding: 8px 0;
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
font-size: 12px;
color: $gray-medium;
&.active {
color: $primary-color;
}
text {
font-size: 10px;
}
}
}
//
.filter-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
// background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
z-index: 9999;
.filter-content {
margin-top:329rpx;
background-color: $white;
// border-radius: 20rpx 20rpx 0 0;
padding: 20rpx 30rpx 60rpx;
width: 100%;
max-height: 80vh;
.filter-tags {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
margin-bottom: 60rpx;
max-height: 65vh;
overflow-y: auto;
.tag-item {
background-color: #f8f8f8;
color: $gray-dark;
padding: 8rpx 24rpx;
border-radius: 30rpx;
font-size: 26rpx;
border: 2rpx solid #efefef;
transition: all 0.3s ease;
&.active {
background-color: #fff;
color: $theme-color;
border-color: $theme-color;
}
}
}
.filter-buttons {
display: flex;
gap: 20rpx;
position: fixed;
bottom: 30rpx;
left: 30rpx;
right: 30rpx;
.btn-reset,
.btn-confirm {
flex: 1;
height: 70rpx;
border-radius: 14rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
}
.btn-reset {
background-color: $white;
color: $theme-color;
border: 2rpx solid $theme-color;
}
.btn-confirm {
border: 2rpx solid $theme-color;
background-color: $theme-color;
color: $white;
}
}
}
}
</style>

607
pages_app/login/login.vue Normal file
View File

@ -0,0 +1,607 @@
<template>
<view class="login-container">
<uni-nav-bar title="登录" color="#8B2316" height="160rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<!-- 主要内容区域 -->
<view class="main-content" >
<!-- 应用图标和名称 -->
<view class="app-info">
<view class="app-icon">
<up-image :src="logo" width="164rpx" height="167rpx" ></up-image>
</view>
<text class="app-name">专家端</text>
</view>
<!-- 手机号显示 -->
<!-- #ifdef APP -->
<view class="phone-display">
<text class="phone-number">176****8628</text>
</view>
<!-- 登录按钮 -->
<view class="login-button" @click="onOneClickLogin">
<text class="button-text">本机号码一键登录</text>
</view>
<!-- 短信验证码登录 -->
<view class="sms-login" @click="onSmsLogin">
<text class="sms-text">短信验证码登录</text>
</view>
<!-- 微信登录 -->
<view class="wechat-login" @click="onWechatLogin">
<view class="wechat-icon">
<up-image :src="wxImg" width="100rpx" height="100rpx" ></up-image>
</view>
<text class="wechat-text">微信登录</text>
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<up-button
v-if="isAgreed"
:customStyle="customStyle"
class="login-button"
type="success"
@getphonenumber="getPhoneNumber"
open-type="getPhoneNumber"
text="手机号快捷登录"
color="#3cc7c0"
size="large"
></up-button>
<up-button
v-else
:customStyle="customStyle"
class="login-button"
type="success"
@click="alertAgree"
text="手机号快捷登录"
color="#3cc7c0"
size="large"
></up-button>
<view class="sms-login" @click="onSmsLogin" style="margin-top: 20rpx;">
<text class="sms-text">短信验证码登录</text>
</view>
<!-- #endif -->
</view>
<!-- 底部协议 -->
<view class="agreement-section">
<view class="agreement-content">
<view class="checkbox" @click="toggleAgreement">
<up-image :src="checkImg" width="45rpx" height="45rpx" v-if="!isAgreed"></up-image>
<up-image :src="checkOnImg" width="45rpx" height="45rpx" v-else></up-image>
</view>
<view class="agreement-text">
<text class="text-content">我已阅读并同意</text>
<text class="link-text" @click="onServiceTerms">中国移动认证服务条款</text>
<text class="text-content"></text>
<text class="link-text" @click="onPrivacyPolicy">肝胆相照隐私政策</text>
<text class="text-content"></text>
<text class="link-text" @click="onUserAgreement">肝胆相照用户服务协议</text>
<text class="text-content">并使用本机号码登录并注册</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import auth from "@/utils/auth";
import logo from "@/static/icon_login_logo.png"
import wxImg from "@/static/weixin_login.png"
import checkImg from "@/static/login_new_unselect.png"
import checkOnImg from "@/static/login_new_select.png"
const customStyle = reactive({
height: "100rpx",
fontSize: "36rpx",
backgroundColor:'#8B2316',
borderRadius: '50rpx'
});
//
const isAgreed = ref(false);
const alertAgree=()=>{
uni.showToast({
title: '请先同意用户协议',
icon:'none'
})
};
//
const onOneClickLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
console.log('一键登录');
uni.showLoading({
title: '登录中...'
});
//
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '登录成功',
icon: 'success'
});
//
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
});
}, 1500);
}, 2000);
};
//
const onSmsLogin = () => {
uni.redirectTo({
url: '/pages_app/smsLogin/smsLogin'
});
};
//
const onWechatLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
console.log('微信登录');
uni.showToast({
title: '微信登录功能开发中',
icon: 'none'
});
};
//
const toggleAgreement = () => {
isAgreed.value = !isAgreed.value;
};
//
const onServiceTerms = () => {
console.log('查看服务条款');
uni.navigateTo({
url: '/pages_app/agreement/service-terms'
});
};
//
const onPrivacyPolicy = () => {
console.log('查看隐私政策');
uni.navigateTo({
url: '/pages_app/agreement/privacy-policy'
});
};
//
const onUserAgreement = () => {
console.log('查看用户协议');
uni.navigateTo({
url: '/pages_app/agreement/user-agreement'
});
};
const getPhoneNumber = (e) => {
if (e.detail.errMsg === "getPhoneNumber:ok") {
console.log(e.target.code)
auth().then((res) => {
console.log(res);
api.wxLogin({
phone_code: e.target.code,
wx_code: res,
source:1
})
.then((data) => {
uni.hideKeyboard()
let result=data.data.data;
if(process.env.UNI_PLATFORM =="h5"){
if(window.location.href.indexOf('//casedata.igandan.com')>-1){
uni.setStorageSync("AUTH_TOKEN_CASEDATA",result.token);
}else{
uni.setStorageSync("DEV_AUTH_TOKEN_CASEDATA",result.token);
}
}else{
const { envVersion } = uni.getAccountInfoSync().miniProgram;
if (envVersion == "release") {
uni.setStorageSync("AUTH_TOKEN_CASEDATA",result.token);
} else {
uni.setStorageSync("DEV_AUTH_TOKEN_CASEDATA",result.token);
};
}
uni.setStorageSync("userInfo",{
avatar:result.avatar,
user_id:result.user_id,
status:result.status,
user_name:result.user_name,
doctor_id:result.doctor_id,
});
goPage()
})
});
}
};
const goPage=()=>{
uni.redirectTo({
url:'/pages/index/index'
})
}
//
onLoad(() => {
console.log('登录页面加载完成');
});
//
onShow(() => {
// #ifdef APP
// uni.login({
// provider: 'univerify',
// univerifyStyle: {
// fullScreen: true
// }
// })
// #endif
console.log('登录页面显示');
});
//
onMounted(() => {
console.log('登录页面组件已挂载');
});
</script>
<style>
.login-container {
min-height: 100vh;
background-color: #ffffff;
display: flex;
flex-direction: column;
}
/* 状态栏 */
.status-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx;
height: 60rpx;
}
.status-left {
display: flex;
align-items: center;
}
.signal-bars {
display: flex;
align-items: flex-end;
gap: 2rpx;
}
.bar {
width: 4rpx;
background-color: #333;
border-radius: 2rpx;
}
.bar:nth-child(1) { height: 8rpx; }
.bar:nth-child(2) { height: 12rpx; }
.bar:nth-child(3) { height: 16rpx; }
.bar:nth-child(4) { height: 20rpx; }
.status-right {
display: flex;
align-items: center;
gap: 8rpx;
}
.battery-text {
font-size: 24rpx;
color: #333;
}
.battery-icon {
width: 40rpx;
height: 20rpx;
border: 2rpx solid #333;
border-radius: 4rpx;
position: relative;
display: flex;
align-items: center;
}
.battery-level {
width: 32rpx;
height: 12rpx;
background-color: #333;
margin: 2rpx;
border-radius: 2rpx;
}
.battery-tip {
position: absolute;
right: -6rpx;
top: 50%;
transform: translateY(-50%);
width: 4rpx;
height: 8rpx;
background-color: #333;
border-radius: 0 2rpx 2rpx 0;
}
.charging-icon {
font-size: 20rpx;
color: #333;
}
/* 主要内容区域 */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 60rpx 0;
}
/* 页面标题 */
.page-title {
margin-bottom: 80rpx;
}
.title-text {
font-size: 48rpx;
font-weight: bold;
color: #8B2316;
}
/* 应用信息 */
.app-info {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 60rpx;
}
.app-icon {
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
position: relative;
}
.icon-content {
position: relative;
width: 80rpx;
height: 80rpx;
}
.liver-shape {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #FF6B35, #FF8C00);
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
position: relative;
}
.bird-shape {
position: absolute;
top: 20rpx;
left: 25rpx;
width: 30rpx;
height: 20rpx;
background-color: white;
border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
transform: rotate(-15deg);
}
.app-name {
font-size: 32rpx;
font-weight: bold;
color: #8B2316;
}
/* 手机号显示 */
.phone-display {
margin-bottom: 60rpx;
}
.phone-number {
font-size: 40rpx;
font-weight: bold;
color: #333;
}
/* 登录按钮 */
.login-button {
width: 100%;
height: 100rpx;
background-color: #8B2316;
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 40rpx;
cursor: pointer;
transition: background-color 0.2s ease;
}
.login-button:active {
background-color: #6B1A0F;
}
.button-text {
font-size: 32rpx;
color: white;
font-weight: bold;
}
/* 短信验证码登录 */
.sms-login {
width:100%;
margin-bottom: 80rpx;
cursor: pointer;
}
.sms-text {
font-size: 28rpx;
color: #8B2316;
}
/* 微信登录 */
.wechat-login {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
cursor: pointer;
}
.wechat-icon {
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.chat-bubble {
position: absolute;
background-color: white;
border-radius: 50%;
}
.chat-bubble-1 {
width: 16rpx;
height: 16rpx;
top: 20rpx;
left: 20rpx;
}
.chat-bubble-2 {
width: 20rpx;
height: 20rpx;
top: 30rpx;
right: 20rpx;
}
.wechat-text {
font-size: 28rpx;
color: #8B2316;
}
/* 底部协议 */
.agreement-section {
padding: 40rpx 60rpx 60rpx;
}
.agreement-content {
display: flex;
align-items: flex-start;
gap: 20rpx;
}
.checkbox {
width: 45rpx;
height:45rpx;
/* border: 2rpx solid #ccc; */
border-radius: 50%;
display: flex;
/* background-size:cover;
background: url("@/static/login_new_unselect.png") no-repeat center center; */
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 4rpx;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
/* .checkbox.checked {
background-size:cover;
background: url("@/static/login_new_select.png") no-repeat center center;
} */
.checkbox-inner {
width: 16rpx;
height: 16rpx;
background-color: white;
border-radius: 50%;
}
.agreement-text {
flex: 1;
font-size: 24rpx;
color: #666;
line-height: 1.6;
}
.text-content {
color: #666;
}
.link-text {
color: #8B2316;
}
/* 响应式调整 */
@media (max-width: 750rpx) {
.main-content {
padding: 80rpx 40rpx 0;
}
.title-text {
font-size: 44rpx;
}
.app-icon {
width: 100rpx;
height: 100rpx;
}
.phone-number {
font-size: 36rpx;
}
.login-button {
height: 90rpx;
}
.button-text {
font-size: 30rpx;
}
.agreement-section {
padding: 30rpx 40rpx 50rpx;
}
.agreement-text {
font-size: 22rpx;
}
}
</style>

37
pages_app/news/news.vue Normal file
View File

@ -0,0 +1,37 @@
<template>
<uni-nav-bar
left-icon="left"
title="肝胆新闻"
@clickLeft="goBack"
fixed
color="#8B2316"
height="140rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
<view class="zhinan-page">
<view class="news-page">
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
//
const goBack = () => {
uni.navigateBack({
fail() {
uni.redirectTo({
url: '/pages/index/index'
});
}
});
};
</script>
<style scoped lang="scss">
.news-page{
}
</style>

View File

@ -0,0 +1,487 @@
<template>
<uni-nav-bar title="登录" fixed color="#8B2316" height="160rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="login-container">
<!-- 主要内容区域 -->
<view class="main-content" >
<!-- 应用图标和名称 -->
<view class="app-info">
<view class="app-icon">
<up-image :src="logo" width="164rpx" height="167rpx" ></up-image>
</view>
<text class="app-name">专家端</text>
</view>
<!-- 手机号输入 -->
<view class="input-section">
<view class="input-group">
<up-image :src="phoneImg" width="36rpx" height="36rpx" ></up-image>
<input
class="phone-input"
type="number"
placeholder="请输入手机号"
v-model="phoneNumber"
maxlength="11"
/>
</view>
<!-- 密码输入 -->
<view class="input-group">
<up-image :src="pwdImg" width="36rpx" height="36rpx" ></up-image>
<input
class="password-input"
type="text"
placeholder="请输入密码"
:password="!showPassword"
v-model="password"
/>
<view class="password-toggle" @click="togglePassword">
<up-image :src="showPassword ? eyeOpenImg : eyeCloseImg" width="36rpx" height="36rpx" ></up-image>
</view>
</view>
</view>
<!-- 登录按钮 -->
<view class="login-button" @click="onPasswordLogin" >
<text class="button-text">登录</text>
</view>
<view class="sms-login" @click="goSmsLogin">
<text class="sms-text">短信验证码登录</text>
</view>
<!-- 其他登录方式 -->
<view class="other-login">
<!-- 微信登录 -->
<view class="wechat-login" @click="onWechatLogin">
<view class="wechat-icon">
<up-image :src="wxImg" width="100rpx" height="100rpx" ></up-image>
</view>
<text class="wechat-text">微信登录</text>
</view>
</view>
</view>
<!-- 底部协议 -->
<view class="agreement-section">
<view class="agreement-content">
<view class="checkbox" @click="toggleAgreement">
<up-image :src="checkImg" width="45rpx" height="45rpx" v-if="!isAgreed"></up-image>
<up-image :src="checkOnImg" width="45rpx" height="45rpx" v-else></up-image>
</view>
<view class="agreement-text">
<text class="text-content">我已阅读并同意</text>
<text class="link-text" @click="onServiceTerms">中国移动认证服务条款</text>
<text class="text-content"></text>
<text class="link-text" @click="onPrivacyPolicy">肝胆相照隐私政策</text>
<text class="text-content"></text>
<text class="link-text" @click="onUserAgreement">肝胆相照用户服务协议</text>
<text class="text-content">并使用本机号码登录并注册</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import auth from "@/utils/auth";
import logo from "@/static/icon_login_logo.png"
import wxImg from "@/static/weixin_login.png"
import checkImg from "@/static/login_new_unselect.png"
import checkOnImg from "@/static/login_new_select.png"
import phoneImg from "@/static/phone.png"
import pwdImg from "@/static/pwd.png"
import eyeOpenImg from "@/static/eye_open.png"
import eyeCloseImg from "@/static/eye_close.png"
const customStyle = reactive({
height: "100rpx",
fontSize: "36rpx",
backgroundColor:'#8B2316',
borderRadius: '50rpx'
});
//
const isAgreed = ref(false);
//
const phoneNumber = ref('');
const password = ref('');
//
const showPassword = ref(false);
//
const canLogin = computed(() => {
return isAgreed.value && phoneNumber.value.length === 11 && password.value.length >= 6;
});
const goSmsLogin=()=>{
uni.redirectTo({
url:'/pages_app/smsLogin/smsLogin'
})
}
const alertAgree=()=>{
uni.showToast({
title: '请先同意用户协议',
icon:'none'
})
};
//
const togglePassword = () => {
showPassword.value = !showPassword.value;
};
//
const onPasswordLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
if (!phoneNumber.value) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!/^1[3-9]\d{9}$/.test(phoneNumber.value)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
if (!password.value) {
uni.showToast({
title: '请输入密码',
icon: 'none'
});
return;
}
if (password.value.length < 6) {
uni.showToast({
title: '密码长度不能少于6位',
icon: 'none'
});
return;
}
console.log('密码登录');
uni.showLoading({
title: '登录中...'
});
//
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '登录成功',
icon: 'success'
});
//
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
});
}, 1500);
}, 2000);
};
//
const onWechatLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
console.log('微信登录');
uni.showToast({
title: '微信登录功能开发中',
icon: 'none'
});
};
//
const toggleAgreement = () => {
isAgreed.value = !isAgreed.value;
};
//
const onServiceTerms = () => {
console.log('查看服务条款');
uni.navigateTo({
url: '/pages_app/agreement/service-terms'
});
};
//
const onPrivacyPolicy = () => {
console.log('查看隐私政策');
uni.navigateTo({
url: '/pages_app/agreement/privacy-policy'
});
};
//
const onUserAgreement = () => {
console.log('查看用户协议');
uni.navigateTo({
url: '/pages_app/agreement/user-agreement'
});
};
//
onLoad(() => {
console.log('密码登录页面加载完成');
});
//
onShow(() => {
console.log('密码登录页面显示');
});
//
onMounted(() => {
console.log('密码登录页面组件已挂载');
});
</script>
<style>
.login-container {
min-height: calc(100vh - 160rpx);
background-color: #ffffff;
display: flex;
flex-direction: column;
}
/* 主要内容区域 */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 60rpx 0;
}
/* 应用信息 */
.app-info {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 80rpx;
}
.app-icon {
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
position: relative;
}
.app-name {
font-size: 32rpx;
font-weight: bold;
color: #8B2316;
}
/* 输入区域 */
.input-section {
width: 100%;
margin-bottom: 60rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
}
.input-group {
display: flex;
padding-left: 20rpx;
align-items: center;
}
.input-group:first-child{
border-bottom: 2rpx solid #e5e5e5;
}
.phone-input {
width: 100%;
height: 80rpx;
padding: 0 40rpx;
font-size: 32rpx;
background-color: #fff;
box-sizing: border-box;
}
.password-input {
flex: 1;
height: 80rpx;
padding: 0 40rpx;
font-size: 32rpx;
background-color: #fff;
box-sizing: border-box;
}
.password-toggle {
width: 60rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
/* 登录按钮 */
.login-button {
width: 100%;
height: 80rpx;
background-color: #8B2316;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
cursor: pointer;
transition: background-color 0.2s ease;
}
.login-button:active {
background-color: #6B1A0F;
}
.button-text {
font-size: 32rpx;
color: white;
font-weight: bold;
}
/* 其他登录方式 */
.other-login {
width: 100%;
margin-bottom: 40rpx;
}
/* 微信登录 */
.wechat-login {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
cursor: pointer;
}
.wechat-icon {
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.wechat-text {
font-size: 28rpx;
color: #8B2316;
}
/* 底部协议 */
.agreement-section {
padding: 40rpx 60rpx 60rpx;
}
.agreement-content {
display: flex;
align-items: flex-start;
gap: 20rpx;
}
.checkbox {
width: 45rpx;
height:45rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 4rpx;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.agreement-text {
flex: 1;
font-size: 24rpx;
color: #666;
line-height: 1.6;
}
.text-content {
color: #666;
}
.link-text {
color: #8B2316;
}
/* 响应式调整 */
@media (max-width: 750rpx) {
.main-content {
padding: 80rpx 40rpx 0;
}
.app-icon {
width: 100rpx;
height: 100rpx;
}
.phone-input,
.password-input {
height: 90rpx;
}
.login-button {
height: 90rpx;
}
.button-text {
font-size: 30rpx;
}
.agreement-section {
padding: 30rpx 40rpx 50rpx;
}
.agreement-text {
font-size: 22rpx;
}
}
.sms-login {
width:100%;
margin-bottom: 0rpx;
cursor: pointer;
}
.sms-text {
font-size: 28rpx;
color: #8B2316;
}
</style>

694
pages_app/qikan/qikan.vue Normal file
View File

@ -0,0 +1,694 @@
<template>
<uni-nav-bar
left-icon="left"
title="期刊杂志"
@clickLeft="goBack"
fixed
color="#8B2316"
height="140rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
<view class="qikan-page">
<!-- 导航头部 -->
<!-- 主要内容区域 -->
<view class="main-content">
<!-- 标签切换区域 -->
<view class="tab-section">
<view class="tab-container">
<view
class="tab-item"
:class="{ active: activeTab === 'daichawenxian' }"
@click="switchTab('daichawenxian')"
>
<text class="tab-text">代查文献</text>
<view class="tab-underline" >
<up-image :src="activeImg" width="48rpx" height="18rpx" v-if="activeTab === 'daichawenxian'"></up-image>
</view>
</view>
<view
class="tab-item"
:class="{ active: activeTab === 'yingwenwenxian' }"
@click="switchTab('yingwenwenxian')"
>
<text class="tab-text">英文文献</text>
<view class="tab-underline">
<up-image :src="activeImg" width="48rpx" height="18rpx" v-if="activeTab === 'yingwenwenxian'"></up-image>
</view>
</view>
</view>
</view>
<!-- 代查文献内容 -->
<view class="content-section" v-if="activeTab === 'daichawenxian'">
<!-- 顶部图标和说明 -->
<up-image :src="paperImg" width="100%" ></up-image>
<!-- 表单区域 -->
<view class="form-section">
<!-- 接收邮箱 -->
<view class="form-group formemail">
<view class="form-label">
<text>接收邮箱</text>
<text class="required">*</text>
</view>
<view class="input-container">
<input
class="form-input"
type="text"
placeholder="请输入文献接收邮箱"
v-model="formData.email"
/>
</view>
</view>
<!-- 文献单元列表 -->
<view
class="from-cell literature-item"
v-for="(literature, index) in literatureList"
:key="literature.id"
>
<!-- 文献类型标签 -->
<view class="form-group wenxian">
<view class="tag-container">
<view class="tag-item active">文献{{ index + 1 }}</view>
</view>
</view>
<view class="formbox">
<!-- 文献名称 -->
<view class="form-group">
<view class="form-label">
<text>文献名称</text>
<text class="required">*</text>
</view>
<view class="input-container">
<textarea
class="form-textarea"
type="text"
placeholder="不支持关键字/广泛查询"
v-model="literature.literatureName"
/>
</view>
</view>
<!-- 作者 -->
<view class="form-group">
<view class="form-label">
<text>作者</text>
</view>
<view class="input-container">
<input
class="form-input"
type="text"
placeholder="请输入作者姓名"
v-model="literature.author"
/>
</view>
</view>
<!-- 期刊名称 -->
<view class="form-group">
<view class="form-label">
<text>期刊名称</text>
</view>
<view class="input-container">
<input
class="form-input"
type="text"
placeholder="请输入期刊名称"
v-model="literature.journalName"
/>
</view>
</view>
</view>
<!-- 删除按钮 -->
<view class="delbox" v-if="literatureList.length > 1" @click="removeLiterature(index)">
<up-image :src="delImg" width="40rpx" height="52rpx"></up-image>
</view>
<!-- 文献分隔线 -->
<view class="literature-divider" v-if="index < literatureList.length - 1"></view>
</view>
<!-- 添加代查文献按钮 -->
<view class="add-literature-section" v-if="literatureList.length < 5">
<view class="add-button" @click="addLiterature">
<up-icon name="plus" size="18" color="#4A90E2"></up-icon>
<text class="add-text">添加代查文献</text>
</view>
<view class="limit-tip">
<view class="imgbox">
<up-image :src="countImg" width="186rpx" height="74rpx"></up-image>
</view>
<view class="count">还可添加{{ 5 - literatureList.length }}</view>
</view>
</view>
</view>
<!-- 常见问题 -->
<view class="faq-section">
<up-image :src="questionImg" width="100%" mode="widtFix"></up-image>
</view>
<view class="tips">
<view class="title">注意</view>
<view class="row">每次至多提交5篇文献代查</view>
<view class="row">每篇文献代查消耗50肝胆积分代查成功后扣除</view>
<view class="row">不支持模糊代查请尽可能详细提供所需文献信息</view>
</view>
<view class="btnbox">
<up-image :src="submitImg" width="100%" height="160rpx" mode="widtFix"></up-image>
</view>
</view>
<!-- 英文文献内容暂时显示占位内容 -->
<view class="content-section" v-if="activeTab === 'yingwenwenxian'">
<view class="placeholder-content">
<uni-icons type="info" size="60" color="#999"></uni-icons>
<text class="placeholder-text">英文文献功能正在开发中...</text>
</view>
</view>
</view>
<!-- 底部导航 -->
<view class="bottom-tabbar">
<view class="tab-item active" @click="switchTab('zhinan')">
<text class="tab-text active">诊疗指南</text>
</view>
<view class="tab-item" @click="switchTab('qikan')">
<text class="tab-text">期刊杂志</text>
</view>
<view class="tab-item" @click="switchTab('tools')">
<text class="tab-text">常用工具</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import paperImg from "@/static/paper_bg.png"
import activeImg from "@/static/route.png"
import emailImg from "@/static/email_bg.png"
import countImg from "@/static/sheng_bg.png"
import questionImg from "@/static/paper_question.png"
import submitImg from "@/static/paper_submit.png"
import delImg from "@/static/delete_paper.png"
//
const activeTab = ref('daichawenxian');
//
const formData = ref({
email: '',
literatureName: '',
author: '',
journalName: ''
});
//
const literatureList = ref([
{
id: 1,
literatureName: '',
author: '',
journalName: ''
}
]);
//
const faqList = ref([
{
question: '如何查找文献?',
answer: '请提供准确的文献标题、作者和期刊信息,我们将为您查找并发送到指定邮箱。',
expanded: false
},
{
question: '查找需要多长时间?',
answer: '通常在1-3个工作日内完成文献查找并发送到您的邮箱。',
expanded: false
},
{
question: '支持哪些文献类型?',
answer: '支持国内外期刊论文、会议论文、学位论文等多种文献类型。',
expanded: false
}
]);
//
const switchTab = (tab) => {
activeTab.value = tab;
};
//
const switchBottomTab = (tab) => {
if (tab === 'zhinan') {
uni.navigateTo({
url: '/pages_app/zhinan/zhinan'
});
} else if (tab === 'tools') {
uni.showToast({
title: '功能开发中',
icon: 'none'
});
}
};
//
const addLiterature = () => {
if (literatureList.value.length >= 5) {
uni.showToast({
title: '最多只能添加5篇文献',
icon: 'none'
});
return;
}
const newLiterature = {
id: Date.now(), // 使ID
literatureName: '',
author: '',
journalName: ''
};
literatureList.value.push(newLiterature);
uni.showToast({
title: '添加成功',
icon: 'success'
});
};
//
const removeLiterature = (index) => {
if (literatureList.value.length <= 1) {
uni.showToast({
title: '至少保留一篇文献',
icon: 'none'
});
return;
}
literatureList.value.splice(index, 1);
uni.showToast({
title: '删除成功',
icon: 'success'
});
};
// FAQ
const toggleFaq = (index) => {
faqList.value[index].expanded = !faqList.value[index].expanded;
};
//
const goBack = () => {
const pages = getCurrentPages();
if (pages.length > 1) {
uni.navigateBack();
} else {
uni.switchTab({
url: '/pages/index/index'
});
}
};
//
onShow(() => {
console.log('期刊杂志页面显示');
});
</script>
<style lang="scss" scoped>
// SCSS Variables
$primary-color: #8B2316;
$accent-color: #4A90E2;
$bg-color: #f5f5f5;
$white: #fff;
$text-primary: #333;
$text-secondary: #666;
$text-light: #999;
$border-color: #e0e0e0;
$nav-height: 140rpx;
.qikan-page {
background:#f6f6f6;
min-height: 100vh;
padding-top:0rpx;
padding-bottom: 100rpx; //
}
.main-content {
flex: 1;
}
// -
.tab-section {
position: fixed;
top: $nav-height; // 140rpx
left: 0;
right: 0;
z-index: 80;
background-color: #a5d9fe;
padding: 0 30rpx;
.tab-container {
display: flex;
align-items: center;
height: 100rpx;
.tab-item {
position: relative;
margin-right: 60rpx;
padding: 20rpx 0;
.tab-text {
font-size: 32rpx;
color: $text-secondary;
font-weight: 500;
}
&.active {
.tab-text {
color: $primary-color;
font-weight: 600;
}
}
.tab-underline {
position: absolute;
bottom:15rpx;
left: 50%;
right: 0;
transform: translateX(-50%);
height: 18rpx;
}
}
}
}
//
.content-section {
background-color: $bg-color;
min-height: calc(100vh - 340rpx);
margin-top: 100rpx; //
}
//
.header-banner {
background: linear-gradient(135deg, #87CEEB, #B0E0E6);
margin: 20rpx 30rpx;
border-radius: 20rpx;
padding: 40rpx 30rpx;
.banner-content {
display: flex;
align-items: center;
.icon-container {
position: relative;
margin-right: 30rpx;
.sparkle-icon {
position: absolute;
top: -10rpx;
right: -10rpx;
font-size: 24rpx;
}
}
.banner-text {
flex: 1;
.main-title {
font-size: 48rpx;
font-weight: bold;
color: $text-primary;
margin-bottom: 10rpx;
}
.sub-title {
font-size: 24rpx;
color: $text-secondary;
line-height: 1.4;
}
}
}
}
//
.form-section {
margin: -156rpx 30rpx 20rpx;
border-radius: 20rpx;
padding: 0rpx 0rpx ;
.wenxian{
margin-top: 40rpx;
overflow: hidden;
}
.from-cell{
position: relative;
.delbox{
top:10rpx;
right:30rpx;
position: absolute;
}
}
.formbox{
padding:30rpx 30rpx 30rpx;
background:#fff url("@/static/email_bg.png") no-repeat 0rpx 0;
background-size: 100% 148rpx;
border-radius: 10rpx;
position: relative;
z-index:8;
}
.formemail{
padding:0 30rpx;
height: 148rpx;
display: flex;
align-items:center;
border-radius: 20rpx;
background:#fff url("@/static/email_bg.png") no-repeat 0rpx 0!important;
background-size: cover!important;
}
// 线
.literature-divider {
height: 20rpx;
margin: 20rpx 0;
background-color: #f0f0f0;
border-radius: 10rpx;
}
.form-group {
margin-bottom: 40rpx;
display: flex;
background-size: 100% 652rpx;
overflow: hidden;
&:last-child {
margin-bottom: 0;
}
.form-label {
display: flex;
align-items: center;
width:160rpx;
font-size: 28rpx;
color: $text-primary;
font-weight: 500;
.required {
color: #ff4757;
margin-left: 8rpx;
}
}
.input-container {
flex:1;
.form-input,.form-textarea{
width: 100%;
height: 80rpx;
padding: 0 20rpx;
background:#f6f6f6;
border: 2rpx solid $border-color;
border-radius: 12rpx;
font-size: 28rpx;
color: $text-primary;
background-color: $white;
box-sizing: border-box;
&::placeholder {
color: $text-light;
}
&:focus {
border-color: $accent-color;
}
}
.form-textarea{
padding:20rpx;
height: 200rpx;
}
}
.tag-container {
.tag-item {
display: inline-block;
padding: 16rpx 32rpx;
background-color: #008aff;
color: $white;
border-radius: 10rpx 10rpx 0 0;
font-size: 24rpx;
font-weight: 500;
}
}
}
.from-cell .form-group:nth-child(1){
margin-bottom: 0;
}
.formbox .form-group:nth-child(1){
margin-bottom: 40rpx;
}
}
//
.add-literature-section {
position: relative;
margin-top: 40rpx;
padding-top: 40rpx;
border-top: 2rpx solid $border-color;
.add-button {
display: flex;
align-items: center;
justify-content: center;
height: 80rpx;
margin:0 20rpx;
border: 2rpx solid #0197f1;
border-radius:40rpx;
background-color: rgba(74, 144, 226, 0.05);
.add-text {
margin-left: 10rpx;
font-size: 28rpx;
color: #0197f1;
font-weight: 500;
}
}
.limit-tip {
position: absolute;
right:0;
top:-10rpx;
text-align: center;
margin-top: 20rpx;
font-size: 24rpx;
color: #fff;
width: 186rpx;
height:74rpx;
display: flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
.imgbox{
top:0;
position: absolute;
}
.count{
margin-top: -20rpx;
position: relative;
z-index:3;
}
}
}
//
.faq-section {
margin: 0rpx 30rpx;
background-color: $white;
border-radius: 20rpx;
padding: 1rpx 1rpx;
}
.tips{
font-size: 24rpx;
margin:30rpx 30rpx;
color:#999;
}
.btnbox{
margin:0 30rpx;
}
//
.placeholder-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 400rpx;
.placeholder-text {
margin-top: 30rpx;
font-size: 28rpx;
color: $text-light;
}
}
//
.bottom-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background-color: $white;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1rpx solid #f0f0f0;
z-index: 100;
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
height: 100rpx;
gap: 8rpx;
&.active {
color: #fff;
background-color: #8B2316;
}
.tab-icon {
width: 44rpx;
height: 44rpx;
}
.tab-text {
font-size: 32rpx;
color: $text-secondary;
&.active {
color: #fff;
}
}
}
.tab-item:nth-child(2){
border-right: 2rpx solid #eee;
border-left: 2rpx solid #eee;
}
}
</style>

357
pages_app/search/search.vue Normal file
View File

@ -0,0 +1,357 @@
<template>
<view class="search-container">
<!-- 头部搜索栏 -->
<view class="search-header">
<view class="back-icon" @click="goBack">
<uni-icons type="left" size="30" color="#8B2316"></uni-icons>
</view>
<view class="search-input-wrapper">
<view class="search-icon">
<uni-icons type="search" size="20" color="#999"></uni-icons>
</view>
<input
class="search-input"
placeholder="搜索视频、精品课、课件、指南等"
v-model="searchKeyword"
@input="onSearchInput"
@confirm="onSearchConfirm"
confirm-type="search"
/>
<view class="clear-icon" v-if="searchKeyword" @click="clearSearch">
<uni-icons type="clear" size="20" color="#999"></uni-icons>
</view>
</view>
<view class="cancel-btn" @click="goBack">
<text class="cancel-text">搜索</text>
</view>
</view>
<!-- 搜索分类 -->
<view class="search-categories" >
<view class="category-header">
<text class="category-title">点击图标选择类型</text>
</view>
<view class="category-grid">
<view
class="category-item"
v-for="(item, index) in categoryList"
:key="index"
@click="onCategoryClick(index)"
>
<view class="category-icon">
<up-image :src="item.icon" width="60rpx" height="60rpx" v-if="tab!=index"></up-image>
<up-image :src="item.activeIcon" width="60rpx" height="60rpx" v-else></up-image>
</view>
<text class="category-text">{{ item.name }}</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import video from "@/static/item_video_no.png"
import videoOn from "@/static/item_video_pass.png"
import videoPatient from "@/static/patient_video_no.png"
import videoPatientOn from "@/static/patient_video_yes.png"
import news from "@/static/item_news_no.png"
import newsOn from "@/static/item_news_pass.png"
import kepu from "@/static/item_science_no.png"
import kepuOn from "@/static/item_science_pass.png"
import zhinan from "@/static/item_drug_no.png"
import zhinanOn from "@/static/item_drug_pass.png"
import course from "@/static/jingpin_no.png"
import courseOn from "@/static/jingpin_yes.png"
import ppt from "@/static/course_no.png"
import pptOn from "@/static/course_yes.png"
import patient from "@/static/item_patient_no.png"
import patientOn from "@/static/item_patient_yes.png"
import hospital from "@/static/item_hospital_no.png"
import hospitalOn from "@/static/item_hospital_yes.png"
import department from "@/static/item_department_no.png"
import departmentOn from "@/static/item_department_yes.png"
import doctor from "@/static/item_doctor_no.png"
import doctorOn from "@/static/item_doctor_yes.png"
import mall from "@/static/item_mall_no.png"
import mallOn from "@/static/item_mall_yes.png"
const tab=ref(-1);
//
const searchKeyword = ref('');
//
const hotSearchList = ref([
'肝病治疗指南', '肝硬化诊断', '肝炎预防', '肝癌早期症状',
'肝功能检查', '肝移植', '肝病饮食', '肝病用药'
]);
//
const categoryList = reactive([
{ name: '会议视频', icon: video,activeIcon:videoOn, type: 'video',},
{ name: '患教视频', icon: videoPatient,activeIcon:videoPatientOn,type: 'videoPatient' },
{ name: '新闻', icon:news,activeIcon:newsOn,type: 'news' },
{ name: '科普', icon: kepu,activeIcon:kepuOn, type: 'kepu' },
{ name: '指南', icon:zhinan, activeIcon:zhinanOn,type: 'zhinan' },
{ name: '精品课', icon:course,activeIcon:courseOn, type: 'course' },
{ name: '肝胆课件', icon:ppt,activeIcon:pptOn, type: 'ppt' },
{ name: '患者', icon:patient, patientIcon:videoOn,type: 'patient' },
{ name: '名院', icon:doctor,activeIcon:doctorOn, type: 'doctor' },
{ name: '名科', icon:department,activeIcon:departmentOn, type: 'department' },
{ name: '名医', icon:doctor, activeIcon:doctorOn,type: 'doctor' },
{ name: '积分商城', icon:mall,activeIcon:mallOn, type: 'mall' }
]);
//
const onSearchInput = (e) => {
searchKeyword.value = e.detail.value;
};
//
const onSearchConfirm = () => {
if (searchKeyword.value.trim()) {
uni.showToast({
title: `搜索:${searchKeyword.value}`,
icon: 'none'
});
}
};
//
const clearSearch = () => {
searchKeyword.value = '';
};
//
const onHotSearchClick = (keyword) => {
searchKeyword.value = keyword;
uni.showToast({
title: `搜索:${keyword}`,
icon: 'none'
});
};
//
const onCategoryClick = (index) => {
tab.value=index;
//
};
//
const goBack = () => {
uni.navigateBack({
delta:1,
fail(){
uni.redirectTo({
url:'/pages/index/index'
})
}
});
};
//
onLoad(() => {
console.log('搜索页面加载完成');
});
//
onShow(() => {
console.log('搜索页面显示');
});
</script>
<style lang="scss">
.search-container {
min-height: calc(100vh - 140rpx);
background-color: #fff;
}
//
.search-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 100;
background-color: #eeeeee;
display: flex;
height:140rpx;
align-items: center;
padding:0 30rpx;
gap: 20rpx;
.search-input-wrapper {
flex: 1;
display: flex;
align-items: center;
background-color: #fff;
border-radius: 20rpx;
padding: 0 20rpx;
height:70rpx;
.search-icon {
margin-right: 15rpx;
}
.search-input {
flex: 1;
height: 80rpx;
font-size: 28rpx;
color: #333;
}
.clear-icon {
margin-left: 15rpx;
padding: 10rpx;
}
}
.cancel-btn {
padding: 10rpx 20rpx;
background:#8B2316;
border-radius: 10rpx;
.cancel-text {
font-size: 28rpx;
color: #fff;
}
}
}
//
.hot-search {
margin-top: 20rpx;
padding: 30rpx;
background-color: #fff;
.hot-header {
margin-bottom: 30rpx;
.hot-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
}
.hot-tags {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.hot-tag {
padding: 15rpx 25rpx;
background-color: #fff5f5;
border: 2rpx solid #ffebeb;
border-radius: 25rpx;
cursor: pointer;
transition: all 0.2s ease;
&:active {
background-color: #ffe0e0;
border-color: #ffcccc;
}
.tag-text {
font-size: 26rpx;
color: #8B2316;
}
}
}
}
//
.search-categories {
margin-top: 140rpx;
padding: 30rpx;
background-color: #fff;
.category-header {
margin-bottom: 30rpx;
display: flex;
justify-content: center;
.category-title {
font-size: 30rpx;
text-align: center;
color: #999;
}
}
.category-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 40rpx;
.category-item {
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
padding: 30rpx 20rpx;
border-radius: 20rpx;
cursor: pointer;
transition: all 0.2s ease;
&:active {
background-color: #f0f0f0;
transform: scale(0.98);
}
.category-icon {
margin-bottom: 15rpx;
}
.category-text {
font-size: 26rpx;
color: #333;
text-align: center;
}
}
}
}
//
@media (max-width: 750rpx) {
.search-header {
padding: 15rpx 20rpx;
.search-input-wrapper {
height: 70rpx;
.search-input {
height: 70rpx;
font-size: 26rpx;
}
}
.cancel-text {
font-size: 26rpx;
}
}
.hot-search,
.search-categories {
padding: 20rpx;
}
.category-grid {
gap: 20rpx;
.category-item {
padding: 20rpx 15rpx;
.category-text {
font-size: 24rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,593 @@
<template>
<uni-nav-bar title="登录" fixed color="#8B2316" height="160rpx" :border="false" backgroundColor="#eeeeee"></uni-nav-bar>
<view class="login-container">
<!-- 主要内容区域 -->
<view class="main-content" >
<!-- 应用图标和名称 -->
<view class="app-info">
<view class="app-icon">
<up-image :src="logo" width="164rpx" height="167rpx" ></up-image>
</view>
<text class="app-name">专家端</text>
</view>
<!-- 手机号输入 -->
<view class="input-section">
<view class="input-group">
<up-image :src="phoneImg" width="36rpx" height="36rpx" ></up-image>
<input
class="phone-input"
type="number"
placeholder="请输入手机号"
v-model="phoneNumber"
maxlength="11"
/>
</view>
<!-- 验证码输入 -->
<view class="input-group">
<up-image :src="smsImg" width="36rpx" height="36rpx" ></up-image>
<view class="code-input-container">
<input
class="code-input"
type="number"
placeholder="请输入验证码"
v-model="smsCode"
maxlength="6"
/>
<view class="send-code-btn" @click="sendSmsCode" :class="{ disabled: isCountingDown }">
<text class="send-code-text">{{ countdownText }}</text>
</view>
</view>
</view>
</view>
<!-- 登录按钮 -->
<view class="login-button" @click="goPwdLogin" >
<text class="button-text">登录</text>
</view>
<view class="sms-login" @click="goPwdLogin">
<text class="sms-text">账号密码登录</text>
</view>
<!-- 其他登录方式 -->
<view class="other-login">
<!-- 微信登录 -->
<view class="wechat-login" @click="onWechatLogin">
<view class="wechat-icon">
<up-image :src="wxImg" width="100rpx" height="100rpx" ></up-image>
</view>
<text class="wechat-text">微信登录</text>
</view>
</view>
</view>
<!-- 底部协议 -->
<view class="agreement-section">
<view class="agreement-content">
<view class="checkbox" @click="toggleAgreement">
<up-image :src="checkImg" width="45rpx" height="45rpx" v-if="!isAgreed"></up-image>
<up-image :src="checkOnImg" width="45rpx" height="45rpx" v-else></up-image>
</view>
<view class="agreement-text">
<text class="text-content">我已阅读并同意</text>
<text class="link-text" @click="onServiceTerms">中国移动认证服务条款</text>
<text class="text-content"></text>
<text class="link-text" @click="onPrivacyPolicy">肝胆相照隐私政策</text>
<text class="text-content"></text>
<text class="link-text" @click="onUserAgreement">肝胆相照用户服务协议</text>
<text class="text-content">并使用本机号码登录并注册</text>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted, computed } from 'vue';
import { onShow, onLoad } from "@dcloudio/uni-app";
import auth from "@/utils/auth";
import logo from "@/static/icon_login_logo.png"
import wxImg from "@/static/weixin_login.png"
import checkImg from "@/static/login_new_unselect.png"
import checkOnImg from "@/static/login_new_select.png"
import phoneImg from "@/static/phone.png"
import smsImg from "@/static/sms.png"
import pwdImg from "@/static/pwd.png"
const customStyle = reactive({
height: "100rpx",
fontSize: "36rpx",
backgroundColor:'#8B2316',
borderRadius: '50rpx'
});
//
const isAgreed = ref(false);
//
const phoneNumber = ref('');
const smsCode = ref('');
//
const isCountingDown = ref(false);
const countdown = ref(0);
const countdownText = computed(() => {
if (isCountingDown.value) {
return `${countdown.value}s后重发`;
}
return '获取验证码';
});
//
const canLogin = computed(() => {
return isAgreed.value && phoneNumber.value.length === 11 && smsCode.value.length === 6;
});
const goPwdLogin=()=>{
uni.redirectTo({
url:'/pages_app/pwdLogin/pwdLogin'
})
}
const alertAgree=()=>{
uni.showToast({
title: '请先同意用户协议',
icon:'none'
})
};
//
const sendSmsCode = () => {
if (isCountingDown.value) {
return;
}
if (!phoneNumber.value) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!/^1[3-9]\d{9}$/.test(phoneNumber.value)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
//
isCountingDown.value = true;
countdown.value = 60;
const timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer);
isCountingDown.value = false;
}
}, 1000);
//
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
// API
console.log('发送验证码到:', phoneNumber.value);
};
//
const onSmsLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
if (!phoneNumber.value) {
uni.showToast({
title: '请输入手机号',
icon: 'none'
});
return;
}
if (!/^1[3-9]\d{9}$/.test(phoneNumber.value)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
if (!smsCode.value) {
uni.showToast({
title: '请输入验证码',
icon: 'none'
});
return;
}
if (smsCode.value.length !== 6) {
uni.showToast({
title: '请输入6位验证码',
icon: 'none'
});
return;
}
console.log('短信验证码登录');
uni.showLoading({
title: '登录中...'
});
//
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '登录成功',
icon: 'success'
});
//
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
});
}, 1500);
}, 2000);
};
//
const onWechatLogin = () => {
if (!isAgreed.value) {
uni.showToast({
title: '请先同意相关协议',
icon: 'none'
});
return;
}
console.log('微信登录');
uni.showToast({
title: '微信登录功能开发中',
icon: 'none'
});
};
//
const toggleAgreement = () => {
isAgreed.value = !isAgreed.value;
};
//
const onServiceTerms = () => {
console.log('查看服务条款');
uni.navigateTo({
url: '/pages_app/agreement/service-terms'
});
};
//
const onPrivacyPolicy = () => {
console.log('查看隐私政策');
uni.navigateTo({
url: '/pages_app/agreement/privacy-policy'
});
};
//
const onUserAgreement = () => {
console.log('查看用户协议');
uni.navigateTo({
url: '/pages_app/agreement/user-agreement'
});
};
//
onLoad(() => {
console.log('短信登录页面加载完成');
});
//
onShow(() => {
console.log('短信登录页面显示');
});
//
onMounted(() => {
console.log('短信登录页面组件已挂载');
});
</script>
<style>
.login-container {
min-height: calc(100vh - 160rpx);
background-color: #ffffff;
display: flex;
flex-direction: column;
}
/* 主要内容区域 */
.main-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 100rpx 60rpx 0;
}
/* 应用信息 */
.app-info {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 80rpx;
}
.app-icon {
border-radius: 24rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
position: relative;
}
.app-name {
font-size: 32rpx;
font-weight: bold;
color: #8B2316;
}
/* 输入区域 */
.input-section {
width: 100%;
margin-bottom: 60rpx;
border: 2rpx solid #e5e5e5;
border-radius: 8rpx;
}
.input-group {
display: flex;
padding-left: 20rpx;
align-items: center;
}
.input-group:first-child{
border-bottom: 2rpx solid #e5e5e5;
}
.input-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
font-weight: 500;
}
.phone-input {
width: 100%;
height: 80rpx;
padding: 0 40rpx;
font-size: 32rpx;
background-color: #fff;
box-sizing: border-box;
}
.code-input-container {
display: flex;
align-items: center;
gap: 20rpx;
}
.code-input {
flex: 1;
height: 80rpx;
border-radius: 50rpx;
padding: 0 40rpx;
font-size: 32rpx;
background-color: #fff;
box-sizing: border-box;
}
.send-code-btn {
width: 200rpx;
height: 44rpx;
background-color: #fff;
border-radius: 50rpx;
margin-right: 10px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border: 2rpx solid #8B2316;
transition: background-color 0.2s ease;
}
.send-code-btn.disabled {
background-color: #ccc;
cursor: not-allowed;
}
.send-code-text {
font-size: 25rpx;
color:#8B2316;
}
/* 登录按钮 */
.login-button {
width: 100%;
height: 80rpx;
background-color: #8B2316;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
cursor: pointer;
transition: background-color 0.2s ease;
}
.login-button.disabled {
background-color: #ccc;
cursor: not-allowed;
}
.login-button:active:not(.disabled) {
background-color: #6B1A0F;
}
.button-text {
font-size: 32rpx;
color: white;
font-weight: bold;
}
/* 其他登录方式 */
.other-login {
width: 100%;
margin-bottom: 40rpx;
}
.divider {
display: flex;
align-items: center;
margin-bottom: 60rpx;
}
.line {
flex: 1;
height: 2rpx;
background-color: #e5e5e5;
}
.divider-text {
padding: 0 30rpx;
font-size: 26rpx;
color: #999;
}
/* 微信登录 */
.wechat-login {
display: flex;
flex-direction: column;
align-items: center;
gap: 20rpx;
cursor: pointer;
}
.wechat-icon {
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.wechat-text {
font-size: 28rpx;
color: #8B2316;
}
/* 底部协议 */
.agreement-section {
padding: 40rpx 60rpx 60rpx;
}
.agreement-content {
display: flex;
align-items: flex-start;
gap: 20rpx;
}
.checkbox {
width: 45rpx;
height:45rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 4rpx;
cursor: pointer;
transition: all 0.3s ease-in-out;
}
.agreement-text {
flex: 1;
font-size: 24rpx;
color: #666;
line-height: 1.6;
}
.text-content {
color: #666;
}
.link-text {
color: #8B2316;
}
/* 响应式调整 */
@media (max-width: 750rpx) {
.main-content {
padding: 80rpx 40rpx 0;
}
.app-icon {
width: 100rpx;
height: 100rpx;
}
.phone-input,
.code-input,
.send-code-btn {
height: 90rpx;
}
.login-button {
height: 90rpx;
}
.button-text {
font-size: 30rpx;
}
.agreement-section {
padding: 30rpx 40rpx 50rpx;
}
.agreement-text {
font-size: 22rpx;
}
}
.sms-login {
width:100%;
margin-bottom:0rpx;
cursor: pointer;
}
.sms-text {
font-size: 28rpx;
color: #8B2316;
}
</style>

468
pages_app/video/video.vue Normal file
View File

@ -0,0 +1,468 @@
<template>
<view class="video-page">
<!-- Header -->
<view class="header">
<view class="header-left" @click="goBack">
<uni-icons type="left" size="20" color="#8B4513"></uni-icons>
</view>
<view class="header-title">肝胆视频</view>
<view class="header-right">
<uni-icons type="search" size="20" color="#8B4513" style="margin-right: 15rpx;" @click="goSearch"></uni-icons>
<uni-icons type="list" size="20" color="#8B4513"></uni-icons>
</view>
</view>
<!-- Main Content -->
<scroll-view
class="scroll-view"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="refreshing"
@refresherrefresh="onRefresh"
@scrolltolower="onLoadMore"
lower-threshold="100"
>
<!-- Featured Banner -->
<view class="banner-section" v-if="bannerVideo">
<image class="banner-image" :src="bannerVideo.thumbnail" mode="aspectFill"></image>
<view class="banner-overlay">
<view class="banner-title">{{bannerVideo.title}}</view>
</view>
</view>
<!-- Filter Tabs -->
<view class="filter-tabs">
<view
class="tab-item"
:class="{ active: activeTab === 0 }"
@click="switchTab(0)"
>
<uni-icons type="list" size="16" color="#666"></uni-icons>
<text class="tab-text">全部视频</text>
<uni-icons type="bottom" size="12" color="#666"></uni-icons>
</view>
<view
class="tab-item"
:class="{ active: activeTab === 1 }"
@click="switchTab(1)"
>
<text class="tab-text">最新</text>
<uni-icons type="top" size="12" color="#E74C3C"></uni-icons>
</view>
<view
class="tab-item"
:class="{ active: activeTab === 2 }"
@click="switchTab(2)"
>
<text class="tab-text">筛选</text>
<uni-icons type="paperplane" size="12" color="#666"></uni-icons>
</view>
</view>
<!-- Video List -->
<view class="video-list">
<view
class="video-item"
v-for="(video, index) in videoList"
:key="video.id"
@click="playVideo(video)"
>
<view class="video-thumbnail">
<image :src="video.thumbnail" mode="aspectFill"></image>
<view class="play-icon">
<uni-icons type="play-filled" size="24" color="#fff"></uni-icons>
</view>
</view>
<view class="video-info">
<view class="video-title">{{video.title}}</view>
<view class="video-meta">
<text class="author">{{video.author}}</text>
<view class="stats">
<uni-icons type="eye" size="14" color="#999"></uni-icons>
<text class="view-count">{{video.viewCount}}</text>
</view>
</view>
</view>
</view>
</view>
<!-- Loading More -->
<uni-load-more
v-if="videoList.length > 0"
:status="loadMoreStatus"
:content-text="{
contentdown: '上拉加载更多',
contentrefresh: '正在加载...',
contentnomore: '没有更多数据了'
}"
></uni-load-more>
<!-- Empty State -->
<view class="empty-state" v-if="videoList.length === 0 && !loading">
<image src="/static/empty-video.png" mode="aspectFit"></image>
<text>暂无视频内容</text>
</view>
</scroll-view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import api from '@/api/api.js';
//
const videoList = ref([]);
const bannerVideo = ref(null);
const activeTab = ref(1); // ""
const loading = ref(false);
const refreshing = ref(false);
const loadMoreStatus = ref('more'); // more, loading, noMore
const currentPage = ref(1);
const pageSize = ref(10);
const hasMoreData = ref(true);
//
onMounted(() => {
});
onShow(() => {
//loadVideoData();
getMockVideoData()
//
});
//
const loadVideoData = async (isRefresh = false) => {
if (loading.value && !isRefresh) return;
loading.value = true;
try {
// API
const response = await api.getVideoList({
page: currentPage.value,
pageSize: pageSize.value,
category: activeTab.value //
});
if (response.data.code === 200) {
const { list, hasMore } = response.data.data;
if (isRefresh) {
videoList.value = list;
currentPage.value = 1;
} else {
videoList.value = [...videoList.value, ...list];
}
// banner
if (isRefresh || currentPage.value === 1) {
bannerVideo.value = list[0];
}
hasMoreData.value = hasMore;
loadMoreStatus.value = hasMoreData.value ? 'more' : 'noMore';
} else {
throw new Error(response.data.message || '获取数据失败');
}
} catch (error) {
console.error('加载视频失败:', error);
// API使
const mockData = await getMockVideoData(currentPage.value, pageSize.value);
if (isRefresh) {
videoList.value = mockData.list;
currentPage.value = 1;
} else {
videoList.value = [...videoList.value, ...mockData.list];
}
// banner
if (isRefresh || currentPage.value === 1) {
bannerVideo.value = mockData.list[0];
}
hasMoreData.value = mockData.hasMore;
loadMoreStatus.value = hasMoreData.value ? 'more' : 'noMore';
uni.showToast({
title: '网络连接异常,显示离线数据',
icon: 'none'
});
} finally {
loading.value = false;
refreshing.value = false;
}
};
//
const onRefresh = () => {
refreshing.value = true;
currentPage.value = 1;
hasMoreData.value = true;
loadVideoData(true);
};
//
const onLoadMore = () => {
if (!hasMoreData.value || loading.value) return;
loadMoreStatus.value = 'loading';
currentPage.value++;
loadVideoData();
};
//
const switchTab = (tabIndex) => {
activeTab.value = tabIndex;
//
currentPage.value = 1;
hasMoreData.value = true;
loadVideoData(true);
};
//
const playVideo = (video) => {
uni.navigateTo({
url: `/pages/videoDetail/videoDetail?id=${video.id}`
});
};
//
const goBack = () => {
uni.navigateBack();
};
//
const goSearch = () => {
uni.navigateTo({
url: '/pages_app/search/search'
});
};
// - API
const getMockVideoData = (page, size) => {
return new Promise((resolve) => {
setTimeout(() => {
const mockList = [];
const startIndex = (page - 1) * size;
for (let i = 0; i < size; i++) {
const index = startIndex + i;
mockList.push({
id: `video_${index}`,
title: index === 0 ? '《2025年版慢加急性肝衰竭指南》解读' :
index % 4 === 1 ? '自身免疫性肝病专栏免疫治疗的双刃剑——1例自…' :
index % 4 === 2 ? '徐医感染:硬化出血发热路,关关难过关关过' :
index % 4 === 3 ? '徐医感染:一场呼吸的迷局' :
'南京市第二医院疑难肝病病理读片会暨疑难肝病MDT',
thumbnail: '/static/video-thumb-' + (index % 4 + 1) + '.png',
author: index % 3 === 0 ? '首都医…' :
index % 3 === 1 ? '徐州医…' : '南京市…',
viewCount: Math.floor(Math.random() * 2000) + 100,
duration: '15:30'
});
}
resolve({
list: mockList,
hasMore: page < 5 // 5
});
}, 1000);
});
};
</script>
<style scoped>
.video-page {
background-color: #f5f5f5;
height: 100vh;
display: flex;
flex-direction: column;
}
/* Header Styles */
.header {
background-color: #fff;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
position: relative;
z-index: 100;
}
.header-left, .header-right {
display: flex;
align-items: center;
}
.header-title {
font-size: 36rpx;
font-weight: 600;
color: #8B4513;
}
/* Scroll View */
.scroll-view {
flex: 1;
background-color: #f5f5f5;
}
/* Banner Styles */
.banner-section {
position: relative;
height: 400rpx;
margin-bottom: 20rpx;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: linear-gradient(transparent, rgba(0,0,0,0.7));
padding: 60rpx 30rpx 30rpx;
}
.banner-title {
color: #fff;
font-size: 32rpx;
font-weight: 600;
line-height: 1.4;
}
/* Filter Tabs */
.filter-tabs {
background-color: #fff;
display: flex;
padding: 20rpx 30rpx;
margin-bottom: 20rpx;
}
.tab-item {
display: flex;
align-items: center;
margin-right: 60rpx;
padding: 10rpx 0;
}
.tab-item.active .tab-text {
color: #E74C3C;
font-weight: 600;
}
.tab-text {
margin: 0 8rpx;
font-size: 28rpx;
color: #666;
}
/* Video List */
.video-list {
padding: 0 20rpx;
}
.video-item {
background-color: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
}
.video-thumbnail {
position: relative;
height: 200rpx;
}
.video-thumbnail image {
width: 100%;
height: 100%;
}
.play-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(0,0,0,0.6);
border-radius: 50%;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.video-info {
padding: 24rpx;
}
.video-title {
font-size: 28rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
margin-bottom: 16rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
line-clamp: 2;
overflow: hidden;
}
.video-meta {
display: flex;
justify-content: space-between;
align-items: center;
}
.author {
font-size: 24rpx;
color: #999;
}
.stats {
display: flex;
align-items: center;
}
.view-count {
font-size: 24rpx;
color: #999;
margin-left: 8rpx;
}
/* Empty State */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty-state image {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
opacity: 0.5;
}
.empty-state text {
color: #999;
font-size: 28rpx;
}
</style>

393
pages_app/zhinan/zhinan.vue Normal file
View File

@ -0,0 +1,393 @@
<template>
<uni-nav-bar
left-icon="left"
title="诊疗指南"
@clickLeft="goBack"
fixed
color="#8B2316"
height="140rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
<view class="zhinan-page">
<!-- 导航栏 -->
<!-- 固定搜索栏 -->
<view class="search-container-fixed filter-bar">
<view class="search-box">
<uni-icons type="search" size="16" color="#999"></uni-icons>
<text class="search-text">搜索</text>
</view>
<view class="divider"></view>
<view class="filter-item" @click="showFilterPopup">
<text>筛选</text>
<up-image :src="isFilterActive ? filterOn : filter" width="30rpx" height="30rpx" ></up-image>
</view>
</view>
<!-- 指南分类网格 -->
<view class="guidelines-grid">
<view
class="guideline-item"
v-for="(item, index) in guidelineCategories"
:key="index"
@click="enterCategory(item)"
>
<view class="item-image" :style="{ backgroundColor: item.bgColor }">
<image :src="item.icon" mode="aspectFit" class="category-icon"></image>
</view>
<view class="item-content">
<text class="category-title">{{ item.title }}</text>
<text class="category-count">({{ item.count }})</text>
</view>
</view>
</view>
<!-- 底部导航 -->
<view class="bottom-tabbar">
<view class="tab-item active" @click="switchTab('zhinan')">
<text class="tab-text active">诊疗指南</text>
</view>
<view class="tab-item" @click="switchTab('qikan')">
<text class="tab-text">期刊杂志</text>
</view>
<view class="tab-item" @click="switchTab('tools')">
<text class="tab-text">常用工具</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { onShow } from "@dcloudio/uni-app";
import upImg from "@/static/cb_up.png"
import downImg from "@/static/cb_up.png"
import filter from "@/static/cb_screen_no.png"
import filterOn from "@/static/cb_screen_yes.png"
//
const searchText = ref('');
const guidelineCategories = ref([]);
//
onMounted(() => {
initGuidelineData();
});
onShow(() => {
//
});
//
const initGuidelineData = () => {
guidelineCategories.value = [
{
title: '肝肿瘤相关',
count: 0,
bgColor: '#2C2C2C',
icon: '/static/liver_icon.png',
category: 'liver'
},
{
title: '感染相关',
count: 0,
bgColor: '#9C6BCF',
icon: '/static/infection_icon.png',
category: 'infection'
},
{
title: '消化相关',
count: 0,
bgColor: '#5CB3E8',
icon: '/static/digestion_icon.png',
category: 'digestion'
},
{
title: '中医/中西医结合',
count: 192,
bgColor: '#4A90E2',
icon: '/static/tcm_icon.png',
category: 'tcm'
},
{
title: '新型冠状病毒肺炎',
count: 450,
bgColor: '#1C1C1C',
icon: '/static/covid_icon.png',
category: 'covid'
},
{
title: 'AASLD',
count: 63,
bgColor: '#FF6B35',
icon: '/static/aasld_icon.png',
category: 'aasld'
},
{
title: 'EASL',
count: 75,
bgColor: '#1E88E5',
icon: '/static/easl_icon.png',
category: 'easl'
},
{
title: '其他指南',
count: 928,
bgColor: '#26C6DA',
icon: '/static/other_icon.png',
category: 'other'
},
{
title: '国内指南',
count: 375,
bgColor: '#42A5F5',
icon: '/static/domestic_icon.png',
category: 'domestic'
},
{
title: '共识指导',
count: 0,
bgColor: '#66BB6A',
icon: '/static/consensus_icon.png',
category: 'consensus'
},
{
title: '专家解读',
count: 0,
bgColor: '#FFA726',
icon: '/static/expert_icon.png',
category: 'expert'
}
];
};
//
const enterCategory = (item) => {
console.log('进入分类:', item.category);
uni.navigateTo({
url: `/pages/guidelineList/guidelineList?category=${item.category}&title=${item.title}`
});
};
//
const showFilterDialog = () => {
console.log('显示筛选');
//
};
//
const switchTab = (tabName) => {
console.log('切换到:', tabName);
switch(tabName) {
case 'qikan':
uni.switchTab({
url: '/pages/qikan/qikan'
});
break;
case 'tools':
uni.switchTab({
url: '/pages/tools/tools'
});
break;
}
};
//
const goBack = () => {
uni.navigateBack({
fail() {
uni.redirectTo({
url: '/pages/index/index'
});
}
});
};
</script>
<style lang="scss" scoped>
// SCSS Variables
$primary-color: #8B2316;
$bg-color: #f5f5f5;
$white: #fff;
$text-primary: #333;
$text-secondary: #666;
$text-light: #999;
$primary-color: #ff6b6b;
$theme-color: #8B2316;
$white: #fff;
$gray-bg: #f5f5f5;
$gray-light: #eee;
$gray-medium: #999;
$gray-dark: #666;
$text-color: #333;
//
$border-radius: 8px;
$border-radius-small: 6px;
$padding: 15px;
$padding-small: 10px;
.zhinan-page {
background-color: $bg-color;
min-height: 100vh;
padding-top: 140rpx; //
}
//
.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: 1px solid $gray-light;
.search-box {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
gap: 5px;
.search-text {
font-size: 14px;
color: $gray-medium;
}
}
.divider {
width: 1px;
height: 16px;
background-color: $gray-medium;
margin: 0 $padding;
}
.filter-item {
flex:1;
display: flex;
align-items: center;
justify-content: center;
gap: 3px;
font-size: 14px;
color: #999;
}
}
//
.guidelines-grid {
display: flex;
flex-wrap: wrap;
padding: 0 30rpx;
gap: 20rpx;
margin-top: 100rpx; // (80rpx + )
.guideline-item {
width: calc(33.333% - 14rpx);
background-color: $white;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
transition: transform 0.2s ease;
&:active {
transform: scale(0.98);
}
.item-image {
height: 160rpx;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.category-icon {
width: 80rpx;
height: 80rpx;
}
}
.item-content {
padding: 20rpx 16rpx;
text-align: center;
.category-title {
display: block;
font-size: 26rpx;
color: $text-primary;
line-height: 1.4;
margin-bottom: 8rpx;
}
.category-count {
font-size: 22rpx;
color: $text-light;
}
}
}
}
//
.bottom-tabbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background-color: $white;
display: flex;
align-items: center;
justify-content: space-around;
border-top: 1rpx solid #f0f0f0;
z-index: 100;
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
flex: 1;
height: 100rpx;
gap: 8rpx;
&.active {
color: #fff;
background-color: #8B2316;
}
.tab-icon {
width: 44rpx;
height: 44rpx;
}
.tab-text {
font-size: 32rpx;
color: $text-secondary;
&.active {
color: #fff;
}
}
}
.tab-item:nth-child(2){
border-right: 2rpx solid #eee;
border-left: 2rpx solid #eee;
}
}
// tabbar
.guidelines-grid {
padding-bottom: 140rpx;
}
</style>

BIN
static/all_video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/bibglijiaoliu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
static/big_home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/big_home_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/big_my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/big_my_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/bo_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
static/bofang.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
static/cb_down.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/cb_screen_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/cb_screen_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/cb_up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/classroom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/classroomOn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/course_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
static/course_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

20
static/customicons.css Normal file
View File

@ -0,0 +1,20 @@
@font-face {
font-family: "customicons"; /* Project id 2878519 */
src:url('/static/customicons.ttf') format('truetype');
}
.customicons {
font-family: "customicons" !important;
}
.youxi:before {
content: "\e60e";
}
.wenjian:before {
content: "\e60f";
}
.zhuanfa:before {
content: "\e610";
}

BIN
static/customicons.ttf Normal file

Binary file not shown.

BIN
static/cyhhk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

BIN
static/czjh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/delete_paper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
static/download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
static/education.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/educationOn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/email_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/eye_close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/eye_open.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/fpgl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/fulicard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
static/fxxbb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/ganbingxueyuan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
static/gandankejian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
static/gandanshipin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
static/ghsjh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/home_more.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/home_nor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/home_sel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
static/hzfz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/hzsh.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
static/icon_home_video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
static/icon_login_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
static/item_doctor_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/item_doctor_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/item_drug_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/item_drug_pass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/item_hospital_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
static/item_mall_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/item_mall_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/item_news_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/item_news_pass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/item_patient_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
static/item_patient_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/item_science_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
static/item_video_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
static/item_video_pass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
static/item_wf_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/item_wf_pass.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/jing_sign.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/jingdian_bingli.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
static/jingdianbingli.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
static/jingpin_no.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/jingpin_yes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/jingpingke.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

BIN
static/jingpinkecheng.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
static/kcmx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/keyanxiangmu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
static/kjmx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Some files were not shown because too many files have changed in this diff Show More