主体查询新增信用档案功能
This commit is contained in:
parent
939ce1783f
commit
04873ddf4f
|
|
@ -217,6 +217,20 @@ export function exportqzzxList(data) {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主体信用档案图谱数据
|
||||
* @param {Object} params
|
||||
* @param {string} params.pripid 主体身份代码
|
||||
* @param {number} [params.reportYear] 年报年度(可选,不传则取最近一年,影响"对外投资"分支)
|
||||
*/
|
||||
export function getCreditArchive(params) {
|
||||
return request({
|
||||
url: '/eBaseinfo/getCreditArchive',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 信用修复预警统计
|
||||
* @param data
|
||||
|
|
|
|||
|
|
@ -0,0 +1,331 @@
|
|||
<template>
|
||||
<div v-loading="loading" class="credit-archive">
|
||||
<div class="toolbar">
|
||||
<span class="toolbar-label">年报年度:</span>
|
||||
<el-select
|
||||
v-model="reportYear"
|
||||
size="small"
|
||||
clearable
|
||||
placeholder="默认最近一年"
|
||||
style="width: 160px;"
|
||||
@change="loadData"
|
||||
>
|
||||
<el-option
|
||||
v-for="y in yearOptions"
|
||||
:key="y"
|
||||
:label="`${y} 年`"
|
||||
:value="y"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-refresh"
|
||||
style="margin-left: 12px;"
|
||||
@click="resetGraph"
|
||||
>重置图谱</el-button>
|
||||
<span class="toolbar-tip">提示:点击一级分支可展开/收起明细,单分支最多展示 {{ maxNodes }} 个节点</span>
|
||||
</div>
|
||||
<div ref="graph" class="graph-container" />
|
||||
|
||||
<!-- 节点详情弹窗 -->
|
||||
<el-dialog
|
||||
:visible.sync="detailVisible"
|
||||
:title="detailTitle"
|
||||
width="560px"
|
||||
append-to-body
|
||||
>
|
||||
<el-descriptions v-if="detailData" :column="1" border size="small">
|
||||
<el-descriptions-item
|
||||
v-for="(value, key) in detailData"
|
||||
:key="key"
|
||||
:label="fieldLabel(key)"
|
||||
>{{ value || '—' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCreditArchive } from '@/api/comprehensive'
|
||||
|
||||
const MAX_NODES = 20
|
||||
const CURRENT_YEAR = new Date().getFullYear()
|
||||
|
||||
const FIELD_LABEL_MAP = {
|
||||
name: '姓名',
|
||||
entName: '企业名称',
|
||||
uniscid: '统一社会信用代码',
|
||||
certType: '证件类型',
|
||||
subConAm: '认缴出资额',
|
||||
subConProp: '认缴出资比例(%)',
|
||||
respForm: '责任形式',
|
||||
position: '职务',
|
||||
lerepsign: '法定代表人标志',
|
||||
tel: '联系电话',
|
||||
email: '电子邮箱',
|
||||
invid: '股东ID',
|
||||
outinvid: '对外投资ID',
|
||||
lmid: '联络员ID'
|
||||
}
|
||||
|
||||
const BRANCH_DEFS = [
|
||||
{ key: 'shareholders', label: '股东信息', color: '#5470c6' },
|
||||
{ key: 'legalPersons', label: '法定代表人', color: '#91cc75' },
|
||||
{ key: 'investments', label: '对外投资', color: '#fac858' },
|
||||
{ key: 'contacts', label: '联络人', color: '#ee6666' }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'CreditArchive',
|
||||
props: {
|
||||
pripid: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
entName: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
chart: null,
|
||||
reportYear: null,
|
||||
yearOptions: this.buildYearOptions(),
|
||||
maxNodes: MAX_NODES,
|
||||
archiveData: {
|
||||
shareholders: [],
|
||||
legalPersons: [],
|
||||
investments: [],
|
||||
contacts: []
|
||||
},
|
||||
truncated: {
|
||||
shareholders: false,
|
||||
investments: false,
|
||||
contacts: false
|
||||
},
|
||||
branches: BRANCH_DEFS,
|
||||
detailVisible: false,
|
||||
detailTitle: '',
|
||||
detailData: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadData()
|
||||
window.addEventListener('resize', this.resize)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.resize)
|
||||
if (this.chart) {
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
buildYearOptions() {
|
||||
const list = []
|
||||
for (let y = CURRENT_YEAR; y >= CURRENT_YEAR - 9; y--) {
|
||||
list.push(y)
|
||||
}
|
||||
return list
|
||||
},
|
||||
fieldLabel(key) {
|
||||
return FIELD_LABEL_MAP[key] || key
|
||||
},
|
||||
async loadData() {
|
||||
if (!this.pripid) return
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await getCreditArchive({
|
||||
pripid: this.pripid,
|
||||
reportYear: this.reportYear || undefined
|
||||
})
|
||||
const data = (res && res.data) || res || {}
|
||||
this.archiveData = {
|
||||
shareholders: data.shareholders || [],
|
||||
legalPersons: data.legalPersons || [],
|
||||
investments: data.investments || [],
|
||||
contacts: data.contacts || []
|
||||
}
|
||||
this.truncated = data.truncated || { shareholders: false, investments: false, contacts: false }
|
||||
// Q5:首次加载用后端返回的 reportYear 作为默认选中
|
||||
if (!this.reportYear && data.reportYear) {
|
||||
this.reportYear = data.reportYear
|
||||
}
|
||||
this.$nextTick(() => this.renderGraph())
|
||||
} catch (e) {
|
||||
this.$message.error('信用档案数据加载失败')
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
renderGraph() {
|
||||
if (!this.$refs.graph) return
|
||||
if (!this.chart) {
|
||||
this.chart = this.$echarts.init(this.$refs.graph)
|
||||
this.chart.on('click', params => this.handleNodeClick(params))
|
||||
}
|
||||
|
||||
const centerName = this.entName || this.archiveData.entName || '主体'
|
||||
const centerNode = {
|
||||
id: 'center',
|
||||
name: centerName,
|
||||
symbolSize: 80,
|
||||
category: 0,
|
||||
fixed: true,
|
||||
x: 0,
|
||||
y: 0,
|
||||
itemStyle: { color: '#409EFF' },
|
||||
label: { fontWeight: 'bold' }
|
||||
}
|
||||
const branchNodes = this.branches.map((b, i) => ({
|
||||
id: b.key,
|
||||
name: `${b.label} (${(this.archiveData[b.key] || []).length})`,
|
||||
symbolSize: 50,
|
||||
category: i + 1,
|
||||
itemStyle: { color: b.color }
|
||||
}))
|
||||
const branchLinks = this.branches.map(b => ({
|
||||
source: 'center',
|
||||
target: b.key,
|
||||
lineStyle: { color: '#aaa', width: 2 }
|
||||
}))
|
||||
|
||||
this.chart.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: params => {
|
||||
if (params.dataType === 'edge') return ''
|
||||
return params.name
|
||||
}
|
||||
},
|
||||
legend: [{
|
||||
data: this.branches.map(b => b.label),
|
||||
bottom: 0
|
||||
}],
|
||||
series: [{
|
||||
type: 'graph',
|
||||
layout: 'force',
|
||||
roam: true,
|
||||
draggable: true,
|
||||
label: { show: true, position: 'right', formatter: '{b}' },
|
||||
force: { repulsion: 400, edgeLength: 120 },
|
||||
categories: [
|
||||
{ name: '主体' },
|
||||
...this.branches.map(b => ({ name: b.label }))
|
||||
],
|
||||
data: [centerNode, ...branchNodes],
|
||||
links: branchLinks,
|
||||
lineStyle: { color: 'source', curveness: 0.1 }
|
||||
}]
|
||||
}, true)
|
||||
},
|
||||
handleNodeClick(params) {
|
||||
// 点击中心节点 / 边 → 忽略
|
||||
if (!params.data || params.dataType === 'edge') return
|
||||
const branch = this.branches.find(b => b.key === params.data.id)
|
||||
if (branch) {
|
||||
this.toggleBranch(branch)
|
||||
return
|
||||
}
|
||||
// 二级节点点击 → 弹出明细
|
||||
if (params.data.rawData) {
|
||||
const parentKey = String(params.data.id).split('-')[0]
|
||||
const parentBranch = this.branches.find(b => b.key === parentKey)
|
||||
this.detailTitle = parentBranch ? `${parentBranch.label}详情` : '详情'
|
||||
this.detailData = params.data.rawData
|
||||
this.detailVisible = true
|
||||
}
|
||||
},
|
||||
toggleBranch(branch) {
|
||||
const list = this.archiveData[branch.key] || []
|
||||
if (!list.length) {
|
||||
this.$message.info(`暂无${branch.label}`)
|
||||
return
|
||||
}
|
||||
const option = this.chart.getOption()
|
||||
const series = option.series[0]
|
||||
const prefix = branch.key + '-'
|
||||
const hasChild = series.data.some(n => String(n.id).startsWith(prefix))
|
||||
|
||||
if (hasChild) {
|
||||
// 收起
|
||||
series.data = series.data.filter(n => !String(n.id).startsWith(prefix))
|
||||
series.links = series.links.filter(l => !String(l.target).startsWith(prefix))
|
||||
} else {
|
||||
// Q11:单分支最多展开 MAX_NODES 个节点,超出部分显示"更多..."
|
||||
const displayList = list.slice(0, MAX_NODES)
|
||||
const categoryIndex = this.branches.indexOf(branch) + 1
|
||||
displayList.forEach((item, i) => {
|
||||
const nodeId = `${branch.key}-${i}`
|
||||
series.data.push({
|
||||
id: nodeId,
|
||||
name: this.getNodeName(branch.key, item),
|
||||
symbolSize: 30,
|
||||
category: categoryIndex,
|
||||
itemStyle: { color: branch.color, opacity: 0.7 },
|
||||
rawData: item
|
||||
})
|
||||
series.links.push({ source: branch.key, target: nodeId })
|
||||
})
|
||||
// 后端返回的截断标志或前端二次判断
|
||||
const isTruncated = this.truncated[branch.key] || list.length > MAX_NODES
|
||||
if (isTruncated) {
|
||||
const moreId = `${branch.key}-more`
|
||||
series.data.push({
|
||||
id: moreId,
|
||||
name: `更多... (共 ${list.length}${list.length > MAX_NODES ? '+' : ''} 项)`,
|
||||
symbolSize: 26,
|
||||
category: categoryIndex,
|
||||
itemStyle: { color: branch.color, opacity: 0.4 }
|
||||
})
|
||||
series.links.push({ source: branch.key, target: moreId })
|
||||
}
|
||||
}
|
||||
this.chart.setOption(option, true)
|
||||
},
|
||||
getNodeName(key, item) {
|
||||
if (key === 'investments') return item.entName || '—'
|
||||
if (key === 'shareholders') return item.name || '—'
|
||||
return item.name || '—'
|
||||
},
|
||||
resetGraph() {
|
||||
this.renderGraph()
|
||||
},
|
||||
resize() {
|
||||
if (this.chart) this.chart.resize()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.credit-archive {
|
||||
.toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 12px;
|
||||
background: #fafafa;
|
||||
border: 1px solid #ebeef5;
|
||||
border-bottom: none;
|
||||
|
||||
.toolbar-label {
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.toolbar-tip {
|
||||
margin-left: auto;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
.graph-container {
|
||||
width: 100%;
|
||||
height: 600px;
|
||||
border: 1px solid #ebeef5;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -149,6 +149,14 @@
|
|||
</table>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<!-- 信用档案 Tab(Q9:放在"基本信息"之后) -->
|
||||
<el-tab-pane label="信用档案" name="creditArchive">
|
||||
<credit-archive
|
||||
v-if="activeName === 'creditArchive' && isReadCreditArchive"
|
||||
:pripid="pripid"
|
||||
:ent-name="entInfo && entInfo.entname"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<!-- <el-tab-pane label="信用信息" name="second" /> -->
|
||||
<el-tab-pane label="检查信息" name="third">
|
||||
<div>
|
||||
|
|
@ -962,11 +970,13 @@ import { getAssignLogList } from '@/api/marketAssign'
|
|||
import EasyForm from '@/components/EasyForm'
|
||||
import dynamicSupervisionBase from '@/views/market/dynamicsupervision/index'
|
||||
import dailySupervisionBase from '@/views/market/dailysupervision/index'
|
||||
import CreditArchive from './components/CreditArchive'
|
||||
import { oauth } from '@/api/user'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EasyForm
|
||||
EasyForm,
|
||||
CreditArchive
|
||||
},
|
||||
mixins: [dynamicSupervisionBase, dailySupervisionBase],
|
||||
data() {
|
||||
|
|
@ -975,6 +985,7 @@ export default {
|
|||
isRead2: false,
|
||||
isRead3: false,
|
||||
isRead4: false,
|
||||
isReadCreditArchive: false,
|
||||
isRead5: false,
|
||||
isRead6: false,
|
||||
isRead7: false,
|
||||
|
|
@ -1222,7 +1233,10 @@ export default {
|
|||
handleClick(tab, event) {
|
||||
console.log(this.activeName)
|
||||
this.loading = true
|
||||
if (this.activeName === 'fourth') {
|
||||
if (this.activeName === 'creditArchive' && !this.isReadCreditArchive) {
|
||||
this.isReadCreditArchive = true
|
||||
this.loading = false
|
||||
} else if (this.activeName === 'fourth') {
|
||||
oauth().then((res) => {
|
||||
const { data } = res
|
||||
const path = `/annualReportService/unifiedMGT/annualReportProgress/baseInfo/detail?pripid=${this.$route.query.pripid}&yearReportMode=1`
|
||||
|
|
|
|||
Loading…
Reference in New Issue