1.6提交

This commit is contained in:
zoujiandong 2026-01-06 08:36:02 +08:00
parent 8025b2abab
commit 56c645a75c
42 changed files with 3902 additions and 2595 deletions

View File

@ -61,6 +61,14 @@ export default {
});
}
}
if(event.indexOf('paySuccess') > -1){
console.log('app.vue监听到成功支付');
if(data.type=='GandanFile'){
uni.$emit('paySuccess',{
type:'GandanFile',
});
}
}
});
// #endif
} catch (error) {

View File

@ -599,6 +599,7 @@ const api = {
getOrderStatus(data){
return request('/expertPay/getOrderStatus', data, 'post', false);
},
getOrderStatus(data){
return request('/expertPay/getOrderStatus', data, 'post', false);
},
@ -660,6 +661,17 @@ const api = {
downloadGanDanFile(data){
return request('/expertAPI/downloadGanDanFile', data, 'post', false,'application/json',{},'arraybuffer');
},
downloadGanDanFileV2(data){
return request('/expertAPI/downloadGanDanFileV2', data, 'post', false);
},
feedBack(data){
return request('/expert/feedBack', data, 'post', false);
},
getPointUnitPrice(data){
return request('/expertApp/getPointUnitPrice', data, 'post', false);
},
}
export default api

View File

@ -2,8 +2,8 @@
"name" : "肝胆相照专家版",
"appid" : "__UNI__89F511F",
"description" : "",
"versionName" : "4.1.5",
"versionCode" : 100,
"versionName" : "4.1.9",
"versionCode" :419,
"transformPx" : false,
"app-plus" : {
/* 5+App */
@ -31,7 +31,8 @@
"VideoPlayer" : {},
"OAuth" : {},
"Barcode" : {},
"Camera" : {}
"Camera" : {},
"Payment" : {}
},
/* */
"distribute" : {

View File

@ -488,6 +488,57 @@
"bounce": "none"
}
}
},
{
"path": "buyPoint/buyPoint",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "myWelfare/myWelfare",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "myWelfareCard/myWelfareCard",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "myPoint/myPoint",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "积分",
"app": {
"bounce": "none"
}
}
},
{
"path": "pointGoods/pointGoods",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "uni-app分页",
"app": {
"bounce": "none"
}
}
},
{
"path": "newsList/newsList",
@ -508,6 +559,16 @@
"bounce": "none"
}
}
},
{
"path": "patientInfo/patientInfo",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "患者信息",
"app": {
"bounce": "none"
}
}
},
{
"path": "replayText/replayText",
@ -743,16 +804,7 @@
// }
// },
// {
// "path": "myWelfareCard/myWelfareCard",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "uni-app分页",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "myWelfareCard/exchange",
// "style": {
@ -773,27 +825,7 @@
// }
// },
// {
// "path": "buyPoint/buyPoint",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "uni-app分页",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "pointGoods/pointGoods",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "uni-app分页",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "msg/msg",
// "style": {
@ -804,16 +836,7 @@
// }
// }
// },
// {
// "path": "myWelfare/myWelfare",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "uni-app分页",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "caseRecord/caseRecord",
@ -1178,15 +1201,7 @@
// }
// },
// {
// "path": "myPoint/myPoint",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "积分",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "feedback/feedback",
// "style": {
@ -1221,83 +1236,83 @@
]
},
{
"root": "pages_goods",
"pages": [
{
"path": "coupon/coupon",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "积分券",
"app": {
"bounce": "none"
}
// {
// "root": "pages_goods",
// "pages": [
// {
// "path": "coupon/coupon",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "积分券",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "pointMall/pointMall",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "积分商城",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "myRedemption/myRedemption",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "我的兑换",
// "app": {
// "bounce": "none"
// }
// }
// },
}
},
{
"path": "pointMall/pointMall",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "积分商城",
"app": {
"bounce": "none"
}
}
},
{
"path": "myRedemption/myRedemption",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "我的兑换",
"app": {
"bounce": "none"
}
}
},
// {
// "path": "productDetail/productDetail",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "商品详情",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "exchange/index",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "在线兑换",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "exchange/address_list",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "地址管理",
// "app": {
// "bounce": "none"
// }
// }
// },
// {
// "path": "exchange/address",
// "style": {
// "navigationStyle": "custom",
// "navigationBarTitleText": "收货地址",
// "app": {
// "bounce": "none"
// }
// }
// }
// ]
// },
{
"path": "productDetail/productDetail",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "商品详情",
"app": {
"bounce": "none"
}
}
},
{
"path": "exchange/index",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "在线兑换",
"app": {
"bounce": "none"
}
}
},
{
"path": "exchange/address_list",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "地址管理",
"app": {
"bounce": "none"
}
}
},
{
"path": "exchange/address",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "收货地址",
"app": {
"bounce": "none"
}
}
}
]
}
// {
// "root": "pages_chat",
// "pages": [

View File

