Commit 0c943aff by Sweet Zhang

解决PDF打开缓慢的问题

parent 969f8366
declare module 'pdfjs-dist/build/pdf.worker.entry';
\ No newline at end of file
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
<view><uni-tag :text="product.categoryName" size="small" type="primary"></uni-tag></view> <view><uni-tag :text="product.categoryName" size="small" type="primary"></uni-tag></view>
</view> </view>
<view class="change-product" @click="navigateToPKPage"> <view class="change-product" @click="navigateToPKPage">
<uni-icons type="loop" size="16" color="#007aff"></uni-icons> <uni-icons type="loop" size="16" color="#20269B"></uni-icons>
<view <view
v-if="productPKInfoList.length > 1">更换</view> v-if="productPKInfoList.length > 1">更换</view>
</view> </view>
...@@ -132,7 +132,7 @@ const getGroupIcon = (groupCode) => { ...@@ -132,7 +132,7 @@ const getGroupIcon = (groupCode) => {
// 根据分组编码获取对应的颜色 // 根据分组编码获取对应的颜色
const getGroupColor = (groupCode) => { const getGroupColor = (groupCode) => {
const colorMap = { const colorMap = {
'A': '#007aff', // 基本信息-蓝色 'A': '#20269B', // 基本信息-蓝色
'B': '#00cc66', // 适合人群-绿色 'B': '#00cc66', // 适合人群-绿色
'C': '#ff9900', // 产品特色-橙色 'C': '#ff9900', // 产品特色-橙色
'D': '#cc66ff' // 产品彩页-紫色 'D': '#cc66ff' // 产品彩页-紫色
...@@ -318,7 +318,7 @@ onMounted(() => { ...@@ -318,7 +318,7 @@ onMounted(() => {
position: absolute; position: absolute;
right: 20rpx; right: 20rpx;
background: transparent; background: transparent;
color: #007aff; color: #20269B;
font-size: 26rpx; font-size: 26rpx;
padding: 0 10rpx; padding: 0 10rpx;
} }
...@@ -363,7 +363,7 @@ onMounted(() => { ...@@ -363,7 +363,7 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 24rpx; font-size: 24rpx;
color: #007aff; color: #20269B;
} }
/* 对比内容 */ /* 对比内容 */
.compare-content { .compare-content {
...@@ -441,7 +441,7 @@ onMounted(() => { ...@@ -441,7 +441,7 @@ onMounted(() => {
} }
.brochure-btn { .brochure-btn {
background-color: #007aff; background-color: #20269B;
color: #fff; color: #fff;
font-size: 24rpx; font-size: 24rpx;
padding: 8rpx 15rpx; padding: 8rpx 15rpx;
...@@ -474,7 +474,7 @@ onMounted(() => { ...@@ -474,7 +474,7 @@ onMounted(() => {
align-items: center; align-items: center;
gap: 8rpx; gap: 8rpx;
padding: 6rpx 0; padding: 6rpx 0;
color: #007aff; color: #20269B;
font-size: 24rpx; font-size: 24rpx;
cursor: pointer; cursor: pointer;
word-break: break-all; word-break: break-all;
......
<template> <template>
<view class="container"> <view class="container">
<!-- 头部 -->
<view class="header">
<view class="title">产品佣率查询</view>
</view>
<!-- 搜索区域 --> <!-- 搜索区域 -->
<view class="search-box"> <view class="search-box">
<input <input
...@@ -12,8 +7,10 @@ ...@@ -12,8 +7,10 @@
type="text" type="text"
placeholder="请输入产品名称" placeholder="请输入产品名称"
v-model="searchKeyword" v-model="searchKeyword"
confirm-type="done"
@confirm = "fetchProducts(1)"
/> />
<view class="search-icon" @click="fetchProducts(1)">🔍</view> <view class="search-icon" @click="fetchProducts(1)"><text class="iconfont icon-sousuo"></text></view>
</view> </view>
<!-- 产品列表 --> <!-- 产品列表 -->
...@@ -49,7 +46,7 @@ ...@@ -49,7 +46,7 @@
<!-- 空状态 --> <!-- 空状态 -->
<view class="empty" v-if="!loading && products.length === 0"> <view class="empty" v-if="!loading && products.length === 0">
<text>暂无产品数据</text> <text>{{tips}}</text>
</view> </view>
</view> </view>
</template> </template>
...@@ -61,7 +58,7 @@ import api from '@/api/api'; ...@@ -61,7 +58,7 @@ import api from '@/api/api';
const searchKeyword = ref('') const searchKeyword = ref('')
const products = ref([]) const products = ref([])
const loading = ref(false) const loading = ref(false)
const tips = ref('无默认产品,请输入产品名称进行查询')
// 方法 // 方法
const handleSearch = () => { const handleSearch = () => {
...@@ -77,6 +74,11 @@ const goToCommissionDetail = (product) => { ...@@ -77,6 +74,11 @@ const goToCommissionDetail = (product) => {
// 获取产品数据 // 获取产品数据
const fetchProducts = async (type=0) => { const fetchProducts = async (type=0) => {
if(!searchKeyword.value){
tips.value = '无默认产品,请输入产品名称进行查询' ;
products.value = [];
return;
}
loading.value = true loading.value = true
try { try {
let params = { let params = {
...@@ -99,6 +101,9 @@ const fetchProducts = async (type=0) => { ...@@ -99,6 +101,9 @@ const fetchProducts = async (type=0) => {
if(response.success){ if(response.success){
products.value = response.data.list || []; products.value = response.data.list || [];
if(products.value.length===0){
tips.value = '暂无此产品数据'
}
} }
...@@ -113,7 +118,6 @@ const fetchProducts = async (type=0) => { ...@@ -113,7 +118,6 @@ const fetchProducts = async (type=0) => {
// 生命周期 // 生命周期
onMounted(() => { onMounted(() => {
fetchProducts()
}) })
</script> </script>
...@@ -122,6 +126,8 @@ onMounted(() => { ...@@ -122,6 +126,8 @@ onMounted(() => {
padding: 20rpx; padding: 20rpx;
background-color: #f5f7fa; background-color: #f5f7fa;
min-height: 100vh; min-height: 100vh;
width: 100%;
overflow-x: hidden;
} }
.header { .header {
...@@ -155,6 +161,8 @@ onMounted(() => { ...@@ -155,6 +161,8 @@ onMounted(() => {
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
color: #999; color: #999;
width: 80rpx;
text-align: right;
} }
.product-list { .product-list {
......
...@@ -227,9 +227,9 @@ const handleScroll = (e) => { ...@@ -227,9 +227,9 @@ const handleScroll = (e) => {
// 关键:windowHeight 是设备可视区域高度(px),不含导航栏/底部栏 // 关键:windowHeight 是设备可视区域高度(px),不含导航栏/底部栏
windowHeight.value = sysInfo.windowHeight; windowHeight.value = sysInfo.windowHeight;
// 获取滚动相关参数 // 获取滚动相关参数
const { scrollTop, scrollHeight } = e.detail; const { scrollTop, scrollHeight } = e.detail
// 计算是否到达底部(距离底部200rpx时触发加载) // 计算是否到达底部(距离底部200rpx时触发加载)
if (scrollHeight - scrollTop - windowHeight.value <= 200) { if (scrollHeight - scrollTop - windowHeight.value <= 400) {
fetchProducts(); // 加载更多 fetchProducts(); // 加载更多
} }
}; };
...@@ -607,7 +607,7 @@ onUnmounted(() => { ...@@ -607,7 +607,7 @@ onUnmounted(() => {
.confirm-btn { .confirm-btn {
flex: 1; flex: 1;
height: 80rpx; height: 80rpx;
background-color: #007aff; background-color: #20269B;
color: #fff; color: #fff;
border-radius: 40rpx; border-radius: 40rpx;
font-size: 28rpx; font-size: 28rpx;
...@@ -660,7 +660,7 @@ onUnmounted(() => { ...@@ -660,7 +660,7 @@ onUnmounted(() => {
width: 150rpx; width: 150rpx;
height: 60rpx; height: 60rpx;
font-size: 26rpx; font-size: 26rpx;
background-color: #007aff; background-color: #20269B;
color: #fff; color: #fff;
border-radius: 30rpx; border-radius: 30rpx;
padding: 0; padding: 0;
...@@ -751,7 +751,7 @@ onUnmounted(() => { ...@@ -751,7 +751,7 @@ onUnmounted(() => {
.compare-btn { .compare-btn {
min-width: 200rpx; min-width: 200rpx;
height: 70rpx; height: 70rpx;
background-color: #007aff; background-color: #20269B;
color: #fff; color: #fff;
border-radius: 35rpx; border-radius: 35rpx;
font-size: 28rpx; font-size: 28rpx;
...@@ -798,7 +798,7 @@ onUnmounted(() => { ...@@ -798,7 +798,7 @@ onUnmounted(() => {
/* 3. 筛选按钮样式:选中状态(突出显示) */ /* 3. 筛选按钮样式:选中状态(突出显示) */
.filter-btn-item.active { .filter-btn-item.active {
background-color: #007aff; background-color: #20269B;
color: #fff; color: #fff;
} }
/* 加载中状态 */ /* 加载中状态 */
......
...@@ -25,9 +25,11 @@ ...@@ -25,9 +25,11 @@
"mp-painter": "^1.0.1", "mp-painter": "^1.0.1",
"nanoid": "^4.0.0", "nanoid": "^4.0.0",
"pdf.js": "^0.1.0", "pdf.js": "^0.1.0",
"pdfjs-dist": "^2.11.338",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"qrcodejs2": "^0.0.2", "qrcodejs2": "^0.0.2",
"uqrcodejs": "^4.0.7" "uqrcodejs": "^4.0.7",
"vite-plugin-top-level-await": "^1.6.0"
}, },
"devDependencies": { "devDependencies": {
"less": "^4.3.0" "less": "^4.3.0"
......
...@@ -480,6 +480,7 @@ ...@@ -480,6 +480,7 @@
"style" : "style" :
{ {
"navigationBarTitleText" : "", "navigationBarTitleText" : "",
"disableScroll": false,
"webview": { "webview": {
// 1. 允许加载本地静态资源(viewer.html /static 目录) // 1. 允许加载本地静态资源(viewer.html /static 目录)
"allowAccessFromFileURLs": true, "allowAccessFromFileURLs": true,
...@@ -588,7 +589,7 @@ ...@@ -588,7 +589,7 @@
},{ },{
"path": "product-list/product-commission", "path": "product-list/product-commission",
"style": { "style": {
"navigationBarTitleText": "持牌人佣金" "navigationBarTitleText": "产品佣率查询"
} }
}, },
{ {
......
...@@ -224,7 +224,7 @@ ...@@ -224,7 +224,7 @@
{key:'policies',title:'制度',icon:'icon-xiaoshoue',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:4}, {key:'policies',title:'制度',icon:'icon-xiaoshoue',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:4},
{key:'products',title:'产品分析',icon:'icon-shujufenxi',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:3}, {key:'products',title:'产品分析',icon:'icon-shujufenxi',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:3},
{key:'cases',title:'案例分享',icon:'icon-shiyongjiaocheng',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:2}, {key:'cases',title:'案例分享',icon:'icon-shiyongjiaocheng',link:'/pages/personalCenter/detail',isOpen:true,isShow:false,identity: true,type:2},
{key:'commission',title:'持牌人佣金',icon:'icon-shiyongjiaocheng',link:'/myPackageA/product-list/product-commission',isOpen:true,isShow:false,identity: true}, {key:'commission',title:'持牌人佣金',icon:'icon-dingdan',link:'/myPackageA/product-list/product-commission',isOpen:true,isShow:false,identity: true},
], ],
},{id:'04',categoryName:'海外资产配置', },{id:'04',categoryName:'海外资产配置',
children:[ children:[
......
import { getDocument, GlobalWorkerOptions } from 'pdfjs-dist/legacy/build/pdf';
// 使用 CDN 避免本地 worker 问题
GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js`;
export const pdfToImage = async (pdfUrl) => {
const loadingTask = getDocument(pdfUrl);
const pdf = await loadingTask.promise;
let pages = [];
for (let num = 1; num <= pdf.numPages; num++) {
const page = await pdf.getPage(num);
const viewport = page.getViewport({ scale: 1 });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = {
canvasContext: context,
viewport: viewport
};
await page.render(renderContext).promise;
pages.push(canvas.toDataURL('image/png'));
}
return pages;
}
\ No newline at end of file
/**
* 创建水印
* @param text 水印文本
*/
export function createWatermark(text: string | string[] = '内部资料') {
// 检查是否在浏览器环境
if (typeof document === 'undefined') {
console.warn('Watermark: 非浏览器环境,无法创建水印');
return;
}
console.log('Watermark: 开始创建水印', text);
try {
// 创建Canvas生成水印图片
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('无法获取Canvas上下文');
}
// 设置Canvas尺寸
canvas.width = 300;
canvas.height = 200;
// 设置样式
ctx.font = 'normal 16px Arial, sans-serif';
ctx.fillStyle = 'rgba(0, 0, 0, 0.06)';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// 旋转画布
ctx.translate(150, 100);
ctx.rotate(-25 * Math.PI / 180);
ctx.translate(-150, -100);
// 绘制文本
const texts = Array.isArray(text) ? text : [text];
const lineHeight = 24;
const startY = (200 - (texts.length - 1) * lineHeight) / 2;
texts.forEach((textItem, index) => {
ctx.fillText(textItem, 150, startY + index * lineHeight);
});
// 转换为DataURL
const dataURL = canvas.toDataURL('image/png');
// 创建水印元素
const watermark = document.createElement('div');
watermark.style.position = 'fixed';
watermark.style.top = '0';
watermark.style.left = '0';
watermark.style.width = '100%';
watermark.style.height = '100%';
watermark.style.backgroundImage = `url(${dataURL})`;
watermark.style.backgroundRepeat = 'repeat';
watermark.style.backgroundSize = '400px 300px';
watermark.style.pointerEvents = 'none';
watermark.style.zIndex = '9999';
watermark.style.opacity = '0.8';
// 添加到body
document.body.appendChild(watermark);
console.log('Watermark: 水印创建成功');
// 返回销毁方法
return () => {
if (watermark.parentNode) {
watermark.parentNode.removeChild(watermark);
console.log('Watermark: 水印已销毁');
}
};
} catch (error) {
console.error('Watermark: 创建水印失败', error);
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment