You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

610 lines
19 KiB

<template>
<div class="home">
<!-- 中间 -->
<div class="warp_body">
<div class="white-body">
<!-- Tab 切换 -->
<div class="tabs">
<div class="tab-item portrayal" :class="{ active: currentTab === 0 }" @click="currentTab = 0">
<div class="tab-item-title">企业画像</div>
</div>
<div class="tab-item record" :class="{ active: currentTab === 1 }" @click="currentTab = 1">
<div class="tab-item-title">执法记录</div>
</div>
</div>
<!-- 企业画像 Tab -->
<div v-if="currentTab === 0">
<!-- 企业信息卡片 -->
<div class="enterprise-card">
<div v-if="enterpriseData" class="enterprise-info">
<div class="info-item">
<div class="info-label">企业名称</div>
<div class="info-value">{{ enterpriseData.enterpriseName }}</div>
</div>
<template v-if="!isCollapsed">
<div class="info-item">
<div class="info-label">统一社会信用代码</div>
<div class="info-value">{{ enterpriseData.enterpriseNumber }}</div>
</div>
<div class="info-item">
<div class="info-label">法定代表人</div>
<div class="info-value">{{ enterpriseData.legalPerson }}</div>
</div>
<div class="info-item">
<div class="info-label">企业类型</div>
<div class="info-value">{{ enterpriseData.enterpriseType }}</div>
</div>
<div class="info-item">
<div class="info-label">注册资本</div>
<div class="info-value">{{ enterpriseData.registeredCapital }}</div>
</div>
<div class="info-item">
<div class="info-label">成立日期</div>
<div class="info-value">{{ formatDate(enterpriseData.establishmentTime) }}</div>
</div>
<div class="info-item">
<div class="info-label">经营期限</div>
<div class="info-value">{{ enterpriseData.operatingTerm }}</div>
</div>
<div class="info-item">
<div class="info-label">注册地址</div>
<div class="info-value address-value">
<span class="address-text" :class="{ expanded: isAddressExpanded }">{{ enterpriseData.enterpriseAddress }}</span>
<span class="expand-text"
v-if="enterpriseData.enterpriseAddress" @click.stop="toggleAddressExpand">
{{ isAddressExpanded ? '收起' : '展开' }}
</span>
</div>
</div>
<div class="info-item">
<div class="info-label">经营范围</div>
<div class="info-value scope-value">
<span class="scope-text" :class="{ expanded: isScopeExpanded }">{{ enterpriseData.businessScope }}</span>
<span class="expand-text"
v-if="enterpriseData.businessScope" @click.stop="toggleScopeExpand">
{{ isScopeExpanded ? '收起' : '展开' }}
</span>
</div>
</div>
</template>
<template v-else>
<div class="info-item">
<div class="info-label">统一社会信用代码</div>
<div class="info-value">{{ enterpriseData.enterpriseNumber }}</div>
</div>
</template>
</div>
<van-empty v-else description="暂无企业信息" />
<!-- 分隔箭头 -->
<div class="divider-arrow" @click="toggleCollapse">
<van-icon :name="isCollapsed ? 'arrow-down' : 'arrow-up'" />
</div>
</div>
</div>
<!-- 执法记录 Tab -->
<div v-if="currentTab === 1" class="tab-content">
<!-- 执法记录子Tab -->
<div class="record-tabs">
<div class="record-tab-item" :class="{ active: recordTab === 0 }" @click="recordTab = 0">
<span>全市</span>
</div>
<div class="record-tab-item" :class="{ active: recordTab === 1 }" @click="recordTab = 1">
<span>本单位</span>
</div>
</div>
<!-- 执法记录列表 -->
<div class="record-list">
<div v-for="(item, index) in cityRecords" :key="index" class="record-card-item">
<div class="record-header">
<div class="record-date">{{ item.createTime }}</div>
<div class="record-company">{{ enterpriseData?.enterpriseName }}</div>
<div class="record-count">{{ item.caseType || '执法检查' }}</div>
</div>
<div class="record-timeline" v-if="isRecordExpanded">
<div class="timeline-item">
<div class="timeline-dot"></div>
<div class="timeline-content">
<div class="timeline-time">{{ item.createTime }}</div>
<div class="timeline-unit"><span class="unit-label">执法单位:</span>{{ item.enforcementUnit || item.unitName }}</div>
</div>
</div>
</div>
<div class="record-expand" @click="toggleRecordExpand">
<van-icon :name="isRecordExpanded ? 'arrow-up' : 'arrow-down'" />
</div>
</div>
<div v-if="cityRecords.length === 0" class="empty-state">
<van-icon name="file-o" class="empty-icon" />
<div class="empty-text">暂无数据</div>
</div>
</div>
</div>
</div>
<!-- 执法记录卡片 -->
<div class="record-card" v-if="currentTab === 0">
<!-- 执法记录子Tab -->
<div class="record-tabs">
<div class="record-tab-item" :class="{ active: recordTab === 0 }" @click="recordTab = 0">
<span>历史执法案件</span>
</div>
<div class="record-tab-item" :class="{ active: recordTab === 1 }" @click="recordTab = 1">
<span>历史处罚案件</span>
</div>
<div class="record-tab-item" :class="{ active: recordTab === 2 }" @click="recordTab = 2">
<span>历史强制案件</span>
</div>
</div>
<!-- 历史执法案件列表 -->
<div class="record-list" v-if="recordTab === 0">
<div v-for="(item, index) in cityRecords" :key="index" class="record-card-item">
<div class="record-header">
<div class="record-date">{{ item.createTime }}</div>
<div class="record-company">{{ enterpriseData?.enterpriseName }}</div>
<div class="record-count">{{ item.caseType || '执法检查' }}</div>
</div>
<div class="record-timeline" v-if="isRecordExpanded">
<div class="timeline-item">
<div class="timeline-dot"></div>
<div class="timeline-content">
<div class="timeline-time">{{ item.createTime }}</div>
<div class="timeline-unit"><span class="unit-label">执法单位:</span>{{ item.enforcementUnit || item.unitName }}</div>
</div>
</div>
</div>
<div class="record-expand" @click="toggleRecordExpand">
<van-icon :name="isRecordExpanded ? 'arrow-up' : 'arrow-down'" />
</div>
</div>
<div v-if="cityRecords.length === 0" class="empty-state">
<van-icon name="file-o" class="empty-icon" />
<div class="empty-text">暂无数据</div>
</div>
</div>
<van-empty v-else description="暂无执法记录" />
</div>
</div>
<!-- 登记按钮 -->
<div class="addinfo" @click="toSign">登记</div>
</div>
</template>
<script setup name="EnterpriseScanPreview">
import { ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { showFailToast } from 'vant';
import { getEnterpriseInformation, queryXzjcList } from '@/api/enforcement/index';
const router = useRouter();
const route = useRoute();
// ========== 数据 ==========
const currentTab = ref(0);
const recordTab = ref(0);
const isCollapsed = ref(false);
const isRecordExpanded = ref(false);
const isAddressExpanded = ref(false);
const isScopeExpanded = ref(false);
const enterpriseData = ref(null);
const enterpriseNumber = ref('');
const qrCodeValid = ref(false);
// 历史执法案件数据
const cityRecords = ref([]);
// ========== 方法 ==========
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value;
};
const toggleRecordExpand = () => {
isRecordExpanded.value = !isRecordExpanded.value;
};
const toggleAddressExpand = () => {
isAddressExpanded.value = !isAddressExpanded.value;
};
const toggleScopeExpand = () => {
isScopeExpanded.value = !isScopeExpanded.value;
};
// ========== 获取历史执法案件数据 ==========
const fetchXzjcList = (entNumber) => {
queryXzjcList(entNumber, (res) => {
if (res.code === 200) {
cityRecords.value = res.rows || [];
console.log('历史执法案件数据加载成功:', cityRecords.value);
} else {
console.error('获取历史执法案件失败:', res.msg);
}
}, (err) => {
console.error('获取历史执法案件接口失败', err);
});
};
// ========== 初始化加载 ==========
onMounted(() => {
// 从路由参数获取企业编号
const entNumber = route.query.enterpriseNumber;
if (entNumber) {
enterpriseNumber.value = entNumber;
fetchEnterpriseInformation(entNumber);
} else {
showFailToast('缺少企业编号,请重新扫码');
}
});
// ========== 获取企业画像数据 ==========
const fetchEnterpriseInformation = (enterpriseNumber) => {
getEnterpriseInformation(enterpriseNumber, (res) => {
if (res.code === 200) {
// 直接使用接口返回的数据
enterpriseData.value = res.data || res;
// 获取企业画像成功后,调用历史执法案件接口
fetchXzjcList(enterpriseNumber);
} else {
console.error('获取企业画像失败:', res.msg);
showFailToast(res.msg || '获取企业画像失败');
}
}, (err) => {
console.error('获取企业画像接口失败', err);
showFailToast('获取企业画像失败,请重试');
});
};
// ========== 工具方法 ==========
const formatDate = (dateStr) => {
if (!dateStr) return '';
const d = new Date(dateStr);
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
};
// ========== 页面跳转 ==========
const toSign = () => {
router.push({
path: '/enforcement/enforcementRegister',
});
};
</script>
<style lang="less" scoped>
.home {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
background-color: #ebf3fb;
.warp_body {
position: relative;
flex: 1;
overflow-y: auto;
background-image: linear-gradient(to bottom, #ebf3fb, transparent);
}
.white-body {
margin: 0 0.3rem;
width: calc(100% - 0.6rem);
background-color: #fff;
border-radius: 0.27rem;
overflow: hidden;
margin-bottom: 20px;
}
}
.tabs {
display: flex;
padding: 0.3rem 0.3rem 0;
}
.tab-item {
flex: 1;
height: 44px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
.tab-item-title {
font-size: 0.38rem;
}
&.portrayal {
background: url('@/assets/images/tab_bg1_1.png') no-repeat center center;
background-size: 100% 100%;
.tab-item-title {
color: #1989fa;
}
&.active {
background: url('@/assets/images/tab_bg1.png') no-repeat center center;
background-size: 100% 100%;
.tab-item-title {
color: #fff;
}
}
}
&.record {
background: url('@/assets/images/tab_bg.png') no-repeat center center;
background-size: 100% 100%;
.tab-item-title {
color: #1989fa;
}
&.active {
background: url('@/assets/images/tab_bg_1.png') no-repeat center center;
background-size: 100% 100%;
.tab-item-title {
color: #fff;
}
}
}
}
.enterprise-card {
background: #fff;
border-radius: 0.2rem;
padding: 0 0.3rem;
margin-bottom: 0.3rem;
}
.enterprise-info {
.info-item {
display: flex;
padding: 0.25rem 0;
border-bottom: 1px solid #f5f5f5;
&:last-child {
border-bottom: none;
}
}
.info-label {
flex: none;
width: 74px;
font-size: 14px;
color: #000;
line-height: 1.5;
margin-right: 30px;
}
.info-value {
flex: 1;
font-size: 0.35rem;
color: #666;
line-height: 1.5;
word-break: break-all;
}
.address-value,
.scope-value {
display: flex;
align-items: flex-start;
}
.address-text,
.scope-text {
flex: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.6;
}
.address-text.expanded,
.scope-text.expanded {
-webkit-line-clamp: unset;
overflow: visible;
text-overflow: unset;
white-space: normal;
}
.expand-text {
flex: none;
color: #1367fe;
font-size: 0.32rem;
margin-left: 0.1rem;
cursor: pointer;
align-self: flex-start;
padding-top: 2px;
}
}
.divider-arrow {
display: flex;
justify-content: center;
padding: 0.2rem 0;
color: #ccc;
font-size: 0.4rem;
cursor: pointer;
}
.record-card {
background: #fff;
border-radius: 0.2rem;
padding: 0 0.3rem;
margin: 0.3rem;
}
.tab-content {
height: calc(100vh - 70px);
background: #fff;
box-sizing: border-box;
}
.record-tabs {
display: flex;
border-bottom: 1px solid #f5f5f5;
margin-bottom: 0.3rem;
}
.record-tab-item {
flex: 1;
text-align: center;
padding: 0.25rem 0;
cursor: pointer;
position: relative;
&.active {
border-bottom: 3px solid #1989fa;
span {
color: #1989fa;
font-weight: 650;
}
}
span {
font-size: 0.35rem;
color: #999;
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 2rem 0;
.empty-icon {
font-size: 2rem;
color: #ddd;
margin-bottom: 0.3rem;
}
.empty-text {
font-size: 0.35rem;
color: #999;
}
}
.record-card-item {
background: #fff;
border-radius: 8px;
padding: 0.3rem;
margin: 10px;
margin-top: 20px;
box-shadow: 0 0px 8px #e5e5e5;
}
.record-header {
margin-bottom: 0.3rem;
.record-date {
font-size: 14px;
color: #999;
margin-bottom: 0.15rem;
}
.record-company {
font-size: 16px;
color: #000;
font-weight: 600;
padding: 10px 0px 10px 20px;
letter-spacing: 0.05rem;
}
.record-count {
font-size: 14px;
color: #393939dd;
padding-left: 20px;
letter-spacing: 0.02rem;
}
}
.record-timeline {
position: relative;
margin-left: 28px;
margin-top: 26px;
}
.timeline-item.has-line::before {
content: '';
position: absolute;
left: 3px;
top: 20px;
bottom: 0;
width: 2px;
height: 48px;
background: #e5e5e5;
}
.timeline-item {
display: flex;
align-items: flex-start;
padding: 0.1rem 0;
position: relative;
.timeline-dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #1367fe;
margin-right: 0.2rem;
flex-shrink: 0;
position: relative;
z-index: 1;
top: 4px;
}
.timeline-content {
flex: 1;
min-width: 0;
.timeline-time {
font-size: 16px;
color: #ccc;
font-weight: 400;
}
.timeline-unit {
font-size: 14px;
color: #999;
padding:10px 0px;
.unit-label{
color: #000;
}
}
}
}
.record-expand {
display: flex;
justify-content: center;
padding: 0.2rem 0;
color: #ccc;
font-size: 0.4rem;
}
.addinfo {
position: absolute;
bottom: 3%;
right: 2%;
z-index: 99999;
width: 1.5rem;
height: 1.5rem;
background-color: #1367fe;
border-radius: 50%;
box-shadow: 0 0 0.27rem #1367fe;
color: #fff;
font-size: 0.4rem;
text-align: center;
vertical-align: middle;
padding-top: 0.45rem;
box-sizing: border-box;
}
</style>