308 lines
8.5 KiB
Vue
308 lines
8.5 KiB
Vue
<template>
|
||
<view>
|
||
<view class="search-wrap uni-flex uni-row">
|
||
<view class="flex-item input-wrap">
|
||
<input class="uni-input" maxlength="50" :placeholder="$lang('files.list.searchPlaceholder')" v-model="keyword" @confirm="search"
|
||
@input="__set_model($event, 'keyword')" />
|
||
<text class="iconfont icon-sousuo3" @tap="search"></text>
|
||
</view>
|
||
</view>
|
||
<mescroll-uni ref="mescroll" top="100" @getData="getData" :style="tabBarPagePaddingStyle">
|
||
<view slot="list">
|
||
<block v-if="list.length > 0">
|
||
<view class="article-wrap">
|
||
<ns-adv keyword="NS_ARTICLE" class-name="adv-wrap"></ns-adv>
|
||
<block v-for="(item, index) in list" :key="index">
|
||
<view class="item" @tap="toDetail(item.$orig)">
|
||
<view class="article-img">
|
||
<image class="cover-img" :src="item.g1" mode="widthFix" @error="imgError(index)" show-menu-by-longpress></image>
|
||
</view>
|
||
<view class="info-wrap">
|
||
<view class="title">{{ item.$orig.files_title }}</view>
|
||
<view class="read-wrap">
|
||
<text>{{ $lang('files.list.viewPdf') }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</block>
|
||
<block v-else>
|
||
<view class="empty-wrap">
|
||
<ns-empty :text="$lang('files.list.emptyText')" :isIndex="false"></ns-empty>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
</mescroll-uni>
|
||
<loading-cover ref="loadingCover"></loading-cover>
|
||
<privacy-popup ref="privacyPopup"></privacy-popup>
|
||
|
||
<!-- 底部tabBar -->
|
||
<view id="tab-bar">
|
||
<diy-bottom-nav></diy-bottom-nav>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
category_id: '',
|
||
list: [],
|
||
title: '',
|
||
keyword: ''
|
||
}
|
||
},
|
||
onLoad(options) {
|
||
if (options.category_id > 0) {
|
||
this.category_id = options.category_id
|
||
}
|
||
},
|
||
onShow() {
|
||
},
|
||
methods: {
|
||
__set_model(event, field) {
|
||
this[field] = event.detail.value
|
||
},
|
||
search() {
|
||
this.list = []
|
||
this.$refs.mescroll.refresh()
|
||
},
|
||
getData(page) {
|
||
this.$api.sendRequest({
|
||
url: '/api/files/getpage',
|
||
data: {
|
||
page_size: page.size,
|
||
page: page.num,
|
||
category_id: this.category_id,
|
||
keyword: this.keyword
|
||
},
|
||
success: res => {
|
||
let list = []
|
||
let message = res.message
|
||
if (res.code === 0 && res.data) {
|
||
list = res.data.list
|
||
if (!this.title && res.data.list.length > 0) {
|
||
uni.setNavigationBarTitle({
|
||
title: res.data.list[0].category_name
|
||
})
|
||
}
|
||
} else {
|
||
this.$util.showToast({
|
||
title: message
|
||
})
|
||
}
|
||
page.endSuccess(list.length)
|
||
if (page.num === 1) {
|
||
this.list = []
|
||
}
|
||
this.list = this.list.concat(list.map(item => {
|
||
const orig = item
|
||
const g1 = this.$util.img("addon/personnel/shop/view/enterprise/fileicon.png")
|
||
return { $orig: orig, g1: g1 }
|
||
}))
|
||
if (this.$refs.loadingCover) {
|
||
this.$refs.loadingCover.hide()
|
||
}
|
||
},
|
||
fail: () => {
|
||
page.endErr()
|
||
if (this.$refs.loadingCover) {
|
||
this.$refs.loadingCover.hide()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
toDetail(item) {
|
||
const title = (item.files_title || '文件').toString().replace(/[\\/:*?"<>|\r\n\t]/g, '_');
|
||
// 根据 URL 推断后缀(若无扩展名则默认 pdf)
|
||
let ext = 'pdf';
|
||
if (item.files_url) {
|
||
const clean = item.files_url.split('?')[0];
|
||
const matched = clean.match(/\.([a-zA-Z0-9]+)$/);
|
||
if (matched) ext = matched[1].toLowerCase();
|
||
}
|
||
uni.showLoading({ title: this.$lang('files.list.loading'), mask: true });
|
||
uni.downloadFile({
|
||
url: item.files_url,
|
||
success: res => {
|
||
if (res.statusCode !== 200) {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' });
|
||
return;
|
||
}
|
||
const fs = uni.getFileSystemManager();
|
||
// 重命名临时文件到用户目录,用短文件名 —— openDocument 的标题会取 filePath 的文件名部分,从而显示短名"乐瑞固企业介绍"而非 tmp_xxx
|
||
const targetPath = `${wx.env.USER_DATA_PATH}/fs_${Date.now()}_${title}.${ext}`;
|
||
try {
|
||
// saveFile:复制临时文件到持久目录并改名(临时文件在某些基础库上禁止直接 rename)
|
||
fs.saveFile({
|
||
tempFilePath: res.tempFilePath,
|
||
filePath: targetPath,
|
||
success: r => {
|
||
uni.hideLoading();
|
||
uni.openDocument({
|
||
filePath: r.savedFilePath,
|
||
fileType: ext,
|
||
showMenu: true,
|
||
fail: () => {
|
||
uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' });
|
||
},
|
||
complete: () => {
|
||
// 预览结束后清理,避免占用持久空间(失败忽略)
|
||
try { fs.removeSavedFile({ filePath: r.savedFilePath }); } catch (e) {}
|
||
}
|
||
});
|
||
},
|
||
fail: () => {
|
||
// saveFile 失败(配额等),直接用临时文件 openDocument 兜底
|
||
uni.hideLoading();
|
||
uni.openDocument({
|
||
filePath: res.tempFilePath,
|
||
fileType: ext,
|
||
showMenu: true,
|
||
fail: () => uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' })
|
||
});
|
||
}
|
||
});
|
||
} catch (e) {
|
||
// 极端异常兜底
|
||
uni.hideLoading();
|
||
uni.openDocument({
|
||
filePath: res.tempFilePath,
|
||
fileType: ext,
|
||
showMenu: true,
|
||
fail: () => uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' })
|
||
});
|
||
}
|
||
},
|
||
fail: () => {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' });
|
||
},
|
||
complete: res => {
|
||
if (res && res.statusCode === 404) {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: this.$lang('files.list.fileNotExist'), icon: 'none' });
|
||
}
|
||
}
|
||
});
|
||
},
|
||
imgError(index) {
|
||
if (this.list[index]) {
|
||
this.list[index].cover_img = this.$util.getDefaultImage().article
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.search-wrap {
|
||
flex: 0.5;
|
||
padding: 30rpx 30rpx 0;
|
||
font-size: 24rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.search-wrap .iconfont {
|
||
margin-left: 16rpx;
|
||
font-size: 36rpx;
|
||
}
|
||
|
||
.search-wrap .input-wrap {
|
||
flex: 1;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
background: #fff;
|
||
height: 64rpx;
|
||
padding-left: 10rpx;
|
||
border-radius: 70rpx;
|
||
}
|
||
|
||
.search-wrap .input-wrap input {
|
||
width: 90%;
|
||
background: #fff;
|
||
font-size: 24rpx;
|
||
height: 100%;
|
||
padding: 0 25rpx 0 40rpx;
|
||
line-height: 50rpx;
|
||
border-radius: 40rpx;
|
||
}
|
||
|
||
.search-wrap .input-wrap text {
|
||
font-size: 32rpx;
|
||
color: #909399;
|
||
width: 80rpx;
|
||
text-align: center;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.empty-wrap {
|
||
padding-top: 200rpx;
|
||
}
|
||
|
||
.article-wrap {
|
||
background: #f8f8f8;
|
||
}
|
||
|
||
.article-wrap .adv-wrap {
|
||
margin: 24rpx 24rpx 0 24rpx;
|
||
width: auto;
|
||
}
|
||
|
||
.article-wrap .item {
|
||
display: flex;
|
||
padding: 20rpx;
|
||
background-color: #fff;
|
||
margin: 24rpx;
|
||
border-radius: 16rpx;
|
||
}
|
||
|
||
.article-wrap .item .article-img {
|
||
margin-right: 20rpx;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
overflow: hidden;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.article-wrap .item .article-img image {
|
||
width: 100%;
|
||
}
|
||
|
||
.article-wrap .item .info-wrap {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.article-wrap .item .info-wrap .title {
|
||
font-weight: 700;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 1;
|
||
-webkit-box-orient: vertical;
|
||
font-size: 24rpx;
|
||
}
|
||
|
||
.article-wrap .item .info-wrap .read-wrap {
|
||
display: flex;
|
||
color: #999ca7;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
margin-top: 10rpx;
|
||
line-height: 1;
|
||
}
|
||
|
||
.article-wrap .item .info-wrap .read-wrap text {
|
||
font-size: 24rpx;
|
||
}
|
||
</style> |