提交 539c605a 作者: 宇宙超人

合并

上级 e07d0d6f
[
{
"key": "ctrl+/",
"command": "editor.action.commentLine",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "shift+alt+a",
"command": "editor.action.blockComment",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "ctrl+k ctrl+c",
"command": "editor.action.addCommentLine",
"when": "editorTextFocus && !editorReadonly"
},
{
"key": "ctrl+k ctrl+u",
"command": "editor.action.removeCommentLine",
"when": "editorTextFocus && !editorReadonly"
}
]
\ No newline at end of file
......@@ -15,9 +15,20 @@ export function bizCommonFileList(params = {}) {
})
}
/**
* 资源列表
* @param params
* @returns
*/
export function getResourceList(params = {}) {
return otherHttp.get({
url: '/resource/list',
params,
})
}
/**
* 添加资源
* @param params
* @returns
* @param params
* @returns
*/
export function addResource(params = {}) {
return otherHttp.post({
......@@ -25,3 +36,14 @@ export function addResource(params = {}) {
params,
})
}
/**
* 下载资源
* @param params
* @returns
*/
export function downloadResource(params = {}) {
return otherHttp.get({
url: '/resource/download',
params,
})
}
......@@ -135,6 +135,10 @@
flex-direction: column;
position: relative;
overflow: hidden;
/* #ifdef APP-PLUS */
position: relative;
z-index: 1;
/* #endif */
}
.fui-swiper__dot {
......@@ -146,7 +150,12 @@
flex-direction: row;
align-items: center;
justify-content: center;
/* #ifdef APP-PLUS */
z-index: 998;
/* #endif */
/* #ifndef APP-PLUS */
z-index: 2;
/* #endif */
overflow: hidden;
}
......
......@@ -365,11 +365,11 @@
<view class="codefun-flex-col section">
<view class="codefun-flex-col mt-52rpx">
<text class="codefun-self-center font text">{{ pageData.header.title }}</text>
<!-- <view class="codefun-flex-col codefun-self-stretch mt-19">
<view class="codefun-flex-row codefun-items-center section_2">
<view class="codefun-flex-col codefun-self-stretch mt-19">
<!-- <view class="codefun-flex-row codefun-items-center section_2">
<image class="image_5" src="/static/images/codefun/b8d30fcc0b08b881a41c8b3e35b7f8ac.png" />
<text class="codefun-ml-8 font_2 text_2">{{ pageData.header.searchPlaceholder }}</text>
</view>
</view> -->
<view class="codefun-mt-14 codefun-flex-row equal-division section_3">
<view
v-for="item in pageData.menuItems"
......@@ -381,7 +381,7 @@
<text class="font_3 mt-13" :class="`text_${item.id + 2}`">{{ item.name }}</text>
</view>
</view>
</view> -->
</view>
</view>
</view>
<view class="codefun-flex-col codefun-relative group_6">
......@@ -755,42 +755,55 @@
.mt-19 {
margin-top: 38rpx;
}
.ml-3 {
margin-left: 6rpx;
}
.mt-7 {
margin-top: 14rpx;
}
.ml-9 {
margin-left: 18rpx;
}
.ml-7 {
margin-left: 14rpx;
}
.ml-11 {
margin-left: 22rpx;
}
.mt-17 {
margin-top: 34rpx;
}
.mt-11 {
margin-top: 22rpx;
}
.mt-5 {
margin-top: 10rpx;
}
.mt-21 {
margin-top: 42rpx;
}
.mt-13 {
margin-top: 26rpx;
}
.ml-5 {
margin-left: 10rpx;
}
.mt-3 {
margin-top: 6rpx;
}
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
......@@ -806,32 +819,39 @@
background-image: url('/static/images/codefun/7a5dc4ee864fe55da98b41c14ee3b931.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.group_2 {
padding-left: 16rpx;
.image {
border-radius: 64rpx;
width: 108rpx;
height: 42rpx;
}
.image_2 {
mix-blend-mode: NOTTHROUGH;
width: 34rpx;
height: 22rpx;
}
.image_3 {
mix-blend-mode: NOTTHROUGH;
width: 30rpx;
height: 22rpx;
}
.image_4 {
width: 48rpx;
height: 22rpx;
}
}
.text {
color: #ffffffe6;
line-height: 29.28rpx;
}
.section_2 {
padding: 16rpx 18rpx;
background-color: #ffffff4d;
......@@ -841,42 +861,53 @@
border-right: solid 1rpx #ffffff7d;
border-top: solid 1rpx #ffffff7d;
border-bottom: solid 1rpx #ffffff7d;
.text_2 {
line-height: 25.5rpx;
}
}
.equal-division {
position: relative;
.equal-division-item {
padding: 8rpx 0;
width: 134rpx;
.text_3 {
line-height: 21.88rpx;
}
}
.group_3 {
margin-left: 0;
.text_4 {
line-height: 21.98rpx;
}
.text_5 {
line-height: 21.98rpx;
}
}
.image_6 {
width: 96rpx;
height: 96rpx;
}
.font_3 {
font-size: 24rpx;
line-height: 22.84rpx;
color: #1d2129;
}
.equal-division-item_2 {
padding: 8rpx 0;
width: 134rpx;
}
.group_4 {
// position: absolute;
// right: 147rpx;
......@@ -885,6 +916,7 @@
line-height: 22.06rpx;
}
}
.equal-division-item_3 {
// position: absolute;
// right: 13rpx;
......@@ -893,11 +925,13 @@
line-height: 21.08rpx;
}
}
.group_5 {
padding: 8rpx 0;
width: 134rpx;
}
}
.section_3 {
display: flex;
justify-content: space-between;
......@@ -908,20 +942,25 @@
mix-blend-mode: NOTTHROUGH;
}
}
.group_6 {
margin-top: -92rpx;
padding-left: 28rpx;
.section_4 {
margin-right: 28rpx;
padding: 28rpx 28rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.text_8 {
line-height: 29.88rpx;
}
.group_7 {
margin-top: 16rpx;
.text-wrapper {
display: flex;
justify-content: center;
......@@ -933,11 +972,13 @@
border-right: solid 2rpx #4f90f1;
border-top: solid 2rpx #4f90f1;
border-bottom: solid 2rpx #4f90f1;
.text_9 {
color: #4f90f1;
line-height: 17.84rpx;
}
}
.text-wrapper_2 {
display: flex;
justify-content: center;
......@@ -949,53 +990,65 @@
border-right: solid 2rpx #5db66f;
border-top: solid 2rpx #5db66f;
border-bottom: solid 2rpx #5db66f;
.text_10 {
color: #5db66f;
line-height: 18.14rpx;
}
}
}
.equal-division_2 {
position: relative;
align-self: flex-end;
margin-top: 12rpx;
.equal-division-item_4 {
padding: 12rpx 0;
width: 113.96rpx;
.text_11 {
color: #5db66f;
line-height: 24.62rpx;
}
.text_14 {
line-height: 18.98rpx;
}
}
.group_8 {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
.text_12 {
color: #fc8145;
}
.text_15 {
line-height: 18.5rpx;
}
}
.group_9 {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
.text_13 {
color: #4f90f1;
line-height: 20rpx;
}
.text_16 {
line-height: 18.52rpx;
}
}
}
.section_5 {
padding: 12rpx 0;
background-color: #f2faf3;
......@@ -1004,35 +1057,43 @@
width: 414rpx;
}
}
.group_10 {
margin-top: 44rpx;
.text_17 {
margin-right: 28rpx;
line-height: 21.86rpx;
}
.section_6 {
margin-right: 28rpx;
padding: 16rpx 0;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.equal-division_3 {
.equal-division-item_5 {
flex: 1 1 207.64rpx;
.image_7 {
width: 64rpx;
height: 64rpx;
}
.text_18 {
margin-top: 20rpx;
line-height: 25.42rpx;
}
.font_7 {
font-size: 20rpx;
line-height: 32rpx;
color: #666666;
}
.text_21 {
margin-left: 8rpx;
margin-top: 16rpx;
......@@ -1040,6 +1101,7 @@
width: 160rpx;
height: 60rpx;
}
.text-wrapper_3 {
margin-top: 36rpx;
padding: 12rpx 0;
......@@ -1047,88 +1109,109 @@
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
width: 136rpx;
.font_8 {
font-size: 24rpx;
line-height: 22.84rpx;
color: #16a34a;
}
.text_24 {
line-height: 22.08rpx;
}
}
.group_13 {
padding: 8rpx 0;
.text_19 {
line-height: 25.62rpx;
}
.text_23 {
line-height: 18.28rpx;
}
}
.text_20 {
margin-right: 12rpx;
margin-top: 20rpx;
line-height: 25.9rpx;
}
.text_22 {
margin-top: 16rpx;
text-align: center;
width: 138rpx;
}
}
.group_11 {
padding: 8rpx 12rpx 26rpx;
}
.section_7 {
margin: 10rpx 0;
}
.horiz-divider {
background-color: #fafafa;
width: 2rpx;
height: 288rpx;
}
.group_12 {
padding: 0 20rpx 26rpx;
}
.group_14 {
padding: 8rpx 8rpx 26rpx;
}
}
}
.section_8 {
margin-right: 28rpx;
padding: 28rpx 28rpx 12rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.equal-division_4 {
align-self: stretch;
.equal-division-item_6 {
flex: 1 1 308rpx;
.font_9 {
font-size: 32rpx;
line-height: 29.32rpx;
color: #1d2129;
}
.text_25 {
line-height: 28.96rpx;
}
.image_8 {
mix-blend-mode: NOTTHROUGH;
width: 94rpx;
height: 106rpx;
}
.text_26 {
line-height: 29.82rpx;
}
.image_9 {
mix-blend-mode: NOTTHROUGH;
width: 118rpx;
height: 98rpx;
}
}
.section_9 {
padding: 28rpx 32rpx 4rpx;
background-color: #fff7ec;
......@@ -1136,6 +1219,7 @@
mix-blend-mode: NOTTHROUGH;
height: 142rpx;
}
.section_10 {
padding: 28rpx 16rpx 12rpx 36rpx;
background-color: #f5fcff;
......@@ -1144,6 +1228,7 @@
height: 142rpx;
}
}
.text_27 {
color: #00000099;
line-height: 40rpx;
......@@ -1151,108 +1236,135 @@
}
}
}
.font_5 {
font-size: 26rpx;
line-height: 25.56rpx;
color: #333333;
}
.group_15 {
margin-top: 44rpx;
.text_28 {
color: #000000;
}
.text_29 {
margin-right: 28rpx;
line-height: 22.24rpx;
}
.equal-division_5 {
margin-right: 28rpx;
.section_11 {
flex: 1 1 124rpx;
.image_10 {
mix-blend-mode: NOTTHROUGH;
width: 32rpx;
height: 32rpx;
}
.font_11 {
font-size: 24rpx;
line-height: 22.84rpx;
color: #666666;
}
.text_30 {
margin-top: 12rpx;
line-height: 21.76rpx;
}
.group_16 {
margin-left: 4rpx;
margin-top: 28rpx;
line-height: 22.84rpx;
.text_35 {
line-height: 21.62rpx;
}
}
.text_31 {
margin-top: 12rpx;
line-height: 21.98rpx;
}
.group_17 {
margin-top: 24rpx;
line-height: 22.84rpx;
.text_38 {
line-height: 21.76rpx;
}
}
.font_12 {
font-size: 28rpx;
line-height: 22.84rpx;
color: #000000;
}
.text_32 {
margin-top: 12rpx;
line-height: 22.12rpx;
}
.group_18 {
margin-top: 28rpx;
line-height: 22.2rpx;
.text_36 {
line-height: 22.2rpx;
}
.text_39 {
line-height: 20.14rpx;
}
}
.text_33 {
margin-top: 12rpx;
line-height: 21.74rpx;
}
.group_19 {
margin-left: 4rpx;
margin-top: 28rpx;
line-height: 22.52rpx;
.text_37 {
line-height: 22.52rpx;
}
.text_40 {
line-height: 21.46rpx;
}
}
.text_34 {
margin-left: 4rpx;
margin-top: 12rpx;
line-height: 22.04rpx;
}
.group_20 {
margin-left: 4rpx;
margin-top: 24rpx;
line-height: 22.84rpx;
.text_41 {
line-height: 20.32rpx;
}
}
}
.equal-division-item_7 {
padding: 32rpx 12rpx 24rpx;
background-color: #ffffff;
......@@ -1262,52 +1374,65 @@
}
}
}
.font_6 {
font-size: 24rpx;
line-height: 22.84rpx;
color: #5db66f;
}
.font_10 {
font-size: 24rpx;
line-height: 22.84rpx;
color: #000000;
}
.group_21 {
margin-top: 44rpx;
.section_12 {
margin-right: 28rpx;
padding: 0 24rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.group_23 {
padding-left: 8rpx;
padding-top: 36rpx;
.font_13 {
font-size: 24rpx;
font-family: Inter;
line-height: 18.3rpx;
color: #89909d;
}
.text_45 {
line-height: 17.94rpx;
}
.text_46 {
line-height: 17.96rpx;
}
.text_47 {
line-height: 17.94rpx;
}
.text_48 {
line-height: 17.94rpx;
}
.text_49 {
line-height: 17.94rpx;
}
.group_24 {
padding: 48rpx 0;
.divider {
mix-blend-mode: NOTTHROUGH;
background-image: repeating-linear-gradient(
......@@ -1320,35 +1445,42 @@
background-position: -4rpx 0rpx;
height: 2rpx;
}
.view_2 {
margin-top: 48rpx;
}
.view_3 {
margin-top: 48rpx;
}
.image-wrapper {
padding-bottom: 104rpx;
background-image: url('/static/images/codefun/e18202eb8182b8d77c464523c2305fa3.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.image_11 {
margin-left: 8rpx;
width: 564rpx;
height: 92rpx;
}
}
.pos_2 {
position: absolute;
left: 17rpx;
right: 6.6rpx;
top: 0;
}
.pos {
position: absolute;
left: 0;
right: 0;
top: 0;
}
.pos_3 {
position: absolute;
left: 0;
......@@ -1357,49 +1489,62 @@
}
}
}
.group_25 {
overflow: hidden;
height: 142rpx;
.equal-division_6 {
position: relative;
margin-top: -16rpx;
.section_13 {
flex: 1 1 201.34rpx;
.image_12 {
width: 48rpx;
height: 48rpx;
}
.text-wrapper_4 {
padding: 4rpx 0;
overflow: hidden;
width: 96rpx;
.text_50 {
line-height: 22rpx;
}
.text_53 {
color: #ef4444;
line-height: 22.16rpx;
}
.text_51 {
line-height: 21.94rpx;
}
.text_54 {
color: #eab308;
line-height: 21.92rpx;
}
}
.text-wrapper_5 {
padding: 4rpx 0;
overflow: hidden;
.text_52 {
line-height: 22.2rpx;
}
.text_55 {
color: #3b82f6;
line-height: 22.22rpx;
}
}
}
.equal-division-item_8 {
padding: 24rpx 0;
background-color: #f9fafb;
......@@ -1407,6 +1552,7 @@
mix-blend-mode: NOTTHROUGH;
height: 176rpx;
}
.section_14 {
padding: 24rpx 40rpx;
background-color: #f9fafb;
......@@ -1418,16 +1564,20 @@
}
}
}
.group_26 {
overflow-x: scroll;
padding-right: 14rpx;
.text_56 {
line-height: 29.76rpx;
}
.text_57 {
margin-right: 24rpx;
line-height: 22.24rpx;
}
.section_15 {
padding: 16rpx 0;
background-color: #ffffff;
......@@ -1436,9 +1586,11 @@
box-shadow: 0rpx 8rpx 64rpx #15161a0a;
width: 300rpx;
height: 120rpx;
.text_58 {
line-height: 25.78rpx;
}
.section_17 {
background-color: #13df00;
mix-blend-mode: NOTTHROUGH;
......@@ -1446,10 +1598,12 @@
width: 12rpx;
height: 12rpx;
}
.text_59 {
color: #13e000;
}
}
.section_16 {
padding: 16rpx 26rpx;
background-color: #ffffff;
......@@ -1458,8 +1612,10 @@
box-shadow: 0rpx 8rpx 64rpx #15161a0a;
width: 300rpx;
height: 120rpx;
.group_27 {
width: 140rpx;
.section_18 {
background-color: #d7d7d9;
mix-blend-mode: NOTTHROUGH;
......@@ -1467,23 +1623,27 @@
width: 12rpx;
height: 12rpx;
}
.text_60 {
color: #75777c;
line-height: 18.04rpx;
}
}
}
.image_13 {
border-radius: 24rpx;
width: 92rpx;
height: 92rpx;
}
.font_14 {
font-size: 28rpx;
line-height: 25.56rpx;
color: #15161a;
}
.image-wrapper_2 {
padding: 16rpx 0;
background-color: #ffffff;
......@@ -1492,6 +1652,7 @@
box-shadow: 0rpx 8rpx 64rpx #15161a0a;
width: 92rpx;
height: 120rpx;
.image_14 {
border-radius: 24rpx 0 0 24rpx;
width: 66rpx;
......@@ -1499,27 +1660,34 @@
}
}
}
.view_4 {
margin-top: 520rpx;
}
.group_28 {
margin-top: 48rpx;
.text_61 {
line-height: 29.4rpx;
}
.section_19 {
margin-right: 28rpx;
padding: 32rpx 64rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.image_15 {
mix-blend-mode: NOTTHROUGH;
width: 210rpx;
height: 210rpx;
}
.group_29 {
width: 260rpx;
.text_62 {
margin-left: 72rpx;
color: #ffaa1e;
......@@ -1527,22 +1695,26 @@
line-height: 28.56rpx;
}
.text_63 {
margin-left: 8rpx;
color: #000000;
line-height: 25.88rpx;
}
.text_64 {
margin-left: 8rpx;
color: #6b7280;
line-height: 22.24rpx;
}
.text-wrapper_6 {
padding: 16rpx 0;
background-color: #5db66f;
border-radius: 19998rpx;
mix-blend-mode: NOTTHROUGH;
width: 208rpx;
.text_65 {
line-height: 22.18rpx;
}
......@@ -1550,8 +1722,10 @@
}
}
}
.group_30 {
margin-top: 48rpx;
.section_20 {
position: relative;
margin-right: 28rpx;
......@@ -1563,6 +1737,7 @@
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
// background-image: url('/static/images/codefun/de7f2f0177d74c2b9c784b3825ea9832.png');
// background-size: 94%;
// background-repeat: no-repeat;
......@@ -1585,35 +1760,44 @@
}
}
}
.describe {
width: 88%;
position: absolute;
bottom: 52rpx;
left: 40rpx;
.text_34 {
color: #ffffff;
}
}
.text_68 {
line-height: 26.58rpx;
}
.group_31 {
margin-top: 20rpx;
.image_16 {
mix-blend-mode: NOTTHROUGH;
border-radius: 50%;
width: 48rpx;
height: 48rpx;
}
.text_69 {
line-height: 21.76rpx;
}
.text_70 {
line-height: 23.04rpx;
}
}
.group_32 {
margin-top: 30rpx;
.section_21 {
background-color: #5db66f;
border-radius: 12rpx;
......@@ -1621,13 +1805,16 @@
width: 40rpx;
height: 12rpx;
}
.image-wrapper_3 {
width: 40rpx;
.image_17 {
width: 40rpx;
height: 12rpx;
}
}
.section_22 {
background-color: #5db66f33;
mix-blend-mode: NOTTHROUGH;
......@@ -1638,24 +1825,31 @@
}
}
}
.group_22 {
padding-bottom: 32rpx;
.text_42 {
line-height: 29.18rpx;
}
.text_43 {
line-height: 22.24rpx;
}
.text_44 {
margin-right: 28rpx;
}
.text_66 {
line-height: 29.48rpx;
}
.text_67 {
margin-right: 24rpx;
}
}
.font_15 {
font-size: 24rpx;
......@@ -1663,11 +1857,13 @@
color: #ffffff;
}
}
.font {
font-size: 32rpx;
line-height: 29.32rpx;
color: #333333;
}
.font_2 {
font-size: 28rpx;
......@@ -1675,22 +1871,27 @@
color: #ffffff;
}
}
.equal-division_7 {
padding: 10rpx 8rpx 16rpx;
background-color: #ffffff;
mix-blend-mode: NOTTHROUGH;
border-top: solid 1rpx #e7e7e7;
.group_33 {
flex: 1 1 146.82rpx;
}
.equal-division-item_9 {
padding: 12rpx 0;
}
}
.image_5 {
width: 32rpx;
height: 32rpx;
}
.font_4 {
font-size: 20rpx;
......
<template>
<u-modal :show="show" :title="dialogTitle" :showConfirmButton="false" :showCancelButton="false" @close="handleClose"
:closeOnClickOverlay="false" >
<u-modal
:show="show"
:title="dialogTitle"
:showConfirmButton="false"
:showCancelButton="false"
@close="handleClose"
:closeOnClickOverlay="false"
>
<view class="dialog-content">
<u-form :model="formData" :rules="rules" ref="formRef" label-width="auto">
<!-- 资源基本信息 -->
......@@ -16,8 +22,7 @@
<u-form-item label="上传文件" prop="file" required>
<view class="file-upload">
<u-button v-if="!formData.file" @click="chooseFile" type="primary"
class="ui-button">
<u-button v-if="!formData.file" @click="chooseFile" type="primary" class="ui-button">
<text class="font_10">选择文件</text>
</u-button>
<view v-else class="file-info">
......@@ -31,8 +36,14 @@
<!-- 操作按钮 -->
<view class="dialog-buttons">
<u-button type="primary" @click="handleSubmit" :loading="loading" size="normal" class="submit-btn"
color="var(--fui-color-success)">
<u-button
type="primary"
@click="handleSubmit"
:loading="loading"
size="normal"
class="submit-btn"
color="var(--fui-color-success)"
>
{{ submitButtonText }}
</u-button>
<u-button @click="handleClose" size="normal" class="cancel-btn">取消</u-button>
......@@ -43,411 +54,414 @@
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue'
import { useUserStore } from '@/store/modules/user'
import { useGlobSetting } from '/@/hooks/setting'
import * as WodeAPI from '@/api/model/wode'
// 定义Props
interface Props {
show: boolean
editData?: any
}
const props = withDefaults(defineProps<Props>(), {
show: false,
editData: null
})
// 定义Emits
const emit = defineEmits<{
'update:show': [value: boolean]
'submit': [data: any]
'close': []
'submitSuccess': []
}>()
// 表单引用
const formRef = ref()
const loading = ref(false)
const uploading = ref(false)
const showFileTypePicker = ref(false)
// 文件类型选项
const fileTypeOptions = [
{ value: 'doc', text: 'Word文档' },
{ value: 'xls', text: 'Excel表格' },
{ value: 'ppt', text: 'PPT演示' },
{ value: 'pdf', text: 'PDF文档' },
{ value: 'img', text: '图片文件' },
{ value: 'video', text: '视频文件' },
{ value: 'audio', text: '音频文件' },
{ value: 'zip', text: '压缩文件' },
{ value: 'other', text: '其他文件' }
]
// 表单数据
const formData = reactive({
fileName: '',
fileType: '',
fileTypeText: '',
file: null,
fileSrc: '',
})
// 计算属性
const dialogTitle = computed(() => {
return props.editData ? '编辑资源' : '上传资源'
})
const submitButtonText = computed(() => {
return props.editData ? '保存' : '上传'
})
// 表单验证规则
const rules = {
fileName: [
{ required: true, message: '请输入文件名称', trigger: 'blur' },
{ min: 2, max: 50, message: '文件名称长度在2-50个字符之间', trigger: 'blur' }
],
fileType: [
{ required: true, message: '请选择文件类型', trigger: 'change' }
],
file: [
{
required: true,
message: '请选择文件',
trigger: 'change',
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('请选择文件'))
} else {
callback()
}
}
}
]
}
// 监听显示状态
watch(() => props.show, (newVal) => {
if (newVal && props.editData) {
// 编辑模式,填充数据
resetFormData()
loadEditData()
} else if (newVal) {
// 添加模式,重置表单
resetFormData()
import { ref, reactive, watch, computed } from 'vue'
import { useUserStore } from '@/store/modules/user'
import { useGlobSetting } from '/@/hooks/setting'
import * as WodeAPI from '@/api/model/wode'
// 定义Props
interface Props {
show: boolean
editData?: any
}
})
// 重置表单数据
const resetFormData = () => {
formData.fileName = ''
formData.fileType = ''
formData.fileTypeText = ''
formData.file = null
formData.fileSrc = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
const props = withDefaults(defineProps<Props>(), {
show: false,
editData: null,
})
// 定义Emits
const emit = defineEmits<{
'update:show': [value: boolean]
submit: [data: any]
close: []
submitSuccess: []
}>()
// 表单引用
const formRef = ref()
const loading = ref(false)
const uploading = ref(false)
const showFileTypePicker = ref(false)
// 文件类型选项
const fileTypeOptions = [
{ value: 'doc', text: 'Word文档' },
{ value: 'xls', text: 'Excel表格' },
{ value: 'ppt', text: 'PPT演示' },
{ value: 'pdf', text: 'PDF文档' },
{ value: 'img', text: '图片文件' },
{ value: 'video', text: '视频文件' },
{ value: 'audio', text: '音频文件' },
{ value: 'zip', text: '压缩文件' },
{ value: 'other', text: '其他文件' },
]
// 表单数据
const formData = reactive({
fileName: '',
fileType: '',
fileTypeText: '',
file: null,
fileSrc: '',
})
// 计算属性
const dialogTitle = computed(() => {
return props.editData ? '编辑资源' : '上传资源'
})
const submitButtonText = computed(() => {
return props.editData ? '保存' : '上传'
})
// 表单验证规则
const rules = {
fileName: [
{ required: true, message: '请输入文件名称', trigger: 'blur' },
{ min: 2, max: 50, message: '文件名称长度在2-50个字符之间', trigger: 'blur' },
],
fileType: [{ required: true, message: '请选择文件类型', trigger: 'change' }],
file: [
{
required: true,
message: '请选择文件',
trigger: 'change',
validator: (rule, value, callback) => {
if (!value) {
callback(new Error('请选择文件'))
} else {
callback()
}
},
},
],
}
}
// 加载编辑数据
const loadEditData = () => {
if (!props.editData) return
formData.fileName = props.editData.fileName || ''
formData.fileType = props.editData.fileType || ''
formData.fileTypeText = props.editData.fileTypeText || ''
// 编辑模式不修改文件本身
// formData.file = null
}
const uplpoadFile = ref(null)
// 选择文件
const chooseFile = () => {
uni.chooseFile({
count: 1,
extension: ['*'],
success: (res) => {
uplpoadFile.value = res
const tempFilePaths = res.tempFilePaths
const tempFiles = res.tempFiles
console.log(tempFiles)
if (tempFiles && tempFiles.length > 0) {
if (!formData.fileName) {
formData.fileName = tempFiles[0].name || ''
}
// 根据文件扩展名设置文件类型
const fileName = tempFiles[0].name || ''
const ext = fileName.split('.').pop()?.toLowerCase() || ''
const fileType = getFileTypeByExt(ext)
formData.file = tempFiles[0]
formData.fileType = fileType.value
formData.fileTypeText = fileType.text
// 文件选择后触发验证
if (formRef.value) {
formRef.value.validateField('file')
}
// 监听显示状态
watch(
() => props.show,
(newVal) => {
if (newVal && props.editData) {
// 编辑模式,填充数据
resetFormData()
loadEditData()
} else if (newVal) {
// 添加模式,重置表单
resetFormData()
}
},
fail: (err) => {
console.error('选择文件失败:', err)
uni.showToast({ title: '选择文件失败', icon: 'none' })
uploading.value = false
)
// 重置表单数据
const resetFormData = () => {
formData.fileName = ''
formData.fileType = ''
formData.fileTypeText = ''
formData.file = null
formData.fileSrc = ''
// 清除验证状态
if (formRef.value) {
formRef.value.resetFields()
}
})
}
// 移除文件
const removeFile = () => {
formData.file = null
// 移除文件后触发验证
if (formRef.value) {
formRef.value.validateField('file')
}
}
// 根据文件扩展名获取文件类型
const getFileTypeByExt = (ext) => {
const map = {
'doc': 'doc',
'docx': 'doc',
'xls': 'xls',
'xlsx': 'xls',
'ppt': 'ppt',
'pptx': 'ppt',
'pdf': 'pdf',
'jpg': 'img',
'jpeg': 'img',
'png': 'img',
'gif': 'img',
'mp4': 'video',
'avi': 'video',
'mp3': 'audio',
'wav': 'audio',
'zip': 'zip',
'rar': 'zip',
'7z': 'zip'
}
const type = map[ext] || 'other'
return fileTypeOptions.find(item => item.value === type) || fileTypeOptions[8]
}
const userStore = useUserStore()
const globSetting = useGlobSetting()
const toastRef = ref()
// 提交表单
const handleSubmit = async () => {
try {
console.log(formData)
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
// 验证失败,返回
return
}
// 额外校验文件是否存在
if (!formData.file) {
uni.showToast({
title: '请选择文件',
icon: 'none'
})
return
}
loading.value = true
// 加载编辑数据
const loadEditData = () => {
if (!props.editData) return
// 准备提交数据
const submitData = {
fileName: formData.fileName,
fileType: formData.fileType,
fileSize: formData.file ? formData.file.size : 0,
fileSrc: formData.fileSrc,
// createTime: new Date().toLocaleString()
}
formData.fileName = props.editData.fileName || ''
formData.fileType = props.editData.fileType || ''
formData.fileTypeText = props.editData.fileTypeText || ''
// API留空
console.log('上传资源数据:', submitData)
uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL
filePath: uplpoadFile.value.tempFilePaths[0],
name: 'file',
formData: {
biz: 'temp',
},
header: {
'X-Access-Token': userStore.getToken,
},
// 编辑模式不修改文件本身
// formData.file = null
}
const uplpoadFile = ref(null)
// 选择文件
const chooseFile = () => {
uni.chooseFile({
count: 1,
extension: ['*'],
success: (res) => {
if (res.statusCode === 200) {
const data = JSON.parse(res.data)
if (data.code === 200 || data.code === 0) {
submitData.fileSrc = data.message;
WodeAPI.addResource(submitData).then(res => {
toastRef.value.show({
type: 'success',
text: `上传成功`,
})
emit('update:show', false)
emit('submitSuccess')
}).catch(error => {
uni.showToast({
title: error.message || '提交失败,请重试',
icon: 'none',
duration: 2000
})
}).finally(() => {
loading.value = false
})
uplpoadFile.value = res
const tempFilePaths = res.tempFilePaths
const tempFiles = res.tempFiles
console.log(tempFiles)
if (tempFiles && tempFiles.length > 0) {
if (!formData.fileName) {
formData.fileName = tempFiles[0].name || ''
}
// 根据文件扩展名设置文件类型
const fileName = tempFiles[0].name || ''
const ext = fileName.split('.').pop()?.toLowerCase() || ''
const fileType = getFileTypeByExt(ext)
formData.file = tempFiles[0]
formData.fileType = fileType.value
formData.fileTypeText = fileType.text
// 文件选择后触发验证
if (formRef.value) {
formRef.value.validateField('file')
}
}
},
fail: () => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
fail: (err) => {
console.error('选择文件失败:', err)
uni.showToast({ title: '选择文件失败', icon: 'none' })
uploading.value = false
},
})
// 模拟上传过程
// setTimeout(() => {
// uni.showToast({ title: '操作成功', icon: 'success' })
// emit('update:show', false)
// emit('submitSuccess')
// }, 1500)
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000
})
} finally {
loading.value = false
}
}
// 关闭弹窗
const handleClose = () => {
emit('update:show', false)
emit('close')
}
// 移除文件
const removeFile = () => {
formData.file = null
// 移除文件后触发验证
if (formRef.value) {
formRef.value.validateField('file')
}
}
// 根据文件扩展名获取文件类型
const getFileTypeByExt = (ext) => {
const map = {
doc: 'doc',
docx: 'doc',
xls: 'xls',
xlsx: 'xls',
ppt: 'ppt',
pptx: 'ppt',
pdf: 'pdf',
jpg: 'img',
jpeg: 'img',
png: 'img',
gif: 'img',
mp4: 'video',
avi: 'video',
mp3: 'audio',
wav: 'audio',
zip: 'zip',
rar: 'zip',
'7z': 'zip',
}
const type = map[ext] || 'other'
return fileTypeOptions.find((item) => item.value === type) || fileTypeOptions[8]
}
const userStore = useUserStore()
const globSetting = useGlobSetting()
const toastRef = ref()
// 提交表单
const handleSubmit = async () => {
try {
console.log(formData)
// 先进行表单验证
const valid = await formRef.value.validate()
if (!valid) {
// 验证失败,返回
return
}
// 额外校验文件是否存在
if (!formData.file) {
uni.showToast({
title: '请选择文件',
icon: 'none',
})
return
}
loading.value = true
// 准备提交数据
const submitData = {
fileName: formData.fileName,
fileType: formData.fileType,
fileSize: formData.file ? formData.file.size : 0,
fileSrc: formData.fileSrc,
// createTime: new Date().toLocaleString()
}
// API留空
console.log('上传资源数据:', submitData)
uni.uploadFile({
url: globSetting.apiUrl + globSetting.urlPrefix + '/sys/common/upload', // 直接使用上传接口URL
filePath: uplpoadFile.value.tempFilePaths[0],
name: 'file',
formData: {
biz: 'temp',
},
header: {
'X-Access-Token': userStore.getToken,
},
success: (res) => {
if (res.statusCode === 200) {
const data = JSON.parse(res.data)
if (data.code === 200 || data.code === 0) {
submitData.fileSrc = data.message
WodeAPI.addResource(submitData)
.then((res) => {
toastRef.value.show({
type: 'success',
text: `上传成功`,
})
// emit('update:show', false)
emit('submitSuccess')
})
.catch((error) => {
uni.showToast({
title: error.message || '提交失败,请重试',
icon: 'none',
duration: 2000,
})
})
.finally(() => {
loading.value = false
})
}
}
},
fail: () => {
toastRef.value.show({
type: 'error',
text: '上传失败',
})
},
})
// 模拟上传过程
// setTimeout(() => {
// uni.showToast({ title: '操作成功', icon: 'success' })
// emit('update:show', false)
// emit('submitSuccess')
// }, 1500)
} catch (error) {
console.log('提交失败:', error)
uni.showToast({
title: '操作失败',
icon: 'none',
duration: 2000,
})
} finally {
loading.value = false
}
}
// 关闭弹窗
const handleClose = () => {
emit('update:show', false)
emit('close')
}
</script>
<style lang="scss" scoped>
.dialog-content {
padding: 10rpx 30rpx;
width: 90%;
max-height: 80vh;
overflow-y: auto;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 30rpx;
border-left: 6rpx solid #5DB66F;
padding-left: 12rpx;
}
.dialog-buttons {
display: flex;
justify-content: space-between;
margin-top: 50rpx;
gap: 20rpx;
}
.submit-btn,
.cancel-btn {
flex: 1;
}
.file-upload {
width: 100%;
}
.file-info {
padding: 20rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
.file-name-container {
position: relative;
display: flex;
align-items: center;
.dialog-content {
padding: 10rpx 30rpx;
width: 90%;
max-height: 80vh;
overflow-y: auto;
}
.file-name {
flex: 1;
width: 40rpx;
font-size: 28rpx;
.section-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 40rpx;
margin-bottom: 30rpx;
border-left: 6rpx solid #5db66f;
padding-left: 12rpx;
}
.remove-icon {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
font-size: 36rpx;
color: #999;
width: 40rpx;
height: 40rpx;
.dialog-buttons {
display: flex;
align-items: center;
justify-content: center;
&:active {
color: #ff4d4f;
background-color: rgba(255, 77, 79, 0.1);
border-radius: 50%;
}
justify-content: space-between;
margin-top: 50rpx;
gap: 20rpx;
}
}
// 模态框样式调整
::v-deep .u-modal {
background: linear-gradient(0deg, rgba(93, 182, 111, 0) 50%, rgba(93, 182, 111, 0.25) 100%);
.submit-btn,
.cancel-btn {
flex: 1;
}
.u-modal__content {
border-radius: 20rpx;
padding: 20rpx 0rpx;
.file-upload {
width: 100%;
}
.u-modal__header {
border-bottom: 2rpx solid #f0f0f0;
padding: 30rpx;
.file-info {
padding: 20rpx;
background-color: #f5f5f5;
border-radius: 8rpx;
.file-name-container {
position: relative;
display: flex;
align-items: center;
}
.u-modal__header__title {
font-size: 32rpx;
font-weight: 600;
.file-name {
flex: 1;
width: 40rpx;
font-size: 28rpx;
color: #333;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right: 40rpx;
}
.remove-icon {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
font-size: 36rpx;
color: #999;
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
&:active {
color: #ff4d4f;
background-color: rgba(255, 77, 79, 0.1);
border-radius: 50%;
}
}
}
}
.ui-button {
padding: 16rpx 0;
background-color: #5db66f26;
border-radius: 10rpx;
mix-blend-mode: NOTTHROUGH;
border-color: #5db66f26;
.font_10 {
font-size: 24rpx;
line-height: 24rpx;
color: #16a34a;
// 模态框样式调整
::v-deep .u-modal {
background: linear-gradient(0deg, rgba(93, 182, 111, 0) 50%, rgba(93, 182, 111, 0.25) 100%);
.u-modal__content {
border-radius: 20rpx;
padding: 20rpx 0rpx;
}
.u-modal__header {
border-bottom: 2rpx solid #f0f0f0;
padding: 30rpx;
.u-modal__header__title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
}
}
.ui-button {
padding: 16rpx 0;
background-color: #5db66f26;
border-radius: 10rpx;
mix-blend-mode: NOTTHROUGH;
border-color: #5db66f26;
.font_10 {
font-size: 24rpx;
line-height: 24rpx;
color: #16a34a;
}
}
}
</style>
......@@ -4,8 +4,13 @@
<view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input v-model="pageData.param.fileName" placeholder="请输入文件名称搜索" border="none"
class="codefun-ml-8" @confirm="handleSearch" />
<u-input
v-model="pageData.param.fileName"
placeholder="请输入文件名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view>
<!-- 资源列表 - 根据图片样式修改 -->
......@@ -15,15 +20,17 @@
<view class="resource-main">
<view class="resource-name">{{ item.fileName }}</view>
<view class="resource-meta">
<text class="resource-size">{{ formatFileSize(item.fileSize) }}</text>
<text class="resource-size">{{ item.fileSize }}</text>
<text class="separator">|</text>
<text class="download-count">已下载{{ item.downloadCount || 25 }}</text>
<text class="download-count">已下载{{ item.downloadCount || 0 }}</text>
<text class="separator">|</text>
<text class="upload-time">{{ formatTime(item.createTime) }}</text>
</view>
</view>
<view class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="handleDownload(item)">
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
@click.stop="handleDownload(item)"
>
<text class="font_10">下载</text>
</view>
<!-- <view class="download-section">
......@@ -36,337 +43,292 @@
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="pageData.list.length === 0">
<image class="empty-icon" src="/static/images/empty-file.png" mode="aspectFit"></image>
<text class="empty-text">暂无资源文件</text>
</view>
<!-- <view class="empty-state" v-if="pageData.list.length === 0">
<image class="empty-icon" src="/static/images/empty.png" mode="aspectFit"></image>
<text class="empty-text">暂无资源</text>
</view> -->
</view>
</z-paging>
<!-- 弹窗组件 -->
<save-dialog :show="showDialog" :editData="currentEditData" @update:show="showDialog = $event"
@submitSuccess="handleSubmitSuccess" />
<save-dialog
:show="showDialog"
:editData="currentEditData"
@update:show="showDialog = $event"
@submitSuccess="handleSubmitSuccess"
/>
</view>
</template>
<script setup>
import { nextTick, reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app'
// import * as ResourceAPI from '@/api/model/resource' // API留空
import SaveDialog from './components/save-dialog.vue'
const isOnePage = ref(true)
const paging = ref(null)
const pageData = reactive({
param: {
pageNo: 1,
pageSize: 10,
fileName: '',
},
list: [],
})
function getList() {
if (!paging.value) return
// API留空,使用模拟数据 - 根据图片内容调整
setTimeout(() => {
const mockData = [
{
id: 1,
fileName: '水稻种植合同模版',
fileType: 'PDF',
fileSize: 128000, // 125kb
downloadCount: 25,
createTime: '2025-11-02 14:00'
},
{
id: 2,
fileName: '农药使用指南',
fileType: 'PDF',
fileSize: 128000,
downloadCount: 25,
createTime: '2025-11-02 14:00'
},
{
id: 3,
fileName: '农业补贴列表说明',
fileType: 'PDF',
fileSize: 128000,
downloadCount: 25,
createTime: '2025-11-02 14:00'
},
{
id: 4,
fileName: '小麦种植合同模版',
fileType: 'PDF',
fileSize: 128000,
downloadCount: 25,
createTime: '2025-11-02 14:00'
},
{
id: 5,
fileName: '化肥使用指南',
fileType: 'PDF',
fileSize: 128000,
downloadCount: 25,
createTime: '2025-11-02 14:00'
},
{
id: 6,
fileName: '油茶种植补贴列表说明',
fileType: 'PDF',
fileSize: 128000,
downloadCount: 25,
createTime: '2025-11-02 14:00'
}
]
pageData.total = mockData.length
paging.value.complete(mockData)
}, 500)
}
function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize
getList()
}
function handleSearch() {
pageData.param.pageNo = 1
if (paging.value) {
paging.value.reload()
import { nextTick, reactive, ref } from 'vue'
import { onLoad, onNavigationBarButtonTap, onShow } from '@dcloudio/uni-app'
import * as API from '@/api/model/wode'
import SaveDialog from './components/save-dialog.vue'
const isOnePage = ref(true)
const paging = ref(null)
const pageData = reactive({
param: {
pageNo: 1,
pageSize: 10,
fileName: '',
},
list: [],
})
function getList() {
if (!paging.value) return
// API留空,使用模拟数据 - 根据图片内容调整
API.getResourceList(pageData.param).then((res) => {
paging.value.complete(res.records)
})
}
function queryList(pageNo, pageSize) {
pageData.param.pageNo = pageNo
pageData.param.pageSize = pageSize
getList()
}
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
const showAddDialog = () => {
currentEditData.value = null
showDialog.value = true
}
// 格式化时间显示
const formatTime = (time) => {
if (!time) return ''
// 如果是完整的时间字符串,可以格式化为图片中的样式
return time.includes(' ') ? time : `${time} 14:00`
}
// 下载资源
const handleDownload = (resource) => {
console.log('下载资源:', resource)
uni.showToast({
title: '开始下载',
icon: 'success',
duration: 2000
function handleSearch() {
pageData.param.pageNo = 1
if (paging.value) {
paging.value.reload()
}
}
const showDialog = ref(false)
const currentEditData = ref(null)
onNavigationBarButtonTap((_) => {
showAddDialog()
})
// 模拟下载逻辑
setTimeout(() => {
const showAddDialog = () => {
currentEditData.value = null
showDialog.value = true
}
// 格式化时间显示
const formatTime = (time) => {
if (!time) return ''
// 如果是完整的时间字符串,可以格式化为图片中的样式
return time.includes(' ') ? time : `${time} 14:00`
}
// 下载资源
const handleDownload = async (resource) => {
await API.downloadResource({ id: resource.id })
// 更新下载次数
const index = pageData.list.findIndex(item => item.id === resource.id)
const index = pageData.list.findIndex((item) => item.id === resource.id)
if (index !== -1) {
pageData.list[index].downloadCount = (pageData.list[index].downloadCount || 0) + 1
}
}, 1000)
}
// 格式化文件大小
const formatFileSize = (bytes) => {
if (!bytes) return '125kb'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(0)) + sizes[i].toLowerCase()
}
const handleSubmitSuccess = () => {
handleSearch()
}
const { downloadResource } = await import('@/utils')
// 使用封装的下载方法
const result = await downloadResource(resource)
if (!result.success) {
console.error('下载失败:', result.error)
}
}
// 格式化文件大小
const formatFileSize = (bytes) => {
if (!bytes) return '125kb'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(0)) + sizes[i].toLowerCase()
}
const handleSubmitSuccess = () => {
showDialog.value = false
// 重新加载数据
handleSearch()
}
</script>
<style lang="scss">
body {
background-color: #f8f9fa;
}
.page {
background-color: #f8f9fa;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
}
.group_3 {
padding: 28rpx 24rpx;
}
.section_2 {
padding: 16rpx 20rpx;
background-color: #ffffff;
border-radius: 1998rpx;
margin-bottom: 30rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
}
.image_6 {
width: 32rpx;
height: 32rpx;
}
/* 资源列表样式 - 根据图片样式重写 */
.resource-list {
margin-top: 0;
}
.resource-item {
background-color: #ffffff;
border-radius: 16rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
overflow: hidden;
transition: all 0.3s ease;
&:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
body {
background: #e6f5e8;
}
}
.resource-content {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 24rpx;
}
.resource-main {
flex: 1;
min-width: 0;
}
.resource-name {
font-size: 32rpx;
font-weight: 500;
color: #333333;
line-height: 1.4;
margin-bottom: 12rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.resource-meta {
display: flex;
align-items: center;
font-size: 24rpx;
color: #999999;
gap: 12rpx;
flex-wrap: wrap;
}
.separator {
color: #dddddd;
font-size: 20rpx;
}
.resource-size,
.download-count,
.upload-time {
color: #666666;
}
.download-section {
margin-left: 30rpx;
flex-shrink: 0;
}
.download-btn {
background-color: #5DB66F;
border: none;
border-radius: 20rpx;
padding: 12rpx 30rpx;
min-width: 120rpx;
transition: all 0.3s ease;
&::after {
border: none;
.page {
background: #e6f5e8;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
}
.group_3 {
padding: 28rpx 24rpx;
}
&:active {
background-color: #4ca85c;
transform: scale(0.95);
.section_2 {
padding: 16rpx 20rpx;
background-color: #ffffff;
border-radius: 1998rpx;
margin-bottom: 30rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
}
}
.text-wrapper_4 {
padding: 16rpx 0;
background-color: #5db66f26;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
width: 136rpx;
.font_10 {
font-size: 24rpx;
line-height: 24rpx;
color: #16a34a;
.image_6 {
width: 32rpx;
height: 32rpx;
}
/* 资源列表样式 - 根据图片样式重写 */
.resource-list {
margin-top: 0;
border-radius: 16rpx;
background-color: #ffffff;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
padding: 0 20rpx;
}
.resource-item {
// border-radius: 16rpx;
// margin-bottom: 20rpx;
overflow: hidden;
transition: all 0.3s ease;
border-bottom: 1px solid #e3e3e3;
&:active {
transform: translateY(2rpx);
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
}
}
}
.btn-text {
color: #ffffff;
font-size: 28rpx;
font-weight: 500;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
padding: 120rpx 0;
color: #999999;
}
.empty-icon {
width: 160rpx;
height: 160rpx;
margin-bottom: 30rpx;
opacity: 0.6;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
/* 响应式调整 */
@media (max-width: 375px) {
.resource-content {
padding: 24rpx 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 24rpx;
}
.resource-main {
flex: 1;
min-width: 0;
}
.resource-name {
font-size: 30rpx;
font-size: 32rpx;
font-weight: 500;
color: #333333;
line-height: 1.4;
margin-bottom: 12rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.resource-meta {
font-size: 22rpx;
display: flex;
align-items: center;
font-size: 20rpx;
color: #999999;
gap: 10rpx;
flex-wrap: wrap;
}
.separator {
color: #dddddd;
font-size: 20rpx;
}
.resource-size,
.download-count,
.upload-time {
color: #666666;
}
.download-section {
margin-left: 30rpx;
flex-shrink: 0;
}
.download-btn {
padding: 10rpx 24rpx;
min-width: 100rpx;
background-color: #5db66f;
border: none;
border-radius: 20rpx;
padding: 12rpx 30rpx;
min-width: 120rpx;
transition: all 0.3s ease;
&::after {
border: none;
}
&:active {
background-color: #4ca85c;
transform: scale(0.95);
}
}
.text-wrapper_4 {
padding: 16rpx 0;
background-color: #5db66f26;
border-radius: 400rpx;
mix-blend-mode: NOTTHROUGH;
width: 136rpx;
.font_10 {
font-size: 24rpx;
line-height: 24rpx;
color: #16a34a;
}
}
.btn-text {
font-size: 26rpx;
color: #ffffff;
font-size: 28rpx;
font-weight: 500;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
padding: 120rpx 0;
color: #999999;
}
.empty-icon {
width: 160rpx;
height: 160rpx;
margin-bottom: 30rpx;
opacity: 0.6;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
/* 响应式调整 */
@media (max-width: 375px) {
.resource-content {
padding: 24rpx 20rpx;
}
.resource-name {
font-size: 30rpx;
}
.resource-meta {
font-size: 22rpx;
}
.download-btn {
padding: 10rpx 24rpx;
min-width: 100rpx;
}
.btn-text {
font-size: 26rpx;
}
}
}
</style>
<script setup lang="ts">
import { reactive } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'
import dayjs from 'dayjs'
import { closeSplashscreenAndChechUpgrade } from '@/utils/upgrade'
import * as WeatherAPI from '@/api/model/weather'
import * as HomeAPI from '@/api/model/home'
import { useDictStore } from '@/store/modules/dict'
const dictStore = useDictStore()
const model = reactive({
// 湖南省人民政府
location: '112.982931,28.116698',
})
onLoad(() => {
// 关闭启动页并检查更新
closeSplashscreenAndChechUpgrade()
})
onShow(() => {
uni.getLocation({
type: 'wgs84',
success(res) {
console.log(`经度:${res.longitude}`)
console.log(`纬度:${res.latitude}`)
if (res.longitude === 0 || res.latitude === 0) {
return
import { reactive, ref } from 'vue'
import { onPullDownRefresh } from '@dcloudio/uni-app'
import dayjs from 'dayjs'
import { closeSplashscreenAndChechUpgrade } from '@/utils/upgrade'
import * as WeatherAPI from '@/api/model/weather'
import * as HomeAPI from '@/api/model/home'
import * as UserAPI from '@/api/model/userInfo'
import { useDictStore } from '@/store/modules/dict'
const dictStore = useDictStore()
const model = reactive({
// 湖南省人民政府
location: '112.982931,28.116698',
})
// 位置获取频率控制
const lastLocationTime = ref(0)
const LOCATION_CACHE_TIME = 5 * 60 * 1000 // 5分钟缓存时间
onLoad(() => {
// 关闭启动页并检查更新
closeSplashscreenAndChechUpgrade()
})
onShow(() => {
// 检查是否需要重新获取位置(5分钟缓存)
const currentTime = Date.now()
const cachedLocation = uni.getStorageSync('location')
// 添加延迟调用,避免频繁触发
setTimeout(() => {
if (
cachedLocation &&
cachedLocation.lon &&
cachedLocation.lat &&
currentTime - lastLocationTime.value < LOCATION_CACHE_TIME
) {
// 使用缓存的位置数据
console.log('使用缓存的位置数据')
pageData.weather.lon = cachedLocation.lon
pageData.weather.lat = cachedLocation.lat
model.location = `${cachedLocation.lon},${cachedLocation.lat}`
// 更新详细地址(仅在缓存存在时)
if (cachedLocation.lat && cachedLocation.lon) {
UserAPI.location({ lat: cachedLocation.lat, lon: cachedLocation.lon })
.then((res) => {
console.log('UserAPI.location', res)
pageData.weather.detailedLocation =
res.province +
'-' +
res.city +
'-' +
res.country +
'-' +
res.road +
'-' +
res.town +
'-' +
res.address
})
.catch(() => {
// 地址获取失败时使用默认显示
pageData.weather.detailedLocation = '获取中'
})
}
reloadWeather()
} else {
// 需要重新获取位置
uni.getLocation({
type: 'wgs84',
success(res) {
console.log(`经度:${res.longitude}`)
console.log(`纬度:${res.latitude}`)
if (res.longitude === 0 || res.latitude === 0) {
console.log('无效的位置数据,使用缓存')
if (cachedLocation && cachedLocation.lon && cachedLocation.lat) {
pageData.weather.lon = cachedLocation.lon
pageData.weather.lat = cachedLocation.lat
model.location = `${cachedLocation.lon},${cachedLocation.lat}`
reloadWeather()
}
return
}
// 更新最后获取位置的时间
lastLocationTime.value = currentTime
UserAPI.location({ lat: res.latitude, lon: res.longitude })
.then((res) => {
console.log('UserAPI.location', res)
pageData.weather.detailedLocation =
res.province +
'-' +
res.city +
'-' +
res.country +
'-' +
res.road +
'-' +
res.town +
'-' +
res.address
})
.catch(() => {
// 地址获取失败时使用默认显示
pageData.weather.detailedLocation = '获取中'
})
pageData.weather.lon = res.longitude
pageData.weather.lat = res.latitude
uni.setStorageSync('location', {
// 缓存地址
lon: res.longitude,
lat: res.latitude,
})
model.location = `${res.longitude},${res.latitude}`
reloadWeather()
},
fail(res) {
console.log('获取位置失败:', res)
// 即使失败也尝试使用缓存数据
if (cachedLocation && cachedLocation.lon && cachedLocation.lat) {
console.log('获取位置失败,使用缓存数据')
pageData.weather.lon = cachedLocation.lon
pageData.weather.lat = cachedLocation.lat
model.location = `${cachedLocation.lon},${cachedLocation.lat}`
reloadWeather()
} else {
reloadWeather()
uni.showToast({
title: '获取地址失败,将导致部分功能不可用',
icon: 'none',
})
}
},
})
}
}, 300) // 延迟300毫秒执行,避免频繁触发
// 获取字典列表
dictStore.setDictList()
// 查询金刚区数据
getServiceItems()
getMenuItems()
// 查询天气信息
getWarningInfo()
// 查询热门产地行情
getProductMarketList()
// 服务展示窗
getServiceStatsList()
// 农技课堂
getAgricultureClassList()
})
pageData.weather.lon = res.longitude
pageData.weather.lat = res.latitude
uni.setStorageSync('location', {
// 缓存地址
lon: res.longitude,
lat: res.latitude,
})
model.location = `${res.longitude},${res.latitude}`
reloadWeather()
},
fail(res) {
console.log('获取位置失败:', res)
reloadWeather()
uni.showToast({
title: '获取地址失败,将导致部分功能不可用',
icon: 'none',
})
},
// 下拉刷新
onPullDownRefresh(() => {
setTimeout(function () {
uni.stopPullDownRefresh()
Message.toast('刷新成功')
}, 1000)
})
// 获取字典列表
dictStore.setDictList()
// 查询金刚区数据
getServiceItems()
getMenuItems()
// 查询天气信息
getWarningInfo()
// 查询热门产地行情
getProductMarketList()
// 服务展示窗
getServiceStatsList()
// 农技课堂
getAgricultureClassList()
})
// 下拉刷新
onPullDownRefresh(() => {
setTimeout(function () {
uni.stopPullDownRefresh()
Message.toast('刷新成功')
}, 1000)
})
function getWeatherRecommend(weather: string) {
switch (weather) {
case '晴':
return '宜喷药'
case '阴':
return '宜少浇水'
case '小雨':
return '宜播种'
case '中雨':
return '注意防涝'
default:
return '无建议'
function getWeatherRecommend(weather: string) {
switch (weather) {
case '晴':
return '宜喷药'
case '阴':
return '宜少浇水'
case '小雨':
return '宜播种'
case '中雨':
return '注意防涝'
default:
return '无建议'
}
}
}
// 刷新天气信息
function reloadWeather() {
WeatherAPI.now(model.location).then((res) => {
console.log('WeatherAPI.now', res)
// 刷新天气信息
function reloadWeather() {
WeatherAPI.now(model.location).then((res) => {
console.log('WeatherAPI.now', res)
pageData.weather.temperature = `${res.data.now.temp}°C`
pageData.weather.condition = `${res.data.now.text} | ${getWeatherRecommend(res.data.now.text)}`
pageData.weather.icon = `${res.data.now.icon}`
})
WeatherAPI.forecast(model.location).then((res) => {
console.log('WeatherAPI.forecast', res)
const weekDays = ['日', '一', '二', '三', '四', '五', '六']
pageData.weather.forecast = res.data.daily.slice(1, 4).map((item: any, index: number) => {
return {
day: index === 0 ? '明天' : `周${weekDays[dayjs(item.fxDate).day()]}`,
temp: `${item.tempMin}~${item.tempMax}°`,
icon: item.iconDay || item.iconNight,
}
pageData.weather.temperature = `${res.data.now.temp}°C`
pageData.weather.condition = `${res.data.now.text} | ${getWeatherRecommend(res.data.now.text)}`
pageData.weather.icon = `${res.data.now.icon}`
})
})
}
// 页面数据
const pageData = reactive({
// 顶部标题和搜索
header: {
title: $app.name,
searchPlaceholder: '请输入搜索内容',
},
// 天气信息
weather: {
icon: '100',
location: '长沙',
date: `${dayjs().format('MM-DD')} ${dayjs().toLunarDay().getName()}`,
temperature: '-°C',
condition: '晴|适宜喷药',
forecast: [
{ day: '明天', temp: '24-28°', icon: '100' },
{ day: '周三', temp: '25-29°', icon: '101' },
{ day: '周四', temp: '26-31°', icon: '102' },
WeatherAPI.forecast(model.location).then((res) => {
console.log('WeatherAPI.forecast', res)
const weekDays = ['日', '一', '二', '三', '四', '五', '六']
pageData.weather.forecast = res.data.daily.slice(1, 4).map((item: any, index: number) => {
return {
day: index === 0 ? '明天' : `周${weekDays[dayjs(item.fxDate).day()]}`,
temp: `${item.tempMin}~${item.tempMax}°`,
icon: item.iconDay || item.iconNight,
}
})
})
}
// 页面数据
const pageData = reactive({
// 顶部标题和搜索
header: {
title: $app.name,
searchPlaceholder: '请输入搜索内容',
},
// 天气信息
weather: {
icon: '100',
location: '长沙',
detailedLocation: '获取中', // 详细位置信息
date: `${dayjs().format('MM-DD')} ${dayjs().toLunarDay().getName()}`,
temperature: '-°C',
condition: '晴|适宜喷药',
forecast: [
{ day: '明天', temp: '24-28°', icon: '100' },
{ day: '周三', temp: '25-29°', icon: '101' },
{ day: '周四', temp: '26-31°', icon: '102' },
],
warning: '',
lon: null,
lat: null,
},
// 功能菜单
menuItems: [],
// 其他服务
serviceItems: [],
// 新闻资讯
newsItems: [
{
id: 1,
type: '最新预警',
title: '积极防范持续高温对农作物的影响',
date: dayjs().format('YYYY-MM-DD'),
},
],
warning: '',
lon: null,
lat: null,
},
// 功能菜单
menuItems: [],
// 其他服务
serviceItems: [],
// 新闻资讯
newsItems: [
{ id: 1, type: '最新', title: '积极防范持续高温对农作物的影响', date: '2025-08-29' },
{ id: 2, type: '预警', title: '', date: '2025-08-29' },
],
// 农产品行情
productMarket: {
title: '热门产地行情',
// updateTime: '08-30日更新',
products: [
// { id: 1, name: '晚稻13号', price: '¥4120', change: '+1.2%', isUp: true },
// { id: 2, name: '晚稻9号', price: '¥3211', change: '+1.2%', isUp: true },
// { id: 3, name: '晚稻11号', price: '¥2120', change: '-1.2%', isUp: false },
// 农产品行情
productMarket: {
title: '热门产地行情',
// updateTime: '08-30日更新',
products: [
// { id: 1, name: '晚稻13号', price: '¥4120', change: '+1.2%', isUp: true },
// { id: 2, name: '晚稻9号', price: '¥3211', change: '+1.2%', isUp: true },
// { id: 3, name: '晚稻11号', price: '¥2120', change: '-1.2%', isUp: false },
],
},
// 服务展示窗
serviceStats: [
// {
// id: 1,
// name: '农场入驻',
// value: '2,360',
// unit: '个',
// icon: '/static/images/codefun/15911306636a361a8dc16ce0283f3830.png',
// },
// {
// id: 2,
// name: '空闲农机',
// value: '126',
// unit: '台',
// icon: '/static/images/codefun/1d0cd168eeffbaf37a90aa949c6ad806.png',
// },
// {
// id: 3,
// name: '产销对接',
// value: '156',
// unit: '笔',
// icon: '/static/images/codefun/24dd00386672f240ef00394b746c2ff0.png',
// },
// {
// id: 4,
// name: '服务农户',
// value: '12,580',
// unit: '人',
// icon: '/static/images/codefun/3fd6a50eaf22431687a6151df0581156.png',
// },
// {
// id: 5,
// name: '覆盖面积',
// value: '268',
// unit: 'km',
// icon: '/static/images/codefun/87773a17a1b64dc686bf935708262002.png',
// },
// {
// id: 6,
// name: '覆盖区县',
// value: '21',
// unit: '个',
// icon: '/static/images/codefun/329a4404092545f2924ad095c531cc66.png',
// },
],
},
// 服务展示窗
serviceStats: [
// {
// id: 1,
// name: '农场入驻',
// value: '2,360',
// unit: '个',
// icon: '/static/images/codefun/15911306636a361a8dc16ce0283f3830.png',
// },
// {
// id: 2,
// name: '空闲农机',
// value: '126',
// unit: '台',
// icon: '/static/images/codefun/1d0cd168eeffbaf37a90aa949c6ad806.png',
// },
// {
// id: 3,
// name: '产销对接',
// value: '156',
// unit: '笔',
// icon: '/static/images/codefun/24dd00386672f240ef00394b746c2ff0.png',
// },
// {
// id: 4,
// name: '服务农户',
// value: '12,580',
// unit: '人',
// icon: '/static/images/codefun/3fd6a50eaf22431687a6151df0581156.png',
// },
// {
// id: 5,
// name: '覆盖面积',
// value: '268',
// unit: 'km',
// icon: '/static/images/codefun/87773a17a1b64dc686bf935708262002.png',
// },
// {
// id: 6,
// name: '覆盖区县',
// value: '21',
// unit: '个',
// icon: '/static/images/codefun/329a4404092545f2924ad095c531cc66.png',
// },
],
// 农技课堂
agricultureClass: {
title: '',
// expert: '张教授',
time: '',
videoList: [],
},
current: 0,
})
function getServiceItems() {
HomeAPI.zoneList({
pageNo: 1,
pageSize: 4,
status: 1,
type: 1,
}).then((res) => {
const { records } = res
pageData.serviceItems = []
pageData.serviceItems = records
})
}
function getMenuItems() {
HomeAPI.zoneList({
pageNo: 1,
pageSize: 4,
status: 1,
type: 2,
}).then((res) => {
const { records } = res
pageData.menuItems = []
pageData.menuItems = records
// 农技课堂
agricultureClass: {
title: '',
// expert: '张教授',
time: '',
videoList: [],
},
current: 0,
})
}
function getWarningInfo() {
if (!pageData.weather.lon || !pageData.weather.lat) {
return
function getServiceItems() {
HomeAPI.zoneList({
pageNo: 1,
pageSize: 4,
status: 1,
type: 1,
}).then((res) => {
const { records } = res
pageData.serviceItems = []
pageData.serviceItems = records
})
}
function getMenuItems() {
HomeAPI.zoneList({
pageNo: 1,
pageSize: 4,
status: 1,
type: 2,
}).then((res) => {
const { records } = res
pageData.menuItems = []
pageData.menuItems = records
})
}
function getWarningInfo() {
if (!pageData.weather.lon || !pageData.weather.lat) {
return
}
HomeAPI.warningInfo({
lon: pageData.weather.lon,
lat: pageData.weather.lat,
}).then((res) => {
pageData.weather.warning = res[0].criteria
})
}
function getProductMarketList() {
HomeAPI.productMarketList({
status: 1,
}).then((res) => {
const { records } = res
console.log(res)
pageData.productMarket.products = records
pageData.productMarket.products.forEach((item: any) => {
switch (item.tendency) {
case 1:
item.isUp = true
break
case 2:
item.isUp = false
break
HomeAPI.warningInfo({
lon: pageData.weather.lon,
lat: pageData.weather.lat,
}).then((res) => {
pageData.weather.warning = res[0].criteria
})
}
function getProductMarketList() {
HomeAPI.productMarketList({
status: 1,
}).then((res) => {
const { records } = res
console.log(res)
pageData.productMarket.products = records
pageData.productMarket.products.forEach((item: any) => {
switch (item.tendency) {
case 1:
item.isUp = true
break
case 2:
item.isUp = false
break
}
})
})
}
function getServiceStatsList() {
HomeAPI.serviceStatsList({
status: 1,
}).then((res) => {
const { records } = res
pageData.serviceStats = records
})
}
function getAgricultureClassList() {
HomeAPI.agricultureClassList({
status: 1,
}).then((res) => {
const { records } = res
pageData.agricultureClass.videoList = records
pageData.agricultureClass.title = records[0]?.title
})
}
// 菜单点击事件
function onMenuItemClick(item: any) {
console.log('点击菜单项:', item)
// 在这里添加具体的菜单点击逻辑
}
// 农产品关注点击事件
function onProductFollowClick(product: any) {
console.log('点击关注农产品:', product)
// 在这里添加具体的关注逻辑
}
// 查看更多农技课堂
function onViewMoreClass() {
console.log('查看全部农技课堂')
// 在这里添加具体的查看逻辑
}
// 轮播视频切换的时候触发
function handleChangeVideo(e: any) {
// console.log('切换视频', e.detail.current)
pageData.current = e.detail.current
pageData.agricultureClass.title = pageData.agricultureClass.videoList[pageData.current]?.title
}
// 获取视频时长
function handleMetadataLoaded(e: any) {
pageData.agricultureClass.time = e.target.duration
}
// 解决轮播视频切换时,上一个视频不停止播放的问题
function handleVideoPlay(currentIndex) {
pageData.agricultureClass.videoList.forEach((_, index) => {
if (index !== currentIndex) {
const videoContext = uni.createVideoContext(`video${index}`)
videoContext.pause()
}
})
})
}
function getServiceStatsList() {
HomeAPI.serviceStatsList({
status: 1,
}).then((res) => {
const { records } = res
pageData.serviceStats = records
})
}
function getAgricultureClassList() {
HomeAPI.agricultureClassList({
status: 1,
}).then((res) => {
const { records } = res
pageData.agricultureClass.videoList = records
pageData.agricultureClass.title = records[0]?.title
})
}
// 菜单点击事件
function onMenuItemClick(item: any) {
console.log('点击菜单项:', item)
// 在这里添加具体的菜单点击逻辑
}
// 农产品关注点击事件
function onProductFollowClick(product: any) {
console.log('点击关注农产品:', product)
// 在这里添加具体的关注逻辑
}
// 查看更多农技课堂
function onViewMoreClass() {
console.log('查看全部农技课堂')
// 在这里添加具体的查看逻辑
}
// 轮播视频切换的时候触发
function handleChangeVideo(e: any) {
// console.log('切换视频', e.detail.current)
pageData.current = e.detail.current
pageData.agricultureClass.title = pageData.agricultureClass.videoList[pageData.current]?.title
}
// 获取视频时长
function handleMetadataLoaded(e: any) {
pageData.agricultureClass.time = e.target.duration
}
// 解决轮播视频切换时,上一个视频不停止播放的问题
function handleVideoPlay(currentIndex) {
pageData.agricultureClass.videoList.forEach((_, index) => {
if (index !== currentIndex) {
const videoContext = uni.createVideoContext(`video${index}`)
videoContext.pause()
}
})
}
}
</script>
<template>
......@@ -342,14 +440,37 @@ function handleVideoPlay(currentIndex) {
<view class="codefun-flex-col">
<view class="codefun-flex-col codefun-self-stretch group_4">
<view class="codefun-flex-col section_3">
<view class="codefun-flex-row codefun-justify-between">
<view class="codefun-flex-row codefun-items-center">
<view class="codefun-flex-row codefun-justify-between" style="align-items: center">
<view
class="codefun-flex-row codefun-items-center codefun-relative codefun-overflow-hidden"
>
<!-- 定位图标 -->
<image
class="codefun-shrink-0 image_13 codefun-mr-4"
src="/static/images/local-address.png"
/>
<!-- 滚动位置信息 -->
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper">
<text class="font_2 text_4">{{ pageData.weather.location }}</text>
class="codefun-flex-row codefun-items-center codefun-overflow-hidden text-wrapper_2"
style="width: 400rpx"
>
<up-notice-bar
v-if="pageData.weather.detailedLocation != '获取中'"
icon="false"
bgColor="#FFFFFF00"
color="#5db66f"
class="text_3"
:text="pageData.weather.detailedLocation"
scrollable
:speed="50"
style="width: 100%; height: auto"
></up-notice-bar>
<view v-else class="text_3">{{ pageData.weather.detailedLocation }}</view>
</view>
<image class="image_6 codefun-ml-6"
src="/static/images/codefun/a2f290fb1b65d093b844e73ddae1aed9.png" />
<!-- <image
class="image_6 codefun-ml-6"
src="/static/images/codefun/a2f290fb1b65d093b844e73ddae1aed9.png"
/> -->
</view>
<view class="codefun-flex-col codefun-justify-start codefun-items-start text-wrapper_2">
<text class="text_3">{{ pageData.weather.date }}</text>
......@@ -357,13 +478,15 @@ function handleVideoPlay(currentIndex) {
</view>
<view class="codefun-flex-row group_5">
<view class="codefun-flex-row codefun-items-center group_8">
<image class="codefun-shrink-0 image_8"
:src="`/static/images/weather/${pageData.weather.icon}.svg`" />
<image
class="codefun-shrink-0 image_8"
:src="`/static/images/weather/${pageData.weather.icon}.svg`"
/>
<view class="codefun-flex-col codefun-items-start codefun-flex-1 codefun-ml-10">
<text class="text_5">{{ pageData.weather.temperature }}</text>
<text class="font_2 text_8 !text-24rpx codefun-mt-16">{{
pageData.weather.condition
}}</text>
}}</text>
</view>
</view>
<view class="codefun-flex-col group_6 ml-2">
......@@ -378,58 +501,78 @@ function handleVideoPlay(currentIndex) {
src="/static/images/codefun/c785818f2c08b7682aa5188542b2dede.png"
/> -->
<image class="image_7" :src="`/static/images/weather/${forecast.icon}.svg`"
v-for="forecast in pageData.weather.forecast" :key="forecast.day" />
<image
class="image_7"
:src="`/static/images/weather/${forecast.icon}.svg`"
v-for="forecast in pageData.weather.forecast"
:key="forecast.day"
/>
</view>
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_9">
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_9">
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_9"
>
<text class="font_3 text_6">{{ pageData.weather.forecast[0].day }}</text>
</view>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3">
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_3"
>
<text class="font_3 text_52">{{ pageData.weather.forecast[1].day }}</text>
</view>
<text class="font_3 text_7">{{ pageData.weather.forecast[2].day }}</text>
</view>
<view class="codefun-flex-row codefun-justify-center">
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4">
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4"
>
<text class="font_4 text_9">{{ pageData.weather.forecast[0].temp }}</text>
</view>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_1 ml-17">
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_1 ml-17"
>
<text class="font_4 text_10">{{ pageData.weather.forecast[1].temp }}</text>
</view>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4 ml-17">
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4 ml-17"
>
<text class="font_4 text_9">{{ pageData.weather.forecast[2].temp }}</text>
</view>
</view>
</view>
</view>
<view class="codefun-flex-row section_4" v-if="pageData.weather.warning">
<image class="codefun-shrink-0 image_10"
src="/static/images/codefun/344155285176a7ac7ccd670a2a1daf19.png" />
<image
class="codefun-shrink-0 image_10"
src="/static/images/codefun/344155285176a7ac7ccd670a2a1daf19.png"
/>
<view
class="codefun-flex-col codefun-justify-start codefun-shrink-0 text-wrapper_5 codefun-ml-6">
class="codefun-flex-col codefun-justify-start codefun-shrink-0 text-wrapper_5 codefun-ml-6"
>
<text class="text_12">{{ pageData.weather.warning }}</text>
</view>
</view>
</view>
<view class="codefun-flex-col codefun-relative section_5">
<view class="codefun-flex-row">
<view v-show="item.status" v-for="item in pageData.menuItems" :key="item.id"
<view
v-show="item.status"
v-for="item in pageData.menuItems"
:key="item.id"
class="codefun-flex-col codefun-items-center group_10"
@click="onMenuItemClick(item)">
@click="onMenuItemClick(item)"
>
<image class="image_11" :src="item.icon_url" />
<text class="font_2 mt-11">{{ item.name }}</text>
</view>
</view>
<view class="codefun-flex-row codefun-mt-20">
<view v-show="item.status" v-for="item in pageData.serviceItems" :key="item.id"
<view
v-show="item.status"
v-for="item in pageData.serviceItems"
:key="item.id"
class="codefun-flex-col codefun-items-center group_10"
@click="onMenuItemClick(item)">
@click="onMenuItemClick(item)"
>
<image class="image_11" :src="item.icon_url" />
<text class="font_2 mt-11">{{ item.name }}</text>
</view>
......@@ -437,13 +580,17 @@ function handleVideoPlay(currentIndex) {
</view>
<view class="codefun-flex-row codefun-justify-between codefun-items-center section_6">
<view class="codefun-flex-col">
<view class="codefun-flex-row codefun-items-baseline">
<text class="font_5 text_17">{{ pageData.newsItems[0].type }}</text>
<text class="font_2 text_18 ml-11">{{ pageData.newsItems[0].title }}</text>
</view>
<view class="codefun-flex-row codefun-items-baseline">
<text class="font_5 text_19">{{ pageData.newsItems[1].type }}</text>
<text class="text-26 text_20 text_21 ml-11">{{ pageData.newsItems[1].date }}</text>
<view class="codefun-flex-row codefun-items-baseline" style="align-items: center">
<view class="font_5 text_17">{{ pageData.newsItems[0].type }}</view>
<view
class="codefun-flex-row"
style="flex-flow: column; justify-content: space-around; height: 90rpx"
>
<view class="font_2 text_18 ml-11">{{ pageData.newsItems[0].title }}</view>
<text class="text-26 text_20 text_21 ml-11">{{
pageData.newsItems[0].date
}}</text>
</view>
</view>
</view>
<image class="image_13" src="/static/images/codefun/64d85a99ca3de5fab9ce0e8dc71aa791.png" />
......@@ -456,32 +603,47 @@ function handleVideoPlay(currentIndex) {
<!-- <text class="font_7 text_22">{{ pageData.productMarket.updateTime }}</text> -->
</view>
<view class="codefun-flex-row equal-division section_8">
<view v-for="(product, index) in pageData.productMarket.products" :key="product.id"
class="codefun-flex-col group_13" :class="{
<view
v-for="(product, index) in pageData.productMarket.products"
:key="product.id"
class="codefun-flex-col group_13"
:class="{
group_17: index === 0,
group_39: index === 1,
group_21: index === 2,
}">
}"
>
<view
class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-center codefun-relative group_1">
class="codefun-flex-col codefun-justify-start codefun-items-start codefun-self-center codefun-relative group_1"
>
<text class="font_8 text_23">{{ product.name }}</text>
<text class="font_9 text_23" :class="`pos${index > 0 ? `_${index + 1}` : ''}`">{{
product.current_price
}}</text>
<text class="font_9 text_23" :class="`pos${index > 0 ? `_${index + 1}` : ''}`"
>¥{{ product.current_price }}</text
>
</view>
<view class="codefun-flex-row codefun-items-center codefun-self-stretch" :class="{
section_10: product.isUp,
section_11: !product.isUp,
}">
<image class="codefun-shrink-0 image_14" :src="product.isUp
? '/static/images/codefun/c6f953be58ac3e9752ab9475a2a53c14.png'
: '/static/images/codefun/c7e797cc626699dcc8999a72145e9f8b.png'
" />
<text class="font_10 ml-3" :class="{
text_25: product.isUp,
text_24: !product.isUp,
text_26: !product.isUp,
}">
<view
class="codefun-flex-row codefun-items-center codefun-self-stretch"
:class="{
section_10: product.isUp,
section_11: !product.isUp,
}"
>
<image
class="codefun-shrink-0 image_14"
:src="
product.isUp
? '/static/images/codefun/c6f953be58ac3e9752ab9475a2a53c14.png'
: '/static/images/codefun/c7e797cc626699dcc8999a72145e9f8b.png'
"
/>
<text
class="font_10 ml-3"
:class="{
text_25: product.isUp,
text_24: !product.isUp,
text_26: !product.isUp,
}"
>
{{ `${product.isUp ? '' : '-'}${product.percent}%` }}
</text>
</view>
......@@ -497,14 +659,20 @@ function handleVideoPlay(currentIndex) {
<!-- <text class="font_7 text_20 text_29">实时数据</text> -->
</view>
<view class="codefun-flex-row equal-division_2 group_16">
<view v-for="stat in pageData.serviceStats" :key="stat.id"
class="codefun-flex-col section_12 section_19">
<view
v-for="stat in pageData.serviceStats"
:key="stat.id"
class="codefun-flex-col section_12 section_19"
>
<view
class="codefun-flex-row codefun-justify-center codefun-items-center codefun-self-stretch codefun-relative group_27">
class="codefun-flex-row codefun-justify-center codefun-items-center codefun-self-stretch codefun-relative group_27"
>
<image class="image_5 mr-1" :class="`pos_${stat.id}`" :src="stat.icon" />
<text class="font_13"
:class="`text_${stat.id === 1 ? 30 : stat.id === 2 ? 1 : stat.id > 4 ? 46 : 37}`">{{
stat.name }}</text>
<text
class="font_13"
:class="`text_${stat.id === 1 ? 30 : stat.id === 2 ? 1 : stat.id > 4 ? 46 : 37}`"
>{{ stat.name }}</text
>
</view>
<view class="codefun-flex-row codefun-justify-center codefun-items-baseline mt-11 group_30">
<text class="font_12 text_37">{{ stat.num }}</text>
......@@ -517,26 +685,44 @@ function handleVideoPlay(currentIndex) {
<!-- <text class="font_7 text_33" @click="onViewMoreClass">查看全部</text> -->
</view>
<view class="codefun-flex-col section_13">
<fui-swiper-dot :items="pageData.agricultureClass.videoList" :current="pageData.current" :styles="{
height: 10,
activeWidth: 40,
background: '#dff0e2',
activeBackground: '#5db66f',
bottom: 10,
}">
<swiper class="fui-banner__wrap" circular :indicator-dots="false" autoplay :interval="4000"
:duration="150" @change="handleChangeVideo">
<fui-swiper-dot
:items="pageData.agricultureClass.videoList"
:current="pageData.current"
:styles="{
height: 10,
activeWidth: 40,
background: '#dff0e2',
activeBackground: '#5db66f',
bottom: 10,
}"
>
<swiper
class="fui-banner__wrap"
circular
:indicator-dots="false"
autoplay
:interval="4000"
:duration="150"
@change="handleChangeVideo"
>
<swiper-item v-for="(video, index) in pageData.agricultureClass.videoList" :key="index">
<video :id="`video${index}`" :src="video.media_video" :poster="video.cover_image"
:controls="false" style="width: 654rpx; height: 358rpx"
@loadedmetadata="handleMetadataLoaded" @play="handleVideoPlay(index)"></video>
<video
:id="`video${index}`"
:src="video.media_video"
:poster="video.cover_image"
:controls="false"
style="width: 654rpx; height: 358rpx"
@loadedmetadata="handleMetadataLoaded"
@play="handleVideoPlay(index)"
></video>
</swiper-item>
</swiper>
</fui-swiper-dot>
<view class="describe">
<text class="codefun-self-start font text_34">{{ pageData.agricultureClass.title }}</text>
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch mt-13">
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch mt-13"
>
<!-- <view class="codefun-flex-row codefun-items-center">
<image
class="codefun-shrink-0 image_15"
......@@ -554,882 +740,895 @@ function handleVideoPlay(currentIndex) {
</template>
<style scoped lang="scss">
.ml-17 {
margin-left: 34rpx;
}
.ml-43 {
margin-left: 86rpx;
}
.mt-13 {
margin-top: 26rpx;
}
.ml-11 {
margin-left: 22rpx;
}
.ml-3 {
margin-left: 6rpx;
}
.ml-19 {
margin-left: 38rpx;
}
.mt-11 {
margin-top: 22rpx;
}
.ml-5 {
margin-left: 10rpx;
}
.mt-3 {
margin-top: 6rpx;
}
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
padding-bottom: 20rpx;
.group {
.section {
padding: 48rpx 28rpx 220rpx;
background-image: url('/static/images/codefun/1086a098c06f7f52e77bd7a646747a13.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.group_2 {
padding-left: 16rpx;
.image {
border-radius: 64rpx;
width: 108rpx;
height: 42rpx;
}
.ml-17 {
margin-left: 34rpx;
}
.image_2 {
mix-blend-mode: NOTTHROUGH;
width: 34rpx;
height: 22rpx;
}
.ml-43 {
margin-left: 86rpx;
}
.image_3 {
mix-blend-mode: NOTTHROUGH;
width: 30rpx;
height: 22rpx;
}
.mt-13 {
margin-top: 26rpx;
}
.image_4 {
width: 48rpx;
height: 22rpx;
}
}
.ml-11 {
margin-left: 22rpx;
}
.text {
margin-left: 5.3rpx;
margin-top: 37.62rpx;
color: #ffffffe6;
font-size: 36rpx;
line-height: 33.58rpx;
letter-spacing: 4.32rpx;
font-family: meixin;
}
.ml-3 {
margin-left: 6rpx;
}
.section_2 {
margin-top: 25.8rpx;
padding: 14rpx 18rpx 16rpx;
background-color: #ffffff4d;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
border: solid 1rpx #ffffff7d;
.ml-19 {
margin-left: 38rpx;
}
.text_2 {
line-height: 25.5rpx;
}
}
}
.mt-11 {
margin-top: 22rpx;
}
.group_3 {
margin-top: -188rpx;
padding-left: 28rpx;
.ml-5 {
margin-left: 10rpx;
}
.group_4 {
.mt-3 {
margin-top: 6rpx;
}
// height: 864rpx;
.section_3 {
margin-right: 28rpx;
padding: 20rpx 28rpx 58rpx;
background-image: linear-gradient(180deg, #dcfce7 0%, #f8fef9 100%);
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.page {
background-color: #e6f5e8;
mix-blend-mode: NOTTHROUGH;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
padding-bottom: 20rpx;
.group {
.section {
padding: 48rpx 28rpx 220rpx;
background-image: url('/static/images/codefun/1086a098c06f7f52e77bd7a646747a13.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.group_2 {
padding-left: 16rpx;
.image {
border-radius: 64rpx;
width: 108rpx;
height: 42rpx;
}
.text-wrapper {
padding: 7.6rpx 0 6.76rpx;
overflow: hidden;
width: 56rpx;
height: 40rpx;
.image_2 {
mix-blend-mode: NOTTHROUGH;
width: 34rpx;
height: 22rpx;
}
.text_4 {
color: #5db66f;
line-height: 25.64rpx;
}
.image_3 {
mix-blend-mode: NOTTHROUGH;
width: 30rpx;
height: 22rpx;
}
.image_6 {
width: 16rpx;
height: 10rpx;
.image_4 {
width: 48rpx;
height: 22rpx;
}
}
.text-wrapper_2 {
overflow: hidden;
width: 140rpx;
height: 40rpx;
.text {
margin-left: 5.3rpx;
margin-top: 37.62rpx;
color: #ffffffe6;
font-size: 36rpx;
line-height: 33.58rpx;
letter-spacing: 4.32rpx;
font-family: meixin;
}
.text_3 {
margin-left: 9.28rpx;
color: #5db66f;
font-size: 24rpx;
line-height: 40rpx;
width: 164rpx;
}
.section_2 {
margin-top: 25.8rpx;
padding: 14rpx 18rpx 16rpx;
background-color: #ffffff4d;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
border: solid 1rpx #ffffff7d;
.text_2 {
line-height: 25.5rpx;
}
}
}
.group_5 {
margin-top: 16rpx;
.group_3 {
margin-top: -188rpx;
padding-left: 28rpx;
.group_4 {
// height: 864rpx;
.section_3 {
width: 694rpx;
// margin-right: 28rpx;
padding: 20rpx 28rpx 58rpx;
background-image: linear-gradient(180deg, #dcfce7 0%, #f8fef9 100%);
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.group_8 {
margin: 4rpx 0;
flex: 1 1 300.68rpx;
.text-wrapper {
padding: 7.6rpx 0 6.76rpx;
overflow: hidden;
width: 56rpx;
height: 40rpx;
.image_8 {
mix-blend-mode: NOTTHROUGH;
width: 112rpx;
height: 112rpx;
.text_4 {
color: #5db66f;
line-height: 25.64rpx;
}
}
.text_5 {
color: #06280b;
font-size: 48rpx;
line-height: 34.28rpx;
}
.image_6 {
width: 16rpx;
height: 10rpx;
}
.text_8 {
color: #555555;
line-height: 26.88rpx;
.text-wrapper_2 {
overflow: hidden;
// width: 140rpx;
// height: 40rpx;
.text_3 {
margin-left: 9.28rpx;
color: #5db66f;
font-size: 28rpx;
}
}
.group_6 {
flex: 1 1 300.68rpx;
.group_5 {
margin-top: 16rpx;
.group_8 {
margin: 4rpx 0;
flex: 1 1 300.68rpx;
.group_7 {
padding: 0 8rpx;
.image_8 {
mix-blend-mode: NOTTHROUGH;
width: 112rpx;
height: 112rpx;
}
.image_9 {
margin-top: 4rpx;
width: 54rpx;
height: 42rpx;
.text_5 {
color: #06280b;
font-size: 48rpx;
line-height: 34.28rpx;
}
.image_7 {
margin-right: 4rpx;
margin-bottom: 4rpx;
width: 56rpx;
height: 42rpx;
.text_8 {
color: #555555;
line-height: 26.88rpx;
}
}
.group_9 {
margin-top: 10rpx;
padding: 0 12rpx;
.group_6 {
flex: 1 1 300.68rpx;
.text-wrapper_9 {
padding: 6.8rpx 0 4.6rpx;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.group_7 {
padding: 0 8rpx;
.image_9 {
margin-top: 4rpx;
width: 54rpx;
height: 42rpx;
}
.text_6 {
line-height: 20.6rpx;
.image_7 {
margin-right: 4rpx;
margin-bottom: 4rpx;
width: 56rpx;
height: 42rpx;
}
}
.text-wrapper_3 {
padding: 6.54rpx 0 4.92rpx;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.group_9 {
margin-top: 10rpx;
padding: 0 12rpx;
.text-wrapper_9 {
padding: 6.8rpx 0 4.6rpx;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.text_6 {
line-height: 20.6rpx;
}
}
.text-wrapper_3 {
padding: 6.54rpx 0 4.92rpx;
overflow: hidden;
width: 48rpx;
height: 32rpx;
.text_52 {
.text_52 {
line-height: 20.54rpx;
}
}
.font_3 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #6b7280;
}
.text_7 {
margin-right: 9rpx;
line-height: 20.54rpx;
}
}
.font_3 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #6b7280;
.text-wrapper_4 {
padding: 7.84rpx 0 7.02rpx;
overflow: hidden;
width: 76rpx;
height: 32rpx;
.text_9 {
line-height: 17.14rpx;
}
}
.text_7 {
margin-right: 9rpx;
line-height: 20.54rpx;
.text-wrapper_1 {
padding: 7.84rpx 0 6.98rpx;
overflow: hidden;
width: 76rpx;
height: 32rpx;
.text_10 {
line-height: 17.18rpx;
}
}
}
}
.text-wrapper_4 {
padding: 7.84rpx 0 7.02rpx;
overflow: hidden;
width: 76rpx;
height: 32rpx;
.section_4 {
margin-top: 30rpx;
padding: 10rpx 20rpx;
background-color: #fb81461f;
border-radius: 12rpx;
mix-blend-mode: NOTTHROUGH;
.text_9 {
line-height: 17.14rpx;
}
.image_10 {
width: 40rpx;
height: 40rpx;
}
.text-wrapper_1 {
padding: 7.84rpx 0 6.98rpx;
overflow: hidden;
width: 76rpx;
height: 32rpx;
.text-wrapper_5 {
margin-right: 180rpx;
width: 90%;
height: 40rpx;
.text_10 {
line-height: 17.18rpx;
.text_12 {
margin-left: 2.3rpx;
margin-right: 13.7rpx;
font-size: 28rpx;
line-height: 40rpx;
overflow: hidden;
text-overflow: ellipsis;
/* 超出以 ...显示 */
display: -webkit-box;
-webkit-line-clamp: 1;
/* // 显示1行 */
-webkit-box-orient: vertical;
color: #ff612c;
}
}
}
}
.section_4 {
margin-top: 30rpx;
padding: 10rpx 20rpx;
background-color: #fb81461f;
border-radius: 12rpx;
.section_5 {
margin-right: 28rpx;
margin-top: -34rpx;
padding: 30rpx 0 40.76rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.image_10 {
width: 40rpx;
height: 40rpx;
.image_11 {
border-radius: 88rpx;
width: 96rpx;
height: 96rpx;
}
.text-wrapper_5 {
margin-right: 180rpx;
width: 90%;
height: 40rpx;
.group_10 {
flex: 1 1 173.5rpx;
.text_12 {
margin-left: 2.3rpx;
margin-right: 13.7rpx;
font-size: 28rpx;
line-height: 40rpx;
overflow: hidden;
text-overflow: ellipsis;
/* 超出以 ...显示 */
display: -webkit-box;
-webkit-line-clamp: 1;
/* // 显示1行 */
-webkit-box-orient: vertical;
color: #ff612c;
.text_50 {
line-height: 25.76rpx;
}
}
}
}
.section_5 {
margin-right: 28rpx;
margin-top: -34rpx;
padding: 30rpx 0 40.76rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.image_11 {
border-radius: 88rpx;
width: 96rpx;
height: 96rpx;
}
.group_10 {
flex: 1 1 173.5rpx;
.text_13 {
line-height: 24.58rpx;
}
.text_50 {
line-height: 25.76rpx;
.text_51 {
line-height: 25.78rpx;
}
}
.text_13 {
line-height: 24.58rpx;
.group_43 {
padding-bottom: 10rpx;
}
.text_51 {
line-height: 25.78rpx;
.group_42 {
padding-bottom: 10rpx;
}
}
.group_43 {
padding-bottom: 10rpx;
}
.group_42 {
padding-bottom: 10rpx;
}
.group_37 {
padding-bottom: 10.06rpx;
}
.group_37 {
padding-bottom: 10.06rpx;
}
.group_40 {
padding-bottom: 10.06rpx;
}
.group_40 {
padding-bottom: 10.06rpx;
}
.group_11 {
padding-left: 31.3rpx;
padding-right: 25.86rpx;
.group_11 {
padding-left: 31.3rpx;
padding-right: 25.86rpx;
.group_38 {
padding: 0 9.7rpx;
.group_38 {
padding: 0 9.7rpx;
.image_12 {
border-radius: 88rpx;
mix-blend-mode: NOTTHROUGH;
width: 88rpx;
height: 88rpx;
.image_12 {
border-radius: 88rpx;
mix-blend-mode: NOTTHROUGH;
width: 88rpx;
height: 88rpx;
}
}
}
.text_14 {
line-height: 25.62rpx;
}
.text_14 {
line-height: 25.62rpx;
}
.text_15 {
line-height: 25.76rpx;
}
.text_15 {
line-height: 25.76rpx;
}
.text_16 {
line-height: 25.78rpx;
.text_16 {
line-height: 25.78rpx;
}
}
}
}
.font_2 {
font-size: 28rpx;
line-height: 25.7rpx;
color: #1d2129;
}
.section_6 {
margin-right: 28rpx;
margin-top: 24rpx;
padding: 18rpx 18rpx 12.32rpx 22.78rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.font_5 {
.font_2 {
font-size: 28rpx;
line-height: 44rpx;
color: #5db66f;
line-height: 25.7rpx;
color: #1d2129;
}
.text_17 {
font-size: 30rpx;
font-family: alimamashuheiti;
}
.section_6 {
margin-right: 28rpx;
margin-top: 24rpx;
padding: 18rpx 18rpx 12.32rpx 22.78rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.text_18 {
color: #000000;
line-height: 26.16rpx;
}
.font_5 {
font-size: 28rpx;
line-height: 44rpx;
color: #5db66f;
}
.text_19 {
font-size: 30rpx;
font-family: alimamashuheiti;
}
.text_17 {
width: 80rpx;
font-size: 30rpx;
font-family: alimamashuheiti;
word-break: break-all;
white-space: normal;
line-height: 1.2;
display: block;
text-align: center;
}
.text_21 {
line-height: 17.18rpx;
}
.text_18 {
color: #000000;
line-height: 26.16rpx;
}
.text_19 {
font-size: 30rpx;
font-family: alimamashuheiti;
}
.text_21 {
line-height: 17.18rpx;
}
}
.image_13 {
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
width: 32rpx;
height: 32rpx;
}
.codefun-mr-4 {
margin-right: 10rpx;
}
.font_4 {
font-size: 20rpx;
line-height: 18.3rpx;
color: #000000;
}
}
.font_4 {
font-size: 20rpx;
line-height: 18.3rpx;
color: #000000;
.section_7 {
margin-right: 8rpx;
background-color: #00000000;
width: 24rpx;
height: 24rpx;
}
}
.section_7 {
margin-right: 8rpx;
background-color: #00000000;
width: 24rpx;
height: 24rpx;
}
.group_12 {
margin-top: 17.72rpx;
.group_12 {
margin-top: 17.72rpx;
.text_22 {
margin-right: 30.72rpx;
color: #33333399;
line-height: 22.16rpx;
.text_22 {
margin-right: 30.72rpx;
color: #33333399;
line-height: 22.16rpx;
}
}
}
.equal-division {
margin-right: 28rpx;
margin-top: 32.72rpx;
.equal-division {
margin-right: 28rpx;
margin-top: 32.72rpx;
.group_13 {
flex: 0 0 33.33%;
text-align: center;
.group_13 {
flex: 0 0 33.33%;
text-align: center;
.group_41 {
padding: 10rpx 0 4.92rpx;
width: 106rpx;
}
.group_41 {
padding: 10rpx 0 4.92rpx;
width: 106rpx;
}
.section_10 {
margin: 24rpx 0 0 0;
padding: 0 14rpx;
background-color: #da14141a;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
}
.section_10 {
margin: 24rpx 0 0 0;
padding: 0 14rpx;
background-color: #da14141a;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
}
.text-wrapper_6 {
margin-top: 40rpx;
padding: 17.3rpx 0 16.66rpx;
background-color: #5db66f29;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.text-wrapper_6 {
margin-top: 40rpx;
padding: 17.3rpx 0 16.66rpx;
background-color: #5db66f29;
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.font_11 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #16a34a;
}
}
.font_11 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #16a34a;
.group_20 {
padding: 10rpx 0 4.92rpx;
width: 100rpx;
}
}
.group_20 {
padding: 10rpx 0 4.92rpx;
width: 100rpx;
}
.font_8 {
font-size: 28rpx;
line-height: 72rpx;
color: #333333;
}
.font_8 {
font-size: 28rpx;
line-height: 72rpx;
color: #333333;
}
.text_23 {
width: 100%;
}
.text_23 {
width: 100%;
}
.font_9 {
font-size: 36rpx;
line-height: 25.7rpx;
color: #f26464;
}
.font_9 {
font-size: 36rpx;
line-height: 25.7rpx;
color: #f26464;
}
.group_1 {
padding: 10rpx 0 4.92rpx;
// width: 106rpx;
.text_24 {
color: #5db66f;
}
}
.group_1 {
padding: 10rpx 0 4.92rpx;
.section_11 {
margin: 24rpx 0 0 0;
padding: 0 14rpx;
background-color: rgba(93, 182, 111, 0.2);
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
// width: 106rpx;
.text_24 {
color: #5db66f;
.text_26 {
color: #5db66f;
padding-left: 10rpx;
}
}
}
.section_11 {
margin: 24rpx 0 0 0;
padding: 0 14rpx;
background-color: rgba(93, 182, 111, 0.2);
border-radius: 1998rpx;
mix-blend-mode: NOTTHROUGH;
.image_14 {
mix-blend-mode: NOTTHROUGH;
width: 28rpx;
height: 16rpx;
margin: 0 8rpx;
}
.text_26 {
color: #5db66f;
padding-left: 10rpx;
.font_10 {
font-size: 24rpx;
line-height: 56rpx;
color: #f44336;
}
}
.image_14 {
mix-blend-mode: NOTTHROUGH;
width: 28rpx;
height: 16rpx;
margin: 0 8rpx;
.group_17 {
padding: 0 31.34rpx 12rpx 32rpx;
}
.font_10 {
font-size: 20rpx;
line-height: 56rpx;
color: #f44336;
.section_9 {
flex-shrink: 0;
margin: 10.62rpx 0 10rpx;
}
}
.group_17 {
padding: 0 31.34rpx 12rpx 32rpx;
}
.section_9 {
flex-shrink: 0;
margin: 10.62rpx 0 10rpx;
}
.horiz-divider {
background-color: #fafafa;
width: 2rpx;
height: 288rpx;
}
.horiz-divider {
background-color: #fafafa;
width: 2rpx;
height: 288rpx;
}
.group_39 {
padding: 0 30.66rpx 12rpx 32.66rpx;
}
.group_39 {
padding: 0 30.66rpx 12rpx 32.66rpx;
.group_21 {
padding: 0 30rpx 12rpx 33.34rpx;
}
}
.group_21 {
padding: 0 30rpx 12rpx 33.34rpx;
.section_8 {
padding: 15.38rpx 0 12rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
overflow: scroll;
}
}
.section_8 {
padding: 15.38rpx 0 12rpx;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
overflow: scroll;
}
.group_15 {
margin-top: 41.54rpx;
.group_15 {
margin-top: 41.54rpx;
.text_28 {
line-height: 29.56rpx;
}
.text_28 {
line-height: 29.56rpx;
.text_29 {
margin-right: 24.44rpx;
}
}
.text_29 {
margin-right: 24.44rpx;
.font_7 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #000000;
}
}
.font_7 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #000000;
}
.text_20 {
opacity: 0.6;
}
.text_20 {
opacity: 0.6;
}
.equal-division_2 {
margin-top: 32.9rpx;
.equal-division_2 {
margin-top: 32.9rpx;
.section_12 {
flex: 0 0 calc(33.33% - 14rpx);
.section_12 {
flex: 0 0 calc(33.33% - 14rpx);
.group_25 {
padding: 5.24rpx 0 4.8rpx;
.group_25 {
padding: 5.24rpx 0 4.8rpx;
.pos_4 {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.pos_4 {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
.text_30 {
line-height: 21.96rpx;
}
}
.text_30 {
line-height: 21.96rpx;
}
}
.group_28 {
margin-left: 5.82rpx;
line-height: 26.88rpx;
.group_28 {
margin-left: 5.82rpx;
line-height: 26.88rpx;
.text_47 {
line-height: 26.88rpx;
}
.text_47 {
line-height: 26.88rpx;
.text_49 {
line-height: 21.62rpx;
}
}
.text_49 {
line-height: 21.62rpx;
}
}
.group_26 {
padding: 5.2rpx 0 4.72rpx;
.group_26 {
padding: 5.2rpx 0 4.72rpx;
.pos_5 {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.pos_5 {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
.text_1 {
line-height: 22.08rpx;
}
}
.text_1 {
line-height: 22.08rpx;
.font_13 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #666666;
}
}
.font_13 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #666666;
}
.group_18 {
margin-left: 5.24rpx;
line-height: 22.84rpx;
.text_48 {
.group_18 {
margin-left: 5.24rpx;
line-height: 22.84rpx;
.text_48 {
line-height: 22.84rpx;
}
}
}
.group_27 {
padding: 5.3rpx 0 4.52rpx;
.group_27 {
padding: 5.3rpx 0 4.52rpx;
.text_46 {
line-height: 22.18rpx;
.text_46 {
line-height: 22.18rpx;
}
}
}
.group_30 {
margin-left: 7.24rpx;
line-height: 22.84rpx;
.text_37 {
.group_30 {
margin-left: 7.24rpx;
line-height: 22.84rpx;
}
.text_31 {
line-height: 21.46rpx;
.text_37 {
line-height: 22.84rpx;
}
.text_31 {
line-height: 21.46rpx;
}
}
}
}
.section_18 {
padding: 32rpx 20rpx 38rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
}
.section_18 {
padding: 32rpx 20rpx 38rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
}
.section_1 {
padding: 32rpx 22rpx 39.98rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
.section_1 {
padding: 32rpx 22rpx 39.98rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
}
.section_19 {
padding: 32rpx 20rpx 40.4rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
}
}
.section_19 {
padding: 32rpx 20rpx 40.4rpx;
background-color: #ffffff;
border-radius: 8rpx;
mix-blend-mode: NOTTHROUGH;
height: 150rpx;
.group_16 {
flex-wrap: wrap;
gap: 20rpx;
justify-content: center;
align-items: center;
margin-right: 10px;
}
}
.group_16 {
flex-wrap: wrap;
gap: 20rpx;
justify-content: center;
align-items: center;
margin-right: 10px;
}
.font_12 {
font-size: 32rpx;
line-height: 22.04rpx;
color: #000000;
}
.font_12 {
font-size: 32rpx;
line-height: 22.04rpx;
color: #000000;
}
.group_19 {
margin-top: 38rpx;
.group_19 {
margin-top: 38rpx;
.text_32 {
line-height: 29.48rpx;
}
.text_32 {
line-height: 29.48rpx;
.text_33 {
margin-right: 25.48rpx;
color: #5db66f;
line-height: 21.86rpx;
}
}
.text_33 {
margin-right: 25.48rpx;
color: #5db66f;
line-height: 21.86rpx;
.font_6 {
font-size: 32rpx;
line-height: 29.56rpx;
color: #333333;
}
}
.font_6 {
font-size: 32rpx;
line-height: 29.56rpx;
color: #333333;
}
.section_13 {
position: relative;
margin-right: 28rpx;
margin-top: 32.86rpx;
height: 418rpx;
// padding: 271.06rpx 36.64rpx 22rpx 48rpx;
padding: 20rpx;
padding-bottom: 0;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
.section_13 {
position: relative;
margin-right: 28rpx;
margin-top: 32.86rpx;
height: 418rpx;
// padding: 271.06rpx 36.64rpx 22rpx 48rpx;
padding: 20rpx;
padding-bottom: 0;
background-color: #ffffff;
border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH;
// background-image: url('/static/images/codefun/de7f2f0177d74c2b9c784b3825ea9832.png');
// background-size: 94%;
// background-repeat: no-repeat;
// background-position-x: 20rpx;
// background-position-y: 20rpx;
.fui-banner__item {
height: 358rpx;
border-radius: 20rpx;
}
// background-image: url('/static/images/codefun/de7f2f0177d74c2b9c784b3825ea9832.png');
// background-size: 94%;
// background-repeat: no-repeat;
// background-position-x: 20rpx;
// background-position-y: 20rpx;
.fui-banner__item {
height: 358rpx;
border-radius: 20rpx;
}
.fui-banner__wrap {
height: 358rpx;
.fui-banner__wrap {
height: 358rpx;
:deep(.uni-video-cover) {
.uni-video-cover-play-button {
width: 70rpx;
height: 70rpx;
line-height: 40rpx;
font-size: 56rpx;
:deep(.uni-video-cover) {
.uni-video-cover-play-button {
width: 70rpx;
height: 70rpx;
line-height: 40rpx;
font-size: 56rpx;
}
}
}
}
.describe {
width: 88%;
position: absolute;
bottom: 52rpx;
left: 40rpx;
}
.text_34 {
line-height: 26.58rpx;
}
.describe {
width: 88%;
position: absolute;
bottom: 52rpx;
left: 40rpx;
}
.image_15 {
mix-blend-mode: NOTTHROUGH;
border-radius: 50%;
width: 48rpx;
height: 48rpx;
}
.text_34 {
line-height: 26.58rpx;
}
.font_14 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #ffffff;
}
.image_15 {
mix-blend-mode: NOTTHROUGH;
border-radius: 50%;
width: 48rpx;
height: 48rpx;
}
.text_35 {
line-height: 21.76rpx;
}
.font_14 {
font-size: 24rpx;
line-height: 22.04rpx;
color: #ffffff;
}
.text_36 {
line-height: 23.04rpx;
}
.text_35 {
line-height: 21.76rpx;
}
.section_14 {
background-color: #5db66f;
border-radius: 12rpx;
mix-blend-mode: NOTTHROUGH;
width: 40rpx;
height: 12rpx;
}
.text_36 {
line-height: 23.04rpx;
}
.image-wrapper {
width: 40rpx;
.section_14 {
background-color: #5db66f;
border-radius: 12rpx;
mix-blend-mode: NOTTHROUGH;
width: 40rpx;
height: 12rpx;
}
.image_16 {
.image-wrapper {
width: 40rpx;
.image_16 {
width: 40rpx;
height: 12rpx;
}
}
.section_15 {
background-color: #5db66f33;
mix-blend-mode: NOTTHROUGH;
border-radius: 50%;
width: 12rpx;
height: 12rpx;
}
}
}
.section_15 {
background-color: #5db66f33;
mix-blend-mode: NOTTHROUGH;
border-radius: 50%;
width: 12rpx;
height: 12rpx;
}
.font {
font-size: 28rpx;
line-height: 25.7rpx;
color: #ffffff;
}
}
.font {
font-size: 28rpx;
line-height: 25.7rpx;
color: #ffffff;
}
}
.equal-division_3 {
padding: 10rpx 7.98rpx 15.66rpx 7.98rpx;
background-color: #ffffff;
mix-blend-mode: NOTTHROUGH;
border-top: solid 1rpx #e7e7e7;
.equal-division_3 {
padding: 10rpx 7.98rpx 15.66rpx 7.98rpx;
background-color: #ffffff;
mix-blend-mode: NOTTHROUGH;
border-top: solid 1rpx #e7e7e7;
.group_22 {
flex: 1 1 146.82rpx;
.group_22 {
flex: 1 1 146.82rpx;
.font_15 {
font-size: 20rpx;
line-height: 18.3rpx;
color: #666666;
}
.font_15 {
font-size: 20rpx;
line-height: 18.3rpx;
color: #666666;
}
.text_44 {
line-height: 18.4rpx;
}
.text_44 {
line-height: 18.4rpx;
.text_45 {
line-height: 18.48rpx;
}
}
.text_45 {
line-height: 18.48rpx;
.group_32 {
padding: 12rpx 0 11.68rpx;
}
}
.group_32 {
padding: 12rpx 0 11.68rpx;
}
.group_33 {
padding: 12rpx 0 10rpx;
}
.group_33 {
padding: 12rpx 0 10rpx;
}
.group_34 {
padding: 12rpx 0 11.48rpx;
}
.group_34 {
padding: 12rpx 0 11.48rpx;
}
.group_35 {
padding: 12rpx 0 11.38rpx;
}
.group_35 {
padding: 12rpx 0 11.38rpx;
.group_36 {
padding: 12rpx 0 11.84rpx;
}
}
.group_36 {
padding: 12rpx 0 11.84rpx;
.image_5 {
width: 32rpx;
height: 32rpx;
}
}
.image_5 {
width: 32rpx;
height: 32rpx;
.u-notice-bar {
padding: unset !important;
font-size: 28rpx !important;
}
:v-deep .u-notice-bar {
padding: unset !important;
font-size: 28rpx;
}
}
</style>
......@@ -248,118 +248,21 @@ function onResourceClick(resource: any) {
}
// 资源下载点击事件
function onDownloadClick(e, resource: any) {
async function onDownloadClick(e, resource: any) {
// 阻止事件冒泡
e?.stopPropagation()
// 显示加载提示
uni.showLoading({
title: '下载中...',
mask: true,
})
// 判断是否为H5平台
/* #ifdef H5 */
downloadFileForWeb(resource)
/* #endif */
/* #ifndef H5 */
downloadFileForNative(resource)
/* #endif */
const { downloadResource } = await import('@/utils')
// 使用封装的下载方法
const result = await downloadResource(resource)
if (!result.success) {
console.error('下载失败:', result.error)
}
}
// H5平台下载文件函数
function downloadFileForWeb(resource: any) {
const url = resource.fileSrc
// 创建一个临时的a标签用于下载
const link = document.createElement('a')
link.href = url
link.download = resource.fileName || 'download' // 设置下载文件名
link.style.display = 'none'
// 添加到文档并触发点击
document.body.appendChild(link)
link.click()
// 清理
document.body.removeChild(link)
uni.hideLoading()
uni.showToast({
title: '开始下载',
icon: 'success',
duration: 1500
})
}
// 原生平台下载文件函数
function downloadFileForNative(resource: any) {
uni.downloadFile({
url: resource.fileSrc,
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
uni.hideLoading()
uni.showToast({
title: '下载成功',
icon: 'success',
duration: 1500
})
// 提示用户文件已保存
uni.showModal({
title: '下载完成',
content: `文件已保存至: ${saveRes.savedFilePath}\n是否立即打开?`,
success: (modalRes) => {
if (modalRes.confirm) {
uni.openDocument({
filePath: saveRes.savedFilePath,
fileType: resource.fileType?.toString() || '',
showMenu: true,
fail: () => {
uni.showToast({
title: '无法打开文件',
icon: 'error',
duration: 1500
})
},
})
}
},
})
},
fail: (err) => {
uni.hideLoading()
console.error('保存文件失败:', err)
uni.showToast({
title: '保存文件失败',
icon: 'error',
duration: 1500
})
},
})
} else {
uni.hideLoading()
uni.showToast({
title: `下载失败,状态码: ${res.statusCode}`,
icon: 'error',
duration: 1500
})
}
},
fail: (err) => {
uni.hideLoading()
console.error('下载失败:', err)
uni.showToast({
title: '网络错误,下载失败',
icon: 'error',
duration: 1500
})
},
})
}
// 查看所有资源
function onViewAllResources() {
......
/**
* 下载工具类
* 提供跨平台的文件下载功能,支持H5和原生平台
*/
/**
* 文件下载选项接口
*/
export interface DownloadOptions {
/** 文件下载URL */
url: string
/** 文件名 */
fileName?: string
/** 文件类型 */
fileType?: string
/** 文件大小 */
fileSize?: string
/** 是否显示下载进度 */
showProgress?: boolean
}
/**
* 下载结果接口
*/
export interface DownloadResult {
/** 是否成功 */
success: boolean
/** 错误信息 */
error?: string
/** 文件保存路径(仅原生平台) */
savedFilePath?: string
}
/**
* H5平台下载文件
* @param options 下载选项
* @returns Promise<DownloadResult>
*/
export function downloadFileForWeb(options: DownloadOptions): Promise<DownloadResult> {
return new Promise((resolve) => {
const { url, fileName = 'download' } = options
try {
// 检查是否在浏览器环境
if (typeof document === 'undefined') {
resolve({
success: false,
error: 'H5下载功能仅支持浏览器环境',
})
return
}
// 创建一个临时的a标签用于下载
const link = document.createElement('a')
link.href = url
link.download = fileName
link.style.display = 'none'
// 添加到文档并触发点击
document.body.appendChild(link)
link.click()
// 清理
document.body.removeChild(link)
// 显示下载成功提示
uni.showToast({
title: '开始下载',
icon: 'success',
duration: 1500,
})
resolve({
success: true,
})
} catch (error) {
console.error('H5下载失败:', error)
resolve({
success: false,
error: 'H5下载失败',
})
}
})
}
/**
* 原生平台下载文件
* @param options 下载选项
* @returns Promise<DownloadResult>
*/
export function downloadFileForNative(options: DownloadOptions): Promise<DownloadResult> {
return new Promise((resolve) => {
const { url, fileName = 'download', fileType = '', showProgress = true } = options
if (showProgress) {
// 显示加载提示
uni.showLoading({
title: '下载中...',
mask: true,
})
}
uni.downloadFile({
url,
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
if (showProgress) {
uni.hideLoading()
uni.showToast({
title: '下载成功',
icon: 'success',
duration: 1500,
})
}
// 提示用户文件已保存
uni.showModal({
title: '下载完成',
content: `文件已保存至: ${saveRes.savedFilePath}\n是否立即打开?`,
success: (modalRes) => {
if (modalRes.confirm) {
uni.openDocument({
filePath: saveRes.savedFilePath,
fileType: fileType?.toString() || '',
showMenu: true,
fail: () => {
uni.showToast({
title: '无法打开文件',
icon: 'none',
duration: 1500,
})
},
})
}
},
})
resolve({
success: true,
savedFilePath: saveRes.savedFilePath,
})
},
fail: (err) => {
if (showProgress) {
uni.hideLoading()
console.error('保存文件失败:', err)
uni.showToast({
title: '保存文件失败',
icon: 'none',
duration: 1500,
})
}
resolve({
success: false,
error: '保存文件失败',
})
},
})
} else {
if (showProgress) {
uni.hideLoading()
uni.showToast({
title: `下载失败,状态码: ${res.statusCode}`,
icon: 'none',
duration: 1500,
})
}
resolve({
success: false,
error: `下载失败,状态码: ${res.statusCode}`,
})
}
},
fail: (err) => {
if (showProgress) {
uni.hideLoading()
console.error('下载失败:', err)
uni.showToast({
title: '网络错误,下载失败',
icon: 'none',
duration: 1500,
})
}
resolve({
success: false,
error: '网络错误,下载失败',
})
},
})
})
}
/**
* 通用下载文件方法
* 自动判断平台并调用相应的下载方法
* @param options 下载选项
* @returns Promise<DownloadResult>
*/
export function downloadFile(options: DownloadOptions): Promise<DownloadResult> {
// 判断是否为H5平台
/* #ifdef H5 */
return downloadFileForWeb(options)
/* #endif */
// 其他平台使用原生下载
/* #ifndef H5*/
return downloadFileForNative(options)
/* #endif */
}
/**
* 便捷下载方法,支持资源对象
* @param resource 资源对象,包含 fileSrc、fileName、fileType 等属性
* @returns Promise<DownloadResult>
*/
export function downloadResource(resource: any): Promise<DownloadResult> {
const options: DownloadOptions = {
url: resource.fileSrc,
fileName: resource.fileName || 'download',
fileType: resource.fileType || '',
fileSize: resource.fileSize || '',
showProgress: true,
}
return downloadFile(options)
}
/**
* 检查下载链接是否有效
* @param url 下载链接
* @returns Promise<boolean>
*/
export function checkDownloadUrl(url: string): Promise<boolean> {
return new Promise((resolve) => {
// 在原生平台检查链接有效性
/* #ifndef H5 */
uni.request({
url,
method: 'HEAD',
success: (res) => {
resolve(res.statusCode === 200)
},
fail: () => {
resolve(false)
},
})
/* #endif */
// 在H5平台,直接返回true(浏览器会处理链接有效性)
/* #ifdef H5 */
resolve(true)
/* #endif */
})
}
......@@ -3,6 +3,8 @@ import type { App, Plugin } from 'vue'
import { unref } from 'vue'
import { isObject } from '/@/utils/is'
export * from './download'
export function noop() {}
/**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论