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
+607
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
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>
+487
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
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
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>
+593
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
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
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>