Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
CFFP-HB
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chao Sun
CFFP-HB
Commits
3967d642
Commit
3967d642
authored
Sep 15, 2025
by
Sweet Zhang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
分享好友海报有订单计入销售佣金,菜单调整
parent
115c9a77
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
263 additions
and
334 deletions
+263
-334
components/pdf-viewer/pdf-viewer.vue
+0
-191
environments/environment.ts
+1
-1
pages.json
+0
-7
pages/courseDetail/courseDetail.vue
+5
-0
pages/personalCenter/detail.vue
+207
-128
pages/personalCenter/personalCenter.vue
+45
-4
pages/saleCourseLists/saleCourseLists.vue
+2
-2
static/pdf/web/viewer.css
+1
-0
util/interceptor.ts
+2
-1
No files found.
components/pdf-viewer/pdf-viewer.vue
deleted
100644 → 0
View file @
115c9a77
<
template
>
<view
class=
"pdf-container"
>
<!-- 顶部导航 -->
<view
class=
"pdf-header"
>
<button
class=
"back-btn"
@
click=
"onBack"
>
<uni-icons
type=
"back"
size=
"28"
color=
"#333"
></uni-icons>
</button>
<text
class=
"pdf-title"
>
{{
title
}}
</text>
<view
class=
"empty-btn"
></view>
<!-- 占位,使标题居中 -->
</view>
<!-- PDF查看区域 -->
<view
class=
"pdf-content"
>
<template
v-if=
"isLoading"
>
<view
class=
"loading"
>
<uni-loading-icon
type=
"spin"
size=
"40"
></uni-loading-icon>
<text
class=
"loading-text"
>
加载中...
</text>
</view>
</
template
>
<
template
v-else-if=
"errorMsg"
>
<view
class=
"error"
>
<uni-icons
type=
"error"
size=
"40"
color=
"#f53f3f"
></uni-icons>
<text
class=
"error-text"
>
{{
errorMsg
}}
</text>
</view>
</
template
>
<
template
v-else
>
<web-view
:src=
"pdfUrl"
@
message=
"handleMessage"
class=
"web-view"
></web-view>
</
template
>
</view>
</view>
</template>
<
script
setup
lang=
"ts"
>
import
{
ref
,
onLoad
,
onReady
}
from
'vue'
;
import
{
onBackPress
}
from
'@dcloudio/uni-app'
;
// 接收参数
const
title
=
ref
(
''
);
const
url
=
ref
(
''
);
const
isLoading
=
ref
(
true
);
const
errorMsg
=
ref
(
''
);
const
pdfUrl
=
ref
(
''
);
// 页面加载时获取参数
onLoad
((
options
:
{
title
?:
string
;
url
?:
string
})
=>
{
if
(
options
.
title
)
{
title
.
value
=
decodeURIComponent
(
options
.
title
);
}
if
(
options
.
url
)
{
url
.
value
=
decodeURIComponent
(
options
.
url
);
loadPdf
();
}
else
{
errorMsg
.
value
=
'未找到PDF文件'
;
isLoading
.
value
=
false
;
}
});
// 加载PDF文件
const
loadPdf
=
()
=>
{
// 使用PDF.js viewer加载PDF,并禁用下载功能
// 注意:需将pdfjs的web/viewer.html放入项目的static目录
const
viewerPath
=
'/static/pdfjs/web/viewer.html'
;
const
fileUrl
=
`
${
viewerPath
}
?file=
${
encodeURIComponent
(
url
.
value
)}
&disableDownload=true`
;
// 本地PDF需要转换为网络路径
if
(
url
.
value
.
startsWith
(
'/static/'
))
{
// 转换为绝对路径
const
absoluteUrl
=
`
${
location
.
origin
}${
url
.
value
}
`
;
pdfUrl
.
value
=
`
${
viewerPath
}
?file=
${
encodeURIComponent
(
absoluteUrl
)}
&disableDownload=true`
;
}
else
{
pdfUrl
.
value
=
fileUrl
;
}
isLoading
.
value
=
false
;
};
// 处理web-view消息
const
handleMessage
=
(
e
:
any
)
=>
{
const
data
=
e
.
detail
.
data
[
0
];
if
(
data
.
action
===
'error'
)
{
errorMsg
.
value
=
data
.
message
||
'PDF加载失败'
;
isLoading
.
value
=
false
;
}
};
// 返回按钮
const
onBack
=
()
=>
{
uni
.
navigateBack
();
};
// 监听物理返回键
onBackPress
(()
=>
{
onBack
();
return
true
;
});
</
script
>
<
style
scoped
>
.pdf-container
{
display
:
flex
;
flex-direction
:
column
;
height
:
100vh
;
background-color
:
#000
;
}
.pdf-header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
20
rpx
30
rpx
;
background-color
:
#fff
;
border-bottom
:
1px
solid
#eee
;
}
.back-btn
{
width
:
60
rpx
;
height
:
60
rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
padding
:
0
;
background-color
:
transparent
;
}
.pdf-title
{
font-size
:
32
rpx
;
font-weight
:
500
;
color
:
#333
;
flex
:
1
;
text-align
:
center
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
padding
:
0
20
rpx
;
}
.empty-btn
{
width
:
60
rpx
;
height
:
60
rpx
;
}
.pdf-content
{
flex
:
1
;
position
:
relative
;
}
.web-view
{
width
:
100%
;
height
:
100%
;
}
.loading
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
}
.loading-text
{
color
:
#fff
;
font-size
:
28
rpx
;
margin-top
:
20
rpx
;
}
.error
{
position
:
absolute
;
top
:
50%
;
left
:
50%
;
transform
:
translate
(
-50%
,
-50%
);
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
padding
:
0
40
rpx
;
text-align
:
center
;
}
.error-text
{
color
:
#fff
;
font-size
:
28
rpx
;
margin-top
:
20
rpx
;
}
</
style
>
environments/environment.ts
View file @
3967d642
...
...
@@ -49,7 +49,7 @@ const config = {
stage
,
prod
}
let
env
=
'
dev
'
;
let
env
=
'
prod
'
;
let
baseURL
=
config
[
env
].
base_url
;
let
apiURL
=
config
[
env
].
api_url
;
...
...
pages.json
View file @
3967d642
...
...
@@ -476,13 +476,6 @@
}
},
{
"path"
:
"components/pdf-viewer/pdf-viewer"
,
"style"
:
{
"navigationBarTitleText"
:
"查看"
}
},
{
"path"
:
"pages/personalCenter/detail"
,
"style"
:
{
...
...
pages/courseDetail/courseDetail.vue
View file @
3967d642
...
...
@@ -299,6 +299,7 @@
},
data
()
{
return
{
sharePosterObj
:{},
userInfo
:
{},
wayType
:
'1'
,
//登陆的类型
partnerType
:
''
,
//是否是合伙人
...
...
@@ -1370,6 +1371,10 @@
},
onLoad
(
option
)
{
this
.
sharePosterObj
=
uni
.
getStorageSync
(
'sharePosterObj'
)
||
{};
// console.log('sharePosterObj======',this.sharePosterObj);
// 如果通过海报分享进入系统,海报分享人为合伙人且普通客户完成购买了,那么海报分享人可以获得销售佣金
this
.
shareUserId
=
this
.
sharePosterObj
.
inviteUserId
||
''
;
if
(
companyInfo
.
companyType
==
'1'
){
this
.
companyLogo
=
'../../static/myteam/Group1633.png'
;
}
else
if
(
this
.
companyType
==
'2'
){
...
...
pages/personalCenter/detail.vue
View file @
3967d642
...
...
@@ -14,15 +14,16 @@
:src=
"getPdfViewerUrl(companyPdf.url)"
class=
"webview"
@
error=
"handlePdfError"
@
load=
"handleWebViewLoad"
></web-view>
</view>
<!-- 2-4. 带Tab的模块(根据type显示不同Tab) -->
<!-- 2-4. 带Tab的模块(根据type显示不同Tab
,且仅显示有权限的Tab
) -->
<view
v-if=
"!loading && currentType >= 2 && currentType
<
=
4
"
>
<!-- Tab切换栏 -->
<!-- Tab切换栏
(仅渲染有权限的Tab)
-->
<view
class=
"tab-bar"
>
<view
v-for=
"(tab, index) in
c
urrentTabs"
v-for=
"(tab, index) in
filteredC
urrentTabs"
:key=
"tab.id"
class=
"tab-item"
:class=
"
{ active: activeTab === index }"
...
...
@@ -33,17 +34,21 @@
</view>
</view>
<!-- Tab对应的PDF内容 -->
<!-- Tab 对应的 PDF 内容:添加 @load 事件 -->
<view
class=
"pdf-tab-content"
>
<web-view
:src=
"getPdfViewerUrl(currentPdf.url)"
class=
"webview"
@
error=
"handlePdfError"
@
load=
"handleWebViewLoad"
:key=
"getPdfViewerUrl(currentPdf.url)"
></web-view>
</view>
<!-- Tab对应的PDF内容(无权限时显示空状态) -->
<view
class=
"pdf-tab-content"
>
<template
v-if=
"filteredCurrentTabs.length > 0"
>
<web-view
:src=
"getPdfViewerUrl(currentPdf.url)"
class=
"webview"
@
error=
"handlePdfError"
@
load=
"handleWebViewLoad"
:key=
"getPdfViewerUrl(currentPdf.url)"
></web-view>
</
template
>
<
template
v-else
>
<view
class=
"pdf-empty"
>
暂无访问权限
</view>
</
template
>
</view>
</view>
<!-- 错误状态 -->
...
...
@@ -57,140 +62,244 @@
<
script
setup
lang=
"ts"
>
import
{
ref
,
computed
}
from
'vue'
;
import
{
onLoad
}
from
'@dcloudio/uni-app'
;
import
api
from
"@/api/api"
;
// 定义PDF文件类型
// ========================== 类型定义 ==========================
// PDF文件类型
interface
PdfItem
{
id
:
string
;
title
:
string
;
url
:
string
;
// PDF文件路径
}
// 接收type参数
// 权限数据类型(与接口返回结构对齐)
interface
PermissionRight
{
key
:
string
;
}
interface
PermissionItem
{
key
:
string
;
// 对应菜单的key(如cases、products)
rights
:
PermissionRight
[];
// 子权限(对应Tab的id)
}
// ========================== 基础配置 ==========================
// OSS基础路径(根据实际OSS地址修改)
const
OSS_BASE_URL
=
'https://csf-doc-center.oss-cn-shanghai-finance-1-pub.aliyuncs.com'
;
// 接收URL参数的type(默认1:公司介绍)
const
currentType
=
ref
<
number
>
(
1
);
// 加载状态
const
loading
=
ref
(
true
);
// 当前激活的Tab索引
const
activeTab
=
ref
(
0
);
// 当前显示的PDF信息
const
currentPdf
=
ref
<
PdfItem
>
({
id
:
''
,
title
:
''
,
url
:
''
});
// 接口返回的权限列表
const
permissionList
=
ref
<
PermissionItem
[]
>
([]);
// OSS基础路径(根据实际OSS地址修改)
const
OSS_BASE_URL
=
'https://csf-doc-center.oss-cn-shanghai-finance-1-pub.aliyuncs.com'
;
// 公司介绍PDF(type=1)- 使用OSS地址
// 公司介绍PDF(type=1,固定配置)
const
companyPdf
=
ref
<
PdfItem
>
({
id
:
'company'
,
title
:
'公司介绍'
,
url
:
`
${
OSS_BASE_URL
}
/public/company-intro.pdf`
// OSS地址
url
:
`
${
OSS_BASE_URL
}
/public/company-intro.pdf`
});
// 所有模块的
Tab配置(根据type匹配
)
const
t
abConfig
=
ref
<
Record
<
number
,
PdfItem
[]
>>
({
2
:
[
// type=2:案例分享
{
id
:
'case1'
,
title
:
'规划案例'
,
url
:
`
${
OSS_BASE_URL
}
/cases/planning.pdf`
},
{
id
:
'case2'
,
title
:
'团财案例'
,
url
:
`
${
OSS_BASE_URL
}
/cases/group-finance.pdf`
}
// 所有模块的
原始Tab配置(未过滤权限
)
const
rawT
abConfig
=
ref
<
Record
<
number
,
PdfItem
[]
>>
({
2
:
[
// type=2:案例分享
(对应权限key=cases)
{
id
:
'case1'
,
title
:
'规划案例'
,
url
:
`
${
OSS_BASE_URL
}
/cases/planning.pdf`
},
{
id
:
'case2'
,
title
:
'团财案例'
,
url
:
''
}
],
3
:
[
// type=3:产品分析
3
:
[
// type=3:产品分析
(对应权限key=products)
{
id
:
'product2'
,
title
:
'港险分析'
,
url
:
`
${
OSS_BASE_URL
}
/products/hk-analysis.pdf`
},
{
id
:
'product1'
,
title
:
'港险明细'
,
url
:
`
${
OSS_BASE_URL
}
/products/hk-detail.pdf`
},
{
id
:
'product1'
,
title
:
'港险明细'
,
url
:
`
${
OSS_BASE_URL
}
/products/2025Q3-hk-detail.pdf`
},
{
id
:
'product3'
,
title
:
'产品搜索'
,
url
:
''
},
],
4
:
[
// type=4:制度
4
:
[
// type=4:制度
(对应权限key=policies)
{
id
:
'policy1'
,
title
:
'个险政策'
,
url
:
`
${
OSS_BASE_URL
}
/policies/individual-policy.pdf`
},
{
id
:
'policy2'
,
title
:
'
团财
政策'
,
url
:
`
${
OSS_BASE_URL
}
/policies/group-policy.pdf`
},
{
id
:
'policy2'
,
title
:
'
家办
政策'
,
url
:
`
${
OSS_BASE_URL
}
/policies/group-policy.pdf`
},
{
id
:
'policy3'
,
title
:
'介绍费政策'
,
url
:
`
${
OSS_BASE_URL
}
/policies/commission-policy.pdf`
}
]
});
// 初始化页面
// 类型与权限key的映射关系(关键:建立type和权限key的关联)
const
typeToPermissionKey
=
ref
<
Record
<
number
,
string
>>
({
2
:
'cases'
,
// type=2(案例分享)→ 权限key=cases
3
:
'products'
,
// type=3(产品分析)→ 权限key=products
4
:
'policies'
// type=4(制度)→ 权限key=policies
});
// ========================== 生命周期 ==========================
onLoad
((
query
)
=>
{
// 解析
type参数(默认1)
// 1. 解析URL中的
type参数(默认1)
currentType
.
value
=
Number
(
query
.
type
)
||
1
;
// 2. 查询用户信息和权限
queryUserInfoAndPermission
();
});
// ========================== 核心逻辑 ==========================
/**
* 查询用户信息和权限列表
*/
const
queryUserInfoAndPermission
=
()
=>
{
const
userId
=
uni
.
getStorageSync
(
'cffp_userId'
);
if
(
!
userId
)
{
uni
.
setStorageSync
(
'loginType'
,
'visitor'
);
initPdfAfterPermission
();
return
;
}
api
.
queryInfo
({
userId
}).
then
(
res
=>
{
if
(
res
.
success
)
{
// 存储接口返回的权限列表(格式:[{key: 'cases', rights: [{key: 'case1'}]}])
permissionList
.
value
=
res
.
data
.
accessPermission
||
[];
}
else
{
uni
.
setStorageSync
(
'loginType'
,
'visitor'
);
permissionList
.
value
=
[];
// 游客无权限
}
// 权限获取后初始化PDF显示
initPdfAfterPermission
();
}).
catch
(()
=>
{
uni
.
setStorageSync
(
'loginType'
,
'visitor'
);
permissionList
.
value
=
[];
initPdfAfterPermission
();
});
};
/**
* 权限获取后初始化PDF(过滤Tab + 设置默认显示项)
*/
const
initPdfAfterPermission
=
()
=>
{
loading
.
value
=
true
;
// 初始化Tab和PDF
const
tabs
=
tabConfig
.
value
[
currentType
.
value
]
||
[];
if
(
currentType
.
value
>=
2
&&
currentType
.
value
<=
4
&&
tabs
.
length
>
0
)
{
activeTab
.
value
=
0
;
currentPdf
.
value
=
tabs
[
0
];
// 直接赋值,避免 computed 延迟
// 1. 过滤当前type对应的有权限的Tab
const
filteredTabs
=
filteredCurrentTabs
.
value
;
// 2. 处理不同type的初始化逻辑
if
(
currentType
.
value
>=
2
&&
currentType
.
value
<=
4
)
{
if
(
filteredTabs
.
length
>
0
)
{
// 有有权限的Tab:默认显示第一个
activeTab
.
value
=
0
;
currentPdf
.
value
=
filteredTabs
[
0
];
}
else
{
// 无权限:清空当前PDF
currentPdf
.
value
=
{
id
:
''
,
title
:
''
,
url
:
''
};
}
}
//
模拟加载延迟(可缩短到 200ms,减少 WebView 等待时间
)
//
3. 模拟加载延迟(优化用户体验
)
setTimeout
(()
=>
{
loading
.
value
=
false
;
},
200
);
};
/**
* 计算属性:过滤当前type对应的有权限的Tab列表
*/
const
filteredCurrentTabs
=
computed
(()
=>
{
// 1. 获取当前type的原始Tab列表
const
originalTabs
=
rawTabConfig
.
value
[
currentType
.
value
]
||
[];
// 2. 若为游客/无权限列表:返回空
if
(
permissionList
.
value
.
length
===
0
)
return
[];
// 3. 获取当前type对应的权限key(如type=2→key=cases)
const
targetPermissionKey
=
typeToPermissionKey
.
value
[
currentType
.
value
];
if
(
!
targetPermissionKey
)
return
[];
// 4. 找到权限列表中对应的权限项
const
targetPermission
=
permissionList
.
value
.
find
(
item
=>
item
.
key
===
targetPermissionKey
);
if
(
!
targetPermission
||
targetPermission
.
rights
.
length
===
0
)
return
[];
// 5. 提取有权限的Tab id集合(如['case1', 'case2'])
const
allowedTabIds
=
new
Set
(
targetPermission
.
rights
.
map
(
right
=>
right
.
key
)
);
// 6. 过滤原始Tab列表:仅保留有权限的项
return
originalTabs
.
filter
(
tab
=>
allowedTabIds
.
has
(
tab
.
id
));
});
/**
* 切换Tab
* @param index 目标Tab索引
*/
const
switchTab
=
(
index
:
number
)
=>
{
const
tabs
=
filteredCurrentTabs
.
value
;
// 边界校验:索引无效或无权限Tab时不处理
if
(
index
<
0
||
index
>=
tabs
.
length
||
tabs
.
length
===
0
)
return
;
// 计算当前模块的Tab列表
const
currentTabs
=
computed
(()
=>
{
return
tabConfig
.
value
[
currentType
.
value
]
||
[];
});
// 1. 生成随机字符串(比时间戳更唯一,避免快速切换重复)
const
getRandomStr
=
(
length
=
8
)
=>
{
const
chars
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
;
let
str
=
''
;
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
str
+=
chars
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
chars
.
length
));
}
return
str
;
// 显示加载状态(优化体验)
uni
.
showLoading
({
title
:
'加载中...'
});
// 延迟100ms更新:避免WebView加载冲突
setTimeout
(()
=>
{
activeTab
.
value
=
index
;
currentPdf
.
value
=
tabs
[
index
];
// 延迟关闭加载提示(给WebView启动时间)
setTimeout
(()
=>
{
uni
.
hideLoading
();
},
300
);
},
100
);
};
// 2. 生成 PDF 查看器 URL:添加随机参数+时间戳,确保每次 src 唯一
/**
* 生成PDF查看器URL(添加随机参数+时间戳,避免缓存)
* @param pdfUrl PDF原始URL
*/
const
getPdfViewerUrl
=
(
pdfUrl
:
string
)
=>
{
if
(
!
pdfUrl
)
return
''
;
const
randomStr
=
getRandomStr
();
// 随机字符串
const
timestamp
=
new
Date
().
getTime
();
// 时间戳
//
同时添加 random 和 timestamp,双重确保 src 唯一
//
编码PDF URL + 拼接唯一参数
return
`/static/pdf/web/viewer.html?file=
${
encodeURIComponent
(
pdfUrl
)}
&random=
${
randomStr
}
&t=
${
timestamp
}
`
;
};
// 新增:WebView 加载完成监听
/**
* 生成指定长度的随机字符串(用于URL唯一标识)
* @param length 字符串长度(默认8)
*/
const
getRandomStr
=
(
length
=
8
)
=>
{
const
chars
=
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
;
let
str
=
''
;
for
(
let
i
=
0
;
i
<
length
;
i
++
)
{
str
+=
chars
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
chars
.
length
));
}
return
str
;
};
// ========================== 事件处理 ==========================
/**
* WebView加载完成监听(调试用)
*/
const
handleWebViewLoad
=
(
e
:
any
)
=>
{
const
loadedSrc
=
e
.
detail
.
src
;
// 获取 WebView 实际加载的 src
console
.
log
(
'WebView
加载完成:'
,
loadedSrc
);
// 解析
加载的 file 参数,确认是否正确
const
loadedSrc
=
e
.
detail
.
src
;
console
.
log
(
'WebView加载完成:'
,
loadedSrc
);
// 解析
并验证PDF地址(可选:调试时用)
const
urlObj
=
new
URL
(
loadedSrc
);
const
fileParam
=
urlObj
.
searchParams
.
get
(
'file'
);
if
(
fileParam
)
{
const
decodedFileUrl
=
decodeURIComponent
(
fileParam
);
console
.
log
(
'
解析的 PDF
地址:'
,
decodedFileUrl
);
//
验证 PDF 地址是否可访问(可选:用 uni.request 测试)
console
.
log
(
'
当前加载的PDF
地址:'
,
decodedFileUrl
);
//
可选:验证PDF地址可用性
uni
.
request
({
url
:
decodedFileUrl
,
method
:
'GET'
,
success
:
(
res
)
=>
{
console
.
log
(
'PDF
地址可访问,响应状态
:'
,
res
.
statusCode
);
console
.
log
(
'PDF
地址可访问,状态码
:'
,
res
.
statusCode
);
},
fail
:
(
err
)
=>
{
console
.
error
(
'PDF
地址访问失败:'
,
err
);
uni
.
showToast
({
title
:
`PDF
地址无效:
${
err
.
errMsg
}
`
,
icon
:
'none'
});
console
.
error
(
'PDF地址访问失败:'
,
err
);
uni
.
showToast
({
title
:
`PDF地址无效:
${
err
.
errMsg
}
`
,
icon
:
'none'
});
}
});
}
};
// // 切换Tab
// const switchTab = (index: number) => {
// if (index
<
0
||
index
>=
currentTabs
.
value
.
length
)
return
;
// activeTab.value = index;
// currentPdf.value = currentTabs.value[index];
// };
// 修改 switchTab 方法,添加 100ms 延迟
const
switchTab
=
(
index
:
number
)
=>
{
if
(
index
<
0
||
index
>=
currentTabs
.
value
.
length
)
return
;
// 先显示加载状态(可选,增强用户体验)
uni
.
showLoading
({
title
:
'加载中...'
});
// 延迟 100ms 再更新 activeTab 和 currentPdf,避免 WebView 加载冲突
setTimeout
(()
=>
{
activeTab
.
value
=
index
;
currentPdf
.
value
=
currentTabs
.
value
[
index
];
// 延迟关闭加载提示(给 WebView 启动时间)
setTimeout
(()
=>
{
uni
.
hideLoading
();
},
300
);
},
100
);
};
// 处理PDF加载错误
/**
* PDF加载错误处理
*/
const
handlePdfError
=
()
=>
{
uni
.
showToast
({
title
:
'PDF加载失败'
,
title
:
'PDF加载失败
,请重试
'
,
icon
:
'none'
,
duration
:
2000
});
...
...
@@ -205,42 +314,6 @@ const handlePdfError = () => {
background-color
:
#f5f5f5
;
}
.navbar
{
display
:
flex
;
align-items
:
center
;
height
:
44px
;
padding
:
0
16px
;
background-color
:
#ffffff
;
border-bottom
:
1px
solid
#eeeeee
;
.back-btn
{
width
:
44px
;
height
:
44px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
background
:
transparent
;
border
:
none
;
padding
:
0
;
.icon-back
{
font-size
:
20px
;
color
:
#333333
;
}
}
.title
{
flex
:
1
;
text-align
:
center
;
font-size
:
17px
;
font-weight
:
500
;
color
:
#333333
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.content
{
flex
:
1
;
display
:
flex
;
...
...
@@ -301,10 +374,10 @@ const handlePdfError = () => {
border-bottom
:
1px
solid
#eeeeee
;
overflow-x
:
auto
;
white-space
:
nowrap
;
scrollbar-width
:
none
;
scrollbar-width
:
none
;
/* 隐藏滚动条(火狐) */
&::-webkit-scrollbar
{
display
:
none
;
display
:
none
;
/* 隐藏滚动条(Chrome/Safari) */
}
.tab-item
{
...
...
@@ -315,6 +388,7 @@ const handlePdfError = () => {
padding
:
0
16px
;
height
:
100%
;
position
:
relative
;
cursor
:
pointer
;
.tab-text
{
font-size
:
14px
;
...
...
@@ -329,6 +403,7 @@ const handlePdfError = () => {
height
:
2px
;
background-color
:
#20269B
;
border-radius
:
1px
;
transition
:
all
0.3s
;
}
&
.active
{
...
...
@@ -340,15 +415,16 @@ const handlePdfError = () => {
}
}
/* Tab对应的PDF内容 */
/* Tab对应的PDF内容
区域
*/
.pdf-tab-content
{
width
:
100%
;
position
:
absolute
;
top
:
48px
;
/*
等于 Tab 栏的高度(.tab-bar { height: 48px; }),从 Tab 栏下方开始
*/
bottom
:
0
;
/* 到屏幕底部结束 */
top
:
48px
;
/*
与Tab栏高度一致,避免重叠
*/
bottom
:
0
;
background-color
:
#ffffff
;
}
/* 无权限/无Tab时的空状态 */
.pdf-empty
{
width
:
100%
;
height
:
100%
;
...
...
@@ -357,17 +433,19 @@ const handlePdfError = () => {
justify-content
:
center
;
color
:
#999999
;
font-size
:
14px
;
background-color
:
#ffffff
;
}
/*
web-view样式
*/
/*
WebView样式(占满父容器)
*/
.webview
{
width
:
100%
;
height
:
100%
;
}
/* 加载动画 */
@keyframes
spin
{
to
{
transform
:
rotate
(
360deg
);
}
}
</
style
>
</
style
>
\ No newline at end of file
pages/personalCenter/personalCenter.vue
View file @
3967d642
...
...
@@ -220,10 +220,14 @@
],
},{
id
:
'03'
,
categoryName
:
'学习研讨'
,
children
:[
{
title
:
'公司介绍'
,
icon
:
'icon-gongsi'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
true
,
identity
:
true
,
type
:
1
},
{
title
:
'案例分享'
,
icon
:
'icon-shiyongjiaocheng'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
true
,
identity
:
true
,
type
:
2
},
{
title
:
'产品分析'
,
icon
:
'icon-shujufenxi'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
true
,
identity
:
true
,
type
:
3
},
{
title
:
'制度'
,
icon
:
'icon-xiaoshoue'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
true
,
identity
:
true
,
type
:
4
},
{
key
:
'company-intro'
,
title
:
'公司介绍'
,
icon
:
'icon-gongsi'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
true
,
identity
:
true
,
type
:
1
},
{
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
:
'cases'
,
title
:
'案例分享'
,
icon
:
'icon-shiyongjiaocheng'
,
link
:
'/pages/personalCenter/detail'
,
isOpen
:
true
,
isShow
:
false
,
identity
:
true
,
type
:
2
},
],
},{
id
:
'04'
,
categoryName
:
'海外资产配置'
,
children
:[
{
title
:
'积分明细'
,
icon
:
'icon-yongjin'
,
link
:
'/pages/personalCenter/helpCenter'
,
isOpen
:
false
,
isShow
:
true
,
islogin
:
true
}
],
},
{
id
:
'02'
,
categoryName
:
'帮助'
,
...
...
@@ -619,11 +623,48 @@
}
});
},
setSpecificMenuIsShow
(
mainMenus
,
permKeys
){
// 找到id=03的主菜单
const
targetMenu
=
mainMenus
.
find
(
menu
=>
menu
.
id
===
'03'
);
if
(
permKeys
){
// 提取权限数组中的key
const
validKeys
=
permKeys
.
map
(
item
=>
item
.
key
);
if
(
targetMenu
&&
targetMenu
.
children
)
{
// 只遍历该菜单的children
targetMenu
.
children
.
forEach
(
subMenu
=>
{
if
(
subMenu
.
key
&&
validKeys
.
includes
(
subMenu
.
key
))
{
subMenu
.
isShow
=
true
;
}
else
{
subMenu
.
isShow
=
false
;
}
});
}
}
else
{
if
(
targetMenu
&&
targetMenu
.
children
)
{
// 只遍历该菜单的children
targetMenu
.
children
.
forEach
(
subMenu
=>
{
// 只有当key不是'company-intro'时,才设置isShow为false
if
(
subMenu
.
key
!==
'company-intro'
)
{
subMenu
.
isShow
=
false
;
}
});
}
}
return
mainMenus
;
},
// 查询个人资料
queryInfo
(){
api
.
queryInfo
({
userId
:
uni
.
getStorageSync
(
'cffp_userId'
)}).
then
(
res
=>
{
if
(
res
[
'success'
]){
this
.
customerBasicInfo
=
res
[
'data'
];
// id=03的权限设置
// 执行处理
const
result
=
this
.
setSpecificMenuIsShow
(
this
.
mainMenuLists
,
this
.
customerBasicInfo
.
accessPermission
);
// 输出结果(仅展示id=03的children验证效果)
// console.log('处理后的"学习研讨"子菜单:',
// JSON.stringify(result.find(menu => menu.id === '03')?.children, null, 2));
let
name
=
this
.
customerBasicInfo
.
realName
||
this
.
customerBasicInfo
.
nickName
if
(
name
&&
name
.
length
>
4
){
this
.
showMyName
=
name
.
substring
(
0
,
4
)
+
'...'
...
...
pages/saleCourseLists/saleCourseLists.vue
View file @
3967d642
...
...
@@ -48,8 +48,8 @@
<!-- 分享明细 -->
<view
class=
"saleDetailContent"
:style=
"
{flex:userCourses.length
<
=
0
||
userShareCourseOrders
.
length
<
=
0
?'
1
'
:
''}"
>
<view
class=
"courseTab"
>
<text
:class=
"
{'actived':tabType===1}" @click="switchTab(1)">我的订单
</text>
<text
:class=
"
{'actived':tabType===2}" @click="switchTab(2)">分享订单
</text>
<text
:class=
"
{'actived':tabType===1}" @click="switchTab(1)">我的订单
</text>
</view>
<view
class=
"totalCountBox"
>
合计(单):
<text>
{{
userCourseCountNum
}}
</text></view>
<h4
class=
"noListTip"
v-if=
"!userCourses || userCourses.length
<
=
0
&&
tabType=
==1"
>
暂无购买记录!
</h4>
...
...
@@ -134,7 +134,7 @@
userShareCourseOrders
:[],
userCourseCountNum
:
0
,
userShareCourseCount
:
0
,
tabType
:
1
,
tabType
:
2
,
partnerType
:
''
}
},
...
...
static/pdf/web/viewer.css
View file @
3967d642
...
...
@@ -5914,6 +5914,7 @@ body.wait::before{
.toolbar
{
z-index
:
2
;
display
:
none
!important
;
}
#toolbarSidebar
{
...
...
util/interceptor.ts
View file @
3967d642
...
...
@@ -114,7 +114,8 @@ const whiteApiList = [`${apiURL}/authorize/obtainToken`,
export
const
interceptor
=
()
=>
{
uni
.
addInterceptor
(
'request'
,
{
// 请求拦截器
invoke
(
args
)
{
invoke
(
args
)
{
// alert(JSON.stringify(args))
// 当本地没有token,并且接口地址没在白名单内,需要重新获取token
if
(
!
uni
.
getStorageSync
(
'uni-token'
)
&&
!
whiteApiList
.
includes
(
args
.
url
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment