Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
2
合并请求
2
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
4a7526c1
提交
4a7526c1
authored
4月 23, 2026
作者:
朱政
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:风险信号样式调整
上级
5ba7a5e0
流水线
#616
已通过 于阶段
in 1 分 49 秒
变更
4
流水线
1
隐藏空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
144 行增加
和
79 行删除
+144
-79
index.vue
src/views/characterPage/index.vue
+34
-7
index.vue
src/views/coopRestriction/detail/index.vue
+24
-4
index.vue
src/views/decree/institution/index.vue
+47
-1
index.vue
src/views/viewRiskSignal/index.vue
+39
-67
没有找到文件。
src/views/characterPage/index.vue
浏览文件 @
4a7526c1
...
@@ -20,24 +20,51 @@ const route = useRoute();
...
@@ -20,24 +20,51 @@ const route = useRoute();
const
type
=
ref
(
route
.
query
.
type
||
1
);
const
type
=
ref
(
route
.
query
.
type
||
1
);
const
decodeMaybeBase64
=
(
raw
)
=>
{
const
decodeMaybeBase64
=
(
raw
)
=>
{
if
(
raw
==
null
)
return
null
;
if
(
raw
==
null
)
return
null
;
cons
t
s0
=
String
(
raw
).
trim
();
le
t
s0
=
String
(
raw
).
trim
();
if
(
!
s0
)
return
null
;
if
(
!
s0
)
return
null
;
// 兼容 URL 里被 encodeURIComponent 的 base64(例如 OTg%3D)
if
(
s0
.
includes
(
"%"
))
{
try
{
const
decodedOnce
=
decodeURIComponent
(
s0
);
if
(
decodedOnce
)
s0
=
String
(
decodedOnce
).
trim
();
}
catch
(
_
)
{
}
}
// 明文 personId(如 Y000064)保持原样,避免误解码
// 明文 personId(如 Y000064)保持原样,避免误解码
if
(
/^
[
A-Za-z
]\d{6,}
$/
.
test
(
s0
)
||
/^Y
\d
+/i
.
test
(
s0
))
{
if
(
/^
[
A-Za-z
]\d{6,}
$/
.
test
(
s0
)
||
/^Y
\d
+/i
.
test
(
s0
))
{
return
s0
;
return
s0
;
}
}
if
(
s0
.
length
>=
12
&&
/^
[
A-Za-z0-9+
/
_-
]
+=
{0,2}
$/
.
test
(
s0
))
{
// 只在“可逆校验通过”时才把它当作 base64(encodeURIComponent(x))
if
(
!
/^
[
A-Za-z0-9+
/
_-
]
+=
{0,2}
$/
.
test
(
s0
))
return
s0
;
const
encodeBase64Param
=
(
val
)
=>
{
const
s
=
String
(
val
??
""
).
trim
();
if
(
!
s
)
return
""
;
try
{
try
{
const
normalized
=
s0
.
replace
(
/-/g
,
"+"
).
replace
(
/_/g
,
"/"
);
return
btoa
(
encodeURIComponent
(
s
));
const
padded
=
normalized
+
"==="
.
slice
((
normalized
.
length
+
3
)
%
4
);
}
catch
(
_
)
{
const
decoded
=
atob
(
padded
);
return
s
;
}
};
const
normalizeBase64
=
(
s
)
=>
{
const
normalized
=
String
(
s
??
""
).
replace
(
/-/g
,
"+"
).
replace
(
/_/g
,
"/"
);
return
normalized
+
"==="
.
slice
((
normalized
.
length
+
3
)
%
4
);
};
try
{
const
padded
=
normalizeBase64
(
s0
);
const
decoded
=
atob
(
padded
);
const
decodedStr
=
(()
=>
{
try
{
try
{
return
decodeURIComponent
(
decoded
);
return
decodeURIComponent
(
decoded
);
}
catch
(
_
)
{
}
catch
(
_
)
{
return
decoded
;
return
decoded
;
}
}
}
catch
(
_
)
{
}
})();
}
const
reEncoded
=
encodeBase64Param
(
decodedStr
);
if
(
reEncoded
&&
normalizeBase64
(
reEncoded
)
===
padded
)
{
return
decodedStr
;
}
}
catch
(
_
)
{
}
return
s0
;
return
s0
;
};
};
const
personId
=
ref
(
decodeMaybeBase64
(
route
.
query
.
personId
)
||
"Y000064"
);
const
personId
=
ref
(
decodeMaybeBase64
(
route
.
query
.
personId
)
||
"Y000064"
);
...
...
src/views/coopRestriction/detail/index.vue
浏览文件 @
4a7526c1
...
@@ -235,15 +235,35 @@ const handleClickOnEntity = (item) => {
...
@@ -235,15 +235,35 @@ const handleClickOnEntity = (item) => {
}
}
})();
})();
if
(
!
encodedPersonId
)
return
;
if
(
!
encodedPersonId
)
return
;
const
url
=
`http://localhost:3000/characterPage?type=2&personId=
${
encodeURIComponent
(
encodedPersonId
)}
`
;
const
{
href
}
=
router
.
resolve
({
window
.
open
(
url
,
"_blank"
);
path
:
"/characterPage"
,
query
:
{
type
:
2
,
personId
:
encodedPersonId
}
});
window
.
open
(
href
,
"_blank"
);
return
;
return
;
}
}
// 默认按公司/机构跳转(含 ENTITYTYPE === 'O' 或字段缺失)
// 默认按公司/机构跳转(含 ENTITYTYPE === 'O' 或字段缺失)
const
companyId
=
item
?.
ENTITYID
||
item
?.
id
;
const
companyId
=
item
?.
ENTITYID
||
item
?.
id
;
if
(
!
companyId
)
return
;
if
(
!
companyId
)
return
;
const
path
=
`/companyPages/
${
companyId
}
`
;
const
encodedInstitutionId
=
(()
=>
{
const
{
href
}
=
router
.
resolve
({
path
});
const
s
=
String
(
companyId
??
""
).
trim
();
if
(
!
s
)
return
""
;
try
{
return
btoa
(
encodeURIComponent
(
s
));
}
catch
(
_
)
{
return
s
;
}
})();
if
(
!
encodedInstitutionId
)
return
;
const
{
href
}
=
router
.
resolve
({
path
:
"/institution"
,
query
:
{
id
:
encodedInstitutionId
}
});
window
.
open
(
href
,
"_blank"
);
window
.
open
(
href
,
"_blank"
);
};
};
...
...
src/views/decree/institution/index.vue
浏览文件 @
4a7526c1
...
@@ -48,6 +48,52 @@ import { ElMessage } from "element-plus";
...
@@ -48,6 +48,52 @@ import { ElMessage } from "element-plus";
const
route
=
useRoute
();
const
route
=
useRoute
();
const
decodeMaybeBase64
=
(
raw
)
=>
{
if
(
raw
==
null
)
return
""
;
let
s0
=
String
(
raw
).
trim
();
if
(
!
s0
)
return
""
;
if
(
s0
.
includes
(
"%"
))
{
try
{
const
decodedOnce
=
decodeURIComponent
(
s0
);
if
(
decodedOnce
)
s0
=
String
(
decodedOnce
).
trim
();
}
catch
(
_
)
{
}
}
// 非 base64 直接返回(机构 id 含字母数字,明文也要支持)
if
(
!
/^
[
A-Za-z0-9+
/
_-
]
+=
{0,2}
$/
.
test
(
s0
))
return
s0
;
const
encodeBase64Param
=
(
val
)
=>
{
const
s
=
String
(
val
??
""
).
trim
();
if
(
!
s
)
return
""
;
try
{
return
btoa
(
encodeURIComponent
(
s
));
}
catch
(
_
)
{
return
s
;
}
};
const
normalizeBase64
=
(
s
)
=>
{
const
normalized
=
String
(
s
??
""
).
replace
(
/-/g
,
"+"
).
replace
(
/_/g
,
"/"
);
return
normalized
+
"==="
.
slice
((
normalized
.
length
+
3
)
%
4
);
};
try
{
const
padded
=
normalizeBase64
(
s0
);
const
decoded
=
atob
(
padded
);
const
decodedStr
=
(()
=>
{
try
{
return
decodeURIComponent
(
decoded
);
}
catch
(
_
)
{
return
decoded
;
}
})();
const
reEncoded
=
encodeBase64Param
(
decodedStr
);
if
(
reEncoded
&&
normalizeBase64
(
reEncoded
)
===
padded
)
{
return
decodedStr
;
}
}
catch
(
_
)
{
}
return
s0
;
};
const
institutionId
=
computed
(()
=>
decodeMaybeBase64
(
route
.
query
.
id
));
const
institutionInfo
=
ref
({
const
institutionInfo
=
ref
({
name
:
""
,
name
:
""
,
enName
:
""
,
enName
:
""
,
...
@@ -66,7 +112,7 @@ const showTagList = computed(() => {
...
@@ -66,7 +112,7 @@ const showTagList = computed(() => {
const
handleGetInfo
=
async
()
=>
{
const
handleGetInfo
=
async
()
=>
{
const
params
=
{
const
params
=
{
id
:
route
.
query
.
id
id
:
institutionId
.
value
};
};
try
{
try
{
const
res
=
await
getGovOrgBasicInfo
(
params
);
const
res
=
await
getGovOrgBasicInfo
(
params
);
...
...
src/views/viewRiskSignal/index.vue
浏览文件 @
4a7526c1
...
@@ -173,59 +173,43 @@
...
@@ -173,59 +173,43 @@
<div
class=
"search-btn"
@
click=
"handleSearch"
></div>
<div
class=
"search-btn"
@
click=
"handleSearch"
></div>
</div>
</div>
<div
class=
"select-box"
>
<div
class=
"select-box"
>
<el-select
v-model=
"sortModel"
class=
"resource-library-sort-select"
placeholder=
"发布时间"
<TimeSortSelectBox
:sort-demension=
"1"
@
handlePxChange=
"handleTimeSortChange"
/>
style=
"width: 120px"
:teleported=
"true"
placement=
"bottom-start"
:popper-options=
"resourceLibrarySortPopperOptions"
@
change=
"handleSortChange"
>
<template
#
prefix
>
<img
v-if=
"sortValue === 1"
src=
"@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image down.png"
class=
"resource-library-sort-prefix-img"
alt=
""
@
click
.
stop=
"toggleSortPrefix"
/>
<img
v-else
src=
"@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image up.png"
class=
"resource-library-sort-prefix-img"
alt=
""
@
click
.
stop=
"toggleSortPrefix"
/>
</
template
>
<el-option
:key=
"'risk-sort-asc'"
label=
"正序"
:value=
"0"
/>
<el-option
:key=
"'risk-sort-desc'"
label=
"倒序"
:value=
"1"
/>
</el-select>
</div>
</div>
</div>
</div>
</div>
</div>
<
template
v-if=
"riskList && riskList.length"
>
<div
v-if=
"riskList && riskList.length"
class=
"right-main"
>
<div
class=
"right-main"
>
<div
class=
"itemlist itemlist--clickable"
v-for=
"(val, idx) in riskList"
:key=
"val.rowKey"
<div
class=
"itemlist itemlist--clickable"
v-for=
"(val, idx) in riskList"
:key=
"val.rowKey"
@
click=
"handleOpenRiskDetail(val)"
>
@
click=
"handleOpenRiskDetail(val)"
>
<div
class=
"box-title"
>
<div
class=
"box-title"
>
<div
class=
"risktitle"
v-html=
"highlightRiskText(val.title)"
/>
<div
class=
"risktitle"
v-html=
"highlightRiskText(val.title)"
/>
<div
v-if=
"!isRiskLevelNoData(val.risktype)"
class=
"risktype"
<div
v-if=
"!isRiskLevelNoData(val.risktype)"
class=
"risktype"
:class=
"'risktype--' + getRiskListItemLevelKey(val.risktype)"
>
:class=
"'risktype--' + getRiskListItemLevelKey(val.risktype)"
>
<div
class=
"icon"
:class=
"'icon--' + getRiskListItemLevelKey(val.risktype)"
/>
<div
class=
"icon"
:class=
"'icon--' + getRiskListItemLevelKey(val.risktype)"
/>
<div
class=
"text"
>
{{
getRiskListItemLevelLabel
(
val
.
risktype
)
}}
</div>
<div
class=
"text"
>
{{
getRiskListItemLevelLabel
(
val
.
risktype
)
}}
</div>
</div>
</div>
<div
class=
"box-source"
>
<img
class=
"source-pic"
:src=
"val.pic || DefaultIcon2"
alt=
""
/>
<div
class=
"source-text"
>
{{
formatRiskSourceLine
(
val
)
}}
</div>
</div>
<div
class=
"desc-box"
v-html=
"highlightRiskText(val.dsc)"
/>
<div
class=
"tag-box"
v-if=
"val.tag.length"
>
<AreaTag
v-for=
"(tag, index) in val.tag"
:key=
"index"
:tagName=
"tag"
>
{{
tag
}}
</AreaTag>
</div>
</div>
</div>
</div>
</div>
<div
class=
"box-source"
>
<div
class=
"right-footer"
>
<img
class=
"source-pic"
:src=
"val.pic || DefaultIcon2"
alt=
""
/>
<div
class=
"footer-left"
>
<div
class=
"source-text"
>
{{
formatRiskSourceLine
(
val
)
}}
</div>
{{
`共 ${formatThousands(totalNum)
}
项调查`
}}
</div>
</div>
<
div
class
=
"
footer-right"
>
<div
class=
"
desc-box"
v-html=
"highlightRiskText(val.dsc)"
/
>
<
el
-
pagination
@
current
-
change
=
"handleCurrentChange"
:
pageSize
=
"pageSize"
:
current
-
page
=
"currentPage"
<div
class=
"tag-box"
v-if=
"val.tag.length"
>
:
total
=
"totalNum"
background
layout
=
"prev, pager, next"
/
>
<AreaTag
v-for=
"(tag, index) in val.tag"
:key=
"index"
:tagName=
"tag"
>
{{
tag
}}
</AreaTag
>
</div>
</div>
</div>
</div>
<
/template
>
</div>
<
template
v
-
else
>
<div
v-else
class=
"right-empty"
>
<
div
class
=
"right-empty"
>
<el-empty
class=
"right-el-empty"
description=
"暂无数据"
:image-size=
"100"
/>
<
el
-
empty
class
=
"right-el-empty"
description
=
"暂无数据"
:
image
-
size
=
"100"
/>
</div>
<div
class=
"right-footer"
>
<div
class=
"footer-left"
>
{{
`共 ${formatThousands(totalNum)
}
项调查`
}}
<
/div
>
<
div
class
=
"footer-right"
>
<
el
-
pagination
@
current
-
change
=
"handleCurrentChange"
:
pageSize
=
"pageSize"
:
current
-
page
=
"currentPage"
:
total
=
"totalNum"
background
layout
=
"prev, pager, next"
/>
<
/div
>
<
/div
>
<
/
template
>
<
/
div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -311,12 +295,14 @@ import riskSourceUpArrow from "./assets/images/up-arrow.png";
...
@@ -311,12 +295,14 @@ import riskSourceUpArrow from "./assets/images/up-arrow.png";
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
{
normalizeExclusiveAllOption
}
from
"@/views/thinkTank/utils/resourceLibraryFilters"
;
import
{
normalizeExclusiveAllOption
}
from
"@/views/thinkTank/utils/resourceLibraryFilters"
;
import
TimeSortSelectBox
from
"@/components/base/TimeSortSelectBox/index.vue"
;
const
riskTypeOptions
=
ref
([]);
const
riskTypeOptions
=
ref
([]);
const
RISK_FILTER_ALL_TYPE
=
"全部类型"
;
const
RISK_FILTER_ALL_TYPE
=
"全部类型"
;
const
selectedRiskTypeModel
=
ref
([
RISK_FILTER_ALL_TYPE
]);
const
selectedRiskTypeModel
=
ref
([
RISK_FILTER_ALL_TYPE
]);
const
handleRiskTypeGroupChange
=
(
val
)
=>
{
const
handleRiskTypeGroupChange
=
(
val
)
=>
{
selectedRiskTypeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_TYPE
);
selectedRiskTypeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_TYPE
);
currentPage
.
value
=
1
;
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -336,6 +322,7 @@ const timeSource = ref([
...
@@ -336,6 +322,7 @@ const timeSource = ref([
const
selectedTimeModel
=
ref
([
Time_FILTER_ALL_SOURCE
]);
const
selectedTimeModel
=
ref
([
Time_FILTER_ALL_SOURCE
]);
const
handleTimeGroupChange
=
(
val
)
=>
{
const
handleTimeGroupChange
=
(
val
)
=>
{
selectedTimeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
Time_FILTER_ALL_SOURCE
);
selectedTimeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
Time_FILTER_ALL_SOURCE
);
currentPage
.
value
=
1
;
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -351,6 +338,7 @@ const RISK_FILTER_ALL_SOURCE = "全部国家";
...
@@ -351,6 +338,7 @@ const RISK_FILTER_ALL_SOURCE = "全部国家";
const
selectedRiskSourceModel
=
ref
([
RISK_FILTER_ALL_SOURCE
]);
const
selectedRiskSourceModel
=
ref
([
RISK_FILTER_ALL_SOURCE
]);
const
handleRiskSourceGroupChange
=
(
val
)
=>
{
const
handleRiskSourceGroupChange
=
(
val
)
=>
{
selectedRiskSourceModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_SOURCE
);
selectedRiskSourceModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_SOURCE
);
currentPage
.
value
=
1
;
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -384,6 +372,7 @@ const RISK_FILTER_ALL_LEVEL = "全部等级";
...
@@ -384,6 +372,7 @@ const RISK_FILTER_ALL_LEVEL = "全部等级";
const
selectedRiskDegreeModel
=
ref
([
RISK_FILTER_ALL_LEVEL
]);
const
selectedRiskDegreeModel
=
ref
([
RISK_FILTER_ALL_LEVEL
]);
const
handleRiskDegreeGroupChange
=
(
val
)
=>
{
const
handleRiskDegreeGroupChange
=
(
val
)
=>
{
selectedRiskDegreeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_LEVEL
);
selectedRiskDegreeModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_LEVEL
);
currentPage
.
value
=
1
;
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -410,6 +399,7 @@ const RISK_FILTER_ALL_AREA = "全部领域";
...
@@ -410,6 +399,7 @@ const RISK_FILTER_ALL_AREA = "全部领域";
const
selectedAreaModel
=
ref
([
RISK_FILTER_ALL_AREA
]);
const
selectedAreaModel
=
ref
([
RISK_FILTER_ALL_AREA
]);
const
handleAreaGroupChange
=
(
val
)
=>
{
const
handleAreaGroupChange
=
(
val
)
=>
{
selectedAreaModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_AREA
);
selectedAreaModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RISK_FILTER_ALL_AREA
);
currentPage
.
value
=
1
;
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -710,26 +700,10 @@ const handleCleandarChart = async () => {
...
@@ -710,26 +700,10 @@ const handleCleandarChart = async () => {
/** sort:0 正序;1 倒序;接口默认倒序=1 */
/** sort:0 正序;1 倒序;接口默认倒序=1 */
const
sortValue
=
ref
(
1
);
const
sortValue
=
ref
(
1
);
/** el-select 展示用:默认 null => 显示 placeholder「发布时间」 */
const
handleTimeSortChange
=
(
val
)
=>
{
const
sortModel
=
ref
(
null
);
// TimeSortSelectBox: 1=时间倒序,2=时间正序
sortValue
.
value
=
val
===
2
?
0
:
1
;
const
resourceLibrarySortPopperOptions
=
{
currentPage
.
value
=
1
;
modifiers
:
[
{
name
:
"preventOverflow"
,
options
:
{
mainAxis
:
false
,
altAxis
:
false
}
}
,
{
name
:
"flip"
,
enabled
:
false
}
]
}
;
const
toggleSortPrefix
=
()
=>
{
sortValue
.
value
=
sortValue
.
value
===
1
?
0
:
1
;
sortModel
.
value
=
sortValue
.
value
;
handleSortChange
();
}
;
const
handleSortChange
=
()
=>
{
if
(
sortModel
.
value
===
0
||
sortModel
.
value
===
1
)
{
sortValue
.
value
=
sortModel
.
value
;
}
handleGetPageQuery
();
handleGetPageQuery
();
}
;
}
;
...
@@ -1308,9 +1282,7 @@ onMounted(async () => {
...
@@ -1308,9 +1282,7 @@ onMounted(async () => {
}
}
.
select
-
box
{
.
select
-
box
{
width
:
120
px
;
height
:
32
px
;
box
-
sizing
:
border
-
box
;
.
resource
-
library
-
sort
-
select
{
.
resource
-
library
-
sort
-
select
{
:
deep
(.
el
-
select__wrapper
)
{
:
deep
(.
el
-
select__wrapper
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论