Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
47bc38c9
提交
47bc38c9
authored
3月 12, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat 新增法案原文页面
feat 完成法案概况-内容概要页面 fix 修复法案首页某些bug
上级
fd608e1e
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
763 行增加
和
79 行删除
+763
-79
bill.js
src/api/bill.js
+1
-1
billHome.js
src/api/bill/billHome.js
+10
-0
request.js
src/api/request.js
+9
-0
index.vue
src/components/base/SiderTabs/index.vue
+3
-3
analysisBox.vue
src/components/base/boxBackground/analysisBox.vue
+17
-0
bill.js
src/router/modules/bill.js
+9
-0
WordCloudMap.vue
src/views/bill/background/WordCloudMap.vue
+1
-1
index.vue
src/views/bill/background/index.vue
+4
-4
ResourceLibrarySection.vue
src/views/bill/billHome/ResourceLibrarySection.vue
+0
-0
index.vue
src/views/bill/billHome/index.vue
+101
-45
doublePieChart.js
src/views/bill/billHome/utils/doublePieChart.js
+21
-6
BillHeader.vue
src/views/bill/billLayout/components/BillHeader.vue
+441
-0
index.vue
src/views/bill/billLayout/index.vue
+0
-0
index.vue
src/views/bill/billOriginalText/index.vue
+110
-0
index.vue
src/views/bill/index.vue
+28
-18
STimeline.vue
src/views/bill/introdoction/STimeline.vue
+1
-1
compare-icon.svg
src/views/bill/template/assets/icons/compare-icon.svg
+3
-0
translate-icon.svg
src/views/bill/template/assets/icons/translate-icon.svg
+4
-0
index.vue
src/views/bill/template/index.vue
+0
-0
没有找到文件。
src/api/bill.js
浏览文件 @
47bc38c9
...
...
@@ -117,7 +117,7 @@ export function getBillContentId(params) {
// 主要条款-根据原文ID获取条款内容
/**
* @param {bill
id,id,cRelated,currentPage,pageSize
}
* @param {bill
Id,id,cRelated,currentPage,pageSize,domainNameList,measuresNameList,content
}
* @header token
*/
export
function
getBillContentTk
(
params
)
{
...
...
src/api/bill/billHome.js
浏览文件 @
47bc38c9
...
...
@@ -145,6 +145,16 @@ export function getBillsPersonRel(params, signal) {
})
}
// 获取涉华委员会及其法案
export
function
getBillsIsCnCommittee
(
params
,
signal
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/billsIsCnCommittee`
,
params
,
signal
})
}
// 获取提出部门列表
export
function
getPostOrgList
()
{
return
request
({
...
...
src/api/request.js
浏览文件 @
47bc38c9
...
...
@@ -72,6 +72,15 @@ service.interceptors.response.use(
},
error
=>
{
console
.
log
(
'err'
+
error
)
const
isCanceledError
=
error
?.
code
===
'ERR_CANCELED'
||
error
?.
name
===
'CanceledError'
||
error
?.
name
===
'AbortError'
||
(
typeof
error
?.
message
===
'string'
&&
/canceled/i
.
test
(
error
.
message
))
// 重复请求触发的取消不提示错误
if
(
isCanceledError
)
return
Promise
.
reject
(
error
)
// 处理token过期或无效的情况
if
(
error
.
response
&&
(
error
.
response
.
status
===
401
||
error
.
response
.
status
===
403
))
{
...
...
src/components/base/SiderTabs/index.vue
浏览文件 @
47bc38c9
...
...
@@ -2,14 +2,14 @@
<div
class=
"sider-tabs-wrapper"
>
<div
class=
"sider-item"
:class=
"
{'sider-item-active': sider.active}"
v-for="
sider, index in siderList" :key="
index"
v-for="
(sider, index) in siderList" :key="sider.name ||
index"
@click="handleClickSiderItem(sider)"
>
<div
class=
"sider-item-text text-primary-65-clor text-tip-1"
:class=
"
{'sider-item-text-active': sider.active}">
{{
sider
.
name
}}
</div>
<div
class=
"sider-item-icon"
v-show=
"sider.active"
>
<img
src=
"./active-icon.svg"
alt=
""
>
<img
src=
"./active-icon.svg"
alt=
""
/
>
</div>
</div>
</div>
...
...
@@ -20,7 +20,7 @@
const
props
=
defineProps
({
siderList
:
{
type
:
Array
,
default
:
[
default
:
()
=>
[
{
name
:
'分析内容1'
,
active
:
true
...
...
src/components/base/boxBackground/analysisBox.vue
浏览文件 @
47bc38c9
...
...
@@ -47,21 +47,38 @@ const props = defineProps({
showAllBtn
:
{
type
:
Boolean
,
default
:
true
},
// 当业务功能尚未实现时,点击右上角图标仅弹出统一提示
devTip
:
{
type
:
Boolean
,
default
:
false
}
})
const
handleSave
=
()
=>
{
if
(
props
.
devTip
)
{
ElMessage
.
warning
(
'当前功能正在开发中,敬请期待!'
)
return
}
ElMessage
.
success
(
'保存当前内容'
)
// emit('save')
}
const
handleDownload
=
()
=>
{
if
(
props
.
devTip
)
{
ElMessage
.
warning
(
'当前功能正在开发中,敬请期待!'
)
return
}
ElMessage
.
success
(
'下载当前内容'
)
// emit('download')
}
const
handleCollect
=
()
=>
{
if
(
props
.
devTip
)
{
ElMessage
.
warning
(
'当前功能正在开发中,敬请期待!'
)
return
}
ElMessage
.
success
(
'收藏当前内容'
)
// emit('collect')
...
...
src/router/modules/bill.js
浏览文件 @
47bc38c9
...
...
@@ -13,6 +13,7 @@ const BillInfluenceLayout = () => import('@/views/bill/influence/index.vue')
const
BillInfluenceIndustry
=
()
=>
import
(
'@/views/bill/influence/industry/index.vue'
)
const
BillInfluenceScientificResearch
=
()
=>
import
(
'@/views/bill/influence/scientificResearch/index.vue'
)
const
BillRelevantCircumstance
=
()
=>
import
(
'@/views/bill/relevantCircumstance/index.vue'
)
const
BillOriginalText
=
()
=>
import
(
'@/views/bill/billOriginalText/index.vue'
)
const
billRoutes
=
[
...
...
@@ -35,6 +36,14 @@ const billRoutes = [
dynamicTitle
:
true
// 标记需要动态设置标题
},
children
:
[
{
path
:
"originalText"
,
name
:
"BillOriginalText"
,
component
:
BillOriginalText
,
meta
:
{
title
:
"法案原文"
}
},
// 法案分析路由
{
path
:
"bill"
,
...
...
src/views/bill/background/WordCloudMap.vue
浏览文件 @
47bc38c9
...
...
@@ -51,7 +51,7 @@ const initChart = () => {
color
:
"#fff"
,
backgroundColor
:
"rgba(189, 33, 33, 0.9)"
,
borderRadius
:
20
,
padding
:
[
8
,
16
]
// 适当增加 padding 以确保背景块足够大
padding
:
[
10
,
16
]
// 适当增加 padding 以确保背景块足够大
}
};
}
...
...
src/views/bill/background/index.vue
浏览文件 @
47bc38c9
<
template
>
<div
class=
"background-wrap"
>
<div
class=
"background-wrap-left"
>
<AnalysisBox
class=
"left-box left-box--background"
title=
"立法背景"
:showAllBtn=
"false"
>
<AnalysisBox
class=
"left-box left-box--background"
title=
"立法背景"
:showAllBtn=
"false"
:devTip=
"true"
>
<template
#
header-btn
>
<div
class=
"header-btn-box"
>
<el-button
:type=
"box1Btn1Type"
plain
@
click=
"handleClickBox1Btn(1)"
>
涉华背景
</el-button>
...
...
@@ -28,7 +28,7 @@
</div>
</AnalysisBox>
<AnalysisBox
class=
"left-box left-box--event"
title=
"相关事件"
:showAllBtn=
"false"
>
<AnalysisBox
class=
"left-box left-box--event"
title=
"相关事件"
:showAllBtn=
"false"
:devTip=
"true"
>
<div
class=
"box2-main"
>
<div
class=
"box2-main-item"
v-for=
"item in eventDisplayList"
:key=
"item.id"
@
click=
"handleClickEvent(item)"
>
<div
class=
"left"
>
...
...
@@ -47,7 +47,7 @@
</div>
</AnalysisBox>
</div>
<AnalysisBox
class=
"right-panel"
title=
"议员相关性分析"
:showAllBtn=
"false"
>
<AnalysisBox
class=
"right-panel"
title=
"议员相关性分析"
:showAllBtn=
"false"
:devTip=
"true"
>
<
template
#
header-btn
>
<div
class=
"header-btn-box"
>
<el-button
:type=
"box2Btn1Type"
plain
@
click=
"handleClickBox2Btn(1)"
>
赞成议员
</el-button>
...
...
@@ -266,7 +266,7 @@ const handleGetRelatedEvent = async () => {
};
try
{
const
res
=
await
getBillInfoEvent
(
params
);
eventList
.
value
=
res
.
data
;
eventList
.
value
=
res
.
data
.
slice
(
0
,
5
)
;
}
catch
(
error
)
{
}
};
...
...
src/views/bill/billHome/ResourceLibrarySection.vue
浏览文件 @
47bc38c9
差异被折叠。
点击展开。
src/views/bill/billHome/index.vue
浏览文件 @
47bc38c9
...
...
@@ -101,7 +101,13 @@
<DivideHeader
id=
"position2"
class=
"divide2"
:titleText=
"'资讯要闻'"
></DivideHeader>
<div
class=
"center-center"
>
<NewsList
:list=
"newsList"
/>
<NewsList
:newsList=
"newsList"
img=
"newsImage"
title=
"newsTitle"
from=
"from"
content=
"newsContent"
/>
<MessageBubble
:messageList=
"messageList"
imageUrl=
"personImage"
@
more-click=
"handleToSocialDetail"
@
person-click=
"handleClickToCharacter"
name=
"personName"
content=
"remarks"
source=
"orgName"
/>
...
...
@@ -116,9 +122,12 @@
<el-option
v-for=
"item in categoryList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</
template
>
<div
class=
"box5-main"
:style=
"getEmptyStateStyle(box5HasData)"
>
<el-empty
v-if=
"!box5HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box5Chart"
style=
"width: 100%; height: 100%"
></div>
<div
class=
"overview-card-body box5-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box5HasData }"
>
<el-empty
v-if=
"!box5HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box5Chart"
class=
"overview-chart"
></div>
</div>
<TipTab
class=
"overview-tip"
/>
</div>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box6"
title=
"涉华法案领域分布"
:icon=
"box6HeaderIcon"
>
...
...
@@ -127,9 +136,12 @@
<el-option
v-for=
"item in box9YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</
template
>
<div
class=
"box6-main"
:style=
"getEmptyStateStyle(box9HasData)"
>
<el-empty
v-if=
"!box9HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box9Chart"
style=
"width: 100%; height: 100%"
></div>
<div
class=
"overview-card-body box6-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box9HasData }"
>
<el-empty
v-if=
"!box9HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box9Chart"
class=
"overview-chart"
></div>
</div>
<TipTab
class=
"overview-tip"
/>
</div>
</OverviewCard>
</div>
...
...
@@ -140,9 +152,12 @@
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</
template
>
<div
class=
"box7-main"
:style=
"getEmptyStateStyle(box7HasData)"
>
<el-empty
v-if=
"!box7HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box7Chart"
style=
"width: 100%; height: 100%"
></div>
<div
class=
"overview-card-body box7-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box7HasData }"
>
<el-empty
v-if=
"!box7HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box7Chart"
class=
"overview-chart"
></div>
</div>
<TipTab
class=
"overview-tip"
/>
</div>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box8"
title=
"涉华法案进展分布"
:icon=
"box7HeaderIcon"
>
...
...
@@ -151,16 +166,24 @@
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</
template
>
<div
class=
"box8-main"
:style=
"getEmptyStateStyle(box8HasData)"
>
<el-empty
v-if=
"!box8HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<
template
v-else
>
<div
class=
"box8-desc"
>
• 通过涉华法案
{{
box8Summary
}}
项
</div>
<div
id=
"box8Chart"
class=
"box8-chart"
></div>
</
template
>
<div
class=
"overview-card-body box8-main"
>
<div
class=
"overview-chart-wrap"
:class=
"{ 'is-empty': !box8HasData }"
>
<el-empty
v-if=
"!box8HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<
template
v-else
>
<div
class=
"box8-desc"
>
• 通过涉华法案
{{
box8Summary
}}
项
</div>
<div
id=
"box8Chart"
class=
"overview-chart box8-chart"
></div>
</
template
>
</div>
<TipTab
class=
"overview-tip"
/>
</div>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box9"
title=
"涉华法案关键条款"
:icon=
"box7HeaderIcon"
>
<div
class=
"box9-main"
id=
"wordCloudChart"
></div>
<div
class=
"overview-card-body box9-main"
>
<div
class=
"overview-chart-wrap"
>
<div
id=
"wordCloudChart"
class=
"overview-chart"
></div>
</div>
<TipTab
class=
"overview-tip"
/>
</div>
</OverviewCard>
</div>
</div>
...
...
@@ -196,6 +219,7 @@ import overviewMainBox from "@/components/base/boxBackground/overviewMainBox.vue
import
OverviewCard
from
"./OverviewCard.vue"
;
import
ResourceLibrarySection
from
"./ResourceLibrarySection.vue"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
TipTab
from
"@/components/base/TipTab/index.vue"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
getWordCloudChart
from
"./utils/worldCloudChart"
;
...
...
@@ -325,12 +349,6 @@ const handleToMoreRiskSignal = () => {
// 风险信号
const
warningList
=
ref
([]);
const
getEmptyStateStyle
=
hasData
=>
({
display
:
hasData
?
"block"
:
"flex"
,
justifyContent
:
"center"
,
alignItems
:
"center"
});
const
box7selectetedTime
=
ref
(
"2025"
);
const
box7YearList
=
ref
([
{
...
...
@@ -420,15 +438,15 @@ const handleGetNews = async () => {
try
{
const
res
=
await
getNews
(
params
);
console
.
log
(
"新闻资讯"
,
res
);
if
(
res
.
code
===
200
)
{
newsList
.
value
=
re
s
.
data
||
[].
map
(
item
=>
{
return
{
...
item
,
from
:
`
${
item
.
newsOrg
}
·
${
item
.
newsDate
?
item
.
newsDate
.
slice
(
5
)
:
""
}
`
};
})
;
if
(
res
.
code
===
200
&&
Array
.
isArray
(
res
.
data
)
)
{
newsList
.
value
=
res
.
data
.
map
(
item
=>
{
re
turn
{
...
item
,
from
:
`
${
item
.
newsOrg
}
·
${
item
.
newsDate
?
item
.
newsDate
.
slice
(
5
)
:
""
}
`
};
});
}
else
{
newsList
.
value
=
[]
;
}
}
catch
(
error
)
{
}
};
...
...
@@ -568,17 +586,28 @@ const handleBox7Data = async () => {
await
nextTick
();
const
data1
=
[];
const
houseTotal
=
Number
(
orgBillNumMap
?.
H
||
0
);
const
senateTotal
=
Number
(
orgBillNumMap
?.
S
||
0
);
const
houseTotal
=
Number
(
orgBillNumMap
?.
H
ouse
||
0
);
const
senateTotal
=
Number
(
orgBillNumMap
?.
S
enate
||
0
);
if
(
houseTotal
>
0
)
data1
.
push
({
name
:
"众议院"
,
value
:
houseTotal
});
if
(
senateTotal
>
0
)
data1
.
push
({
name
:
"参议院"
,
value
:
senateTotal
});
const
data2
=
orgBillNumList
.
map
(
item
=>
({
name
:
item
.
orgName
,
value
:
Number
(
item
.
count
||
0
),
percent
:
typeof
item
.
percent
===
"number"
?
item
.
percent
:
Number
(
item
.
percent
||
0
),
type
:
item
.
orgType
===
"S"
?
"参议院"
:
"众议院"
}));
const
getOrgTypeLabel
=
orgType
=>
(
orgType
===
"Senate"
?
"参议院"
:
"众议院"
);
const
typeOrderMap
=
{
众议院
:
0
,
参议院
:
1
};
const
data2
=
orgBillNumList
.
map
(
item
=>
({
name
:
item
.
orgName
,
value
:
Number
(
item
.
count
||
0
),
percent
:
typeof
item
.
percent
===
"number"
?
item
.
percent
:
Number
(
item
.
percent
||
0
),
type
:
getOrgTypeLabel
(
item
.
orgType
)
}))
// 关键:外环顺序必须按内环(众→参)分组,否则扇区角度会交错导致“不对应”
.
sort
((
a
,
b
)
=>
{
const
t1
=
typeOrderMap
[
a
.
type
]
??
99
;
const
t2
=
typeOrderMap
[
b
.
type
]
??
99
;
if
(
t1
!==
t2
)
return
t1
-
t2
;
return
(
b
.
value
??
0
)
-
(
a
.
value
??
0
);
});
const
box7Chart
=
getDoublePieChart
(
data1
,
data2
);
setChart
(
box7Chart
,
"box7Chart"
);
...
...
@@ -2051,13 +2080,13 @@ onUnmounted(() => {
.box9-main
{
height
:
100%
;
box-sizing
:
border-box
;
padding
:
8px
30px
;
padding
:
8px
30px
20px
;
}
.box8-main
{
height
:
100%
;
box-sizing
:
border-box
;
padding
:
12px
30px
18
px
;
padding
:
12px
30px
20
px
;
.box8-desc
{
height
:
24px
;
...
...
@@ -2069,14 +2098,41 @@ onUnmounted(() => {
}
.box8-chart
{
width
:
100%
;
height
:
calc
(
100%
-
30px
);
cursor
:
pointer
;
}
}
.box9-main
{
padding
:
10px
30px
;
padding
:
10px
30px
20px
;
}
.overview-card-body
{
display
:
flex
;
flex-direction
:
column
;
}
.overview-chart-wrap
{
flex
:
1
;
min-height
:
0
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
stretch
;
justify-content
:
flex-start
;
&
.is-empty
{
align-items
:
center
;
justify-content
:
center
;
}
}
.overview-chart
{
width
:
100%
;
height
:
100%
;
min-height
:
0
;
}
.overview-tip
{
margin-top
:
10px
;
}
}
}
...
...
src/views/bill/billHome/utils/doublePieChart.js
浏览文件 @
47bc38c9
...
...
@@ -7,9 +7,22 @@ const truncateLabel = (value, maxLen = 6) => {
return
`
${
chars
.
slice
(
0
,
maxLen
).
join
(
''
)}
...`
}
const
getCssVar
=
(
varName
,
fallback
)
=>
{
try
{
if
(
typeof
window
===
'undefined'
)
return
fallback
const
val
=
window
.
getComputedStyle
(
document
.
documentElement
).
getPropertyValue
(
varName
)
return
(
val
||
''
).
trim
()
||
fallback
}
catch
(
e
)
{
return
fallback
}
}
const
getDoublePieChart
=
(
data1
,
data2
)
=>
{
const
colorList
=
[
'#8AC4FF'
,
'#FFD591'
]
const
colorList1
=
[
'#055FC2'
,
'#FFA940'
]
const
senateInnerColor
=
getCssVar
(
'--color-primary-100'
,
'#055FC2'
)
const
senateDeptColor
=
getCssVar
(
'--color-primary-50'
,
'#89C1FF'
)
const
houseInnerColor
=
'rgba(255, 169, 64, 1)'
const
houseDeptColor
=
'rgba(255, 213, 145, 1)'
const
innerLabelColor
=
getCssVar
(
'--text-primary-80-color'
,
'#3b414b'
)
let
option
=
{
series
:
[
{
...
...
@@ -26,14 +39,16 @@ const getDoublePieChart = (data1, data2) => {
position
:
'inside'
,
fontSize
:
'16px'
,
fontWeight
:
700
,
// color: '#333'
color
:
innerLabelColor
,
textBorderColor
:
'#fff'
,
textBorderWidth
:
1
},
data
:
data1
.
map
(
item
=>
{
return
{
name
:
item
.
name
,
value
:
item
.
value
,
itemStyle
:
{
color
:
item
.
name
===
'参议院'
?
'#055FC2'
:
'#FFA940'
color
:
item
.
name
===
'参议院'
?
senateInnerColor
:
houseInnerColor
}
}
})
...
...
@@ -70,7 +85,7 @@ const getDoublePieChart = (data1, data2) => {
time
:
{
fontSize
:
14
,
fontFamily
:
'Microsoft YaHei'
,
color
:
'
#
rgba(95, 101, 108, 1)'
,
color
:
'rgba(95, 101, 108, 1)'
,
padding
:
[
10
,
0
,
10
,
0
]
}
}
...
...
@@ -97,7 +112,7 @@ const getDoublePieChart = (data1, data2) => {
value
:
item
.
value
,
percent
:
item
.
percent
,
itemStyle
:
{
color
:
item
.
type
===
'参议院'
?
'#8AC4FF'
:
'#FFD591'
color
:
item
.
type
===
'参议院'
?
senateDeptColor
:
houseDeptColor
}
}
...
...
src/views/bill/billLayout/components/BillHeader.vue
0 → 100644
浏览文件 @
47bc38c9
<
template
>
<div
class=
"header-main"
>
<div
class=
"layout-main-header"
>
<div
class=
"layout-main-header-left-box"
>
<div
class=
"left-box-top"
>
<el-skeleton
:loading=
"isLoading"
animated
>
<template
#
template
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-avatar"
variant=
"image"
/>
</div>
<div
class=
"info"
>
<el-skeleton-item
class=
"skeleton-title"
variant=
"h1"
/>
<el-skeleton-item
class=
"skeleton-subtitle"
variant=
"text"
/>
</div>
</
template
>
<
template
#
default
>
<div
class=
"icon"
>
<img
:src=
"billInfo?.imageUrl || defaultLogo"
alt=
""
/>
</div>
<div
class=
"info"
>
<div
class=
"info-box1"
>
{{
billInfo
?.
billName
}}
</div>
<div
class=
"info-box2"
>
{{
billInfo
?.
description
}}
{{
billInfo
?.
billNameEn
}}
</div>
</div>
</
template
>
</el-skeleton>
</div>
<div
class=
"left-box-bottom"
v-if=
"showTabs"
>
<
template
v-if=
"isLoading"
>
<div
class=
"left-box-bottom-item is-skeleton"
v-for=
"n in 4"
:key=
"n"
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-tab-icon"
variant=
"text"
/>
</div>
<div
class=
"name"
>
<el-skeleton-item
class=
"skeleton-tab-text"
variant=
"text"
/>
</div>
</div>
</
template
>
<
template
v-else
>
<div
class=
"left-box-bottom-item"
:class=
"
{ leftBoxBottomItemActive: activeTitle === item.name }"
v-for="item in tabs"
:key="item.path"
@click="emit('tab-click', item)"
>
<div
class=
"icon"
>
<img
v-if=
"activeTitle === item.name"
:src=
"item.activeIcon"
alt=
""
/>
<img
v-else
:src=
"item.icon"
alt=
""
/>
</div>
<div
class=
"name"
:class=
"
{ nameActive: activeTitle === item.name }">
{{
item
.
name
}}
</div>
</div>
</
template
>
</div>
</div>
<div
class=
"layout-main-header-right-box"
>
<div
class=
"right-box-top"
>
<el-skeleton
:loading=
"isLoading"
animated
>
<
template
#
template
>
<div
class=
"time"
>
<el-skeleton-item
class=
"skeleton-right-line"
variant=
"text"
/>
</div>
<div
class=
"name"
>
<el-skeleton-item
class=
"skeleton-right-line"
variant=
"text"
/>
</div>
</
template
>
<
template
#
default
>
<div
class=
"time"
>
{{
billInfo
?.
introductionDate
}}
</div>
<div
class=
"name"
>
{{
billInfo
?.
tarName
}}
</div>
</
template
>
</el-skeleton>
</div>
<div
class=
"right-box-bottom"
v-if=
"showActions"
>
<
template
v-if=
"isLoading"
>
<div
class=
"btn1 is-skeleton"
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-action-icon"
variant=
"text"
/>
</div>
<div
class=
"text"
>
<el-skeleton-item
class=
"skeleton-action-text"
variant=
"text"
/>
</div>
</div>
<div
class=
"btn3 is-skeleton"
>
<div
class=
"icon"
>
<el-skeleton-item
class=
"skeleton-action-icon"
variant=
"text"
/>
</div>
<div
class=
"text"
>
<el-skeleton-item
class=
"skeleton-action-text"
variant=
"text"
/>
</div>
</div>
</
template
>
<
template
v-else
>
<div
class=
"btn1"
@
click=
"emit('open-original-text')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconOriginalText"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"法案原文"
}}
</div>
</div>
<div
class=
"btn3"
@
click=
"emit('open-analysis')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconAnalysis"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"分析报告"
}}
</div>
</div>
</
template
>
</div>
</div>
</div>
</div>
</template>
<
script
setup
>
import
{
computed
}
from
"vue"
;
import
btnIconOriginalText
from
"@/views/thinkTank/ReportDetail/images/btn-icon1.png"
;
import
btnIconAnalysis
from
"@/views/thinkTank/ReportDetail/images/btn-icon3.png"
;
const
props
=
defineProps
({
billInfo
:
{
type
:
Object
,
default
:
()
=>
({})
},
defaultLogo
:
{
type
:
String
,
default
:
""
},
tabs
:
{
type
:
Array
,
default
:
()
=>
[]
},
activeTitle
:
{
type
:
String
,
default
:
""
},
showTabs
:
{
type
:
Boolean
,
default
:
true
},
showActions
:
{
type
:
Boolean
,
default
:
true
}
});
const
isLoading
=
computed
(()
=>
!
props
.
billInfo
||
!
props
.
billInfo
.
billName
);
const
emit
=
defineEmits
([
"tab-click"
,
"open-original-text"
,
"open-analysis"
]);
</
script
>
<
style
lang=
"scss"
scoped
>
.skeleton-avatar
{
width
:
64px
;
height
:
64px
;
border-radius
:
50%
;
}
.skeleton-title
{
width
:
360px
;
height
:
20px
;
}
.skeleton-subtitle
{
width
:
520px
;
height
:
14px
;
margin-top
:
8px
;
}
.skeleton-right-line
{
width
:
140px
;
height
:
14px
;
}
.skeleton-tab-icon
,
.skeleton-action-icon
{
width
:
16px
;
height
:
16px
;
border-radius
:
4px
;
}
.skeleton-tab-text
,
.skeleton-action-text
{
width
:
80px
;
height
:
14px
;
border-radius
:
6px
;
}
.header-main
{
position
:
sticky
;
top
:
0
;
z-index
:
1000
;
width
:
100%
;
background-color
:
#fff
;
box-shadow
:
0px
4px
10px
0px
rgba
(
0
,
0
,
0
,
0
.05
);
overflow
:
hidden
;
}
.layout-main-header
{
width
:
1600px
;
background
:
#fff
;
display
:
flex
;
justify-content
:
space-between
;
margin
:
0
auto
;
padding-top
:
10px
;
.layout-main-header-left-box
{
width
:
2600px
;
.left-box-top
{
height
:
64px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
left
;
margin-bottom
:
21px
;
:deep
(
.el-skeleton
)
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
}
.icon
{
width
:
64px
;
height
:
64px
;
flex
:
0
0
64px
;
flex-shrink
:
0
;
img
{
width
:
100%
;
height
:
100%
;
display
:
block
;
object-fit
:
contain
;
}
}
.info
{
margin-left
:
8px
;
display
:
flex
;
align-items
:
left
;
flex-direction
:
column
;
.info-box1
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
"Microsoft YaHei"
;
font-size
:
20px
;
font-weight
:
600
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.info-box2
{
margin-top
:
4px
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
"Microsoft YaHei"
;
font-size
:
14px
;
font-weight
:
400
;
letter-spacing
:
0px
;
text-align
:
left
;
display
:
-
webkit-box
;
-webkit-box-orient
:
vertical
;
-webkit-line-clamp
:
2
;
line-clamp
:
2
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
}
}
}
.left-box-bottom
{
display
:
flex
;
height
:
40px
;
// margin-top: 21px;
.left-box-bottom-item
{
display
:
flex
;
margin-right
:
32px
;
margin-top
:
3px
;
height
:
36px
;
cursor
:
pointer
;
.icon
{
margin-top
:
4px
;
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.name
{
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
18px
;
font-weight
:
400
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
left
;
margin-left
:
3px
;
}
.nameActive
{
color
:
rgba
(
20
,
89
,
187
,
1
);
font-weight
:
700
;
}
}
.leftBoxBottomItemActive
{
border-bottom
:
3px
solid
rgba
(
20
,
89
,
187
,
1
);
}
}
}
.layout-main-header-right-box
{
width
:
600px
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
align-items
:
right
;
.right-box-top
{
height
:
64px
;
display
:
flex
;
align-items
:
right
;
flex-direction
:
column
;
justify-content
:
center
;
:deep
(
.el-skeleton
)
{
width
:
100%
;
}
.time
{
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
right
;
}
.name
{
margin-top
:
4px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
right
;
}
}
.right-box-bottom
{
margin-bottom
:
8px
;
display
:
flex
;
justify-content
:
flex-end
;
gap
:
8px
;
.btn1
{
cursor
:
pointer
;
width
:
120px
;
height
:
36px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
6px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
gap
:
8px
;
.icon
{
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
height
:
24px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
}
.btn3
{
cursor
:
pointer
;
width
:
120px
;
height
:
36px
;
border-radius
:
6px
;
background
:
rgba
(
5
,
95
,
194
,
1
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
gap
:
8px
;
.icon
{
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
height
:
24px
;
color
:
rgba
(
255
,
255
,
255
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
}
.is-skeleton
{
pointer-events
:
none
;
}
}
}
}
</
style
>
src/views/bill/billLayout/index.vue
浏览文件 @
47bc38c9
差异被折叠。
点击展开。
src/views/bill/billOriginalText/index.vue
0 → 100644
浏览文件 @
47bc38c9
<
template
>
<div
class=
"bill-original-text-page"
>
<div
class=
"page-header"
>
<div
class=
"page-title"
>
法案原文
</div>
<div
class=
"page-actions"
>
<div
class=
"action-btn"
@
click=
"handleBack"
>
返回
</div>
</div>
</div>
<div
class=
"page-content"
>
<iframe
v-if=
"billFullText"
:src=
"billFullText"
width=
"100%"
height=
"100%"
frameborder=
"0"
></iframe>
<div
v-else
class=
"empty-state"
>
暂无原文
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
onMounted
,
ref
}
from
"vue"
;
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
{
getBillFullText
}
from
"@/api/bill"
;
const
route
=
useRoute
();
const
router
=
useRouter
();
const
billFullText
=
ref
(
""
);
const
getBillFullTextFn
=
async
()
=>
{
const
res
=
await
getBillFullText
({
id
:
route
.
query
.
billId
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
billFullText
.
value
=
typeof
res
.
data
===
"string"
?
res
.
data
.
trim
()
:
res
.
data
;
}
};
const
handleBack
=
()
=>
{
router
.
back
();
};
onMounted
(()
=>
{
getBillFullTextFn
();
});
</
script
>
<
style
lang=
"scss"
scoped
>
.bill-original-text-page
{
width
:
100%
;
box-sizing
:
border-box
;
background
:
rgba
(
248
,
249
,
250
,
1
);
padding
:
0
0
20px
;
.page-header
{
width
:
100%
;
height
:
64px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.page-title
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
18px
;
font-weight
:
700
;
}
.page-actions
{
display
:
flex
;
justify-content
:
flex-end
;
.action-btn
{
cursor
:
pointer
;
height
:
32px
;
line-height
:
32px
;
padding
:
0
12px
;
border-radius
:
6px
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
}
}
}
.page-content
{
width
:
100%
;
height
:
calc
(
100vh
-
320px
);
min-height
:
600px
;
background
:
#fff
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
overflow
:
hidden
;
iframe
{
display
:
block
;
}
.empty-state
{
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
}
}
}
</
style
>
src/views/bill/index.vue
浏览文件 @
47bc38c9
...
...
@@ -2,20 +2,7 @@
<div
class=
"home-container"
>
<div
class=
"home-center"
>
<div
class=
"home-sider"
>
<div
class=
"sider-btn"
:class=
"
{ siderBtnActive: siderBtnActive === item.name }"
@click="handleClickLeftSiderBtn(item)"
v-for="item,index in siderBtnList"
:key="index"
>
<div
class=
"btn-text"
>
{{
item
.
name
}}
</div>
<div
class=
"btn-icon"
>
<el-icon
v-if=
"siderBtnActive === item.name"
color=
"#fff"
><CaretRight
/></el-icon>
</div>
</div>
<SiderTabs
:siderList=
"siderTabs"
@
clickSiderItem=
"handleClickLeftSiderBtn"
/>
</div>
<div
class=
"home-main"
>
<router-view
/>
...
...
@@ -25,9 +12,10 @@
</
template
>
<
script
setup
>
import
{
onMounted
,
ref
}
from
"vue"
;
import
{
onMounted
,
ref
,
computed
,
watch
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
router
from
'@/router'
import
SiderTabs
from
"@/components/base/SiderTabs/index.vue"
;
const
route
=
useRoute
();
...
...
@@ -47,6 +35,20 @@ const siderBtnList = ref([
])
const
siderBtnActive
=
ref
(
"法案简介"
);
const
getSiderActiveByRoutePath
=
path
=>
{
if
(
path
.
includes
(
"/billLayout/bill/background"
))
return
"法案背景"
;
if
(
path
.
includes
(
"/billLayout/bill/template"
))
return
"内容概要"
;
return
"法案简介"
;
};
const
siderTabs
=
computed
(()
=>
siderBtnList
.
value
.
map
(
item
=>
({
...
item
,
active
:
siderBtnActive
.
value
===
item
.
name
}))
);
const
handleClickLeftSiderBtn
=
(
item
)
=>
{
siderBtnActive
.
value
=
item
.
name
router
.
push
({
...
...
@@ -58,6 +60,14 @@ const handleClickLeftSiderBtn = (item) => {
}
onMounted
(()
=>
{});
watch
(
()
=>
route
.
path
,
(
newPath
)
=>
{
siderBtnActive
.
value
=
getSiderActiveByRoutePath
(
newPath
);
},
{
immediate
:
true
}
);
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
@@ -168,10 +178,10 @@ onMounted(() => {});
height
:
879px
;
position
:
relative
;
.home-sider
{
width
:
1
6
0px
;
width
:
1
2
0px
;
position
:
absolute
;
top
:
8
px
;
left
:
-1
6
0px
;
top
:
16
px
;
left
:
-1
4
0px
;
.sider-btn
{
margin-top
:
20px
;
margin-left
:
20px
;
...
...
src/views/bill/introdoction/STimeline.vue
浏览文件 @
47bc38c9
...
...
@@ -17,7 +17,7 @@
<div
class=
"item-title"
>
{{
item
.
actionTitle
}}
</div>
</el-tooltip>
<div
class=
"right"
>
<
div
v-if=
"item.riskText"
class=
"risk-tag"
:class=
"item.riskClass"
>
•
{{
item
.
riskText
}}
</div
>
<
!--
<div
v-if=
"item.riskText"
class=
"risk-tag"
:class=
"item.riskClass"
>
•
{{
item
.
riskText
}}
</div>
--
>
<div
class=
"arrow"
>
>
</div>
</div>
</div>
...
...
src/views/bill/template/assets/icons/compare-icon.svg
0 → 100644
浏览文件 @
47bc38c9
<svg
viewBox=
"0 0 12.375 13.5"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"12.375000"
height=
"13.500000"
fill=
"none"
customFrame=
"#000000"
>
<path
id=
"矢量 359"
d=
"M10.125 1L10.125 5.0625L11.375 5.0625C11.9273 5.0625 12.375 5.51022 12.375 6.0625L12.375 12.5C12.375 13.0523 11.9273 13.5 11.375 13.5L3.8125 13.5C3.26022 13.5 2.8125 13.0523 2.8125 12.5L2.8125 11.25L1 11.25C0.447715 11.25 0 10.8023 0 10.25L0 1C0 0.447715 0.447715 0 1 0L9.125 0C9.67728 0 10.125 0.447715 10.125 1ZM11.25 6.1875L10.125 6.1875L10.125 10.25C10.125 10.8023 9.67729 11.25 9.125 11.25L3.9375 11.25L3.9375 12.375L11.25 12.375L11.25 6.1875ZM9 1.125L1.125 1.125L1.125 10.125L9 10.125L9 1.125ZM6.1875 7.3125L6.1875 8.4375L2.8125 8.4375L2.8125 7.3125L6.1875 7.3125ZM7.3125 5.0625L7.3125 6.1875L2.8125 6.1875L2.8125 5.0625L7.3125 5.0625ZM7.3125 2.8125L7.3125 3.9375L2.8125 3.9375L2.8125 2.8125L7.3125 2.8125Z"
fill=
"rgb(5,95,194)"
fill-rule=
"nonzero"
/>
</svg>
src/views/bill/template/assets/icons/translate-icon.svg
0 → 100644
浏览文件 @
47bc38c9
<svg
viewBox=
"0 0 16 16"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"16.000000"
height=
"16.000000"
fill=
"none"
>
<rect
id=
"翻译 1"
width=
"16.000000"
height=
"16.000000"
x=
"0.000000"
y=
"0.000000"
/>
<path
id=
"矢量 455"
d=
"M3.33398 10.0007L3.33398 11.334C3.33397 11.3756 3.3359 11.4171 3.33977 11.4585C3.34364 11.4999 3.34943 11.541 3.35715 11.5819C3.36487 11.6227 3.37448 11.6632 3.38598 11.7031C3.39748 11.7431 3.41082 11.7824 3.426 11.8211C3.44119 11.8599 3.45814 11.8978 3.47687 11.9349C3.4956 11.9721 3.51602 12.0082 3.53814 12.0434C3.56026 12.0787 3.58397 12.1128 3.60927 12.1458C3.63458 12.1788 3.66137 12.2105 3.68965 12.241C3.71793 12.2715 3.74757 12.3006 3.77857 12.3283C3.80957 12.3561 3.8418 12.3823 3.87525 12.407C3.9087 12.4317 3.94324 12.4548 3.97885 12.4762C4.01447 12.4977 4.051 12.5175 4.08847 12.5355C4.12593 12.5536 4.16416 12.5699 4.20314 12.5843C4.24213 12.5988 4.2817 12.6114 4.32187 12.6222C4.36204 12.633 4.40262 12.6419 4.44362 12.6488C4.48461 12.6558 4.52585 12.6609 4.56732 12.664L4.66732 12.6673L6.66732 12.6673L6.66732 14.0007L4.66732 14.0007C4.57998 14.0007 4.49285 13.9964 4.40594 13.9878C4.31902 13.9792 4.23273 13.9665 4.14708 13.9494C4.06142 13.9324 3.9768 13.9112 3.89322 13.8858C3.80965 13.8605 3.72752 13.8311 3.64683 13.7977C3.56614 13.7642 3.48728 13.7269 3.41026 13.6858C3.33324 13.6446 3.25841 13.5998 3.1858 13.5512C3.11318 13.5027 3.04311 13.4508 2.9756 13.3953C2.90809 13.3399 2.84346 13.2814 2.7817 13.2196C2.71994 13.1578 2.66136 13.0932 2.60596 13.0257C2.55055 12.9582 2.49859 12.8881 2.45007 12.8155C2.40154 12.7429 2.3567 12.6681 2.31553 12.591C2.27436 12.514 2.23706 12.4352 2.20364 12.3545C2.17022 12.2738 2.14083 12.1917 2.11548 12.1081C2.09012 12.0245 2.06893 11.9399 2.05189 11.8542C2.03485 11.7686 2.02205 11.6823 2.01349 11.5954C2.00493 11.5084 2.00065 11.4213 2.00065 11.334L2.00065 10.0007L3.33398 10.0007L3.33398 10.0007ZM12.0007 6.66732L14.934 14.0007L13.4973 14.0007L12.6967 12.0007L9.96999 12.0007L9.17065 14.0007L7.73465 14.0007L10.6673 6.66732L12.0007 6.66732L12.0007 6.66732ZM11.334 8.59065L10.5027 10.6673L12.164 10.6673L11.334 8.59065ZM5.33398 1.33398L5.33398 2.66732L8.00065 2.66732L8.00065 7.33398L5.33398 7.33398L5.33398 9.33398L4.00065 9.33398L4.00065 7.33398L1.33398 7.33398L1.33398 2.66732L4.00065 2.66732L4.00065 1.33398L5.33398 1.33398ZM11.334 2.00065C11.4213 2.00065 11.5084 2.00493 11.5954 2.01349C11.6823 2.02205 11.7686 2.03485 11.8542 2.05189C11.9399 2.06893 12.0245 2.09012 12.1081 2.11548C12.1917 2.14083 12.2738 2.17022 12.3545 2.20364C12.4352 2.23706 12.514 2.27436 12.591 2.31553C12.6681 2.3567 12.7429 2.40154 12.8155 2.45007C12.8881 2.49859 12.9582 2.55055 13.0257 2.60596C13.0932 2.66136 13.1578 2.71994 13.2196 2.7817C13.2814 2.84346 13.3399 2.90809 13.3953 2.9756C13.4508 3.04311 13.5027 3.11318 13.5512 3.1858C13.5998 3.25841 13.6446 3.33324 13.6858 3.41026C13.7269 3.48728 13.7642 3.56614 13.7977 3.64683C13.8311 3.72752 13.8605 3.80965 13.8858 3.89323C13.9112 3.9768 13.9324 4.06142 13.9494 4.14708C13.9665 4.23274 13.9793 4.31902 13.9878 4.40594C13.9964 4.49286 14.0007 4.57998 14.0007 4.66732L14.0007 6.00065L12.6673 6.00065L12.6673 4.66732C12.6673 4.62365 12.6652 4.58009 12.6609 4.53663C12.6566 4.49317 12.6502 4.45003 12.6417 4.4072C12.6332 4.36437 12.6226 4.32206 12.6099 4.28027C12.5972 4.23848 12.5825 4.19742 12.5658 4.15707C12.5491 4.11673 12.5305 4.0773 12.5099 4.03879C12.4893 4.00028 12.4669 3.96287 12.4426 3.92656C12.4184 3.89025 12.3924 3.85522 12.3647 3.82146C12.337 3.7877 12.3077 3.75539 12.2768 3.72451C12.2459 3.69363 12.2136 3.66434 12.1798 3.63664C12.1461 3.60893 12.1111 3.58295 12.0747 3.55869C12.0384 3.53443 12.001 3.51201 11.9625 3.49142C11.924 3.47084 11.8846 3.45219 11.8442 3.43548C11.8039 3.41877 11.7628 3.40407 11.721 3.3914C11.6792 3.37872 11.6369 3.36812 11.5941 3.3596C11.5513 3.35108 11.5081 3.34468 11.4647 3.3404C11.4212 3.33612 11.3777 3.33398 11.334 3.33398L9.33399 3.33398L9.33399 2.00065L11.334 2.00065L11.334 2.00065ZM4.00065 4.00065L2.66732 4.00065L2.66732 6.00065L4.00065 6.00065L4.00065 4.00065ZM6.66732 4.00065L5.33398 4.00065L5.33398 6.00065L6.66732 6.00065L6.66732 4.00065Z"
fill=
"rgb(95,101,108)"
fill-rule=
"nonzero"
/>
</svg>
src/views/bill/template/index.vue
浏览文件 @
47bc38c9
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论