@ -1,5 +1,5 @@
<template>
<uni-nav-bar
<!-- <uni-nav-bar
left-icon="left"
title="购买积分"
@clickLeft="goBack"
@ -8,7 +8,8 @@
height="180rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
></uni-nav-bar> -->
<navBar :title="'购买积分'" ></navBar>
<view class="buy-point-page">
@ -46,20 +47,52 @@
</view>
</view>
</view>
<unidialog
:visible="freeVisible"
:content="freeContent"
@close="freeClose"
@confirm="freeConfirm"
></unidialog>
</template>
<script setup>
import { ref, computed } from 'vue';
import api from '@/api/api';
import { onLoad } from '@dcloudio/uni-app';
import unidialog from '@/components/dialog/dialog.vue';
import navBar from '@/components/navBar/navBar.vue';
const freeVisible = ref(false);
const freeContent = ref('您确定是否购买?');
const freeClose = () => {
freeVisible.value = false;
};
const freeConfirm = () => {
freeVisible.value = false;
};
onLoad(() => {
getPointUnitPrice();
});
const pointUnitPrice = ref(1);
// - 5
const packages = ref([
{ id: 1, points: 500, price: '45.00' },
{ id: 2, points: 1000, price: '88.00' },
{ id: 3, points: 2500, price: '198.00' },
{ id: 4, points: 5000, price: '398.00' },
{ id: 5, points: 10000, price: '758.00' }
{ id: 1, points: 500, price: 500*pointUnitPrice.value/100 },
{ id: 2, points: 1000, price: 1000*pointUnitPrice.value/100 },
{ id: 3, points: 2500, price: 2500*pointUnitPrice.value/100 },
{ id: 4, points: 5000, price: 5000*pointUnitPrice.value/100 },
{ id: 5, points: 10000, price: 10000*pointUnitPrice.value/100 }
]);
const getPointUnitPrice = () => {
api.getPointUnitPrice().then(res => {
if(res.code==200){
pointUnitPrice.value=Number(res.PointUnitPrice);
console.log(pointUnitPrice.value);
packages.value.forEach(pkg => {
pkg.price = pkg.points * pointUnitPrice.value / 100;
});
}
});
};
//
const selectedPackage = ref(0); //
@ -96,18 +129,7 @@
}
const packageData = selectedPackageData.value;
uni.showModal({
title: '确认购买',
content: `确认购买${packageData.points}积分,支付金额¥${packageData.price}`,
success: (res) => {
if (res.confirm) {
uni.showToast({
title: '购买成功',
icon: 'none'
});
}
}
});
freeVisible.value=true;
};
</script>
@ -138,7 +160,7 @@
}
.buy-point-page {
height: calc(100vh - 180rpx);
height: 100vh;
background-color: $bg-color;
overflow: hidden; //
@ -224,6 +246,7 @@
}
.main-content {
margin-top: calc(var(--status-bar-height) + 44px);
padding: 40rpx 0rpx;
.page-title {

View File

@ -4,6 +4,7 @@
<navBar title="公益咨询" />
<view class="tabs">
<view :class="['tab', activeTab==='new' ? 'active' : '']" @tap="switchTab('new')">新的咨询</view>
<view class="bar"></view>
<view :class="['tab', activeTab==='mine' ? 'active' : '']" @tap="switchTab('mine')">我已回答</view>
</view>
<view class="tabs-spacer"></view>
@ -20,14 +21,18 @@
>
<view v-for="(item, idx) in displayList" :key="idx" class="consult-card" @click="goDetail(item.id,item.patientUuid)">
<view class="card-head">
<view class="namebox">
<text class="user-name">{{ item.maskName }}</text>
<text class="user-avatar" v-if="bottomActive!=='quick'">({{item.sex==1?'':'' }}<text decode>&nbsp;</text>{{ calcAge(item.birthDate) }})</text>
</view>
<text class="date">{{ item.date }}</text>
</view>
<view class="card-body">
<text class="content">{{ item.content }}</text>
<text class="content twoline">{{ item.disease_describe }}</text>
</view>
<view class="card-foot" v-if="bottomActive==='multi'">
<text class="reply-count">{{ item.answer_num }}位医生已回答</text>
<text class="reply-count" v-if="item.answer_num>0">{{ item.answer_num }}位医生已回答</text>
<text class="reply-count-none" v-else>暂未有医生回答</text>
<view v-if="item.tag" class="tag">{{ item.tag }}</view>
</view>
<view class="card-foot" v-else>
@ -52,7 +57,7 @@
<script setup>
import { ref, computed } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { onShow,onBackPress } from '@dcloudio/uni-app'
import navBar from '@/components/navBar/navBar.vue'
import empty from '@/components/empty/empty.vue'
import api from '@/api/api.js'
@ -65,6 +70,10 @@ const pageSize=ref(10)
const hasMore = ref(true)
const isLoading = ref(false)
const isRefreshing = ref(false)
onBackPress(()=>{
plus.runtime.quit();
return true;
})
const goDetail=async(uuid,patientUuid)=>{
if(bottomActive.value==='quick'){
if(activeTab.value==='new'){
@ -73,11 +82,16 @@ const goDetail=async(uuid,patientUuid)=>{
})
}else{
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
let conversationId=userId+'|1|'+patientUuid.toLowerCase();
await uni.$UIKitStore.uiStore.selectConversation(conversationId)
navTo({
url:'/pages_chat/chat/index?from=consult&&patientUuid='+patientUuid+'&&uuid='+uuid
uni.sendNativeEvent('goConsultPage', {
msg: 'chat'
},ret => {
console.log(ret);
})
//let conversationId=userId+'|1|'+patientUuid.toLowerCase();
//await uni.$UIKitStore.uiStore.selectConversation(conversationId)
// navTo({
// url:'/pages_chat/chat/index?from=consult&&patientUuid='+patientUuid+'&&uuid='+uuid
// })
}
}else{
@ -97,6 +111,22 @@ function maskName(name){
const first = name.slice(0,1)
return `${first}**`
}
// birth 'YYYY-MM-DD' Date /
function calcAge(birth) {
if (!birth) return ''
const birthDate = new Date(birth)
if (isNaN(birthDate.getTime())) {
return ''
}
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const m = today.getMonth() - birthDate.getMonth()
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--
}
// 0
return age >= 0 ? age : ''
}
const newConsultList=async(isRefresh=false)=>{
if(isLoading.value) return
isLoading.value = true
@ -113,10 +143,12 @@ const newConsultList=async(isRefresh=false)=>{
if(res && res.code===200 && res.data && res.data.consult_list){
const list = Array.isArray(res.data.consult_list.list) ? res.data.consult_list.list : []
const mapped = list.map(item=>({
maskName: maskName(item.realName || ''),
date: (item.createDate || '').slice(0,10),
maskName: item.realName,
date: (item.createDate || '').slice(0,16),
content: item.content || '',
replyCount: 0,
sex: item.sex || 0,
birthDate: item.birthDate || item.birthday,
tag: item.diseaseName || '',
id:item.uuid || '',
patientUuid:item.patientUuid || ''
@ -150,10 +182,12 @@ const consultListHis=async(isRefresh=false)=>{
if(res.code==200){
const list = Array.isArray(res.data.list) ? res.data.list : []
const mapped = list.map(item=>({
maskName: maskName(item.realName || ''),
date: (item.createDate || '').slice(0,10),
maskName: item.realName,
date: (item.createDate || '').slice(0,16),
content: item.content || '',
replyCount: 0,
sex: item.sex || 0,
birthDate: item.birthDate || item.birthday,
tag: item.diseaseName || '',
id:item.uuid || '',
patientUuid:item.patientUuid || ''
@ -191,7 +225,9 @@ const listNewInterrogation=async(isRefresh=false)=>{
maskName: maskName(item.name || ''),
date: (item.create_date || '').slice(0,10),
content: item.your_question || '',
disease_describe:item.your_question || '',
disease_describe:item.disease_describe || '',
sex: item.sex || 0,
birthDate: item.birthday || '',
answer_num: item.answer_num || 0,
tag: item.disease_name || '',
id:item.step1_uuid || ''
@ -229,6 +265,8 @@ const listMyAnsweredInterrogation=async(isRefresh=false)=>{
date: (item.create_date || '').slice(0,10),
content: item.your_question || '',
disease_describe:item.disease_describe || '',
sex: item.sex || 0,
birthDate: item.birthday || '',
answer_num: item.answer_num || 0,
tag: item.disease_name || '',
id:item.step1_uuid || ''
@ -249,17 +287,19 @@ const listMyAnsweredInterrogation=async(isRefresh=false)=>{
onShow(()=>{
page.value = 1
hasMore.value = true;
listNew.value = [];
listMine.value=[];
if(bottomActive.value==='quick'){
if(activeTab.value==='new'){
newConsultList(true)
newConsultList(false)
}else{
consultListHis(true)
consultListHis(false)
}
}else{
if(activeTab.value==='new'){
listNewInterrogation(true)
listNewInterrogation(false)
}else{
listMyAnsweredInterrogation(true)
listMyAnsweredInterrogation(false)
}
}
@ -276,18 +316,20 @@ function switchTab(key) {
isLoading.value = false;
listNew.value = [];
listMine.value=[];
page.value = 1
hasMore.value = true;
if(bottomActive.value==='quick'){
if(activeTab.value==='new'){
newConsultList(true)
newConsultList(false)
}else{
consultListHis(true)
consultListHis(false)
}
}else{
if(activeTab.value==='new'){
listNewInterrogation(true)
listNewInterrogation(false)
}else{
listMyAnsweredInterrogation(true)
listMyAnsweredInterrogation(false)
}
}
@ -303,25 +345,32 @@ function goBack() {
}
// tab
const bottomActive = ref('quick')
const bottomActive = ref('multi')
const switchBottomTab=(key)=>{
isLoading.value = false;
bottomActive.value = key;
page.value = 1
hasMore.value = true;
listNew.value = [];
listMine.value=[];
if(key=='quick'){
try {
plus.runtime.quit();
} catch (error) {
}
if(activeTab.value==='new'){
newConsultList(true)
newConsultList(false)
}else{
consultListHis(true)
consultListHis(false)
}
}else{
if(activeTab.value==='new'){
console.log('listNewInterrogation')
listNewInterrogation(true);
listNewInterrogation(false);
}else{
listMyAnsweredInterrogation(true)
listMyAnsweredInterrogation(false)
}
}
}
@ -331,6 +380,8 @@ function onRefresh(){
isRefreshing.value = true
page.value = 1
hasMore.value = true
listNew.value = [];
listMine.value=[];
if(bottomActive.value==='quick'){
if(activeTab.value==='new'){
newConsultList(true)
@ -381,7 +432,7 @@ function onReachBottom(){
display: flex;
justify-content: space-around;
align-items: center;
height: 44px;
height: 56px;
padding: 0 16px;
position: fixed;
top: calc(var(--status-bar-height) + 44px);
@ -389,24 +440,38 @@ function onReachBottom(){
right: 0;
z-index: 10;
background-color: #ffffff;
box-shadow: 0 1px 0 rgba(0,0,0,0.06);
border-bottom: 1px solid #e5e5e5;
.bar{
width:1px;
height: 100%;
background-color: #e5e5e5;
}
.tab {
flex: 1;
text-align: center;
font-size: 16px;
font-size: 36rpx;
color: #7a7a7a;
padding: 10px 0;
&.active { color: #8B2316; position: relative; }
&.active::after { content: ''; position: absolute; left: 25%; right: 25%; bottom: -1px; height: 3px; background-color: #8B2316; border-radius: 2px; }
}
}
.tabs-spacer { height: 44px; }
.namebox{
display: flex;
align-items: center;
justify-content: center;
.user-avatar{
margin-left: 10rpx;
font-size:32rpx;
color: #666;
}
}
.list-scroll {
flex: 1;
position: fixed;
top: calc(var(--status-bar-height) + 44px + 44px);
bottom: 136rpx;
padding: 8px 0px 0 0px;
top: calc(var(--status-bar-height) + 44px + 56px);
bottom:56px;
margin: 20rpx rpx 0;
box-sizing: border-box;
width:100%;
@ -421,8 +486,8 @@ function onReachBottom(){
display: flex;
justify-content: space-between;
align-items: center;
.user-name { font-size: 16px; color: #a31712; }
.date { font-size: 14px; color: #9aa0a6; }
.user-name { font-size: 36rpx; color: #a31712; }
.date { font-size: 36rpx; color: #9aa0a6; }
}
.card-body {
background: #efefef;
@ -452,31 +517,49 @@ function onReachBottom(){
}
display: flex; align-items: center; justify-content: space-between; margin-top: 8px;
.reply-count { font-size:28rpx; color: #8B2316; }
.reply-count-none{
font-size:28rpx;
color: #999;
position: relative;
padding-left: 25rpx;
}
.reply-count-none::after{
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 0;
width: 20rpx;
height: 20rpx;
background: red;
border-radius: 50%;
}
.tag {
display: flex;
align-items: center;
justify-content: center;
padding: 8rpx 16rpx; background: #fff5f5; color: #a31712; border-radius: 28rpx; font-size: 24rpx; border:2rpx solid #a31712;}
padding: 0rpx 16rpx; background: #fff; color: #a31712; border-radius: 28rpx; font-size: 24rpx; border:2rpx solid #a31712;}
}
}
.bottom-bar {
border-top: 1px solid #e5e5e5;
position: fixed;
left: 0; right: 0; bottom: 0;
background-color: #ffffff;
box-shadow: 0 -2px 8px rgba(0,0,0,0.06);
display: flex; align-items: center; justify-content: center;
padding: 8px 12px;
gap: 12px;
display: flex;
align-items: center;
justify-content: center;
.bottom-tab {
flex: 1;
height: 40px;
line-height: 40px;
height: 56px;
line-height: 56px;
text-align: center;
border-radius: 6px;
font-size: 16px;
color: #a31712;
background-color: #fff5f5;
font-size: 36rpx;
color: #999;
background-color: #fff;
}
.bottom-tab.active {
background-color: #a31712;

View File

@ -1,7 +1,8 @@
<template>
<navBar title="问题详情" />
<view class="consult-detail-page">
<!-- 导航栏 -->
<navBar title="问题详情" />
<!-- 内容区域 -->
<scroll-view scroll-y class="content-scroll">
@ -9,11 +10,13 @@
<view class="user-section">
<view class="user-info">
<view class="user-name">
<text class="name">{{ userInfo.name }}</text>
<text class="gender-age">{{ userInfo.gender }} {{ userInfo.age }}</text>
<text class="name">{{ maskName(userInfo.name) }}</text>
<text class="gender-age"
>{{ userInfo.gender }} {{ userInfo.age }}</text
>
</view>
<view class="detail-btn" @click="goInfo">
<up-image :src="detailImg" width="183rpx" height="34rpx" ></up-image>
<up-image :src="detailImg" width="183rpx" height="34rpx"></up-image>
</view>
</view>
</view>
@ -28,7 +31,12 @@
<!-- 问题内容 -->
<view class="question-content">
<text class="content-text">{{ questionInfo.diseaseDescribe }}</text>
<view class="content-text">
{{ questionInfo.diseaseDescribe }}
</view>
<view class="content-text">
{{ questionInfo.your_question }}
</view>
</view>
<!-- 疾病描述 -->
@ -40,39 +48,109 @@
<!-- 图片网格 -->
<view class="image-grid" v-if="questionInfo.images">
<image
v-if="questionInfo.images && questionInfo.images.split(',').length>0"
v-for="(img, index) in questionInfo.images.split(',')"
:key="index"
:src="docUrl+img"
:src="docUrl + img"
class="grid-image"
mode="aspectFill"
@click="previewImage(docUrl+img, index)"
@click="previewImage(docUrl + img, index)"
/>
</view>
<view class="bar"></view>
<view
class="lookmore"
v-if="
questionInfo.SupplementList &&
questionInfo.SupplementList.length > 1 && questionInfo.AnswerList.length > 0
"
@click="supplementShowAll = !supplementShowAll"
>
<view class="lookmore-text">
{{ supplementShowAll ? "收起" : "查看更多" }}
</view>
<uni-icons :type="supplementShowAll?'up':'down'" size="34rpx" color="#8B2316"></uni-icons>
</view>
<view
class="doctor-reply-section"
style="margin-bottom: 10rpx;"
v-for="(item,index) in displaySupplementList"
:key="index"
v-if="questionInfo.SupplementList && questionInfo.SupplementList.length > 0"
>
<view class="addbox">
<view class="addwrap">
<image :src="bgImg" class="addimg"></image>
<view class="addtext">信息补充</view>
</view>
<view class="date" > {{formatDate(item.create_date) }} </view>
</view>
<view class="question-content" style="margin-top:25rpx;" >
<text class="content-text" >
{{item.disease_describe }}
</text>
</view>
</view>
<!-- 补充信息查看更多 / 收起 -->
<view class="topbar"></view>
<!-- 医生回答区域 -->
<view class="doctor-reply-section">
<view
class="doctor-reply-section"
v-if="questionInfo.AnswerList.length > 0"
>
<view class="section-title">医生回答</view>
<view class="doctor-cell" v-for="item in questionInfo.AnswerList" :key="item.answer_uuid">
<view
class="doctor-cell"
v-for="item in questionInfo.AnswerList"
:key="item.answer_uuid"
>
<view class="doctor-card">
<view class="doctor-info">
<up-image :src="docUrl+item.photo" mode="aspectFill"
<up-image
:src="docUrl + item.photo"
mode="aspectFill"
:loadingIcon="lazyImg"
:errorIcon="lazyImg"
:lazy-load="true" class="doctor-avatar" width="90rpx" height="90rpx" radius="10rpx">
:lazy-load="true"
class="doctor-avatar"
width="90rpx"
height="90rpx"
radius="10rpx"
>
<template #error>
<image :src="lazyImg" mode="aspectFill" height="90rpx" width="90rpx" radius="10rpx"></image>
<image
:src="lazyImg"
mode="widthFix"
height="90rpx"
width="90rpx"
radius="10rpx"
></image>
</template>
<template v-slot:loading>
<image :src="lazyImg" mode="aspectFill" height="90rpx" width="90rpx" radius="10rpx"></image>
<image
:src="lazyImg"
mode="widthFix"
height="90rpx"
width="90rpx"
radius="10rpx"
></image>
</template>
</up-image>
<view class="doctor-details">
<view class="namebox">
<view class="namecontet">
<view class="doctor-name">{{ item.realname }}</view>
<view class="bar"></view>
<view class="doctor-hospital" style="margin-left: 0rpx;color:#999">{{ item.name }}</view>
</view>
</view>
<view class="hospital-time-row">
<view class="doctor-hospital" >{{ item.hospital }}</view>
<view class="doctor-hospital">{{ item.hospital_name }}</view>
<view class="reply-time">{{ item.create_date }}</view>
</view>
</view>
@ -80,26 +158,22 @@
<view class="reply-content">
<text class="reply-text">{{ item.note }}</text>
</view>
<view class="reply-content" style="background:none;padding:0;">
<view class="reply-content" style="background: none; padding: 0">
<view v-if="item.imgs" class="reply-images">
<image
v-for="(img, idx) in item.imgs.split(',')"
:key="idx"
:src="docUrl+img"
:src="docUrl + img"
class="reply-image"
@click="previewReplyImages(item, idx)"
/>
</view>
</view>
</view>
<view class="smallbar"></view>
</view>
</view>
</scroll-view>
<!-- 底部固定区域 -->
@ -107,175 +181,215 @@
<!-- 特别声明 -->
<view class="disclaimer">
<text class="disclaimer-title">特别声明</text>
<text class="disclaimer-text">答案仅为医生个人经验或建议分享不能视为诊断依据如有诊疗需求请务必前往正规医院就诊</text>
<text class="disclaimer-text"
>答案仅为医生个人经验或建议分享不能视为诊断依据如有诊疗需求请务必前往正规医院就诊</text
>
</view>
<!-- 编辑按钮 -->
<view class="edit-btn" @click="editQuestion(status)">
{{status==1?'我要编辑':'我要回答'}}
{{ status == 1 ? "我要编辑" : "我要回答" }}
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import navBar from '@/components/navBar/navBar.vue'
import detailImg from "@/static/iv_jiwangshi.png"
import navTo from '@/utils/navTo.js'
import { onLoad,onShow } from '@dcloudio/uni-app'
import docUrl from '@/utils/docUrl'
import api from "@/api/api.js"
import lazyImg from "@/static/avastar.png"
const uuid = ref('');
const step1_uuid = ref('');
const answer_uuid = ref('');
const status = ref(0)
import { ref, computed } from "vue";
import navBar from "@/components/navBar/navBar.vue";
import detailImg from "@/static/iv_jiwangshi.png";
import navTo from "@/utils/navTo.js";
import { onLoad, onShow,onUnload } from "@dcloudio/uni-app";
import docUrl from "@/utils/docUrl";
import api from "@/api/api.js";
import lazyImg from "@/static/avastar.png";
import bgImg from "@/static/complete_question.png";
const uuid = ref("");
const step1_uuid = ref("");
const answer_uuid = ref("");
const status = ref(0);
onLoad((options) => {
uuid.value = options.uuid
status.value = options.status || 0
console.log(uuid.value)
})
const goInfo=()=>{
uuid.value = options.uuid;
status.value = options.status || 0;
console.log(uuid.value);
});
const goInfo = () => {
navTo({
url:'/pages_app/patientInfo/patientInfo?step1_uuid='+step1_uuid.value
url: "/pages_app/patientInfo/patientInfo?step1_uuid=" + step1_uuid.value,
});
};
const getInterrogation = () => {
api
.getInterrogation({
uuid: uuid.value,
})
}
const getInterrogation=()=>{
api.getInterrogation({
uuid:uuid.value
}).then(res=>{
console.log(res)
if(res.code === '200' && res.data) {
step1_uuid.value = res.data.step1_uuid || ''
.then((res) => {
console.log(res);
if (res.code === "200" && res.data) {
step1_uuid.value = res.data.step1_uuid || "";
//
userInfo.value = {
name: res.data.name || '提**',
gender: res.data.sex === 1 ? '男' : '女',
age: res.data.birthday ? calculateAge(res.data.birthday) : '未知'
}
name: res.data.name || "提**",
gender: res.data.sex === 1 ? "女" : "男",
age: res.data.birthday ? calculateAge(res.data.birthday) : "未知",
};
//
questionInfo.value = {
date: res.data.create_date ? formatDate(res.data.create_date) : '未知',
diseaseTag: res.data.disease_name || '未知疾病',
content: res.data.your_question || '暂无问题描述',
images: res.data.imgs || '',
date: res.data.create_date
? formatDate(res.data.create_date)
: "未知",
diseaseTag: res.data.disease_name || "未知疾病",
content: res.data.your_question || "暂无问题描述",
images: res.data.imgs || "",
AnswerList: res.data.AnswerList || [],
your_question: res.data.your_question || ''
SupplementList: res.data.SupplementList || [],
your_question: res.data.your_question || "",
};
if(res.data.AnswerList.length == 0 && res.data.SupplementList.length > 0){
supplementShowAll.value = true;
}else{
supplementShowAll.value = false;
}
//
if(res.data.disease_describe) {
questionInfo.value.diseaseDescribe = res.data.disease_describe
if (res.data.disease_describe) {
questionInfo.value.diseaseDescribe = res.data.disease_describe;
}
let user=uni.getStorageSync('userInfo');
let arr=res.data.AnswerList.filter(item=>{
return user.uuid == item.expert_uuid
})
if(arr.length>0){
let user = uni.getStorageSync("userInfo");
let arr = res.data.AnswerList.filter((item) => {
return user.uuid == item.expert_uuid;
});
if (arr.length > 0) {
status.value = 1;
answer_uuid.value = arr[0].answer_uuid;
}
}
})
}
onShow(()=>{
getInterrogation()
});
};
onUnload(() => {
uni.$off('updateStatus');
})
onShow(() => {
getInterrogation();
uni.$on('updateStatus',() => {
status.value = 1;
})
});
const maskName = (name) => {
if (!name) return "**";
const first = name.slice(0, 1);
return `${first}**`;
};
//
function calculateAge(birthday) {
const birthDate = new Date(birthday)
const today = new Date()
let age = today.getFullYear() - birthDate.getFullYear()
const monthDiff = today.getMonth() - birthDate.getMonth()
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
age--
const birthDate = new Date(birthday);
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const monthDiff = today.getMonth() - birthDate.getMonth();
if (
monthDiff < 0 ||
(monthDiff === 0 && today.getDate() < birthDate.getDate())
) {
age--;
}
return age.toString()
return age.toString();
}
//
function formatDate(dateString) {
const date = new Date(dateString)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
const date = new Date(dateString);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
//
const userInfo = ref({
name: '提**',
gender: '男',
age: '15'
})
name: "提**",
gender: "男",
age: "15",
});
//
const questionInfo = ref({
date: '2022-11-09',
diseaseTag: '甲型肝炎',
content: '为什么程序员总是分不清万圣节和圣诞节因为Oct31==Dec25。\n任何我写的代码超过6个月不去看它当我再看时都像是别人写的。',
diseaseDescribe: '', //
images: [
'/static/images/placeholder1.jpg',
'/static/images/placeholder2.jpg',
'/static/images/placeholder3.jpg',
'/static/images/placeholder4.jpg',
'/static/images/placeholder5.jpg',
'/static/images/placeholder6.jpg',
'/static/images/placeholder7.jpg',
'/static/images/placeholder8.jpg'
]
})
date: "2022-11-09",
diseaseTag: "甲型肝炎",
content:
"为什么程序员总是分不清万圣节和圣诞节因为Oct31==Dec25。\n任何我写的代码超过6个月不去看它当我再看时都像是别人写的。",
diseaseDescribe: "", //
images: "",
SupplementList: [],
AnswerList: [],
your_question: "",
});
// /
const supplementShowAll = ref(false);
const displaySupplementList = computed(() => {
if (
!questionInfo.value.SupplementList ||
questionInfo.value.SupplementList.length === 0
) {
return [];
}
return supplementShowAll.value
? questionInfo.value.SupplementList
: [];
});
//
const doctorReply = ref({
avatar: '/static/images/doctor-avatar.jpg',
name: 'los测试',
hospital: '隆福医院',
time: '28天前',
content: '徐徐,喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵',
image: '/static/images/reply-image.jpg'
})
avatar: "/static/images/doctor-avatar.jpg",
name: "los测试",
hospital: "隆福医院",
time: "28天前",
content:
"徐徐,喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵喵",
image: "/static/images/reply-image.jpg",
});
//
function goBack() {
uni.navigateBack()
uni.navigateBack();
}
//
function previewImage(current, index) {
uni.previewImage({
urls: questionInfo.value.images?questionInfo.value.images.split(',').map(path=> docUrl + path):[],
current: index
})
urls: questionInfo.value.images
? questionInfo.value.images.split(",").map((path) => docUrl + path)
: [],
current: index,
});
}
//
function previewReplyImages(item, index){
if(!item || !item.imgs){
return
function previewReplyImages(item, index) {
if (!item || !item.imgs) {
return;
}
const urls = item.imgs.split(',').map(path=> docUrl + path)
const urls = item.imgs.split(",").map((path) => docUrl + path);
uni.previewImage({
urls,
current: index
})
current: index,
});
}
//
function editQuestion() {
if(status.value == 1){
if (status.value == 1) {
navTo({
url:'/pages_app/myAnswer/myAnswer?answer_uuid='+answer_uuid.value+'&uuid='+uuid.value
})
}else{
url:
"/pages_app/myAnswer/myAnswer?answer_uuid=" +
answer_uuid.value +
"&uuid=" +
uuid.value,
});
} else {
navTo({
url:'/pages_app/myAnswer/myAnswer?uuid='+uuid.value
})
url: "/pages_app/myAnswer/myAnswer?uuid=" + uuid.value,
});
}
}
</script>
@ -309,7 +423,7 @@ function editQuestion() {
.back-icon {
font-size: 48rpx;
color: #8B2316;
color: #8b2316;
font-weight: bold;
}
}
@ -317,28 +431,81 @@ function editQuestion() {
.nav-title {
font-size: 36rpx;
font-weight: 500;
color: #8B2316;
color: #8b2316;
}
.nav-right {
width: 80rpx;
}
}
.bar{
width:100%;
height:20rpx;
.topbar{
width: 100%;
height: 20rpx;
background-color: #efefef;
}
.smallbar{
width:100%;
height:10rpx;
background-color: #efefef;
.bar {
width: 2rpx;
height: 30rpx;
margin:0 20rpx;
background-color: #999;
}
.doctor-hospital{
margin-left: 20rpx;
}
.namecontet{
display: flex;
margin-left: 20rpx;
align-items: center;
}
.lookmore{
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
margin: 20rpx 30rpx 20rpx;
.lookmore-text{
font-size: 28rpx;
color: #8B2316;
}
}
.addbox {
display: flex;
align-items: center;
justify-content: space-between;
margin: 20rpx 30rpx 0;
.addwrap {
display: flex;
align-items: center;
position: relative;
.addimg {
width: 110rpx;
height: 60rpx;
}
}
.addtext {
position: absolute;
top: 9rpx;
left: 6rpx;
font-size: 24rpx;
color: #fff;
font-weight: 500;
}
.date {
font-size: 28rpx;
color: #999;
}
}
// .smallbar {
// width: 100%;
// height: 10rpx;
// background-color: #efefef;
// }
.content-scroll {
flex: 1;
position: fixed;
top: 135rpx;
width:auto;
top: calc(var(--status-bar-height) + 44px);
width: auto;
box-sizing: border-box;
padding: 30rpx 0;
bottom: 313rpx;
@ -362,7 +529,7 @@ function editQuestion() {
.name {
font-size: 32rpx;
color: #8B2316;
color: #8b2316;
font-weight: 500;
}
@ -377,7 +544,6 @@ function editQuestion() {
display: flex;
margin-left: 10rpx;
.detail-text {
color: #ffffff;
font-size: 24rpx;
@ -390,7 +556,6 @@ function editQuestion() {
}
}
}
}
.tag-date-row {
@ -405,8 +570,8 @@ function editQuestion() {
.tag-text {
display: inline-block;
background-color: #ffffff;
color: #8B2316;
border: 2rpx solid #8B2316;
color: #8b2316;
border: 2rpx solid #8b2316;
border-radius: 40rpx;
padding: 7rpx 22rpx;
font-size: 24rpx;
@ -430,6 +595,7 @@ function editQuestion() {
font-size: 28rpx;
color: #333;
line-height: 1.6;
word-break: break-all;
}
}
@ -438,11 +604,11 @@ function editQuestion() {
border-radius: 16rpx;
padding: 32rpx;
margin: 0 30rpx 24rpx;
border-left: 6rpx solid #8B2316;
border-left: 6rpx solid #8b2316;
.describe-title {
font-size: 30rpx;
color: #8B2316;
color: #8b2316;
font-weight: 500;
margin-bottom: 16rpx;
}
@ -460,7 +626,6 @@ function editQuestion() {
gap: 8rpx;
margin: 0 30rpx 40rpx;
.grid-image {
width: 100%;
height: 160rpx;
@ -472,14 +637,14 @@ function editQuestion() {
margin: 0 0rpx 40rpx;
.section-title {
font-size: 32rpx;
padding:24rpx 30rpx;
border-bottom:1rpx solid #efefef;
color: #8B2316;
padding: 24rpx 30rpx;
border-bottom: 1rpx solid #efefef;
color: #8b2316;
font-weight: 500;
}
.doctor-card {
margin:20rpx 30rpx 0;
margin: 20rpx 30rpx 0;
background-color: #ffffff;
border-radius: 16rpx;
.doctor-info {
@ -501,11 +666,10 @@ function editQuestion() {
font-size: 32rpx;
color: #333;
font-weight: 500;
margin-left: 8rpx;
margin-bottom: 8rpx;
}
.hospital-time-row {
margin-top: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
@ -534,7 +698,7 @@ function editQuestion() {
color: #333;
line-height: 1.6;
}
.reply-images{
.reply-images {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 8rpx;
@ -544,7 +708,7 @@ function editQuestion() {
.reply-image {
width: 100%;
height:150rpx;
height: 150rpx;
border-radius: 8rpx;
object-fit: cover;
}
@ -569,14 +733,13 @@ function editQuestion() {
.disclaimer-title {
font-size: 28rpx;
color: #8B2316;
font-weight: 500;
color: #892b1b;
}
.disclaimer-text {
font-size: 28rpx;
color: #666;
line-height: 1.5;
color: #9c9492;
}
}
@ -585,7 +748,7 @@ function editQuestion() {
height: 88rpx;
line-height: 88rpx;
text-align: center;
background-color: #00bcd4;
background-color: #3cc7c0;
color: #ffffff;
font-size: 32rpx;
font-weight: 500;

View File

@ -158,12 +158,17 @@ const countConsult=()=>{
}
const answerConsult=async()=>{
if(hasAnswer.value){
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
let conversationId=userId+'|1|'+patientUuid.value.toLowerCase();
await uni.$UIKitStore.uiStore.selectConversation(conversationId)
navTo({
url:'/pages_chat/chat/index?from=consult&patientUuid='+patientUuid.value
uni.sendNativeEvent('goConsultPage', {
msg: 'chat'
},ret => {
console.log(ret);
})
// let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
// let conversationId=userId+'|1|'+patientUuid.value.toLowerCase();
// await uni.$UIKitStore.uiStore.selectConversation(conversationId)
// navTo({
// url:'/pages_chat/chat/index?from=consult&patientUuid='+patientUuid.value
// })
}else{
countConsult()
}

View File

@ -117,7 +117,8 @@ const updateInterrogationAnswer=()=>{
imgsBean: imgobj
}).then(res=>{
if(res.code == 200){
uni.showToast({title: '提交成功', icon: 'none'})
uni.showToast({title: '提交成功', icon: 'none'});
uni.$emit('updateStatus',1)
uni.navigateBack()
}
})
@ -139,6 +140,7 @@ const addInterrogationAnswer=()=>{
imgsBean: imgobj
}).then(res=>{
if(res.code == 200){
uni.$emit('updateStatus',1)
uni.showToast({title: '提交成功', icon: 'none'})
uni.navigateBack()
}
@ -205,7 +207,7 @@ function submit(){
.content-scroll{
flex: 1;
position: fixed;
top: 135rpx;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
bottom: 160rpx;
@ -303,7 +305,7 @@ function submit(){
height: 88rpx;
line-height: 88rpx;
text-align: center;
background: #00bcd4;
background: #3cc7c0;
color: #fff;
font-size: 32rpx;
border-radius: 16rpx;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
<template>
<uni-nav-bar
<!-- <uni-nav-bar
left-icon="left"
title="我的福利"
@clickLeft="goBack"
@ -8,7 +8,8 @@
height="180rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
></uni-nav-bar> -->
<navBar :title="'我的福利'" />
<view class="benefits-page">
@ -90,6 +91,7 @@
import jifenImg from "@/static/duihuan.png"
import api from '@/api/api';
import navTo from "@/utils/navTo.js";
import navBar from '@/components/navBar/navBar.vue'
//
const activeTab = ref(0);
@ -332,7 +334,7 @@
.segmented-control {
position: fixed;
top: $nav-height;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
z-index: 10;

View File

@ -28,43 +28,61 @@
<view v-if="activeTab === 'basic'" class="basic-info">
<view class="info-item">
<text class="info-label">姓名</text>
<text class="info-value">{{ patientInfo.name || '提**' }}</text>
<text class="info-value">{{ maskName(patientInfo.name) }}</text>
</view>
<view class="info-item">
<text class="info-label">性别</text>
<text class="info-value">{{ patientInfo.gender || '男' }}</text>
<text class="info-value">{{ patientInfo.gender }}</text>
</view>
<view class="info-item">
<text class="info-label">年龄</text>
<text class="info-value">{{ patientInfo.age || '15' }}</text>
<text class="info-value">{{ patientInfo.age }}</text>
</view>
<view class="info-item">
<text class="info-label">地址</text>
<text class="info-value">{{ patientInfo.address || '北京市东城区' }}</text>
<text class="info-value twoline" style="max-width:380rpx;flex:none">{{ patientInfo.address }}</text>
</view>
<view class="info-item" v-if="patientInfo.gender=='女'">
<text class="info-label">是否怀孕</text>
<text class="info-value">{{ formatwhetherpregnant(patientInfo.whether_pregnant) }}</text>
</view>
<view class="info-item" v-if="patientInfo.gender=='女' && patientInfo.expected_date_of_childbirth" >
<text class="info-label">预产期</text>
<text class="info-value">{{ patientInfo.expected_date_of_childbirth }}</text>
</view>
<view class="info-item">
<text class="info-label">肝硬化或肝癌家族史</text>
<text class="info-value">{{ patientInfo.familyHistory || '无' }}</text>
<text class="info-value">{{ whetherHbv(patientInfo.whether_hbv) }}</text>
</view>
</view>
<!-- 病史信息内容 -->
<view v-if="activeTab === 'history'" class="history-info">
<view class="info-item">
<text class="info-label">既往病史</text>
<text class="info-value">暂无</text>
<text class="info-label">前往医院就诊该疾病情况</text>
<text class="info-value">{{ goHospital(patientInfo.go_hospital) }}</text>
</view>
<view class="info-item">
<text class="info-label">过敏史</text>
<text class="info-value">暂无</text>
<text class="info-label">患病时间</text>
<text class="info-value">{{ patientInfo.disease_date }}</text>
</view>
<view class="info-item">
<text class="info-label">手术史</text>
<text class="info-value">暂无</text>
<text class="info-label">目前肝脏状态</text>
<text class="info-value">{{ patientInfo.liver_status }}</text>
</view>
<view class="info-item">
<text class="info-label">用药史</text>
<text class="info-value">暂无</text>
<text class="info-label">当前服用肝病用药情况</text>
<text class="info-value">{{ patientInfo.boolean_medication }}</text>
</view>
<view class="info-item column" v-if="patientInfo.medication_info">
<text class="info-label" style="padding-top: 20rpx;">当前服用的肝病药物以及服用时长</text>
<text class="info-content">{{ patientInfo.medication_info }}</text>
</view>
<view class="info-item column" >
<text class="info-label" style="padding-top: 20rpx;">是否合并其他慢性疾病</text>
<view class="otherbox" v-if="patientInfo.other_disease">
<view class="cell" v-for="item in patientInfo.other_disease.split(',')" :key="item">{{ item}}</view>
</view>
</view>
</view>
</scroll-view>
@ -96,17 +114,22 @@ const interrogationPatientInfo=()=>{
step1_uuid: step1_uuid.value
}).then(res=>{
if(res.code == 200 && res.data){
const d = res.data
patientInfo.name = d.name || '提**'
patientInfo.gender = d.sex === 1 ? '男' : '女'
const d = res.data;
Object.assign(patientInfo, d);
// patientInfo.name = d.name || '**'
patientInfo.gender = d.sex === 1 ? '女' : '男'
patientInfo.age = d.birthday ? calculateAge(d.birthday) : '未知'
patientInfo.address = d.address || ''
//
patientInfo.familyHistory = '未知'
// patientInfo.address = d.address || ''
// //
// patientInfo.familyHistory = ''
}
})
}
const maskName = (name)=>{
if(!name) return '**'
const first = name.slice(0,1)
return `${first}**`
}
function calculateAge(birthday){
const birth = new Date(birthday)
const today = new Date()
@ -126,7 +149,33 @@ const statusBarStyle = computed(() => ({
const goBack = () => {
uni.navigateBack()
}
const formatwhetherpregnant = (value)=>{
if(value==1){
return '无计划'
}else if(value==2){
return '计划中'
}else if(value==3){
return '已怀孕'
}else if(value==4){
return '家有宝宝'
}
}
const goHospital = (val)=>{
if(val==1){
return '是'
}else if(val==0){
return '否'
}
}
const whetherHbv = (value)=>{
if(value==0){
return '无'
}else if(value==1){
return '有'
}else{
return '未知'
}
}
const switchTab = (tab) => {
activeTab.value = tab
}
@ -141,7 +190,7 @@ onMounted(() => {
<style lang="scss" scoped>
//
$primary-color: #ff0000;
$primary-color: #8B2316;
$text-color: #333333;
$text-color-light: #666666;
$border-color: #f0f0f0;
@ -152,7 +201,22 @@ $tab-height: 88rpx;
$info-item-height: 100rpx;
$padding-horizontal: 30rpx;
$padding-small: 10rpx;
.info-content{
font-size: 28rpx;
color:#999;
width: 100%;
background-color: #f0f0f0;
border-radius: 16rpx;
padding:20rpx;
box-sizing: border-box;
margin-top: 20rpx;
margin-bottom: 20rpx;
}
.column{
flex-direction: column;
justify-content: flex-start!important;
align-items: flex-start!important;
}
.patient-info-container {
background-color: $background-color;
min-height: 100vh;
@ -161,7 +225,21 @@ $padding-small: 10rpx;
.status-bar {
background-color: $background-color;
}
.otherbox{
display: flex;
flex-wrap: wrap;
margin-top: 20rpx;
.cell{
font-size: 24rpx;
padding: 10rpx 12rpx;
border-radius: 20rpx;
margin-bottom: 20rpx;
background-color: #fff;
color:#8B2316;
border: 1rpx solid #8B2316;
margin-right: 10rpx;
}
}
.nav-bar {
display: flex;
align-items: center;
@ -199,6 +277,10 @@ $padding-small: 10rpx;
}
.tab-bar {
top:calc(var(--status-bar-height) + 44px);
position: fixed;
left: 0;
right: 0;
display: flex;
background-color: $background-color;
border-bottom: 2rpx solid $border-color-light;
@ -232,6 +314,10 @@ $padding-small: 10rpx;
}
.content-area {
top:calc(var(--status-bar-height) + 44px + 90rpx);
position: fixed;
left: 0;
right: 0;
flex: 1;
background-color: $background-color;
}
@ -244,7 +330,7 @@ $padding-small: 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
height: $info-item-height;
min-height: $info-item-height;
border-bottom: 2rpx solid $border-color;
padding: 0 $padding-small;
@ -255,14 +341,17 @@ $padding-small: 10rpx;
.info-label {
font-size: 32rpx;
color: $text-color;
flex: 1;
text-align: left;
flex:1.5;
}
.info-value {
font-size: 32rpx;
color: $text-color-light;
color:#999;
text-align: right;
flex: 1;
display: flex;
justify-content: flex-end;
}
}
}

View File

@ -761,6 +761,10 @@ const goSearch = () => {
.author {
font-size: 24rpx;
color: #999;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 20rpx;
}
.stats {

View File

@ -1,14 +1,5 @@
<template>
<uni-nav-bar
left-icon="left"
title="在线支付"
@clickLeft="goBack"
fixed
color="#8B2316"
height="180rpx"
:border="false"
backgroundColor="#eeeeee"
></uni-nav-bar>
<navBar :showLeft="true" title="在线支付" />
<view class="pay-page">
<!-- 主要内容区域 -->
<view class="main-content">
@ -26,7 +17,7 @@
</view>
<radio-group @change="radioChange">
<!-- 余额支付选项 -->
<label class="payment-option" @tap="selectPayment('balance')">
<label class="payment-option" @click="selectPayment('balance')">
<view class="option-left">
<up-image :src="moneyImg" width="56rpx" height="56rpx" ></up-image>
</view>
@ -37,6 +28,7 @@
<view class="option-right">
<radio
@click.stop="selectPayment('balance')"
:checked="selectedPayment === 'balance'"
value="balance"
:disabled="balance<paymentInfo.amount/100"
@ -51,7 +43,7 @@
</view>
<!-- 微信支付选项 -->
<label class="payment-option" @tap="selectPayment('wechat')">
<label class="payment-option" @click="selectPayment('wechat')">
<view class="option-left">
<up-image :src="wxImg" width="56rpx" height="56rpx" ></up-image>
</view>
@ -61,6 +53,7 @@
<view class="option-right">
<radio
@click.stop="selectPayment('wechat')"
:checked="selectedPayment === 'wechat'"
value="wechat"
color="#8B2316"
@ -77,6 +70,11 @@
</view>
</view>
</view>
<up-modal :show="showPwdModal" showCancelButton :title="'提示'" @confirm="confirmPwd" @cancel="showPwdModal=false" confirmColor="#8B2316">
<view class="slot-content">
<input type="text" password v-model="pwd" placeholder="请输入您的登录密码" />
</view>
</up-modal>
</template>
<script setup>
@ -90,6 +88,8 @@
const type=ref('');
const trade_no=ref('');
const balance=ref(0);
const pwd=ref('');
const showPwdModal=ref(false);
onLoad((options) => {
if(options.type=='ganDanFile'){
file_uuid.value=options.uuid;
@ -121,11 +121,13 @@
if(res.code==200){
const payParams = res.data
requestPayment(payParams,()=>{
console.log('支付成功回调')
uni.showToast({
title: '支付成功',
icon: 'none'
icon: 'none',
duration:10000
});
uni.navigateBack();
//uni.navigateBack();
},(err)=>{
console.log(err)
uni.showToast({
@ -139,7 +141,7 @@
const getBalance=()=>{
api.getBalance().then(res=>{
if(res.code==200){
balance.value=res.data.toFixed(2);
balance.value=(res.data/100).toFixed(2);
}
})
};
@ -153,6 +155,21 @@
}
})
};
const payGanDanFileOrder=()=>{
api.payGanDanFile({
trade_no:trade_no.value,
channel:'balance',
pwd:pwd.value
}).then(res=>{
if(res.code==200){
uni.showToast({
title: '支付成功',
icon: 'none'
});
uni.navigateBack();
}
})
};
// .png
const paymentInfo = ref({
amount:0,
@ -187,11 +204,17 @@
}else{
selectedPayment.value = paymentType;
}
console.log('selectedPayment22222222222')
console.log(selectedPayment.value)
};
const confirmPwd=()=>{
showPwdModal.value=false;
payGanDanFileOrder();
}
const confirmPayment = () => {
console.log(selectedPayment.value)
if (!selectedPayment.value) {
uni.showToast({
title: '请选择支付方式',
@ -199,8 +222,12 @@
});
return;
}
payGanDanFile()
if(selectedPayment.value=='balance'){
//payGanDanFileOrder();
showPwdModal.value=true;
}else{
payGanDanFile();
}
};
</script>
@ -228,9 +255,27 @@
align-items: center;
justify-content: space-between;
}
.slot-content{
width: 100%;
display: flex;
align-items: center;
input{
flex:1;
height: 90rpx;
background:#f5f5f5;
border-radius: 10rpx;
padding:0 20rpx;
font-size: 28rpx;
}
}
.pay-page {
height: calc(100vh - 180rpx);
position: fixed;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
height: calc(100vh - var(--status-bar-height) - 44px - 130rpx);
background-color: $bg-color;
overflow: hidden;
}

View File

@ -334,6 +334,7 @@
min-height: 100vh;
background-color: $bg-color;
padding-top: $nav-height; //
overflow: hidden;
}
//

View File

@ -11,8 +11,8 @@
backgroundColor="#eeeeee"
>
<template v-slot:right>
<view class="nav-right" @click="testLoadMore">
<text style="font-size: 24rpx; color: #8B2316;">测试加载</text>
<view class="collect-img" @click="goSearch" style="margin-right: 20rpx;">
<image class="img-icon" :src="searchImg" mode="aspectFill" />
</view>
</template>
</uni-nav-bar>
@ -52,11 +52,11 @@
>
<view class="item-left">
<view class="pdf-icon">
<up-image :src="pptImg" width="114rpx" height="114rpx" ></up-image>
<up-image :src="item.type=='pdf'?pptImg:wordImg" width="114rpx" height="114rpx" ></up-image>
</view>
</view>
<view class="item-content">
<view class="item-title">{{item.title}}</view>
<view class="item-title twoline">{{item.title}}</view>
<view class="info">
<view >{{ item.providername }}</view>
<view class="item-author">{{ item.hospitalname }}</view>
@ -71,9 +71,9 @@
<view class="priceImg" style="margin-top: -4rpx;">
<up-image :src="downLoadImg" width="32rpx" height="32rpx" ></up-image>
</view>
<text class="price-value" v-if="item.price>0"><text class="money-unit">¥</text>{{ item.price>item.discount?fromatPrice(item.discount):fromatPrice(item.price) }}</text>
<text class="yuanjia" v-if="item.price>0 && item.price>item.discount">原价<text class="jiaprice">{{fromatPrice(item.price/100)}}</text></text>
<text v-if="item.price==0" class="free">免费</text>
<text class="price-value" v-if="item.price>0 && item.discount>0"><text class="money-unit">¥</text>{{ item.price/100>item.discount?fromatPrice(item.discount):fromatPrice(item.price/100) }}</text>
<text class="yuanjia" v-if="item.price>0 && item.price/100>item.discount && item.discount>0">原价<text class="jiaprice">{{fromatPrice(item.price/100)}}</text></text>
<text v-if="item.price==0 || item.discount===0" class="free">免费</text>
</view>
</view>
</view>
@ -109,11 +109,19 @@
<up-image :src="tougaoImg" width="152rpx" height="80rpx" ></up-image>
</view>
</view>
<unidialog
:visible="pptVisible"
:content="pptContent"
@close="pptVisible=false"
@confirm="pptConfirm"
></unidialog>
</template>
<script setup>
import { ref } from 'vue';
import { onShow,onLoad} from "@dcloudio/uni-app";
import unidialog from "@/components/dialog/dialog.vue";
import { onShow,onLoad,onBackPress} from "@dcloudio/uni-app";
import searchImg from "@/static/search.png";
import filter from "@/static/cb_screen_no.png"
import filterOn from "@/static/cb_screen_yes.png"
import upImg from "@/static/cb_up.png"
@ -121,9 +129,12 @@
import tougaoImg from "@/static/kejiantougao.png"
import downLoadImg from "@/static/wdxz.png"
import pptImg from "@/static/pdf.png"
import wordImg from "@/static/word.png"
import api from '@/api/api.js';
import navTo from '@/utils/navTo.js';
const isFilterActive=ref(false)
const pptVisible=ref(false)
const pptContent=ref('肝胆相照将稍后与您沟通课件分享,谢谢您对平台的支持!')
const hcp_token=ref('')
const keywords=ref('')
const sort = ref(0); //
@ -133,9 +144,17 @@
const noMore = ref(false);
const page = ref(1);
const pageSize = ref(10);
const pptConfirm=()=>{
pptVisible.value=false;
feedBack();
}
//
const coursewareList = ref([]);
onBackPress(()=>{
plus.runtime.quit();
return true;
})
const checkUser= async()=>{
const res = await api.checkUser();
if(res.code==200){
@ -148,7 +167,17 @@
checkUser();
loadData(false);
})
const goSearch = () => {
uni.sendNativeEvent(
"goHomeSearch",
{
msg: "ppt",
},
(ret) => {
console.log(ret);
}
);
};
//
const goBack = () => {
uni.navigateBack({
@ -194,11 +223,21 @@
};
const submitCourseware = () => {
pptVisible.value=true;
};
const feedBack=()=>{
const expertUuid=uni.getStorageSync('userInfo').uuid
api.feedBack({
content: '我要共享课件',
expertUuid:expertUuid
}).then((res)=>{
uni.showToast({
title: '课件投稿功能',
title: '谢谢您的支持',
icon: 'none'
});
};
})
}
const loadGuideTags = async () => {
try {
const res = await api.guideTag({
@ -477,7 +516,10 @@
align-items: center;
justify-content: center;
}
.img-icon{
width: 34rpx;
height: 34rpx;
}
@mixin flex-between {
display: flex;
align-items: center;
@ -575,7 +617,7 @@
.courseware-item {
background-color: $white;
border-radius: 16rpx;
padding: 30rpx 0;
padding: 30rpx 20rpx;
margin-bottom: 20rpx;
@include shadow;
display: flex;

View File

@ -32,11 +32,18 @@
<!-- 下载提示条 -->
<view class="download-bar" @click="downloadGanDanFile('free')" v-if="orderInfo &&orderInfo.price==0 && downLoadStatus == 'start'">
<view class="download-inner">
<u-icon name="download" color="#fff" size="28"></u-icon>
<text class="download-text">本课件</text>
<text class="download-text">免费</text>
<text class="download-unit">下载</text>
</view>
</view>
<view
class="download-bar"
@click="goView"
v-if="order && order.order_status == 'paid' && hasDownload && downLoadStatus == 'completed'"
v-else-if="hasDownload && downLoadStatus == 'completed'"
>
<view class="download-inner">
<text class="download-text">查看课件</text>
@ -45,7 +52,7 @@
<view
class="download-bar"
@click="alertDownloading"
v-else-if="order && order.order_status == 'paid' && hasDownload && downLoadStatus == 'loading'"
v-else-if="hasDownload && downLoadStatus == 'loading'"
>
<view class="download-inner">
<text class="download-text">下载中...</text>
@ -53,14 +60,14 @@
</view>
<view
class="download-bar"
@click="downloadGanDanFile"
@click="downloadGanDanFile('reDownload')"
v-else-if="order && order.order_status == 'paid' && !hasDownload"
>
<view class="download-inner">
<text class="download-text">重新下载本课件</text>
</view>
</view>
<view class="download-bar" @click="goPay" v-else-if="!order && price>0">
<view class="download-bar" @click="downLoadByType" v-else-if="!order && price>0">
<view class="download-inner">
<u-icon name="download" color="#fff" size="28"></u-icon>
<text class="download-text">本课件下载</text>
@ -74,14 +81,7 @@
<text class="download-text">本课件不支持下载</text>
</view>
</view>
<view class="download-bar" @click="downloadGanDanFile" v-else>
<view class="download-inner">
<u-icon name="download" color="#fff" size="28"></u-icon>
<text class="download-text">本课件</text>
<text class="download-price">免费</text>
<text class="download-unit">下载</text>
</view>
</view>
<!-- <web-view :src="src"></web-view> -->
<!-- 图片浏览 -->
<!-- <view class="viewer">
@ -110,8 +110,8 @@
</template>
<script setup>
import { ref, computed, nextTick } from "vue";
import { onShow, onLoad, onHide, onUnload } from "@dcloudio/uni-app";
import { ref, computed, nextTick,onMounted } from "vue";
import { onShow, onLoad, onHide,onUnload,onBackPress } from "@dcloudio/uni-app";
import api from "@/api/api";
import navTo from "@/utils/navTo.js";
import collectImg from "@/static/icon_book_collect_sel.png";
@ -125,11 +125,71 @@ import downloadStore from "@/store/downloadStorePpt.js";
import unidialog from "@/components/dialog/dialog.vue";
const freeVisible = ref(false);
const freeContent = ref('');
const canDownload = ref(false);
const orderId = ref('');
import otherHost from "@/utils/otherHost.js";
import docUrl from "@/utils/docUrl.js";
const isFirstDownload = ref(false);
const freeConfirm = () => {
freeVisible.value = false;
downloadGanDanFile();
};
//
const removeTask = (index) => {
downloadStore.removeTask(index);
syncTasksFromStore();
};
const goBack = () => {
if(downLoadStatus.value == 'loading'){
uni.showModal({
title: '提示',
content: '正在下载课件,退出界面将取消下载,是否退出?',
showCancel: true,
cancelText: '取消',
confirmText: '确定',
confirmColor: '#8B2316',
success: (res) => {
if(res.confirm){
const taskIndex = downloadTasks.value.findIndex((t) => t.id === uuid.value);
if (taskIndex !== -1) {
removeTask(taskIndex);
}
uni.navigateBack();
}
}
})
}else{
uni.navigateBack();
}
};
onBackPress((event)=>{
console.log('onBackPress');
console.log(event);
if(event.from == 'backbutton'){
if(downLoadStatus.value == 'loading'){
uni.showModal({
title: '提示',
content: '正在下载课件,退出界面将取消下载,是否退出?',
showCancel: true,
cancelText: '取消',
confirmText: '确定',
confirmColor: '#8B2316',
success: (res) => {
if(res.confirm){
const taskIndex = downloadTasks.value.findIndex((t) => t.id === uuid.value);
if (taskIndex !== -1) {
removeTask(taskIndex);
}
uni.navigateBack();
}
}
})
return true;
}
}
});
const downloadTasks=ref([]);
const downLoadtaskList=computed(()=>{
@ -151,18 +211,28 @@ onLoad((options) => {
console.log(options);
uuid.value = options.uuid;
checkUser(options);
//ganDanFileDetials();
});
onUnload(() => {
uni.$off('paySuccess');
});
onShow(() => {
uni.$on('paySuccess',(data)=>{
console.log('详情监听到成功支付');
console.log(data);
canDownload.value = true;
});
hasDownload.value = false;
downLoadStatus.value = 'start';
syncTasksFromStore();
// store
downloadStore.addListener((tasks) => {
downloadTasks.value = tasks;
});
//
resumeDownloadingTasks();
ganDanFileDetials();
if(downloadTasks.value.length > 0) {
for(let i = 0; i < downloadTasks.value.length; i++) {
if(downloadTasks.value[i].id == uuid.value) {
@ -179,6 +249,17 @@ onShow(() => {
}
}
};
console.log('canDownload');
console.log(canDownload.value);
if(!canDownload.value){
ganDanFileDetials();
}else{
if(!hasDownload.value){
downloadGanDanFile('auto');
}
}
});
// ===== webview.vue =====
// 使 uni-popup
@ -588,83 +669,132 @@ const freeClose = () => {
goPay();
};
const goPay = () => {
navTo({
url: "/pages_app/pay/pay?uuid=" + uuid.value + "&type=ganDanFile",
});
// navTo({
// url: "/pages_app/pay/pay?uuid=" + uuid.value + "&type=ganDanFile",
// });
createGanDanFileOrder();
};
const createGanDanFileOrder=()=>{
api.createGanDanFileOrder({
file_uuid:uuid.value
}).then(res=>{
console.log(res);
if(res.code==200){
console.log(res.data.provider_name);
console.log(orderInfo.value.price);
console.log(res.data.order_id);
console.log(res.data.trade_no);
orderId.value = res.data.order_id;
console.log('跳转原生支付页')
uni.sendNativeEvent('payPptPage', {
msg: {
"providername":res.data.provider_name,
"price":orderInfo.value.price,
"order_id":res.data.order_id,
"trade_no":res.data.trade_no,
"amount":res.data.amount,
"account":res.data.account,
"title":orderInfo.value.name,
"tags":orderInfo.value.tags?orderInfo.value.tags:''
},
});
// trade_no.value=res.data.trade_no;
// paymentInfo.value=res.data;
}
})
};
const downLoadByType=()=>{
if(orderInfo.value.price==0){
downloadGanDanFile();
downloadGanDanFile('free');
}else if(orderInfo.value.price>0){
if(orderInfo.value.welfareNum>0){
freeVisible.value = true;
//freeVisible.value = true;
freeContent.value = '您还有'+orderInfo.value.welfareNum+'次免费下载机会,希望本次下载免费吗?';
uni.showModal({
title: '提示',
content: '您还有'+orderInfo.value.welfareNum+'次免费下载机会,希望本次下载免费吗?',
showCancel: true,
cancelText: '取消',
confirmText: '确定',
confirmColor: '#8B2316',
success: (res) => {
if(res.confirm){
downloadGanDanFile('welfare');
}else{
goPay();
}
}
})
}else if(orderInfo.value.freeRecord>0){
freeVisible.value = true;
//freeVisible.value = true;
freeContent.value = '您还有'+orderInfo.value.freeRecord+'次免费下载机会,希望本次下载免费吗?';
uni.showModal({
title: '提示',
content: '您还有'+orderInfo.value.freeRecord+'次免费下载机会,希望本次下载免费吗?',
showCancel: true,
cancelText: '取消',
confirmText: '确定',
confirmColor: '#8B2316',
success: (res) => {
if(res.confirm){
downloadGanDanFile('freeRecord');
}else{
goPay();
}
}
})
}else if(orderInfo.value.order && orderInfo.value.order.order_status == 'paid'){
downloadGanDanFile()
downloadGanDanFile('reDownload')
}else{
goPay();
}
}
}
const downloadGanDanFile = () => {
const downloadGanDanFile = (type) => {
let order_id='';
if(orderInfo.value.price==0){
order_id='Free';
}else if(orderInfo.value.price>0){
if(orderInfo.value.welfareNum>0){
if(type=='free'){
order_id='FREE';
} else if(type=='welfare'){
order_id='USEWELFARENUM';
}else if(orderInfo.value.freeRecord>0){
}else if(type=='freeRecord'){
order_id='FREERECORD';
}else if(orderInfo.value.order && orderInfo.value.order.order_status == 'paid'){
order_id=uuid.value+"&R";
}else if(type=="auto"){
order_id= orderId.value;
}else if(type=="reDownload"){
order_id=orderInfo.value.order.order_id+"&R";
}
}
if(downLoadStatus.value == 'loading'){
uni.showToast({
title: "正在下载中",
icon: "none",
});
return false;
};
// 使store
const taskIndex = downloadStore.addTask({
title: orderInfo.value.name,
id: uuid.value,
type: 'ppt',
status: 'downloading',
});
hasDownload.value = true;
downLoadStatus.value = 'loading';
//
syncTasksFromStore();
//
// startDownload(taskIndex);
api.downloadGanDanFile({
console.log('1218');
api.downloadGanDanFileV2({
file_uuid: uuid.value,
order_id: order_id,
}).then((res) => {
console.log(res);
const base64 = uni.arrayBufferToBase64(res);
base64ToFile(base64, orderInfo.value.name+'.pdf', (path) => {
downLoadStatus.value = 'completed';
uni.showToast({
title: "下载成功",
icon: "none",
});
downloadStore.updateTask(taskIndex, {
status: "completed",
localPath: path,
});
console.log('qweqweqweqwe');
if(res.code == 200){
addDownloadTask({
url: docUrl + res.data,
id: uuid.value,
title: orderInfo.value.name,
type: 'ppt',
status: 'downloading',
})
}
//const base64 = uni.arrayBufferToBase64(res);
// base64ToFile(base64, orderInfo.value.name+'.pdf', (path) => {
// downLoadStatus.value = 'completed';
// uni.showToast({
// title: "",
// icon: "none",
// });
// downloadStore.updateTask(taskIndex, {
// status: "completed",
// localPath: path,
// });
});
//});
});
};
@ -786,14 +916,11 @@ const ganDanFileDetials = async () => {
if (res.code == 200) {res.data
orderInfo.value = res.data;
//
shareTitle.value = res.data.name || "课件分享";
summary.value = "分享一份来自“肝胆相照”的课件:" + shareTitle.value;
shareTitle.value = res.data.name;
summary.value = "肝胆相照-国内专业优质肝胆课件共享平台" ;
// H5
shareLink.value = "https://www.igandan.com";
//
if (res.data.cover) {
shareImg.value = res.data.cover;
}
shareLink.value =otherHost+'/gandanfile/detail?uuid='+uuid.value+'&fromtype=doctor';
isCollection.value = res.data.iscollection;
order.value = res.data.order;
let money = res.data.price/ 100;
@ -813,6 +940,10 @@ const ganDanFileDetials = async () => {
});
}
});
// if(canDownload.value){
// console.log('');
// downloadGanDanFile();
// }
}
};
@ -828,16 +959,7 @@ const onSwiperChange = (e) => {
currentIndex.value = e.detail.current;
};
const goBack = () => {
uni.navigateBack({
delta: 1,
fail: (err) => {
uni.redirectTo({
url: "/pages/index/index",
});
},
});
};
const alertDownloading = () => {
uni.showToast({
@ -845,6 +967,97 @@ const alertDownloading = () => {
icon: "none",
});
};
const addDownloadTask = (item) => {
// 使store
const taskIndex = downloadStore.addTask(item);
//
syncTasksFromStore();
//
startDownload(taskIndex);
};
//
const startDownload = (index) => {
const taskItem = downloadStore.getTask(index);
if (!taskItem) return;
hasDownload.value = true;
downLoadStatus.value = 'loading';
const task = uni.downloadFile({
url: taskItem.url,
success: (res1) => {
//console.log("res1:"+JSON.stringify(res1));
if (res1.statusCode === 200) {
downloadStore.updateTask(index, {
status: "completed",
filePath: res1.tempFilePath,
});
downLoadStatus.value = 'completed';
uni.showToast({
title: "下载成功",
icon: "none",
});
downLoadStatus.value = 'completed';
uni.saveFile({
tempFilePath: res1.tempFilePath,
success: function (res2) {
console.log("res2:"+JSON.stringify(res2));
uni.getSavedFileInfo({
filePath: res2.savedFilePath,
success: function (res) {
console.log("res:"+JSON.stringify(res));
console.log("size:"+res.size);
downloadStore.updateTask(index, {
status: "completed",
localPath: res2.savedFilePath,
size: res.size,
});
},
});
},
});
} else {
downloadStore.updateTask(index, {
status: "failed",
});
uni.showToast({
title: "下载失败",
icon: "none",
});
}
},
fail: (err) => {
downloadStore.updateTask(index, {
status: "failed",
});
uni.showToast({
title: "下载失败: " + (err.errMsg || "未知错误"),
icon: "none",
duration: 2000,
});
},
});
//
task.onProgressUpdate((update) => {
const currentTask = downloadStore.getTask(index);
if (currentTask && currentTask.status === "downloading") {
downloadStore.updateTask(index, {
progress: update.progress,
downloadSize: update.totalBytesWritten,
totalSize: update.totalBytesExpectedToWrite,
});
}
});
// taskstore/
downloadStore.updateTask(index, {
task: task,
});
};
const syncTasksFromStore = () => {
downloadTasks.value = downloadStore.getTasks();
};
@ -863,6 +1076,13 @@ const resumeDownloadingTasks = () => {
// ===== =====
const shareToWechat = () => {
// #ifdef APP-PLUS
uni.downloadFile({
url: 'https://doc.igandan.com/app/html/img/2016/20160714132557.png',
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneSession",
@ -870,7 +1090,7 @@ const shareToWechat = () => {
title: shareTitle.value,
summary: summary.value,
href: shareLink.value,
imageUrl: shareImg.value,
imageUrl: res2.tempFilePath,
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
@ -878,6 +1098,25 @@ const shareToWechat = () => {
console.log("fail:" + JSON.stringify(err));
},
});
},
});
},
});
// uni.share({
// provider: "weixin",
// scene: "WXSceneSession",
// type: 0,
// title: shareTitle.value,
// summary: summary.value,
// href: shareLink.value,
// imageUrl: shareImg.value,
// success: function (res) {
// console.log("success:" + JSON.stringify(res));
// },
// fail: function (err) {
// console.log("fail:" + JSON.stringify(err));
// },
// });
// #endif
// #ifdef H5
@ -919,6 +1158,13 @@ const shareToWechat = () => {
// ===== =====
const shareToMoments = () => {
// #ifdef APP-PLUS
uni.downloadFile({
url: 'https://doc.igandan.com/app/html/img/2016/20160714132557.png',
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneTimeline",
@ -926,7 +1172,7 @@ const shareToMoments = () => {
title: shareTitle.value,
summary: summary.value,
href: shareLink.value,
imageUrl: shareImg.value,
imageUrl: res2.tempFilePath,
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
@ -934,6 +1180,11 @@ const shareToMoments = () => {
console.log("fail:" + JSON.stringify(err));
},
});
},
});
},
});
// #endif
// #ifdef H5

View File

@ -29,31 +29,28 @@
class="guideline-item"
v-for="(item, index) in downLoadtaskList"
:key="item.id || index"
@click="viewGuideline(item)"
@longpress="handleLongPress(item)"
>
<!-- 指南信息 -->
<view class="item-content">
<view class="item-title">{{ item.title }}</view>
<view class="item-bottom">
<!-- <view class="item-bottom">
<view class="item-date">{{ formatDate(item.releaseTime) }}</view>
<!-- 操作按钮 -->
<view class="item-action">
<view
class="view-btn"
@click.stop="viewGuideline(item)"
>查看</view>
</view>
</view> -->
</view>
</view>
</view>
</view>
<!-- 无数据提示 -->
<view class="no-data" v-if="downLoadtaskList.length === 0 ">
<uni-icons type="info" size="60" color="#999"></uni-icons>
<text>暂无数据</text>
<empty></empty>
</view>
</scroll-view>
</view>
@ -101,12 +98,26 @@
></uni-icons>
</view>
</view>
<!-- 删除确认弹窗 -->
<view v-if="showDeleteModal" class="delete-modal-mask" @click="closeDeleteModal">
<view class="delete-modal-content" @click.stop>
<view class="delete-modal-title">确认删除</view>
<view class="delete-modal-text">确定要删除"{{ currentDeleteItem?.title }}"</view>
<view class="delete-modal-buttons">
<view class="delete-modal-btn cancel-btn" @click="closeDeleteModal">取消</view>
<view class="delete-modal-btn confirm-btn" @click="confirmDelete">删除</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, onMounted,computed,nextTick} from "vue";
import api from "@/api/api.js";
import { onShow, onLoad } from "@dcloudio/uni-app";
import { onShow, onLoad,onBackPress} from "@dcloudio/uni-app";
import empty from "@/components/empty/empty.vue";
import docUrl from "@/utils/docUrl.js";
import navTo from "@/utils/navTo.js";
import hotImg from "@/static/hot_booklist.png";
@ -117,6 +128,8 @@
const pageSize = ref(10);
const isRefreshing = ref(false);
const keywords = ref("");
const showDeleteModal = ref(false);
const currentDeleteItem = ref(null);
import upImg from "@/static/triangle_green_theme.png";
import downImg from "@/static/triangle_normal.png";
const loadMoreStatus = ref("more"); // 'loading', 'more', 'noMore'
@ -125,11 +138,15 @@
const sort = ref(2);
const showInnerSort = ref(false);
const innerSortTitle = ref("上传时间");
import downloadStore from "@/store/downloadStoreFile.js";
import downloadStore from "@/store/downloadStorePpt.js";
const downloadTasks=ref([]);
const downLoadtaskList=computed(()=>{
return downloadTasks.value.filter((item)=>item.status == "completed" && item.type == "ppt");
});
onBackPress(()=>{
plus.runtime.quit();
return true;
})
const chooseInnerSort = (index) => {
sort.value = index;
if (index == 1) {
@ -597,6 +614,71 @@
return dateString;
}
};
//
const handleLongPress = (item) => {
currentDeleteItem.value = item;
showDeleteModal.value = true;
};
//
const closeDeleteModal = () => {
showDeleteModal.value = false;
currentDeleteItem.value = null;
};
//
const confirmDelete = () => {
if (!currentDeleteItem.value) return;
// store id task index
const allTasks = downloadStore.getTasks();
const taskIndex = allTasks.findIndex(task => task.id === currentDeleteItem.value.id);
if (taskIndex !== -1) {
const taskItem = downloadStore.getTask(taskIndex);
//
if (taskItem && taskItem.localPath) {
uni.removeSavedFile({
filePath: taskItem.localPath,
success: () => {
console.log('本地文件删除成功');
},
fail: (err) => {
console.log('本地文件删除失败:', err);
// 使
},
complete: () => {
//
removeTask(taskIndex);
uni.showToast({
title: "删除成功",
icon: "none",
duration: 1500,
});
closeDeleteModal();
}
});
} else {
//
removeTask(taskIndex);
uni.showToast({
title: "删除成功",
icon: "success",
duration: 1500,
});
closeDeleteModal();
}
} else {
uni.showToast({
title: "删除失败,未找到任务",
icon: "none",
duration: 1500,
});
closeDeleteModal();
}
};
</script>
<style lang="scss" scoped>
@ -750,7 +832,7 @@
font-size: 32rpx;
color: $text-primary;
line-height: 1.5;
margin-bottom: 16rpx;
font-weight: 500;
display: -webkit-box;
-webkit-box-orient: vertical;

View File

@ -450,6 +450,10 @@ const getVideoType=async () => {
.author {
font-size: 24rpx;
color: #999;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-right: 20rpx;
}
.stats {

View File

@ -812,21 +812,7 @@ const hideFilterPopup = () => {
};
const toggleTag = (index) => {
const currentTag = filterTags.value[index];
const selectedCount = filterTags.value.filter((tag) => tag.selected).length;
// 3
if (!currentTag.selected && selectedCount >= 3) {
uni.showToast({
title: "最多只能选择3个标签",
icon: "none",
duration: 2000,
});
return;
}
//
currentTag.selected = !currentTag.selected;
filterTags.value[index].selected = !filterTags.value[index].selected;
isFilterActive.value = filterTags.value.some((tag) => tag.selected);
};

View File

@ -267,6 +267,13 @@ const downloadTasks = ref([]);
let userInfo = uni.getStorageSync("userInfo");
const current_user_id = ref(userInfo.uuid);
//
const onFullscreenChange = (e) => {
let { fullScreen, direction } = e;
nextTick(() => {
isFullScreen.value = fullScreen;
});
};
const addDownloadTask = (item) => {
// 使store
@ -276,12 +283,6 @@ const addDownloadTask = (item) => {
//
startDownload(taskIndex);
};
const onFullscreenChange = (e) => {
let { fullScreen, direction } = e;
nextTick(() => {
isFullScreen.value = fullScreen;
});
};
//
const startDownload = (index) => {
const taskItem = downloadStore.getTask(index);
@ -611,7 +612,13 @@ const closeShare = () => {
const shareToWechat = () => {
// #ifdef APP-PLUS
// 使
uni.downloadFile({
url:isAndroid?docUrl + videoInfo.value.imgpath:'https://doc.igandan.com/app/html/img/2016/20160714132557.png',
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneSession",
@ -619,14 +626,33 @@ const shareToWechat = () => {
title: videoInfo.value.name,
summary: videoInfo.value.note,
href: shareLink.value,
imageUrl: docUrl + videoInfo.value.imgpath,
imageUrl: res2.tempFilePath,
success: function (res) {
//console.log("success:" + JSON.stringify(res));
console.log("success:" + JSON.stringify(res));
},
fail: function (err) {
//console.log("fail:" + JSON.stringify(err));
console.log("fail:" + JSON.stringify(err));
},
});
},
});
},
});
// uni.share({
// provider: "weixin",
// scene: "WXSceneSession",
// type: 0,
// title: videoInfo.value.name,
// summary: videoInfo.value.note,
// href: shareLink.value,
// imageUrl: docUrl + videoInfo.value.imgpath,
// success: function (res) {
// //console.log("success:" + JSON.stringify(res));
// },
// fail: function (err) {
// //console.log("fail:" + JSON.stringify(err));
// },
// });
// #endif
// #ifdef H5
@ -680,6 +706,13 @@ const shareToWechat = () => {
//
const shareToMoments = () => {
// #ifdef APP-PLUS
uni.downloadFile({
url: isAndroid?docUrl + videoInfo.value.imgpath:'https://doc.igandan.com/app/html/img/2016/20160714132557.png',
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneTimeline",
@ -687,13 +720,17 @@ const shareToMoments = () => {
title: videoInfo.value.name,
summary: videoInfo.value.note,
href: shareLink.value,
imageUrl: docUrl + videoInfo.value.imgpath,
imageUrl: res2.tempFilePath,
success: function (res) {
//console.log("success:" + JSON.stringify(res));
},
fail: function (err) {
//console.log("fail:" + JSON.stringify(err));
},
});
},
});
},
});
// #endif

View File

@ -2,7 +2,6 @@
<view class="container" :style="{ backgroundColor: backgroundColor }">
<!-- 分享弹窗 -->
<view class="navbox">
<view class="status_bar"></view>
<uni-nav-bar
@ -16,14 +15,18 @@
<template #right>
<view class="nav-actions">
<view class="collect-img" @click="shareToggle" v-if="canShare">
<image class="share-img-icon" :src="shareIcon" mode="aspectFill" />
<image
class="share-img-icon"
:src="shareIcon"
mode="aspectFill"
/>
</view>
</view>
</template>
</uni-nav-bar>
</view>
</view>
<uni-popup ref="shareRef" type="bottom" safeArea backgroundColor="#fff">
</view>
<uni-popup ref="shareRef" type="bottom" safeArea backgroundColor="#fff">
<view class="share-popup">
<view class="share-title">分享到</view>
<view class="share-content">
@ -51,12 +54,11 @@
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref } from "vue";
import { onLoad,onHide,onShow,onUnload} from "@dcloudio/uni-app";
import { onLoad, onHide, onShow, onUnload } from "@dcloudio/uni-app";
import navBar from "@/components/navBar/navBar.vue";
import shareIcon from "@/static/icon_share.png";
import sinaImg from "@/static/share_sina.png";
@ -70,23 +72,21 @@ const hasBg = ref(false);
const canShare = ref(false);
const summary = ref("");
const shareLink = ref("");
const shareImg=ref("");
const shareImg = ref("");
const shareTitle = ref("");
const goBack = () => {
uni.navigateBack({
fail() {
uni.redirectTo({
url: '/pages/index/index'
url: "/pages/index/index",
});
}
},
});
};
onShow(() => {
uni.hideLoading();
// console.log('show');
// plus.screen.lockOrientation('portrait-primary');
});
onUnload(() => {
// console.log('onUnload');
@ -95,17 +95,15 @@ onUnload(() => {
onHide(() => {
// console.log('onHide');
// plus.screen.lockOrientation('landscape-primary');
});
onLoad((query) => {
if(query.title){
if (query.title) {
title.value = query.title;
}
if(query.share == 1){
if (query.share == 1) {
canShare.value = true;
}
if(query.bg == 1){
if (query.bg == 1) {
hasBg.value = true;
backgroundColor.value = "linear-gradient(to bottom,'#fff' , '#398775')";
@ -116,32 +114,30 @@ onLoad((query) => {
success: (sysinfo) => {
height = sysinfo.windowHeight; //
},
complete: () => {}
complete: () => {},
});
const raw = query && (query.url || "");
try {
safeUrl.value = decodeURIComponent(raw);
shareImg.value = decodeURIComponent(query.imgPath);
if(query.type == "live_yugao"){
if (query.type == "live_yugao") {
shareTitle.value = query.sharetitle;
summary.value = "分享一篇来自“肝胆相照”的会议预告:"+shareTitle.value;
}else if(query.type == "live_old"){
summary.value = "分享一篇来自“肝胆相照”的会议预告:" + shareTitle.value;
} else if (query.type == "live_old") {
shareTitle.value = query.sharetitle;
summary.value = "分享一篇来自“肝胆相照”的历史会议:"+shareTitle.value;
}else if(query.type == "live"){
shareTitle.value = '肝胆相照直播:'+query.sharetitle;
summary.value = "分享一篇来自“肝胆相照”的历史会议:" + shareTitle.value;
} else if (query.type == "live") {
shareTitle.value = "肝胆相照直播:" + query.sharetitle;
summary.value = shareTitle.value;
}
// #ifdef APP-PLUS
const resInfo = uni.getSystemInfoSync(); // 使 uni.getSystemInfo({...}).then(res => {...})
let statusBarHeight = resInfo.statusBarHeight;
let wv = plus.webview.create("", "custom-webview", {
top: (statusBarHeight+44) + "px",
bottom:"0rpx",
top: statusBarHeight + 44 + "px",
bottom: "0rpx",
});
wv.loadURL( safeUrl.value);
wv.loadURL(safeUrl.value);
let pages = getCurrentPages();
let page = pages[pages.length - 1];
@ -150,44 +146,49 @@ onLoad((query) => {
currentWebview.append(wv);
setTimeout(function () {
wv = currentWebview.children()[0];
wv.setStyle({ top: (statusBarHeight+44)+"px",height: height- 80,bottom:0,scalable:true, videoFullscreen: 'landscape',zIndex:-1});
wv.setStyle({
top: statusBarHeight + 44 + "px",
height: height - 80,
bottom: 0,
scalable: true,
videoFullscreen: "landscape",
zIndex: -1,
});
}, 300); //
wv.onloaded = (e) => {
wv.show();
};
uni.onWindowResize((res) => {
if (res.size.windowHeight < height) {
console.log(res.size.windowHeight);
console.log(height)
console.log('键盘高度',res.height);
setTimeout(function() {
wv.setStyle({ //web-viewpx
top:(statusBarHeight+44)+"px",
videoFullscreen: 'landscape',
height: height-res.size.windowHeight+100,
console.log(height);
console.log("键盘高度", res.height);
setTimeout(function () {
wv.setStyle({
//web-viewpx
top: statusBarHeight + 44 + "px",
videoFullscreen: "landscape",
height: height - res.size.windowHeight + 100,
scalable: true, //webview
})
},0);
});
}, 0);
//
//
} else {
setTimeout(function() {
wv.setStyle({ //web-viewpx
top:(statusBarHeight+44)+"px",
height:height-80,
videoFullscreen: 'landscape',
setTimeout(function () {
wv.setStyle({
//web-viewpx
top: statusBarHeight + 44 + "px",
height: height - 80,
videoFullscreen: "landscape",
scalable: true, //webview
})
},0);
});
}, 0);
}
})
});
//
createNativePopup();
@ -195,8 +196,6 @@ onLoad((query) => {
} catch (e) {
safeUrl.value = raw;
}
});
const shareRef = ref(null);
shareRef.value?.open();
@ -237,7 +236,7 @@ const popupInfo = ref({
cancelH: 0,
contentTop: 0,
iconSize: 0,
textSize: 0
textSize: 0,
});
function createNativePopup() {
@ -262,57 +261,82 @@ function createNativePopup() {
cancelH,
contentTop,
iconSize,
textSize
textSize,
};
//
nativeMaskView.value = new plus.nativeObj.View('native-share-mask', {
left: '0px',
top: '0px',
width: screenW + 'px',
height: screenH + 'px',
nativeMaskView.value = new plus.nativeObj.View(
"native-share-mask",
{
left: "0px",
top: "0px",
width: screenW + "px",
height: screenH + "px",
zindex: 99998,
touchable: true,
interceptTouchEvent: true
}, [
{ tag: 'rect', id: 'mask', position: { left: '0px', top: '0px', width: screenW + 'px', height: screenH + 'px' }, color: 'rgba(0,0,0,0.5)' }
]);
interceptTouchEvent: true,
},
[
{
tag: "rect",
id: "mask",
position: {
left: "0px",
top: "0px",
width: screenW + "px",
height: screenH + "px",
},
color: "rgba(0,0,0,0.5)",
},
]
);
//
nativePopupView.value = new plus.nativeObj.View('native-share-panel', {
left: '0px',
top: (screenH - panelH) + 'px',
width: screenW + 'px',
height: panelH + 'px',
nativePopupView.value = new plus.nativeObj.View(
"native-share-panel",
{
left: "0px",
top: screenH - panelH + "px",
width: screenW + "px",
height: panelH + "px",
zindex: 99999,
touchable: true,
interceptTouchEvent: true
}, []);
interceptTouchEvent: true,
},
[]
);
// +
nativePopupView.value.drawRect({
color: '#FFFFFF',
nativePopupView.value.drawRect(
{
color: "#FFFFFF",
radius: radius,
rectStyles: {}
}, {
left: uni.upx2px(0) + 'px',
top: uni.upx2px(0) + 'px',
width: screenW + 'px',
height: panelH + 'px'
});
rectStyles: {},
},
{
left: uni.upx2px(0) + "px",
top: uni.upx2px(0) + "px",
width: screenW + "px",
height: panelH + "px",
}
);
//
nativePopupView.value.drawText('分享到', {
left: '0px',
top: uni.upx2px(20) + 'px',
width: screenW + 'px',
height: titleH + 'px'
}, {
size: uni.upx2px(32) + 'px',
color: '#333333',
align: 'center',
verticalAlign: 'middle',
weight: '500'
});
nativePopupView.value.drawText(
"分享到",
{
left: "0px",
top: uni.upx2px(20) + "px",
width: screenW + "px",
height: titleH + "px",
},
{
size: uni.upx2px(32) + "px",
color: "#333333",
align: "center",
verticalAlign: "middle",
weight: "500",
}
);
const items = [
{ id: 'it-wechat', text: '微信' },
{ id: 'it-moments', text: '朋友圈' },
{ id: "it-wechat", text: "微信" },
{ id: "it-moments", text: "朋友圈" },
// { id: 'it-weibo', text: '' }
];
// 使
@ -320,23 +344,21 @@ function createNativePopup() {
const iconTop = contentTop;
const textTop = iconTop + iconSize + uni.upx2px(16);
console.log('图标布局信息:', {
console.log("图标布局信息:", {
screenW,
itemW,
iconSize,
iconTop,
contentTop
contentTop,
});
// 使
const iconFiles = [
'share_weixin.png', //
'share_wxc.png', //
'share_sina.png' //
"share_weixin.png", //
"share_wxc.png", //
"share_sina.png", //
];
items.forEach((it, idx) => {
const left = idx * itemW;
//
@ -346,7 +368,11 @@ function createNativePopup() {
const iconTopPx = Math.round(iconTop);
const iconSizePx = iconSize;
console.log(`图标 ${idx} (${it.text}): left=${left}, itemW=${itemW.toFixed(2)}, iconLeft=${iconLeftPx}, iconTop=${iconTopPx}, iconSize=${iconSizePx}`);
console.log(
`图标 ${idx} (${it.text}): left=${left}, itemW=${itemW.toFixed(
2
)}, iconLeft=${iconLeftPx}, iconTop=${iconTopPx}, iconSize=${iconSizePx}`
);
//
//
@ -358,109 +384,132 @@ function createNativePopup() {
try {
const iconFile = iconFiles[idx];
// 使 _www iOS file://
iconPath = '_www/static/' + iconFile;
iconPath = "_www/static/" + iconFile;
console.log(`图标 ${it.text} 路径: ${iconPath}`);
} catch (e) {
console.log('构建图标路径失败:', e);
console.log("构建图标路径失败:", e);
iconPath = null;
}
//
if (iconPath) {
try {
console.log(`绘制图标 ${it.text}: 位置=(${iconLeftPx}, ${iconTopPx}), 大小=${iconSizePx}x${iconSizePx}`);
console.log(
`绘制图标 ${it.text}: 位置=(${iconLeftPx}, ${iconTopPx}), 大小=${iconSizePx}x${iconSizePx}`
);
// 使 drawBitmap
//
// 1: drawBitmap(src, position, options)
try {
nativePopupView.value.drawBitmap(iconPath, {}, {
left: iconLeftPx + 'px',
top: iconTopPx + 'px',
width: iconSizePx + 'px',
height: iconSizePx + 'px'
});
nativePopupView.value.drawBitmap(
iconPath,
{},
{
left: iconLeftPx + "px",
top: iconTopPx + "px",
width: iconSizePx + "px",
height: iconSizePx + "px",
}
);
} catch (e1) {
// 12: drawBitmap(src, position)
try {
nativePopupView.value.drawBitmap(iconPath, {
left: iconLeftPx + 'px',
top: iconTopPx + 'px',
width: iconSizePx + 'px',
height: iconSizePx + 'px'
left: iconLeftPx + "px",
top: iconTopPx + "px",
width: iconSizePx + "px",
height: iconSizePx + "px",
});
} catch (e2) {
console.log('drawBitmap 两种格式都失败:', e1, e2);
console.log("drawBitmap 两种格式都失败:", e1, e2);
throw e2;
}
}
} catch (e) {
console.log('绘制图标失败,使用圆形色块代替:', e);
console.log("绘制图标失败,使用圆形色块代替:", e);
// 使
const bgColor = idx === 2 ? '#E6162D' : '#07C160';
nativePopupView.value.drawRect({
const bgColor = idx === 2 ? "#E6162D" : "#07C160";
nativePopupView.value.drawRect(
{
color: bgColor,
radius: Math.round(iconSize / 2)
}, {
left: Math.round(iconLeft) + 'px',
top: Math.round(iconTop) + 'px',
width: Math.round(iconSize) + 'px',
height: Math.round(iconSize) + 'px'
});
radius: Math.round(iconSize / 2),
},
{
left: Math.round(iconLeft) + "px",
top: Math.round(iconTop) + "px",
width: Math.round(iconSize) + "px",
height: Math.round(iconSize) + "px",
}
);
}
} else {
// 使
const bgColor = idx === 2 ? '#E6162D' : '#07C160';
nativePopupView.value.drawRect({
const bgColor = idx === 2 ? "#E6162D" : "#07C160";
nativePopupView.value.drawRect(
{
color: bgColor,
radius: Math.round(iconSize / 2)
}, {
left: Math.round(iconLeft) + 'px',
top: Math.round(iconTop) + 'px',
width: Math.round(iconSize) + 'px',
height: Math.round(iconSize) + 'px'
});
radius: Math.round(iconSize / 2),
},
{
left: Math.round(iconLeft) + "px",
top: Math.round(iconTop) + "px",
width: Math.round(iconSize) + "px",
height: Math.round(iconSize) + "px",
}
);
}
//
nativePopupView.value.drawText(it.text, {
left: left + 'px',
top: textTop + 'px',
width: itemW + 'px',
height: textSize + uni.upx2px(20) + 'px'
}, {
size: textSize + 'px',
color: '#666666',
align: 'center',
verticalAlign: 'top'
});
nativePopupView.value.drawText(
it.text,
{
left: left + "px",
top: textTop + "px",
width: itemW + "px",
height: textSize + uni.upx2px(20) + "px",
},
{
size: textSize + "px",
color: "#666666",
align: "center",
verticalAlign: "top",
}
);
});
// 线
const cancelTop = panelH - cancelH;
nativePopupView.value.drawRect({ color: '#F0F0F0' }, {
left: '0px',
top: (cancelTop - 1) + 'px',
width: screenW + 'px',
height: '1px'
});
nativePopupView.value.drawText('取消', {
left: '0px',
top: cancelTop + 'px',
width: screenW + 'px',
height: cancelH + 'px'
}, {
size: uni.upx2px(32) + 'px',
color: '#333333',
align: 'center',
verticalAlign: 'middle'
});
nativePopupView.value.drawRect(
{ color: "#F0F0F0" },
{
left: "0px",
top: cancelTop - 1 + "px",
width: screenW + "px",
height: "1px",
}
);
nativePopupView.value.drawText(
"取消",
{
left: "0px",
top: cancelTop + "px",
width: screenW + "px",
height: cancelH + "px",
},
{
size: uni.upx2px(32) + "px",
color: "#333333",
align: "center",
verticalAlign: "middle",
}
);
//
const handleMaskClick = () => {
console.log('遮罩被点击');
console.log("遮罩被点击");
closeNativePopup();
};
const handlePanelClick = (e) => {
console.log('面板被点击', e);
console.log("面板被点击", e);
const info = popupInfo.value;
//
@ -482,11 +531,11 @@ function createNativePopup() {
y = e.changedTouches[0].clientY || e.changedTouches[0].pageY || 0;
}
console.log('原始坐标:', x, y);
console.log('屏幕信息:', info);
console.log("原始坐标:", x, y);
console.log("屏幕信息:", info);
if (!x || !y) {
console.log('坐标无效');
console.log("坐标无效");
return;
}
@ -500,64 +549,95 @@ function createNativePopup() {
// 使
relativeY = y;
relativeX = x;
console.log('使用相对于视图的坐标:', relativeX, relativeY);
} else if (y >= (info.screenH - info.panelH)) {
console.log("使用相对于视图的坐标:", relativeX, relativeY);
} else if (y >= info.screenH - info.panelH) {
//
relativeY = y - (info.screenH - info.panelH);
relativeX = x;
console.log('使用相对于屏幕的坐标,转换为相对视图:', relativeX, relativeY);
console.log(
"使用相对于屏幕的坐标,转换为相对视图:",
relativeX,
relativeY
);
} else {
// 使
console.log('坐标类型不确定,尝试直接使用');
console.log("坐标类型不确定,尝试直接使用");
}
// -
const cancelTop = info.panelH - info.cancelH;
console.log('取消区域判断: relativeY =', relativeY, ', cancelTop =', cancelTop);
console.log(
"取消区域判断: relativeY =",
relativeY,
", cancelTop =",
cancelTop
);
if (relativeY >= cancelTop) {
console.log('点击了取消按钮');
console.log("点击了取消按钮");
closeNativePopup();
return;
}
// +-
const shareAreaTop = info.contentTop;
const shareAreaBottom = shareAreaTop + info.iconSize + info.textSize + uni.upx2px(20);
const shareAreaBottom =
shareAreaTop + info.iconSize + info.textSize + uni.upx2px(20);
console.log('分享区域: relativeY =', relativeY, ', 范围 =', shareAreaTop, '到', shareAreaBottom);
console.log(
"分享区域: relativeY =",
relativeY,
", 范围 =",
shareAreaTop,
"到",
shareAreaBottom
);
if (relativeY >= shareAreaTop && relativeY <= shareAreaBottom) {
// 0:, 1:, 2:
const itemWidth = info.screenW / items.length;
const idx = Math.min(2, Math.max(0, Math.floor(relativeX / itemWidth)));
console.log('点击了分享项:', idx, ', x =', relativeX, ', itemWidth =', itemWidth);
console.log(
"点击了分享项:",
idx,
", x =",
relativeX,
", itemWidth =",
itemWidth
);
if (idx === 0) {
console.log('执行微信分享');
console.log("执行微信分享");
shareToWechat();
closeNativePopup();
} else if (idx === 1) {
console.log('执行朋友圈分享');
console.log("执行朋友圈分享");
shareToMoments();
closeNativePopup();
} else if (idx === 2) {
console.log('执行微博分享');
console.log("执行微博分享");
// shareToWeibo();
// closeNativePopup();
}
} else {
console.log('点击位置不在分享区域内, relativeY =', relativeY, ', 需要范围:', shareAreaTop, '到', shareAreaBottom);
console.log(
"点击位置不在分享区域内, relativeY =",
relativeY,
", 需要范围:",
shareAreaTop,
"到",
shareAreaBottom
);
}
};
// click touchstart
nativeMaskView.value.addEventListener('click', handleMaskClick, false);
nativeMaskView.value.addEventListener('touchstart', handleMaskClick, false);
nativeMaskView.value.addEventListener("click", handleMaskClick, false);
nativeMaskView.value.addEventListener("touchstart", handleMaskClick, false);
nativePopupView.value.addEventListener('click', handlePanelClick, false);
nativePopupView.value.addEventListener('touchstart', handlePanelClick, false);
nativePopupView.value.addEventListener('touchend', handlePanelClick, false);
nativePopupView.value.addEventListener("click", handlePanelClick, false);
nativePopupView.value.addEventListener("touchstart", handlePanelClick, false);
nativePopupView.value.addEventListener("touchend", handlePanelClick, false);
// #endif
}
@ -586,14 +666,21 @@ function closeNativePopup() {
const shareToWechat = () => {
// #ifdef APP-PLUS
// 使
uni.downloadFile({
url: shareImg.value,
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneSession",
type: 0,
title: shareTitle.value,
summary:summary.value,
summary: summary.value,
href: safeUrl.value,
imageUrl: shareImg.value,
imageUrl: res2.tempFilePath,
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
@ -601,6 +688,11 @@ const shareToWechat = () => {
console.log("fail:" + JSON.stringify(err));
},
});
},
});
},
});
// #endif
// #ifdef H5
@ -659,10 +751,14 @@ onHide(() => {
});
onUnload(() => {
// #ifdef APP-PLUS
try{
nativeMaskView.value && nativeMaskView.value.close && nativeMaskView.value.close();
nativePopupView.value && nativePopupView.value.close && nativePopupView.value.close();
}catch(e){}
try {
nativeMaskView.value &&
nativeMaskView.value.close &&
nativeMaskView.value.close();
nativePopupView.value &&
nativePopupView.value.close &&
nativePopupView.value.close();
} catch (e) {}
nativeMaskView.value = null;
nativePopupView.value = null;
popupShowing.value = false;
@ -671,14 +767,21 @@ onUnload(() => {
//
const shareToMoments = () => {
// #ifdef APP-PLUS
uni.downloadFile({
url: shareImg.value,
success: function (res) {
uni.compressImage({
src: res.tempFilePath,
quality: 60,
success: function (res2) {
uni.share({
provider: "weixin",
scene: "WXSceneTimeline",
type: 0,
title: shareTitle.value,
summary:summary.value,
summary: summary.value,
href: safeUrl.value,
imageUrl: shareImg.value,
imageUrl: res2.tempFilePath,
success: function (res) {
console.log("success:" + JSON.stringify(res));
},
@ -686,6 +789,14 @@ const shareToMoments = () => {
console.log("fail:" + JSON.stringify(err));
},
});
},
fail: function (err) {
console.log("fail:" + JSON.stringify(err));
},
});
},
});
// #endif
// #ifdef H5
@ -717,8 +828,8 @@ const shareToWeibo = () => {
uni.share({
provider: "sinaweibo",
type: 0,
title: shareTitle.value ,
summary:summary.value,
title: shareTitle.value,
summary: summary.value,
href: safeUrl.value,
imageUrl: logoImg,
success: function (res) {
@ -763,7 +874,7 @@ const shareToWeibo = () => {
</script>
<style>
.mask{
.mask {
position: fixed;
top: 0;
left: 0;
@ -869,7 +980,7 @@ const shareToWeibo = () => {
.container {
height: 100vh;
position: relative;
z-index:0;
z-index: 0;
overflow: scroll;
}
.tip {

View File

@ -52,8 +52,7 @@
<!-- 无数据提示 -->
<view class="no-data" v-if="downLoadtaskList.length === 0 ">
<uni-icons type="info" size="60" color="#999"></uni-icons>
<text>暂无数据</text>
<empty></empty>
</view>
</scroll-view>
</view>
@ -130,6 +129,7 @@
const keywords = ref("");
import upImg from "@/static/triangle_green_theme.png";
import downImg from "@/static/triangle_normal.png";
import empty from "@/components/empty/empty.vue";
const loadMoreStatus = ref("more"); // 'loading', 'more', 'noMore'
const typeUuid = ref("");
const title = ref("");

View File

@ -1,6 +1,6 @@
<template>
<view class="coupon-page">
<uni-nav-bar
<!-- <uni-nav-bar
left-icon="left"
title="积分券"
@clickLeft="goBack"
@ -9,7 +9,8 @@
height="180rpx"
:border="false"
backgroundColor="#ffffff"
/>
/> -->
<navBar :title="'积分券'" ></navBar>
<!-- 顶部 tabs -->
<view class="tabs">
@ -43,7 +44,10 @@
</view>
</view>
</view>
<view v-else class="empty">暂无数据</view>
<empty v-else></empty>
<!-- <view v-else class="empty">暂无数据</view> -->
</scroll-view>
</view>
</template>
@ -52,7 +56,8 @@
import { ref, computed, onMounted } from 'vue'
import navTo from '@/utils/navTo.js'
import api from '@/api/api.js'
import navBar from '@/components/navBar/navBar.vue'
import empty from '@/components/empty/empty.vue'
const tabs = [
{ label: '未兑换', value: '1' },
{ label: '已兑换', value: '2' },
@ -124,11 +129,24 @@ const formatDate = (seconds) => {
<style scoped>
.coupon-page{background:#f5f5f5;min-height:100vh}
.tabs{display:flex;align-items:center;justify-content:space-around;height:88rpx;background:#fff;border-bottom:1px solid #f0f0f0}
.tabs{
position: fixed;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
z-index: 100;
display:flex;align-items:center;justify-content:space-around;height:88rpx;background:#fff;border-bottom:1px solid #f0f0f0}
.tab-item{flex:1;display:flex;align-items:center;justify-content:center}
.tab-text{font-size:28rpx;color:#999}
.tab-item.active .tab-text{color:#8B2316;font-weight:600}
.list{height:calc(100vh - 88rpx - 180rpx);}
.list{
position: fixed;
top: calc(var(--status-bar-height) + 44px + 88rpx);
left: 0;
right: 0;
z-index: 100;
height:calc(100vh - var(--status-bar-height) - 44px - 88rpx);
}
.card-wrap{padding:24rpx}
.coupon-card{display:flex;flex-direction: column; background:linear-gradient(90deg,#ff7381, #ff6a7a);border-radius:16rpx;color:#fff;position:relative;margin-bottom:24rpx}
.coupon-card.gray{background:#e5e5e5;color:#666}

View File

@ -1,6 +1,7 @@
<template>
<view class="address-page">
<uni-nav-bar left-icon="left" title="收货地址" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
<navBar :title="'收货地址'" />
<!-- <uni-nav-bar left-icon="left" title="收货地址" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" /> -->
<scroll-view scroll-y class="content">
<view class="form-item">
@ -35,8 +36,8 @@
</view>
</scroll-view>
<view class="footer-bar">
<view class="confirm-btn" @click="submit">确定</view>
<view class="footer-bar" @click="submit">
<view class="confirm-btn" >确定</view>
</view>
<!-- 省市区选择器 -->
@ -205,7 +206,7 @@ const submit = () => {
<style scoped>
.address-page { min-height: 100vh; background: #fff; }
.content { position: absolute; top: 180rpx; bottom: 120rpx; left: 0; right: 0; background: #fff; }
.content { position: absolute; top: calc(var(--status-bar-height) + 44px); bottom: 120rpx; left: 0; right: 0; background: #fff; }
.form-item { display: flex; align-items: center; padding: 24rpx; }
.label { width: 160rpx; color: #333; font-size: 30rpx; }
.input { flex: 1; color: #333; font-size: 30rpx; }

View File

@ -1,6 +1,7 @@
<template>
<view class="addr-list-page">
<uni-nav-bar left-icon="left" title="地址管理" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
<navBar :title="'地址管理'" />
<!-- <uni-nav-bar left-icon="left" title="地址管理" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" /> -->
<scroll-view scroll-y class="list-wrap">
<view v-if="!list.length" class="empty">暂无收货地址</view>
@ -74,7 +75,7 @@ const select = (item) => {
<style scoped>
.addr-list-page { min-height: 100vh; background: #fff; }
.list-wrap { position: absolute; top: 180rpx; bottom: 120rpx; left: 0; right: 0; }
.list-wrap { position: absolute; top: calc(var(--status-bar-height) + 44px); bottom: 120rpx; left: 0; right: 0; }
.empty { text-align: center; color: #999; padding: 80rpx 24rpx; }
.addr-item { display: flex; align-items: center; justify-content: space-between; padding: 24rpx; border-bottom: 1rpx solid #f0f0f0; }
.addr-main { flex: 1; }

View File

@ -1,6 +1,7 @@
<template>
<view class="exchange-page">
<uni-nav-bar left-icon="left" title="在线兑换" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
<navBar :title="'在线兑换'" />
<!-- <uni-nav-bar left-icon="left" title="在线兑换" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" /> -->
<scroll-view scroll-y class="content">
<!-- 收货地址 -->
@ -168,7 +169,7 @@ const getTotalPoints = () => {
<style scoped>
.exchange-page { min-height: 100vh; background: #fff; }
.content { position: absolute; top: 180rpx; bottom: 120rpx; left: 0; right: 0; background: #fff; }
.content { position: absolute; top: calc(var(--status-bar-height) + 44px); bottom: 120rpx; left: 0; right: 0; background: #fff; }
.addr-card { background: #fff; padding: 24rpx; border-bottom: 1rpx solid #f0f0f0; }
.addr-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12rpx; }
.addr-title { color: #333; font-size: 30rpx; }
@ -178,7 +179,7 @@ const getTotalPoints = () => {
.addr-row.small { color: #666; font-size: 26rpx; }
.addr-empty { color: #bbb; font-size: 28rpx; }
.goods-title { padding: 24rpx; font-size: 32rpx; color: #333; line-height: 1.6; }
.price { padding: 0 24rpx 24rpx; color: #e74c3c; font-size: 30rpx; font-weight: 700; }
.price { padding: 0 24rpx 24rpx; color: #e74c3c; font-size: 30rpx; }
.divider { height: 16rpx; background: #f5f5f5; }
.section { padding: 24rpx; }
.section-label { color: #333; font-size: 30rpx; margin-bottom: 20rpx; }

View File

@ -1,7 +1,7 @@
<template>
<view class="page">
<uni-nav-bar left-icon="left" title="我的兑换" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" />
<!-- <uni-nav-bar left-icon="left" title="我的兑换" fixed color="#8B2316" height="180rpx" :border="false" backgroundColor="#ffffff" @clickLeft="goBack" /> -->
<navBar :title="'我的兑换'" />
<scroll-view
scroll-y
class="content"
@ -11,7 +11,8 @@
@scrolltolower="onReachBottom"
:lower-threshold="80"
>
<view v-if="!orderList.length" class="empty">暂无兑换记录</view>
<empty v-if="!orderList.length" />
<!-- <view v-if="!orderList.length" class="empty">暂无兑换记录</view> -->
<view v-for="item in orderList" :key="item.uuid" class="card">
<view class="row">
<text class="label">兑换物品</text>
@ -35,6 +36,8 @@
<script setup>
import goods_api from '@/api/goods_api'
import { ref, onMounted } from 'vue'
import navBar from '@/components/navBar/navBar.vue'
import empty from '@/components/empty/empty.vue'
const orderList = ref([])
const page = ref(1)
const pageSize = ref(10)
@ -99,7 +102,7 @@ const goBack = () => uni.navigateBack()
<style scoped>
.page { min-height: 100vh; background: #fff; }
.content { position: absolute; top: 180rpx; bottom: 0; left: 0; right: 0; background: #fff; }
.content { position: absolute; top: calc(var(--status-bar-height) + 44px); bottom: 0; left: 0; right: 0; background: #fff; }
.card { background: #fff; padding: 24rpx; border-bottom: 16rpx solid #f5f5f5; }
.row { display: flex; align-items: center; padding: 10rpx 0; }
.label { color: #333; font-size: 30rpx; width: 180rpx; }

View File

@ -1,7 +1,24 @@
<template>
<view class="point-mall-container">
<!-- 顶部导航栏 -->
<view class="navbox">
<view class="status_bar"></view>
<uni-nav-bar
left-icon="left"
title="积分商城"
@clickLeft="goBack"
color="#8B2316"
:border="false"
backgroundColor="#eeeeee"
>
<template v-slot:right>
<view class="nav-actions">
<view class="btn" @click="goToSearch">搜索</view>
</view>
</template>
</uni-nav-bar>
</view>
<!-- <uni-nav-bar
left-icon="left"
title="积分商城"
@clickLeft="goBack"
@ -14,27 +31,59 @@
<template v-slot:right>
<text class="search-btn" @click="goToSearch">搜索</text>
</template>
</uni-nav-bar>
</uni-nav-bar> -->
<!-- 轮播图横幅 -->
<view class="banner-section">
<swiper class="banner-swiper" :indicator-dots="true" :autoplay="true" :interval="3000" :duration="500">
<view class="swipemask">
<view class="banner-subtitle" v-if="bannerList.length > 0">{{
bannerList[currentBannerIndex].title
}}</view>
<view class="dotbox">
<view
class="circle"
:class="{ active: currentBannerIndex == index }"
v-for="(banner, index) in bannerList"
:key="banner.id"
></view>
</view>
</view>
<swiper
class="banner-swiper"
:indicator-dots="true"
:autoplay="true"
:interval="3000"
:duration="500"
indicator-active-color="#8B2316"
@change="onSwiperChange"
>
<swiper-item v-for="(banner, index) in bannerList" :key="banner.uuid">
<view class="banner-item" @click="goToBannerDetail(banner)">
<image class="banner-image" :src="banner.headImg" mode="aspectFill"></image>
<view class="banner-content">
<image
class="banner-image"
:src="banner.headImg"
mode="aspectFill"
></image>
<!-- <view class="banner-content tips">
<view class="banner-text green">{{ banner.title }}</view>
<view class="banner-text orange">{{ banner.create_date }}</view>
</view>
</view> -->
</view>
</swiper-item>
<!-- 如果没有数据显示默认轮播图 -->
<swiper-item v-if="bannerList.length === 0">
<view class="banner-item">
<image class="banner-image" src="/static/banner-bg.jpg" mode="aspectFill"></image>
<image
class="banner-image"
src="/static/banner-bg.jpg"
mode="aspectFill"
></image>
<view class="banner-content">
<view class="banner-text green">第二届京津冀感染肝病高峰论坛&</view>
<view class="banner-text green">第九届河北省感染科医师培训班</view>
<view class="banner-text green"
>第二届京津冀感染肝病高峰论坛&</view
>
<view class="banner-text green"
>第九届河北省感染科医师培训班</view
>
<view class="banner-text orange">2016.10.14-2016.10.16</view>
<view class="banner-text orange">河北石家庄</view>
</view>
@ -46,29 +95,42 @@
<!-- 筛选排序栏 -->
<view class="filter-bar">
<view class="filter-item" @click="showFilter">
<text class="filter-text">{{ selectedTagName || '筛选' }}</text>
<text class="filter-icon"></text>
<text class="filter-text" :class="{ active: selectedTagName }">{{
selectedTagName || "筛选"
}}</text>
<up-image
:src="selectedTagName ? filterOn : filter"
width="26rpx"
height="26rpx"
></up-image>
</view>
<view class="filter-divider"></view>
<view class="filter-item" @click="showSort">
<text class="filter-text">{{ selectedSortLabel || '排序' }}</text>
<text class="filter-icon"></text>
<text class="filter-text" :class="{ active: selectedSortValue }">{{
selectedSortLabel || "排序"
}}</text>
<up-image
:src="selectedSortValue ? filterOn : filter"
width="26rpx"
height="26rpx"
></up-image>
</view>
</view>
<!-- 筛选下拉 -->
<view v-if="showFilterDropdown" class="dropdown">
<view
<!-- <view
class="dropdown-item"
:class="{ active: selectedTagId === null }"
@click="onTagSelect({ id: null, name: '全部' })">
全部
</view>
</view> -->
<view
v-for="tag in tagList"
:key="tag.id"
class="dropdown-item"
:class="{ active: selectedTagId === tag.id }"
@click="onTagSelect(tag)">
@click="onTagSelect(tag)"
>
{{ tag.name }}
</view>
</view>
@ -80,17 +142,32 @@
:key="opt.value"
class="dropdown-item"
:class="{ active: selectedSortValue === opt.value }"
@click="onSortSelect(opt)">
@click="onSortSelect(opt)"
>
{{ opt.label }}
</view>
</view>
<!-- 商品网格上拉加载 -->
<scroll-view class="product-grid" scroll-y @scrolltolower="getGoodsList" :lower-threshold="100">
<scroll-view
class="product-grid"
scroll-y
@scrolltolower="getGoodsList"
:lower-threshold="100"
>
<view class="grid-wrap">
<view class="product-item" v-for="(product, index) in products" :key="product.uuid || index" @click="goToProductDetail(product)">
<view
class="product-item"
v-for="(product, index) in products"
:key="product.uuid || index"
@click="goToProductDetail(product)"
>
<view class="product-image-container">
<image class="product-image" :src="product.image" mode="aspectFill"></image>
<image
class="product-image"
:src="product.image"
mode="aspectFill"
></image>
</view>
<view class="product-info">
<text class="product-title">{{ product.title }}</text>
@ -111,11 +188,13 @@
<view class="bottom-nav">
<view class="nav-item active" @click="goToMyRedemption">
<!-- <view class="nav-icon">💰</view> -->
<up-image :src="pointImg" width="44rpx" height="44rpx"></up-image>
<text class="nav-text">我的兑换</text>
</view>
<view class="nav-divider"></view>
<view class="nav-item" @click="goToBuyPoints">
<!-- <view class="nav-icon">🛒</view> -->
<up-image :src="buyPointImg" width="44rpx" height="44rpx"></up-image>
<text class="nav-text">购买积分</text>
</view>
</view>
@ -123,184 +202,209 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import goods_api from '@/api/goods_api'
import docUrl from '@/utils/docUrl'
import { ref, onMounted } from "vue";
import goods_api from "@/api/goods_api";
import docUrl from "@/utils/docUrl";
import pointImg from "@/static/integralticket.png";
import buyPointImg from "@/static/buy_points.png";
import filter from "@/static/triangle_normal.png";
import filterOn from "@/static/triangle_green_theme.png";
//
const bannerList = ref([])
const bannerList = ref([]);
const currentBannerIndex = ref(0);
//
const products = ref([])
const page = ref(1)
const pageSize = ref(10)
const isLoadingMore = ref(false)
const noMore = ref(false)
const products = ref([]);
const page = ref(1);
const pageSize = ref(10);
const isLoadingMore = ref(false);
const noMore = ref(false);
const onSwiperChange = (e) => {
currentBannerIndex.value = e.detail.current;
};
//
const tagList = ref([])
const selectedTagId = ref(null)
const selectedTagName = ref('')
const showFilterDropdown = ref(false)
const tagList = ref([]);
const selectedTagId = ref(null);
const selectedTagName = ref("");
const showFilterDropdown = ref(false);
//
const showSortDropdown = ref(false)
const selectedSortValue = ref(null)
const selectedSortLabel = ref('')
const showSortDropdown = ref(false);
const selectedSortValue = ref(null);
const selectedSortLabel = ref("");
const sortOptions = ref([
{ label: '积分从小到大', value: 4 },
{ label: '积分从大到小', value: 3 },
{ label: '兑换从多到少', value: 5 },
{ label: '兑换从少到多', value: 6 }
])
{ label: "积分从小到大", value: 4 },
{ label: "积分从大到小", value: 3 },
{ label: "兑换从多到少", value: 5 },
{ label: "兑换从少到多", value: 6 },
]);
//
const goBack = () => {
uni.navigateBack()
}
uni.navigateBack();
};
const goToSearch = () => {
uni.navigateTo({
url: '/pages_app/search/search'
})
}
url: "/pages_app/search/search",
});
};
const showFilter = () => {
showFilterDropdown.value = !showFilterDropdown.value
}
showFilterDropdown.value = !showFilterDropdown.value;
showSortDropdown.value = false;
};
const showSort = () => {
showSortDropdown.value = !showSortDropdown.value
}
showSortDropdown.value = !showSortDropdown.value;
showFilterDropdown.value = false;
};
const onTagSelect = (tag) => {
selectedTagId.value = tag.id
selectedTagName.value = tag.name
showFilterDropdown.value = false
selectedTagId.value = tag.id;
selectedTagName.value = tag.name;
showFilterDropdown.value = false;
//
products.value = []
page.value = 1
noMore.value = false
getGoodsList()
}
products.value = [];
page.value = 1;
noMore.value = false;
getGoodsList();
};
const onSortSelect = (opt) => {
selectedSortValue.value = opt.value
selectedSortLabel.value = opt.label
showSortDropdown.value = false
products.value = []
page.value = 1
noMore.value = false
getGoodsList()
}
selectedSortValue.value = opt.value;
selectedSortLabel.value = opt.label;
showSortDropdown.value = false;
products.value = [];
page.value = 1;
noMore.value = false;
getGoodsList();
};
const goToProductDetail = (product) => {
const id = product.uuid || product.id
const id = product.uuid || product.id;
uni.navigateTo({
url: `/pages_goods/productDetail/productDetail?id=${id}`
})
}
url: `/pages_goods/productDetail/productDetail?id=${id}`,
});
};
const goToMyRedemption = () => {
uni.navigateTo({
url: '/pages_goods/myRedemption/myRedemption'
})
}
url: "/pages_goods/myRedemption/myRedemption",
});
};
const goToBuyPoints = () => {
uni.navigateTo({
url: '/pages_app/buyPoint/buyPoint'
})
}
url: "/pages_app/buyPoint/buyPoint",
});
};
const goToBannerDetail = (banner) => {
//
uni.navigateTo({
url: `/pages_app/webview/webview?url=${encodeURIComponent(banner.path)}&title=${encodeURIComponent(banner.title)}`
})
}
url: `/pages_app/webview/webview?url=${encodeURIComponent(
banner.path
)}&title=${banner.title}`,
});
};
const getGoodsNewsList = () => {
goods_api.goodsNewsList().then(res => {
console.log('轮播图数据:', res)
goods_api
.goodsNewsList()
.then((res) => {
console.log("轮播图数据:", res);
if (res.code === 200 && res.data && res.data.length > 0) {
//
bannerList.value = res.data.map(item => ({
bannerList.value = res.data.map((item) => ({
uuid: item.uuid,
title: item.title,
headImg: docUrl + item.headImg,
create_date: item.create_date,
path: item.path,
agreenum: item.agreenum,
readnum: item.readnum
}))
readnum: item.readnum,
}));
} else {
console.log('轮播图数据为空或请求失败')
console.log("轮播图数据为空或请求失败");
}
}).catch(err => {
console.error('获取轮播图数据失败:', err)
})
.catch((err) => {
console.error("获取轮播图数据失败:", err);
uni.showToast({
title: '获取数据失败',
icon: 'none'
})
})
}
title: "获取数据失败",
icon: "none",
});
});
};
const getGoodsList = () => {
if (noMore.value || isLoadingMore.value) return
isLoadingMore.value = true
const tagParam = selectedTagId.value ? selectedTagId.value : ""
const sortParam = selectedSortValue.value ? selectedSortValue.value : 1
goods_api.goodsList({ name: '', page: page.value, sort: sortParam, tag_type: tagParam }).then(res => {
console.log('商品数据:', res)
if ((res.code === 200 || res.code === '200') && res.data && res.data.list) {
const list = res.data.list.map(item => ({
if (noMore.value || isLoadingMore.value) return;
isLoadingMore.value = true;
const tagParam = selectedTagId.value ? selectedTagId.value : "";
const sortParam = selectedSortValue.value ? selectedSortValue.value : 1;
goods_api
.goodsList({
name: "",
page: page.value,
sort: sortParam,
tag_type: tagParam,
})
.then((res) => {
console.log("商品数据:", res);
if (
(res.code === 200 || res.code === "200") &&
res.data &&
res.data.list
) {
const list = res.data.list.map((item) => ({
uuid: item.uuid,
title: item.name,
price: item.bonuspoints,
image: docUrl + item.img,
times: item.times,
type: item.type,
upan: item.upan
}))
products.value = products.value.concat(list)
const { isLastPage, pageNum } = res.data
page.value = pageNum + 1
noMore.value = !!isLastPage
upan: item.upan,
}));
products.value = products.value.concat(list);
const { isLastPage, pageNum } = res.data;
page.value = pageNum + 1;
noMore.value = !!isLastPage;
} else {
console.log('商品列表为空或请求失败')
console.log("商品列表为空或请求失败");
}
}).catch(err => {
console.error('获取商品列表失败:', err)
uni.showToast({ title: '获取商品失败', icon: 'none' })
}).finally(() => {
isLoadingMore.value = false
})
}
.catch((err) => {
console.error("获取商品列表失败:", err);
uni.showToast({ title: "获取商品失败", icon: "none" });
})
.finally(() => {
isLoadingMore.value = false;
});
};
const getGoodsTagList = () => {
goods_api.goodsTagList({}).then(res => {
console.log('商品类型数据:', res)
goods_api.goodsTagList({}).then((res) => {
console.log("商品类型数据:", res);
if (res.code === 200 && res.data) {
tagList.value = res.data.map(i => ({ id: i.id, name: i.name }))
tagList.value = res.data.map((i) => ({ id: i.id, name: i.name }));
}
})
}
});
};
onMounted(() => {
getGoodsNewsList()
getGoodsNewsList();
//
page.value = 1
noMore.value = false
products.value = []
getGoodsList()
getGoodsTagList()
})
page.value = 1;
noMore.value = false;
products.value = [];
getGoodsList();
getGoodsTagList();
});
</script>
<style scoped>
<style scoped lang="scss">
.point-mall-container {
width: 100%;
min-height: 100vh;
@ -308,7 +412,14 @@ onMounted(() => {
position: relative;
padding-bottom: 80px;
}
.nav-actions {
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #8b2316;
padding: 10rpx;
}
/* 搜索按钮样式 */
.search-btn {
color: #e74c3c;
@ -318,8 +429,46 @@ onMounted(() => {
/* 轮播图样式 */
.banner-section {
margin: 0;
position: relative;
top: calc(var(--status-bar-height) + 44px);
position: fixed;
left: 0;
right: 0;
z-index: 100;
.swipemask {
width: 100%;
z-index: 3;
box-sizing: border-box;
position: absolute;
bottom: 0;
padding: 0 20rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: space-between;
background-color: rgba(0, 0, 0, 0.7);
.banner-subtitle{
color:#fff;
font-size: 28rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.dotbox {
display: flex;
align-items: center;
.circle {
margin: 0 4rpx;
width: 16rpx;
height: 16rpx;
background-color: #eee;
border-radius: 50%;
}
.circle.active {
background-color: #8b2316;
}
}
}
}
.banner-swiper {
@ -335,40 +484,43 @@ onMounted(() => {
.banner-image {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #87CEEB 0%, #98FB98 50%, #F0E68C 100%);
background: linear-gradient(135deg, #87ceeb 0%, #98fb98 50%, #f0e68c 100%);
}
.banner-content {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 20px;
padding: 0 5px;
}
.tips {
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
}
.banner-text {
background-color: rgba(255, 255, 255, 0.95);
padding: 6px 12px;
margin: 3px 0;
border-radius: 6px;
font-size: 13px;
font-weight: bold;
text-align: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
color: #fff;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.banner-text.green {
/* .banner-text.green {
color: #27ae60;
}
.banner-text.orange {
color: #e67e22;
}
} */
/* 轮播图指示器样式 */
.banner-swiper ::v-deep .uni-swiper-dots {
@ -389,35 +541,44 @@ onMounted(() => {
/* 筛选排序栏样式 */
.filter-bar {
position: fixed;
top: calc(var(--status-bar-height) + 44px + 200px);
left: 0;
right: 0;
display: flex;
align-items: center;
background-color: #fff;
padding: 12px 16px;
padding: 0px 16px;
height: 88rpx;
border-bottom: 1px solid #eee;
}
.dropdown {
position: fixed;
top: calc(var(--status-bar-height) + 44px + 200px + 88rpx);
left: 0;
right: 0;
z-index: 100;
background: #fff;
border-top: 1px solid #eee;
border-bottom: 1px solid #eee;
padding: 8px 0;
/* border-bottom: 1px solid #eee; */
}
.dropdown-item {
padding: 12px 16px;
font-size: 14px;
color: #333;
text-align: center;
border-bottom: 1px solid #eee;
}
.dropdown-item.active {
color: #e74c3c;
font-weight: bold;
background: #fff7f7;
color: #8b2316;
}
.filter-item {
display: flex;
align-items: center;
/* align-items: center; */
flex: 1;
justify-content: center;
padding: 8px;
@ -429,6 +590,10 @@ onMounted(() => {
margin-right: 4px;
}
.filter-text.active {
color: #8b2316;
}
.filter-icon {
font-size: 10px;
color: #666;
@ -442,7 +607,14 @@ onMounted(() => {
/* 商品网格样式 */
.product-grid {
height: calc(100vh - 320rpx); /* 预留顶部导航/筛选及底部栏 */
position: fixed;
top: calc(var(--status-bar-height) + 44px + 200px + 88rpx);
left: 0;
right: 0;
z-index: 1;
height: calc(
100vh - var(--status-bar-height) - 44px - 88rpx
); /* 预留顶部导航/筛选及底部栏 */
background-color: #f5f5f5;
}
@ -503,7 +675,6 @@ onMounted(() => {
.product-price {
font-size: 14px;
color: #e74c3c;
font-weight: bold;
}
/* 底部导航栏样式 */
@ -512,7 +683,7 @@ onMounted(() => {
bottom: 0;
left: 0;
right: 0;
height: 60px;
height: 50px;
background-color: #20b2aa;
display: flex;
align-items: center;
@ -523,7 +694,7 @@ onMounted(() => {
.nav-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 8px;
@ -542,14 +713,15 @@ onMounted(() => {
}
.nav-text {
font-size: 12px;
font-size: 13px;
color: #fff;
margin-left: 5rpx;
font-weight: 500;
}
.nav-divider {
width: 1px;
height: 40px;
background-color: rgba(255, 255, 255, 0.3);
background-color: #fff;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<view class="product-detail-container">
<!-- 顶部导航栏 -->
<uni-nav-bar
<!-- <uni-nav-bar
left-icon="left"
:title="navTitle"
@clickLeft="goBack"
@ -10,13 +10,13 @@
height="180rpx"
:border="false"
backgroundColor="#ffffff"
/>
/> -->
<navBar :title="navTitle" />
<!-- 内容区 -->
<scroll-view scroll-y class="detail-scroll">
<!-- 商品主图轮播 -->
<view class="swiper-box">
<swiper class="detail-swiper" :indicator-dots="true" :autoplay="false" :interval="3000" :duration="400">
<swiper class="detail-swiper" :indicator-dots="true" :autoplay="false" :interval="3000" :duration="400" indicator-color="#ccc" indicator-active-color="#8B2316">
<swiper-item v-for="(img, idx) in images" :key="idx">
<image class="swiper-image" :src="img" mode="aspectFit"></image>
</swiper-item>
@ -62,6 +62,7 @@ import { ref, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import goods_api from '@/api/goods_api'
import docUrl from '@/utils/docUrl'
import navBar from '@/components/navBar/navBar.vue'
const product = ref({ id: '', title: '', price: 0, times: 0, content: '' })
const images = ref([])
@ -116,7 +117,7 @@ const goExchange = () => {
.detail-scroll {
position: absolute;
top: 180rpx;
top: calc(var(--status-bar-height) + 44px);
left: 0;
right: 0;
bottom: 100rpx;

BIN
static/buy_points.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
static/fulicard_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
static/integralticket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
static/myjifen_big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

BIN
static/point_shop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
static/sign_day_false.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
static/word.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -76,6 +76,16 @@

View File

@ -1,4 +1,3 @@
//const app = getApp({allowDefault: true});
let DOC_URL='https://dev-doc.igandan.com/app/';
//let DOC_URL='https://doc.igandan.com/app/'
// if(app.globalData.apiHost.indexOf('dev')>-1){

View File

@ -116,11 +116,43 @@ export const request = (url, data = {}, method = 'post', loading = false, conten
e(res.data)
}else if (res.data.code == 401 || res.data.code == 403 || res.data.code ==
405 || res.data.code == 406 || res.data.code == 37006) {
uni.hideLoading();
if(process.env.UNI_PLATFORM == "mp-weixin"){
uni.redirectTo({url:'/pages_app/login/login'})
}
uni.sendNativeEvent('getNewToken', {
msg: 'getNewToken'
},ret => {
console.log('ret数据');
console.log(ret);
uni.setStorageSync('AUTH_TOKEN_App', ret);
let pages = getCurrentPages();
let len = pages.length
let curParam = pages[len - 1].options //获取当前页面参数
let param = []
for (let key in curParam) { //获取key=value键值对格式数组
param.push(key + '=' + curParam[key])
}
let _url = '' //除去第一个参数拼接后面参数
param.forEach((item, i) => {
if (i != 0) { //拼接&符号,由于第一组前拼接的是?所有第一组需要单独处理
_url += '&' + item
}
})
let redirectUrl = '/' + pages[len - 1].route + '?' + param[0] + _url //最终格式**/pages/index/index/?id=11&name='boyyang'&sex='man'**
console.log('redirectUrl');
console.log(redirectUrl);
uni.redirectTo({
url: '/pages_app/login/login'
});
url: redirectUrl
})
})
// uni.redirectTo({
// url: '/pages_app/login/login'
// });
} else if (res.data.code == 500) {

View File

@ -1,2 +1,2 @@
const version="4.1.6"
const version="4.1.9"
export default version