提交 3cf485d8 authored 作者: 李顺's avatar 李顺

合并分支 'ls_dev' 到 'master'

add:增加商业管制清单简介和列表功能 查看合并请求 !86
...@@ -566,3 +566,75 @@ export function getSingleSanctionEntityInternationalPaper(params) { ...@@ -566,3 +566,75 @@ export function getSingleSanctionEntityInternationalPaper(params) {
params, params,
}) })
} }
// 商业管制清单-CCL清单简介-基本信息
export function getCCLInfo() {
return request({
method: 'GET',
url: `/api/sanctionList/baseInfo/ccl`
})
}
// 商业管制清单-CCL清单简介-出口管制分类编码
export function getECCN() {
return request({
method: 'GET',
url: `/api/ccl/eccn`
})
}
// 商业管制清单-CCL清单简介-出口管制分类编码信息列表
/**
* @param {Object} params
* @param {Integer} params.id - 上一接口查询的EccnCategoryID
* @header token
*/
export function getECCNList(params) {
return request({
method: 'GET',
url: `/api/ccl/eccn/rank`,
params,
})
}
// 商业管制清单-CCL清单列表-类别字典
export function getECCNCategory() {
return request({
method: 'GET',
url: `/api/commonDict/ccl/eccnCategory`
})
}
// 商业管制清单-CCL清单列表-科技领域字典
export function getAreaType() {
return request({
method: 'GET',
url: `/api/commonDict/areaType`
})
}
// 商业管制清单-CCL清单列表-管控原因字典
export function getControlReason() {
return request({
method: 'GET',
url: `/api/commonDict/ccl/controlReason`
})
}
// 商业管制清单-CCL清单简介-CCL清单查询
/**
* @param {Object} params
* @param {String} params.categoryCode - 类别Id
* @param {List<Integer>} params.techDomainIds - 科技领域I
* @param {String} params.keyword - 搜索物项或ECCN编码
* @param {List<Integer>} params.controlIds - 类别ID
* @param {Boolean} params.isLatest - 查看最近更新内容
* @header token
*/
export function getCclQuery(data) {
return request({
method: 'POST',
url: `/api/ccl/query`,
data,
})
}
\ No newline at end of file
...@@ -114,6 +114,15 @@ const exportControlRoutes = [ ...@@ -114,6 +114,15 @@ const exportControlRoutes = [
// title: "实体清单原文" // title: "实体清单原文"
// } // }
}, },
// V2.0全部实体清单
{
path: "/exportControl/commercialControlList",
name: "commercialControlList",
component: () => import("@/views/exportControl/v2.0CommercialControlList/index.vue"),
meta: {
title: "全部实体清单"
}
}
] ]
export default exportControlRoutes export default exportControlRoutes
\ No newline at end of file
...@@ -1127,6 +1127,12 @@ const handleToEntityListNoId = item => { ...@@ -1127,6 +1127,12 @@ const handleToEntityListNoId = item => {
}); });
// 打开一个新页面 // 打开一个新页面
window.open(routeData.href, "_blank"); window.open(routeData.href, "_blank");
} else if (item.nameZh == "商业管制清单") {
const routeData = router.resolve({
path: "/exportControl/commercialControlList"
});
// 打开一个新页面
window.open(routeData.href, "_blank");
} else { } else {
return; return;
} }
......
<template>
<div class="introduction-page">
<div class="left">
<div class="left-top">
<div class="title">
<div class="box"></div>
<div class="text">基本信息</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt />
<img src="../../../../assets/收藏按钮.png" alt />
</div>
</div>
<div class="left-top-main">
<div class="left-top-main-title">{{ CCLInfo.description }}</div>
<div class="left-top-main-content">
<div class="content-item">
<span class="label">法律依据:</span>
<span class="text">{{ CCLInfo.legalBasis }}</span>
</div>
<div class="content-item">
<span class="label">管制对象:</span>
<span class="text">{{ CCLInfo.controlledObject }}</span>
</div>
<div class="content-item">
<span class="label">核心限制措施:</span>
<span class="text">{{ CCLInfo.restrictiveMeasure }}</span>
</div>
</div>
</div>
</div>
<div class="left-center">
<div class="title">
<div class="box"></div>
<div class="text">出口管制分类编码(ECCN)</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt />
<img src="../../../../assets/收藏按钮.png" alt />
</div>
</div>
<div class="button-list">
<div
:class="['button', {'click': item.isClick}]"
@click="changeECCN(item)"
v-for="(item, i) in ECCNList"
>
<span>{{ item.ranking }}{{ item.name }}</span>
</div>
</div>
<div class="description">
<li>{{ currentECCN.description }}</li>
</div>
<el-table :data="tableData" stripe class="table-class">
<el-table-column prop="categoryCode" label="第一项" />
<el-table-column prop="name" label="物项类别" width="460" />
<el-table-column prop="nameZh" label="说明" width="460" />
</el-table>
</div>
<div class="left-bottom">
<div class="title">
<div class="box"></div>
<div class="text">商业管制清单更新历史</div>
<div class="filters">
<el-select
v-model="selectedDomain"
placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- <el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox> -->
</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt />
<img src="../../../../assets/收藏按钮.png" alt />
</div>
</div>
<div class="left-bottom-main">
<div class="sanction-list" v-for="(item, i) in sanctionList" :key="item.id">
<div class="time">
<div class="year">{{ item.year }}</div>
<div class="date">{{ item.date }}</div>
</div>
<div class="img-zone">
<img :src="item.icon || title" alt />
<div :class="['img-line', {'img-line-last': i === sanctionList.length - 1}]"></div>
</div>
<div class="main">
<div class="main-title">{{ item.name }}</div>
<!-- <div class="main-title" @click="handleClick(item)">{{ item.name }}</div> -->
<el-tooltip
effect="dark"
:content="item.summary"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="main-desc">{{ item.summary }}</div>
</el-tooltip>
<div class="tag-box">
<div v-for="tag in item.techDomainList" :key="tag" class="tag-item">{{ tag }}</div>
</div>
<div
:class="{ 'count-tag': item.cnEntityCount }"
>{{ item.cnEntityCount ? `${item.cnEntityCount}家中国实体` : "" }}</div>
</div>
</div>
</div>
<div class="left-footer">
<div class="total-count">{{ totalAll }}</div>
<el-pagination
v-model:current-page="currentPageAll"
:page-size="pageSizeAll"
:total="totalAll"
layout="prev, pager, next"
background
@current-change="handlePageChangeAll"
/>
</div>
</div>
</div>
<div class="right">
<div class="title">
<div class="box"></div>
<div class="text">发布机构</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt />
<img src="../../../../assets/收藏按钮.png" alt />
</div>
</div>
<div class="right-main">
<div class="right-main-title">
<img :src="publishInfo.imageUrl" alt />
<div class="title-zone">
<div class="title-line">
<div class="title-text">{{ publishInfo.orgNameZh }} ></div>
<div class="title-detail" @click="handleClickOrg(publishInfo)">
<span>查看官网</span>
<img src="../../../../assets/dakai.png" alt />
</div>
</div>
<div class="title-entext">{{ publishInfo.orgName }}</div>
</div>
</div>
<!-- 关键人物 -->
<div class="right-main-key-person">
<div class="key-person-title">
<img :src="icon01" alt />
<span>关键人物</span>
</div>
<div class="key-person-list">
<div
class="person-item"
v-for="(item, index) in publishInfo.personList"
:key="index"
@click="handlePerClick(item)"
>
<img :src="item.imageUrl" alt />
<div class="person-info">
<el-tooltip
effect="dark"
:content="item.name"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="name">{{ item.name }}</div>
</el-tooltip>
<el-tooltip
effect="dark"
:content="item.position"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="title1">{{ item.position }}</div>
</el-tooltip>
</div>
</div>
</div>
</div>
<!-- 机构动态 -->
<div class="right-main-dynamic">
<div class="dynamic-title">
<img :src="icon02" alt />
<span>机构动态</span>
</div>
<div class="dynamic-list">
<div class="dynamic-item" v-for="(item, index) in publishOrgInfo" :key="item.newsId">
<div class="dot-line">
<div class="dot"></div>
<div class="line" v-if="index !== publishOrgInfo.length - 1"></div>
</div>
<div class="content-box">
<div class="date">{{ item.publishDate }}</div>
<div class="text">{{ item.newsContent }}</div>
</div>
</div>
</div>
<div
class="more-btn"
v-if="publishOrgInfo.length < dynamicTotal"
@click="handleLoadMoreDynamic"
>
<span>查看更多</span>
<el-icon>
<ArrowDown />
</el-icon>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch, onBeforeMount } from "vue";
import router from "@/router";
import title from "../../../../assets/title.png";
import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import icon01 from "../../assets/icon01.png";
import icon02 from "../../assets/icon02.png";
import { ArrowDown } from "@element-plus/icons-vue";
import { ElTable, ElTableColumn, ElButton, ElSelect, ElOption, ElInput } from 'element-plus'
import { getCCLInfo, getECCN, getECCNList, getPublishInfo, getPublishOrgInfo, getEntityUpdateInfo } from "@/api/exportControlV2.0.js";
// 处理点击发布机构的方法
const handleClickOrg = item => {
// console.log("点击了发布机构:", item);
const route = router.resolve({
path: "/institution",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
// 处理点击关键人物的方法
const handlePerClick = item => {
console.log("点击了关键人物:", item);
const route = router.resolve({
path: "/characterPage",
query: {
type: item.type,
personId: item.id
}
});
window.open(route.href, "_blank");
};
// 处理点击实体名称的方法
const handleClick = item => {
// console.log("点击了实体名称:", item);
const route = router.resolve({
path: "/exportControl/singleSanction",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
const selectedDomain = ref(0);
const onlyChina = ref(false);
const domainOptions = [
{ label: "全部领域", value: 0 },
{ label: "人工智能", value: 1 },
{ label: "生物科技", value: 2 },
{ label: "新一代信息技术", value: 3 },
{ label: "量子科技", value: 4 },
{ label: "新能源", value: 5 },
{ label: "集成电路", value: 6 },
{ label: "海洋", value: 7 },
{ label: "先进制造", value: 8 },
{ label: "新材料", value: 9 },
{ label: "航空航天", value: 10 },
{ label: "深海", value: 11 },
{ label: "极地", value: 12 },
{ label: "太空", value: 13 },
{ label: "核", value: 14 }
];
const sanctionList = ref([]);
const currentPageAll = ref(1);
const pageSizeAll = ref(10);
const totalAll = ref(0);
// 获取商业管制清单更新历史
const getSanctionUpdate = async () => {
// 传递的参数
// {"isCn":false,"techDomainIds":[1],"typeName":"商业管制清单","pageNum":1,"pageSize":10}
const data = {
isCn: onlyChina.value,
techDomainIds: selectedDomain.value ? [selectedDomain.value] : [],
// typeName: "实体清单",
typeName: "商业管制清单",
pageNum: currentPageAll.value,
pageSize: pageSizeAll.value
};
try {
const res = await getEntityUpdateInfo(data);
console.log('-----getSanctionUpdate', res)
if (res && res.code === 200) {
console.log(res.data.content);
sanctionList.value = (res.data.content || []).map(item => ({
...item,
year: item.postDate ? item.postDate.split("-")[0] : "",
date: item.postDate ? `${item.postDate.split("-")[1]}月${item.postDate.split("-")[2]}日` : "",
techDomainList: item.techDomainList || [],
icon: ""
}));
totalAll.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取商业管制清单更新历史失败:", error);
}
};
// 监听筛选条件变化
watch([selectedDomain, onlyChina], () => {
currentPageAll.value = 1;
getSanctionUpdate();
});
const handlePageChangeAll = val => {
currentPageAll.value = val;
getSanctionUpdate();
const container = document.querySelector(".entity-list");
const target = document.querySelector(".left-bottom");
if (container && target) {
const containerRect = container.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();
// 148是吸顶头部的高度,减去它以避免标题被遮挡
const top = targetRect.top - containerRect.top + container.scrollTop - 148;
container.scrollTo({
top: top,
behavior: "smooth"
});
}
};
// 获取商业管制清单发布机构
const publishInfo = ref({});
const getPublishInfoFn = async () => {
const params = {
sanTypeId: 13 // 商业管制清单固定13
};
try {
const res = await getPublishInfo(params);
if (res && res.code === 200) {
publishInfo.value = res.data;
console.log('------getPublishInfoFn', res.data)
// 获取发布机构动态
getPublishOrgInfoFn();
}
} catch (error) {
console.error("获取商业管制清单发布机构失败:", error);
}
};
// 获取发布机构动态
const publishOrgInfo = ref([]);
const dynamicPage = ref(1);
const dynamicPageSize = ref(3);
const dynamicTotal = ref(0);
const getPublishOrgInfoFn = async (isLoadMore = false) => {
if (publishInfo.value && !publishInfo.value.id) return;
const params = {
orgId: publishInfo.value.id,
pageNum: dynamicPage.value,
pageSize: dynamicPageSize.value
};
try {
const res = await getPublishOrgInfo(params);
if (res && res.code === 200) {
const newRows = (res.data.content || []).map(item => ({
...item,
publishDate: item.newsDate,
title: item.newsTitle
}));
if (isLoadMore) {
publishOrgInfo.value = [...publishOrgInfo.value, ...newRows];
} else {
publishOrgInfo.value = newRows;
}
dynamicTotal.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取发布机构动态失败:", error);
}
};
const handleLoadMoreDynamic = () => {
dynamicPage.value++;
getPublishOrgInfoFn(true);
};
// 获取商业管制清单基本信息
// todo: 待对接后端接口
const CCLInfo = ref({
description: "xxxxx",
legalBasis: "法律依据",
controlledObject: "管制对象",
name: '',
orgId: '',
orgLogoUrl: '',
orgName: '',
originalName: '',
shortName: '',
restrictiveMeasure: "核心限制措施"
});
const getCCLInfoFn = async () => {
try {
const res = await getCCLInfo();
if (res && res.code === 200) {
CCLInfo.value = res.data;
console.log('getCCLInfoFn', CCLInfo.value)
}
} catch (error) {
console.error("获取商业管制清单基本信息失败:", error);
}
};
// 定义ECCN列表
const ECCNList = ref([
{
name: '第1位: 物项类别',
isClick: true,
description: 'ECCN的第一位是一个数字,它指明了受控物项所属的技术或行业类别,对于快速定位物项在《商业管制清单》中的位置至关重要',
key: 'wxlb' // 用于和后端对接的
}
])
const getCCL_ECCN_Type = async () => {
try {
const res = await getECCN();
if (res && res.code === 200) {
ECCNList.value = res.data;
console.log('getCCL_ECCN_Type', ECCNList.value)
// 为每个对象增加是否点击对象
ECCNList.value.forEach((item) => {
item.isClick = false
})
// 默认点击第一个
ECCNList.value[0].isClick = true
// 默认将第一个赋值给currentECCN
currentECCN.value = ECCNList.value[0]
}
} catch (error) {
console.error("获取商业管制清单出口管制分类编码失败:", error);
}
};
// 表格数据
const tableData = ref([
{
categoryCode: '0',
categoryId: 1,
code: null,
description: null,
descriptionZh: null,
id: 1,
name: 'Nuclear Materials, Facilities and Equipment and Miscellaneous',
nameZh: "核材料、设备设施及其他类似物项"
}
])
const currentECCN = ref({
name: '第1位: 物项类别',
isClick: true,
description: 'ECCN的第一位是一个数字,它指明了受控物项所属的技术或行业类别,对于快速定位物项在《商业管制清单》中的位置至关重要',
id: 1,
ranking: 1
})
/**
* 修改ECCN
*/
function changeECCN(item) {
ECCNList.value.forEach((i) => i.isClick = false)
item.isClick = true
currentECCN.value = item
}
// 监听当前的ECCN,更新获取列表数据
watch(
() => currentECCN.value,
async (newValue) => {
// 调用接口更新table数据
const params = {
id: currentECCN.value.id
}
try {
const res = await getECCNList(params);
if (res && res.code === 200) {
tableData.value = res.data;
console.log('getECCNList', tableData.value)
}
} catch (error) {
console.error("获取商业管制清单出口管制分类编码信息列表列表数据:", error);
}
},
{ deep: true }
);
onMounted(() => {
// 获取商业管制清单基本信息
getCCLInfoFn();
// 获取商业管制清单的分类编码
getCCL_ECCN_Type()
// 获取商业管制清单发布机构
getPublishInfoFn();
// 获取商业管制清单更新历史
getSanctionUpdate();
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
user-select: none;
}
.introduction-page {
width: 1601px;
margin: 0 auto;
padding-top: 16px;
padding-bottom: 50px;
display: flex;
justify-content: space-between;
.left {
width: 1064px;
.left-top {
width: 100%;
height: auto;
padding-bottom: 20px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
margin-bottom: 16px;
.left-top-main {
width: 100%;
padding: 8px 26px 0 26px;
.left-top-main-title {
padding: 16px 24px;
border-radius: 4px;
border: 1px solid rgba(231, 243, 255, 1);
background: linear-gradient(to bottom right, rgba(231, 243, 255, 1), rgba(231, 243, 255, 0));
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(5, 95, 194);
margin-bottom: 17px;
}
.left-top-main-content {
.content-item {
margin-bottom: 13px;
font-size: 16px;
font-family: "Microsoft YaHei";
display: flex;
.label {
width: 120px;
flex-shrink: 0;
font-weight: 700;
color: rgb(59, 65, 75);
white-space: nowrap;
}
.text {
color: rgb(59, 65, 75);
text-align: justify;
}
}
}
}
}
.left-center {
width: 100%;
// height: 705px;
height: auto;
border-radius: 10px;
background-color: #fff;
margin-bottom: 16px;
.button-list {
width: 1012px;
height: 32px;
margin-left: 26px;
display: flex;
align-items: center;
justify-content: space-around;
.button {
width: 196px;
height: 32px;
border-radius: 4px;
border: 1px solid rgba($color: #eeeeee, $alpha: 0.8);
display: flex;
align-items: center;
justify-content: center;
color: rgb(59, 65, 75);
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
letter-spacing: 0px;
font-style: Regular;
}
}
.click {
background: rgba(231, 243, 255, 1);
border: 1px solid rgba(231, 243, 255, 1);
color: rgb(5, 95, 194);
}
}
.description {
width: 991px;
height: auto;
min-height: 30px;
margin-top: 16px;
margin-left: 63px;
}
.table-class {
width: 1013px;
height: auto;
margin-top: 16px;
margin-left: 24px;
color: rgb(59, 65, 75);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
letter-spacing: 0px;
font-style: Regular;
}
}
.left-bottom {
width: 100%;
min-height: 1000px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.title {
border-bottom: 1px solid rgb(234, 236, 238);
.filters {
margin-left: auto;
display: flex;
align-items: center;
margin-right: 20px;
}
.btn {
margin-left: 0;
}
}
.left-bottom-main {
padding: 16px 42px 0 25px;
.sanction-list {
width: 1169px;
// padding: 0px 0 12px 0;
display: flex;
// justify-content: flex-start;
height: 154px;
.time {
width: 80px;
height: 50px;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: center;
margin-right: 16px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
font-weight: 700;
.year {
font-size: 16px;
line-height: 24px;
}
.date {
font-size: 16px;
line-height: 24px;
}
}
.img-zone {
display: flex;
flex-direction: column;
align-items: center;
// justify-content: center;
// width: 30px;
margin-top: 14px;
// margin-right: 16px;
// height: calc(100% - 16px);
margin-right: 16px;
img {
width: 30px;
height: 30px;
border-radius: 50%;
z-index: 2;
}
.img-line {
width: 1px;
border: 1px solid rgba($color: #eeeeee, $alpha: 1);
// height: calc(100% - 30px);
position: absolute;
height: 154px;
}
.img-line-last {
height: 140px;
}
}
.main {
width: 855px;
padding-top: 14px;
position: relative;
.main-title {
cursor: pointer;
width: 700px;
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
margin-bottom: 11px;
}
.main-desc {
font-size: 16px;
font-weight: 400;
line-height: 30px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
margin-bottom: 9px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.tag-box {
display: flex;
.tag-item {
padding: 1px 8px;
margin-right: 8px;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
line-height: 22px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
background-color: rgba(231, 243, 255, 1);
}
}
.count-tag {
position: absolute;
padding: 2px 8px;
top: 0;
right: 0;
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(206, 79, 81);
border-radius: 20px;
background-color: rgba(206, 79, 81, 0.1);
}
}
}
}
.left-footer {
width: 100%;
height: 73px;
border-top: 1px solid rgb(234, 236, 238);
padding: 0 31px;
display: flex;
justify-content: space-between;
align-items: center;
.total-count {
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
}
}
}
}
.right {
width: 520px;
height: 1020px;
border-radius: 10px;
padding-bottom: 20px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.right-main {
padding: 7px 24px 0px 23px;
.right-main-title {
cursor: pointer;
width: 473px;
height: auto;
border-radius: 4px;
background-color: rgb(247, 248, 249);
border: 1px solid rgb(234, 236, 238);
display: flex;
margin-bottom: 20px;
padding: 16px;
.title-zone {
width: calc(100% - 64px);
}
img {
width: 64px;
height: 64px;
margin-right: 14px;
}
.title-line {
display: flex;
height: 26px;
margin-bottom: 6px;
justify-content: space-between;
align-items: center;
}
.title-detail {
display: flex;
align-items: center;
justify-content: center;
span {
font-family: Microsoft YaHei;
color: rgba(5, 95, 194, 1);
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: center;
margin-top: 1px;
}
img {
width: 16px;
height: 16px;
margin-right: 0px;
}
}
.title-text {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
}
.title-entext {
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
}
}
.right-main-key-person {
width: 100%;
padding-bottom: 20px;
border-bottom: 1px solid rgb(234, 236, 238);
margin-bottom: 18px;
.key-person-title {
display: flex;
align-items: center;
margin-bottom: 19px;
img {
width: 14px;
height: 14px;
margin-right: 12px;
}
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
}
}
.key-person-list {
display: flex;
flex-wrap: wrap;
.person-item {
width: 185px;
cursor: pointer;
display: flex;
align-items: center;
margin-bottom: 16px;
&:nth-child(2n-1) {
margin-left: 28px;
margin-right: 39px;
}
img {
width: 48px;
height: 48px;
border-radius: 50%;
margin-right: 8px;
object-fit: cover;
flex-shrink: 0;
}
.person-info {
width: calc(100% - 48px - 8px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* 防止文本换行 */
.name {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
margin-bottom: 1px;
white-space: nowrap;
}
.title1 {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
line-height: 1.2;
// white-space: nowrap;
}
}
}
}
}
.right-main-dynamic {
width: 100%;
.dynamic-title {
display: flex;
align-items: center;
margin-bottom: 19px;
img {
width: 14px;
height: 14px;
margin-right: 12px;
}
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
}
}
.dynamic-list {
max-height: 500px;
overflow-y: auto;
padding-right: 10px;
/* 滚动条样式 */
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
&:hover {
background: #a8a8a8;
}
}
.dynamic-item {
display: flex;
position: relative;
padding-bottom: 24px;
.dot-line {
width: 12px;
display: flex;
flex-direction: column;
align-items: center;
margin-right: 12px;
margin-top: 6px;
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
border: 2px solid rgb(5, 95, 194);
background-color: #fff;
z-index: 1;
}
.line {
width: 1px;
height: calc(100% - 2px);
background-color: rgb(234, 236, 238);
position: absolute;
top: 12px;
left: 5px;
}
}
.content-box {
flex: 1;
.date {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
margin-bottom: 8px;
}
.text {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
line-height: 30px;
text-align: justify;
}
}
}
}
.more-btn {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
color: rgb(5, 95, 194);
cursor: pointer;
margin-top: 8px;
span {
margin-right: 4px;
}
}
}
}
}
}
.title {
width: 100%;
height: 56px;
display: flex;
align-items: center;
padding: 14px 12px 16px 0;
.box {
width: 8px;
height: 20px;
background-color: rgb(5, 95, 194);
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
margin-right: 14px;
}
.text {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
.btn {
width: 60px;
height: 28px;
margin-left: auto;
img {
width: 28px;
height: 28px;
cursor: pointer;
}
img:first-child {
margin-right: 4px;
}
}
}
</style>
<style scoped>
.common-prompt-popper.el-popper {
padding: 8px 16px !important;
border-radius: 10px !important;
background-color: rgb(59, 65, 75) !important;
font-size: 16px !important;
font-weight: 400 !important;
font-family: "Microsoft YaHei" !important;
line-height: 30px !important;
color: #fff !important;
border: none !important;
max-width: 500px !important;
}
.common-prompt-popper.el-popper .el-popper__arrow::before {
background-color: rgb(59, 65, 75) !important;
border-color: rgb(59, 65, 75) !important;
}
:deep(.el-table thead) {
color: rgb(59, 65, 75);
}
:deep(.el-table tr) {
height: 48px;
}
</style>
<template>
<el-dialog
v-model="visible"
width="1280px"
:show-close="false"
:close-on-click-modal="false"
class="rule-subsidiary-dialog"
destroy-on-close
top="5vh"
draggable
>
<template #header>
<div class="dialog-header">
<div class="left-title">
<img :src="defaultIcon" alt="" class="title-icon" />
<span class="company-name">{{ companyName }}</span>
<span class="suffix-text">“实体清单50%规则” 涉及实体列表</span>
</div>
<div class="right-actions">
<div class="right-count">
<span class="highlight">{{ totalCount }}</span>
</div>
<el-icon class="close-btn" @click="visible = false"><Close /></el-icon>
</div>
</div>
</template>
<div class="dialog-content">
<el-table
:data="tableData"
table-layout="fixed"
:row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }"
style="width: 100%"
>
<el-table-column label="实体名称" min-width="300">
<template #default="{ row }">
<div class="entity-name-cell">
<el-avatar class="avatar" :size="24" :src="row.avatar || defaultIcon" />
<div class="name" :title="row.name">{{ row.name }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="涉及领域" width="200">
<template #default="{ row }">
<div class="domain-cell">
<el-tag
v-for="tag in row.domains"
:key="tag"
class="domain-tag"
effect="plain"
:disable-transitions="true"
:style="getTagStyle(tag)"
>
{{ tag }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="equityRatio" label="股权占比" width="120" align="center" />
<el-table-column prop="location" label="上市地点" width="120" align="center" />
<el-table-column prop="revenue" label="营收(亿元)" width="120" align="center" />
</el-table>
<div class="dialog-footer">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="totalCount"
layout="prev, pager, next"
prev-text="<"
next-text=">"
@current-change="handleCurrentChange"
/>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { ref, defineProps, defineEmits, computed, watch } from "vue";
import { Close } from "@element-plus/icons-vue";
import defaultIcon from "../../../../../assets/icons/default-avatar.png";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
companyName: {
type: String,
default: ""
},
totalCount: {
type: Number,
default: 0
},
dataList: {
type: Array,
default: () => []
}
});
const emit = defineEmits(["update:modelValue"]);
const visible = computed({
get: () => props.modelValue,
set: val => emit("update:modelValue", val)
});
const currentPage = ref(1);
const pageSize = ref(10);
const tableData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return props.dataList.slice(start, end).map(item => ({
...item,
name: item.orgName,
domains: item.techDomains || [],
equityRatio: item.equityRatio ? (item.equityRatio * 100).toFixed(2) + '%' : '--',
location: '--',
revenue: item.revenue || '--'
}));
});
const handleCurrentChange = val => {
currentPage.value = val;
};
const tableRowClassName = ({ rowIndex }) => {
return rowIndex % 2 === 0 ? "odd-row" : "";
};
const getTagStyle = tag => {
const colorPool = [
{ color: "#CD4246", background: "rgba(255, 242, 240, 1)", borderColor: "rgba(255, 163, 158, 1)" },
{ color: "#0E78F1", background: "rgba(230, 244, 255, 1)", borderColor: "rgba(145, 206, 255, 1)" },
{ color: "#722ED1", background: "rgba(249, 240, 255, 1)", borderColor: "rgba(211, 173, 247, 1)" },
{ color: "#13A8A8", background: "rgba(230, 255, 251, 1)", borderColor: "rgba(135, 232, 222, 1)" },
{ color: "#FA8C16", background: "rgba(255, 247, 230, 1)", borderColor: "rgba(255, 213, 145, 1)" },
{ color: "#52C41A", background: "rgba(246, 255, 237, 1)", borderColor: "rgba(183, 235, 143, 1)" }
];
let hash = 0;
for (let i = 0; i < tag.length; i++) {
hash = tag.charCodeAt(i) + ((hash << 5) - hash);
}
const index = Math.abs(hash) % colorPool.length;
return colorPool[index];
};
</script>
<style lang="scss" scoped>
.rule-subsidiary-dialog {
:deep(.el-dialog__header) {
margin-right: 0;
padding: 24px;
border-bottom: 1px solid #edeff2;
}
:deep(.el-dialog__body) {
padding: 0;
}
}
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
.left-title {
display: flex;
align-items: center;
.title-icon {
width: 24px;
height: 24px;
margin-right: 8px;
}
.company-name {
font-size: 18px;
font-weight: 700;
color: #3b414b;
margin-right: 8px;
font-family: "Microsoft YaHei";
}
.suffix-text {
font-size: 18px;
font-weight: 700;
color: #3b414b;
font-family: "Microsoft YaHei";
}
}
.right-actions {
display: flex;
align-items: center;
.right-count {
font-size: 14px;
color: #5f656c;
font-weight: 700;
font-family: "Microsoft YaHei";
margin-right: 20px;
.highlight {
color: #cd4246;
margin: 0 4px;
font-size: 16px;
}
}
.close-btn {
font-size: 20px;
color: #909399;
cursor: pointer;
transition: color 0.2s;
&:hover {
color: #409eff;
}
}
}
}
.dialog-content {
height: 722px; /* Adjusted to fit total 851px approx with header (65px) and footer (64px) */
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 0 24px;
:deep(.el-table) {
--el-table-header-bg-color: #fff;
--el-table-border-color: transparent;
--el-table-row-hover-bg-color: rgba(248, 249, 250, 1);
}
:deep(.el-table__inner-wrapper::before) {
background-color: transparent;
}
:deep(.el-table__header-wrapper th) {
height: 60px;
background-color: #fff;
font-size: 16px;
font-weight: 700;
color: rgba(59, 65, 75, 1);
font-family: "Microsoft YaHei";
border-bottom: 1px solid rgba(230, 231, 232, 1);
}
:deep(.el-table__header-wrapper .cell) {
line-height: 22px;
}
:deep(.el-table__row) {
height: 64px;
}
:deep(.el-table__cell) {
border-bottom: 0;
font-size: 16px;
font-weight: 400;
color: rgb(95, 101, 108);
font-family: "Microsoft YaHei";
}
:deep(.odd-row td.el-table__cell) {
background-color: rgba(248, 249, 250, 1);
}
.entity-name-cell {
display: flex;
align-items: center;
.avatar {
flex: 0 0 24px;
margin-right: 9px;
}
.name {
font-size: 16px;
font-weight: 700;
color: rgba(59, 65, 75, 1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.domain-cell {
display: flex;
align-items: center;
gap: 8px;
:deep(.el-tag) {
height: auto;
padding: 2px 8px;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
}
}
}
.dialog-footer {
height: 64px;
display: flex;
justify-content: center;
align-items: center;
border-top: 1px solid #edeff2;
:deep(.el-pagination) {
--el-pagination-button-bg-color: #fff;
--el-pagination-hover-color: #0e78f1;
--el-pagination-font-size: 14px;
.el-pager li {
border: 1px solid #dcdfe6;
border-radius: 4px;
margin: 0 4px;
font-weight: 400;
color: #5f656c;
min-width: 32px;
height: 32px;
line-height: 30px;
&.is-active {
background-color: #0e78f1;
color: #fff;
border-color: #0e78f1;
}
&:hover:not(.is-active) {
color: #0e78f1;
border-color: #0e78f1;
}
}
.btn-prev,
.btn-next {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0;
margin: 0 4px;
min-width: 32px;
height: 32px;
line-height: 30px;
text-align: center;
&:hover {
color: #0e78f1;
border-color: #0e78f1;
}
&[disabled] {
border-color: #e4e7ed;
color: #c0c4cc;
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="list-page">
<div class="search-box">
<div style="display: flex; justify-content: center">
<el-select v-model="currentCCLType" style="width: 388px; height: 32px; margin-right: 14px">
<el-option v-for="item in CCLTypeList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
<el-input
v-model="searchKeyword"
class="search-input"
placeholder="搜索物项或ECCN编码"
:suffix-icon="Search"
/>
</div>
<div class="filters">
<el-checkbox v-model="viewNew" label="查看最近更新内容" />
</div>
</div>
<div class="main">
<div class="left">
<div class="title">
<div class="box"></div>
<div class="text">科技领域</div>
</div>
<div class="checkbox-group">
<el-checkbox
v-for="(item, index) in techFields"
:key="index"
v-model="item.checked"
:label="item.name"
@change="handleFilterChange(item, techFields, 'tech')"
/>
</div>
<div class="title">
<div class="box"></div>
<div class="text">管控原因</div>
</div>
<div class="checkbox-group">
<el-checkbox
v-for="(item, index) in controlReason"
:key="index"
v-model="item.checked"
:label="item.name"
@change="handleFilterChange(item, controlReason, 'reason')"
/>
</div>
</div>
<div class="right">
<div class="title">
<div class="left-wrapper">
<div class="box"></div>
<div class="text">CCL清单列表</div>
</div>
<div class="right-wrapper">
<!-- <div class="stats">
<el-switch v-model="value" size="small" />
<span>显示原文</span>
</div>-->
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt />
<img src="../../../../assets/收藏按钮.png" alt />
</div>
</div>
</div>
<div class="right-table">
<div class="list" v-for="(item, i) in cclList">
<div class="list-title" @click="item.isExpand = !item.isExpand">
<span>类别 {{ item.cclCode }}-{{ item.cclTitleZh }}</span>
<img src="../../assets/downArrow_white.png" alt v-if="item.isExpand" />
<img src="../../assets/upArrow_white.png" alt v-else />
</div>
<div style="width: 100%" v-if="item.isExpand">
<div style="width: 100%" v-for="element in item.cclChildren">
<div class="list-desc">{{ element.cclCode }}. {{ element.cclTitleZh }}</div>
<div class="list-content" v-for="(ele, j) in element.cclChildren">
<div class="content-title" @click="ele.isExpand = !ele.isExpand">
<div class="code-zone">
<!-- <div class="dot" v-if="ele.isDot"></div> -->
<span class="code">{{ ele.cclCode }}</span>
</div>
<span class="name">{{ ele.cclTitleZh }}</span>
<img src="../../assets/upArrow_gray.png" alt v-if="ele.isExpand" />
<img src="../../assets/downArrow_gray.png" alt v-else />
</div>
<div class="content-body" v-if="ele.isExpand">
<!-- <img src="../../assets/cclDetail.png" alt /> -->
<div v-if="ele.cclDescription" v-html="ele.cclDescription"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
import { Search, Select } from "@element-plus/icons-vue";
import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import { getECCNCategory, getAreaType, getControlReason, getCclQuery, getExportControlList, get50PercentEntityCount } from "@/api/exportControlV2.0.js"
const router = useRouter();
const currentCCLType = ref('')
const CCLTypeList = ref([])
const getTypeList = async () => {
try {
const res = await getECCNCategory()
if (res && res.code === 200) {
console.log('-----getTypeList', res.data)
CCLTypeList.value = res.data
currentCCLType.value = CCLTypeList.value[0].id
}
} catch (error) {
console.error("获取类别字典失败:", error);
}
}
const techFields = ref([])
const getTechFields = async () => {
try {
const res = await getAreaType()
if (res && res.code === 200) {
console.log('-----getTechFields', res.data)
techFields.value = res.data
// 默认选中第一个
techFields.value[0].checked = true
}
} catch (error) {
console.error("获取科技领域字典失败:", error);
}
}
const controlReason = ref([])
const getControlReasonList = async () => {
try {
const res = await getControlReason()
if (res && res.code === 200) {
console.log('-----getControlReasonList', res.data)
controlReason.value = res.data
// 默认选中第一个
controlReason.value[0].checked = true
}
} catch (error) {
console.error("获取管控原因字典失败:", error);
}
}
const searchKeyword = ref('');
const onlyChina = ref(false);
const viewNew = ref(true)
// 获取ccl清单列表
const getCclList = async () => {
let techDomains = techFields.value.filter(item => item.checked).map(item => +item.id)
let controls = controlReason.value.filter(item => item.checked).map(item => +item.id)
const params = {
categoryCode: currentCCLType.value,
techDomainIds: techDomains,
keyword: searchKeyword.value || '',
controlIds: controls,
isLatest: viewNew.value
}
console.log(JSON.stringify(params))
try {
// const res = await getCclQuery(null);
const res = await getCclQuery(params);
// const res = {
// "code": 200,
// "message": "操作成功",
// "success": true,
// "data": [
// {
// "id": 1,
// "cclCode": "0",
// "cclTitle": "Nuclear Materials, Facilities and Equipment and Miscellaneous",
// "cclTitleZh": "核材料、设备设施及其他类似物项",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": [
// {
// "id": 11,
// "cclCode": "A",
// "cclTitle": "Equipment, Assemblies and Components",
// "cclTitleZh": "设备、组件和部件",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": [
// {
// "id": 1,
// "cclCode": "0A002",
// "cclTitle": "Power generating or propulsion equipment \"specially designed\" for use with space, marine or mobile \"nuclear reactors\". (These items are \"subject to the ITAR.\" See 22 CFR parts 120 through 130.)",
// "cclTitleZh": "专为太空、海洋或移动“核反应堆”设计的发电或推进设备。(这些项目“受 ITAR 约束”。参见 22 CFR 第 120 至 130 部分。)",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": null
// },
// {
// "id": 2,
// "cclCode": "0A501",
// "cclTitle": "Firearms (except 0A502 shotguns, 0A506 semi-automatic rifles, 0A507 semi-automatic pistols, and 0A508 semi-automatic shotguns) and related commodities (except semi-automatic related commodities enumerated or otherwise described in Eccn 0A509 for Eccns 0A506, 0A507, or 0A508) as follows (see List of Items controlled).",
// "cclTitleZh": "火器(除 0A502 霰弹枪、0A506 半自动步枪、0A507 半自动手枪和 0A508 半自动霰弹枪外)及相关商品(除 Eccn 0A509 中列举或以其他方式描述的 Eccns 0A506、0A507 或 0A508 相关物品外),具体如下(参见管制物品列表)。",
// "cclDescription": "<p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">License Requirements</span></p><p class=\"flush-paragraph-1\"><em>Reason for Control:</em> NS, RS, FC, UN, AT</p><div class=\"table-wrapper\"><div class=\"gpotbl_div\"><table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" class=\"gpo_table\" frame=\"void\" width=\"100%\"><thead><tr><th class=\"center\">Control(s)</th><th class=\"center\">Country chart<br>(see Supp. No. 1 to part 738)</th></tr></thead><tbody><tr><td class=\"left\">NS applies to entire entry except 0A501.y</td><td class=\"left\">NS Column 1.</td></tr><tr><td class=\"left\">RS applies to entire entry except 0A501.y</td><td class=\"left\">RS Column 1.</td></tr><tr><td class=\"left\">FC applies to entire entry except 0A501.y</td><td class=\"left\">FC Column 1.</td></tr><tr><td class=\"left\">UN applies to entire entry</td><td class=\"left\">See § 746.1 of the EAR for UN controls.</td></tr><tr><td class=\"left\">AT applies to entire entry</td><td class=\"left\">AT Column 1.</td></tr></tbody></table></div></div><div class=\"note\"><div class=\"header\"><em>License Requirement Note:</em></div><p><em>In addition to using the Commerce Country Chart to determine license requirements, a license is required for exports and reexports of ECCN 0A501.y.7 firearms to the People's Republic of China.</em></p></div><p class=\"flush-paragraph-1\">List Based License Exceptions (See Part 740 for a Description of All License Exceptions)</p><p class=\"flush-paragraph-1\"><em>LVS:</em> $500 for 0A501.c, .d, and .x.</p><p class=\"flush-paragraph-1\">$500 for 0A501.c, .d, .e, and .x if the ultimate destination is Canada.</p><p class=\"flush-paragraph-1\"><em>GBS:</em> N/A</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">Special Conditions for STA</span></p><p class=\"flush-paragraph-1\">License Exception STA may not be used for ECCN 0A501.a, .b, .c, .d, or .e, to any of the destinations listed in Country Group A:5 or A:6 (See supplement no.1 to part 740 of the EAR). License Exception STA may not be used for any item in this entry to any of the destinations listed in Country Group A:6 (See Supplement No.1 to part 740 of the EAR).</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">List of Items Controlled</span></p><p class=\"flush-paragraph-1\"><em>Related Controls:</em> (1) See USML Category I for firearms that are fully automatic, and certain related parts, components, accessories, and attachments (including magazines with a capacity of greater than 50 rounds). (2) See ECCN 0A506 for semi-automatic rifles. (3) See ECCN 0A507 for semi-automatic pistols. (4) See ECCN 0A508 for semi-automatic shotguns and ECCN 0A502 for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (5) See ECCN 0A509 for enumerated or otherwise described \"parts,\" \"components,\" devices, \"accessories,\" and \"attachments\" for ECCNs 0A506, 0A507, and 0A508. (6) See .d, .x, and .y of this entry for other \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" for 0A506 and 0A507, or 0A508. (7) See ECCN 0A502 for non-automatic shotguns and their \"parts\" and \"components\" that are subject to the EAR and for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (8) See ECCN 0A504 and USML Category XII for controls on optical sighting devices.</p><p class=\"flush-paragraph-1\"><em>Related Definitions:</em> N/A.</p><p class=\"flush-paragraph\"><em>Items:</em></p><p>a. Non-automatic and non-semi-automatic firearms equal to .50 caliber (12.7 mm) or less.</p><div class=\"note\"><div class=\"header\"><em>Note 1 to paragraph 0A501.a:</em></div><p><em>'Combination pistols' are controlled under ECCN 0A501.a. A 'combination pistol' (a.k.a., a combination gun) has at least one rifled barrel and at least one smoothbore barrel (generally a shotgun style barrel).</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 2 to paragraph 0A501.a:</em></div><p><em>Semi-automatic firearms</em> equal to .50 caliber (12.7 mm) or less <em>are controlled under ECCNs 0A506 and 0A507.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.a:</em></div><p><em>Firearms described in 0A501.a include those chambered for the .50 BMG cartridge.</em></p></div><p>b. Non-automatic and non-semi-automatic rifles, carbines, revolvers or pistols with a caliber greater than .50 inches (12.7 mm) but less than or equal to .72 inches (18.0 mm).</p><p>c. The following types of \"parts\" and \"components\" if \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or ECCNs 0A506 or 0A507, or USML Category I (unless otherwise enumerated or elsewhere specified on the USML or controlled under ECCN 0A509): Barrels, cylinders, barrel extensions, mounting blocks (trunnions), bolts, bolt carriers, operating rods, gas pistons, trigger housings, triggers, hammers/striker, sears, disconnectors, pistol grips that contain fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors) and buttstocks that contain fire control \"parts\" or \"components.\"</p><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.c:</em></div><p><em>Barrel blanks that have reached a stage in manufacturing in which they are either chambered or rifled are controlled by 0A501.c.</em></p></div><p>d. Detachable magazines with a capacity of 17 to 50 rounds \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or controlled by ECCNs 0A506 or 0A507.</p><div class=\"note\"><div class=\"header\"><em>Note 3 to paragraph 0A501.d</em></div><p><em>Magazines with a capacity of 16 rounds or less are controlled under 0A501.x; for magazines with a capacity greater than 50 rounds, see USML Category I. Magazines that hold only blank ammunition controlled under 0A505.d are controlled under 0A501.d or 0A501.x, depending on the magazine's capacity.</em></p></div><p>e. Receivers (frames) and \"complete breech mechanisms,\" including castings, forgings, stampings, or machined items thereof, \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry.</p><div class=\"note\"><div class=\"header\"><em>Note 4 to 0A501.e:</em></div><p><em>Frames (receivers) under 0A501.e refers to any \"part\" or \"component\" of the firearm that has or is customarily marked with a serial number when required by law. This paragraph 0A501.e is synonymous with a \"part\" or \"component\" that is regulated by the Bureau of Alcohol, Tobacco, Firearms and Explosives (see <a href=\"https://www.govinfo.gov/link/uscode/18/921\" class=\"usc external\" target=\"_blank\" rel=\"noopener noreferrer\">18 U.S.C. 921(a)(3)</a>; <a href=\"https://www.ecfr.gov/current/title-27/part-447\" class=\"cfr external\">27 CFR parts 447</a>, <a href=\"https://www.ecfr.gov/current/title-27/part-478\" class=\"cfr external\">478</a>, and <a href=\"https://www.ecfr.gov/current/title-27/part-479\" class=\"cfr external\">479</a>,) as a firearm.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 5 to 0A501.e:</em></div><p><em>Frames (receivers) \"specially designed\" for semi-automatic firearms are controlled under ECCN 0A509.b or .c.</em></p></div><p>f. through w. [Reserved]</p><p>x. \"Parts\" and \"components\" that are \"specially designed\" for a commodity classified under paragraphs .a through .c of this entry, a commodity classified under ECCNs 0A506 or 0A507, or the USML and not elsewhere specified on the USML or CCL or controlled under ECCN 0A509.</p><p>y. Specific \"parts,\" \"components,\" \"accessories\" and \"attachments\" \"specially designed\" for a commodity subject to control in this ECCN, ECCNs 0A506, 0A507, or common to a defense article in USML Category I and not elsewhere specified in the USML or CCL as follows, and \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" therefor.</p><p>y.1. Stocks (including adjustable, collapsible, blades and braces), grips, handguards, or forends, that do not contain any fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors);</p><p>y.2 through y.5. [Reserved]</p><p>y.6. Bayonets; and</p><p>y.7. Firearms manufactured from 1890 to 1898 and reproductions thereof.</p><div class=\"note\"><div class=\"header\"><em>Technical Note 1 to 0A501:</em></div><p><em>ECCN 0A501 includes \"parts\" and \"components\" that are not \"subject to the ITAR\" even though they are common to firearms described in ECCN 0A501 and to those firearms \"subject to the ITAR.\"</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 2 to 0A501:</em></div><p><em>A receiver with any other controlled \"part\" or \"component\" ( e.g., a barrel (0A501.c), or trigger guard (0A501.x), or stock (0A501.y.1)) is still controlled under 0A501.e.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 3 to 0A501:</em></div><p><em>Blank firing adapters, which are attachments to semi-automatic and automatic firearms used in conjunction with blank cartridges for safety and functional reasons and used for firearm training purposes by police, military, sporting shooters, as well as in the movie industry, are designated as EAR99.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 6 to 0A501:</em></div><p><em>Antique firearms (i.e., those manufactured before 1890) and reproductions thereof, muzzle loading and black powder firearms except those designs based on centerfire weapons of a post 1937 design, BB guns, pellet rifles, paint ball, and all other air rifles are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 7 to 0A501:</em></div><p><em>Muzzle loading and black powder firearms with a caliber less than 20 mm that were manufactured post 1937 that are used for hunting or sporting purposes that were not \"specially designed\" for military use and are not described on the USML nor controlled as shotguns under ECCN 0A502 are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 8 to 0A501:</em></div><p><em>Scope mounts or accessory rails, iron sights, sling swivels, and butt plates or recoil pads that are subject to the EAR are designated as EAR99. These commodities have been determined to no longer warrant being \"specially designed\" for purposes of ECCN 0A501.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 9 to 0A501:</em></div><p><em>A kit, including a replacement or repair kit, of firearms \"parts\" or \"components\" customarily sold and exported together takes on the classification of the most restrictive \"part\" or \"component\" that is included in the kit. For example, a kit containing 0A501.y and .x \"parts,\" is controlled as a 0A501.x kit because the .x \"part\" is the most restrictive \"part\" included in the kit. A complete 0A501 firearm disassembled in a kit form is controlled as a firearm under 0A501.a, .b, or .y.7.</em></p></div>",
// "cclDescriptionZh": "<p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">License Requirements</span></p><p class=\"flush-paragraph-1\"><em>Reason for Control:</em> NS, RS, FC, UN, AT</p><div class=\"table-wrapper\"><div class=\"gpotbl_div\"><table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" class=\"gpo_table\" frame=\"void\" width=\"100%\"><thead><tr><th class=\"center\">控制原因</th><th class=\"center\">Country chart<br>(参见第738部分补充1号文)</th></tr></thead><tbody><tr><td class=\"left\">NS applies to entire entry except 0A501.y</td><td class=\"left\">NS Column 1.</td></tr><tr><td class=\"left\">RS applies to entire entry except 0A501.y</td><td class=\"left\">RS Column 1.</td></tr><tr><td class=\"left\">FC applies to entire entry except 0A501.y</td><td class=\"left\">FC Column 1.</td></tr><tr><td class=\"left\">UN applies to entire entry</td><td class=\"left\">See § 746.1 of the EAR for UN controls.</td></tr><tr><td class=\"left\">AT applies to entire entry</td><td class=\"left\">AT Column 1.</td></tr></tbody></table></div></div><div class=\"note\"><div class=\"header\"><em>License Requirement Note:</em></div><p><em>In addition to using the Commerce Country Chart to determine license requirements, a license is required for exports and reexports of ECCN 0A501.y.7 firearms to the People's Republic of China.</em></p></div><p class=\"flush-paragraph-1\">List Based License Exceptions (See Part 740 for a Description of All License Exceptions)</p><p class=\"flush-paragraph-1\"><em>LVS:</em> $500 for 0A501.c, .d, and .x.</p><p class=\"flush-paragraph-1\">$500 for 0A501.c, .d, .e, and .x if the ultimate destination is Canada.</p><p class=\"flush-paragraph-1\"><em>GBS:</em> N/A</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">Special Conditions for STA</span></p><p class=\"flush-paragraph-1\">License Exception STA may not be used for ECCN 0A501.a, .b, .c, .d, or .e, to any of the destinations listed in Country Group A:5 or A:6 (See supplement no.1 to part 740 of the EAR). License Exception STA may not be used for any item in this entry to any of the destinations listed in Country Group A:6 (See Supplement No.1 to part 740 of the EAR).</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">List of Items Controlled</span></p><p class=\"flush-paragraph-1\"><em>Related Controls:</em> (1) See USML Category I for firearms that are fully automatic, and certain related parts, components, accessories, and attachments (including magazines with a capacity of greater than 50 rounds). (2) See ECCN 0A506 for semi-automatic rifles. (3) See ECCN 0A507 for semi-automatic pistols. (4) See ECCN 0A508 for semi-automatic shotguns and ECCN 0A502 for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (5) See ECCN 0A509 for enumerated or otherwise described \"parts,\" \"components,\" devices, \"accessories,\" and \"attachments\" for ECCNs 0A506, 0A507, and 0A508. (6) See .d, .x, and .y of this entry for other \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" for 0A506 and 0A507, or 0A508. (7) See ECCN 0A502 for non-automatic shotguns and their \"parts\" and \"components\" that are subject to the EAR and for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (8) See ECCN 0A504 and USML Category XII for controls on optical sighting devices.</p><p class=\"flush-paragraph-1\"><em>Related Definitions:</em> N/A.</p><p class=\"flush-paragraph\"><em>Items:</em></p><p>a. Non-automatic and non-semi-automatic firearms equal to .50 caliber (12.7 mm) or less.</p><div class=\"note\"><div class=\"header\"><em>Note 1 to paragraph 0A501.a:</em></div><p><em>'Combination pistols' are controlled under ECCN 0A501.a. A 'combination pistol' (a.k.a., a combination gun) has at least one rifled barrel and at least one smoothbore barrel (generally a shotgun style barrel).</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 2 to paragraph 0A501.a:</em></div><p><em>Semi-automatic firearms</em> equal to .50 caliber (12.7 mm) or less <em>are controlled under ECCNs 0A506 and 0A507.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.a:</em></div><p><em>Firearms described in 0A501.a include those chambered for the .50 BMG cartridge.</em></p></div><p>b. Non-automatic and non-semi-automatic rifles, carbines, revolvers or pistols with a caliber greater than .50 inches (12.7 mm) but less than or equal to .72 inches (18.0 mm).</p><p>c. The following types of \"parts\" and \"components\" if \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or ECCNs 0A506 or 0A507, or USML Category I (unless otherwise enumerated or elsewhere specified on the USML or controlled under ECCN 0A509): Barrels, cylinders, barrel extensions, mounting blocks (trunnions), bolts, bolt carriers, operating rods, gas pistons, trigger housings, triggers, hammers/striker, sears, disconnectors, pistol grips that contain fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors) and buttstocks that contain fire control \"parts\" or \"components.\"</p><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.c:</em></div><p><em>Barrel blanks that have reached a stage in manufacturing in which they are either chambered or rifled are controlled by 0A501.c.</em></p></div><p>d. Detachable magazines with a capacity of 17 to 50 rounds \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or controlled by ECCNs 0A506 or 0A507.</p><div class=\"note\"><div class=\"header\"><em>Note 3 to paragraph 0A501.d</em></div><p><em>Magazines with a capacity of 16 rounds or less are controlled under 0A501.x; for magazines with a capacity greater than 50 rounds, see USML Category I. Magazines that hold only blank ammunition controlled under 0A505.d are controlled under 0A501.d or 0A501.x, depending on the magazine's capacity.</em></p></div><p>e. Receivers (frames) and \"complete breech mechanisms,\" including castings, forgings, stampings, or machined items thereof, \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry.</p><div class=\"note\"><div class=\"header\"><em>Note 4 to 0A501.e:</em></div><p><em>Frames (receivers) under 0A501.e refers to any \"part\" or \"component\" of the firearm that has or is customarily marked with a serial number when required by law. This paragraph 0A501.e is synonymous with a \"part\" or \"component\" that is regulated by the Bureau of Alcohol, Tobacco, Firearms and Explosives (see <a href=\"https://www.govinfo.gov/link/uscode/18/921\" class=\"usc external\" target=\"_blank\" rel=\"noopener noreferrer\">18 U.S.C. 921(a)(3)</a>; <a href=\"https://www.ecfr.gov/current/title-27/part-447\" class=\"cfr external\">27 CFR parts 447</a>, <a href=\"https://www.ecfr.gov/current/title-27/part-478\" class=\"cfr external\">478</a>, and <a href=\"https://www.ecfr.gov/current/title-27/part-479\" class=\"cfr external\">479</a>,) as a firearm.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 5 to 0A501.e:</em></div><p><em>Frames (receivers) \"specially designed\" for semi-automatic firearms are controlled under ECCN 0A509.b or .c.</em></p></div><p>f. through w. [Reserved]</p><p>x. \"Parts\" and \"components\" that are \"specially designed\" for a commodity classified under paragraphs .a through .c of this entry, a commodity classified under ECCNs 0A506 or 0A507, or the USML and not elsewhere specified on the USML or CCL or controlled under ECCN 0A509.</p><p>y. Specific \"parts,\" \"components,\" \"accessories\" and \"attachments\" \"specially designed\" for a commodity subject to control in this ECCN, ECCNs 0A506, 0A507, or common to a defense article in USML Category I and not elsewhere specified in the USML or CCL as follows, and \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" therefor.</p><p>y.1. Stocks (including adjustable, collapsible, blades and braces), grips, handguards, or forends, that do not contain any fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors);</p><p>y.2 through y.5. [Reserved]</p><p>y.6. Bayonets; and</p><p>y.7. Firearms manufactured from 1890 to 1898 and reproductions thereof.</p><div class=\"note\"><div class=\"header\"><em>Technical Note 1 to 0A501:</em></div><p><em>ECCN 0A501 includes \"parts\" and \"components\" that are not \"subject to the ITAR\" even though they are common to firearms described in ECCN 0A501 and to those firearms \"subject to the ITAR.\"</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 2 to 0A501:</em></div><p><em>A receiver with any other controlled \"part\" or \"component\" ( e.g., a barrel (0A501.c), or trigger guard (0A501.x), or stock (0A501.y.1)) is still controlled under 0A501.e.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 3 to 0A501:</em></div><p><em>Blank firing adapters, which are attachments to semi-automatic and automatic firearms used in conjunction with blank cartridges for safety and functional reasons and used for firearm training purposes by police, military, sporting shooters, as well as in the movie industry, are designated as EAR99.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 6 to 0A501:</em></div><p><em>Antique firearms (i.e., those manufactured before 1890) and reproductions thereof, muzzle loading and black powder firearms except those designs based on centerfire weapons of a post 1937 design, BB guns, pellet rifles, paint ball, and all other air rifles are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 7 to 0A501:</em></div><p><em>Muzzle loading and black powder firearms with a caliber less than 20 mm that were manufactured post 1937 that are used for hunting or sporting purposes that were not \"specially designed\" for military use and are not described on the USML nor controlled as shotguns under ECCN 0A502 are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 8 to 0A501:</em></div><p><em>Scope mounts or accessory rails, iron sights, sling swivels, and butt plates or recoil pads that are subject to the EAR are designated as EAR99. These commodities have been determined to no longer warrant being \"specially designed\" for purposes of ECCN 0A501.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 9 to 0A501:</em></div><p><em>A kit, including a replacement or repair kit, of firearms \"parts\" or \"components\" customarily sold and exported together takes on the classification of the most restrictive \"part\" or \"component\" that is included in the kit. For example, a kit containing 0A501.y and .x \"parts,\" is controlled as a 0A501.x kit because the .x \"part\" is the most restrictive \"part\" included in the kit. A complete 0A501 firearm disassembled in a kit form is controlled as a firearm under 0A501.a, .b, or .y.7.</em></p></div>",
// "cclChildren": null
// },
// {
// "id": 3,
// "cclCode": "0A502",
// "cclTitle": "Shotguns; shotguns \"parts\" and \"components,\" consisting of complete trigger mechanisms; magazines and magazine extension tubes; \"complete breech mechanisms;\" except: semi-automatic shotguns controlled under Eccn 0A508; certain \"parts,\" components,\" devices, \"accessories,\" and \"attachments\" for semi-automatic shotguns controlled under Eccn 0A509; equipment used to slaughter domestic animals or used exclusively to treat or tranquilize animals; and arms designed solely for signal, flare, or saluting use.",
// "cclTitleZh": "霰弹枪;霰弹枪“零件”和“组件”,由完整的扳机机构组成;弹药库和弹匣延长管;“完整的闭锁机构”;除外:根据 Eccn 0A508 控制的半自动霰弹枪;根据 Eccn 0A509 控制的某些半自动霰弹枪的“零件”、“组件”、“装置”、“配件”;用于屠宰家畜或专门用于治疗或镇静动物的设备;以及仅用于信号、照明或敬礼使用的武器。",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": null
// }
// ]
// }
// ]
// }
// ]
// }
// cclList.value = res.data
// // 给数据添加isExpand字段
// cclList.value.forEach((item) => {
// item.isExpand = false
// item.cclChildren.forEach((ele) => {
// ele.cclChildren.forEach((i) => {
// i.isExpand = false
// })
// })
// })
if (res && res.code === 200) {
console.log('----getCclList', res.data)
cclList.value = res.data
// 给数据添加isExpand字段
cclList.value.forEach((item) => {
item.isExpand = false
item.cclChildren.forEach((ele) => {
ele.cclChildren.forEach((i) => {
i.isExpand = false
})
})
})
}
} catch (error) {
console.error("获取ccl清单列表失败:", error);
}
}
// 筛选逻辑处理
const handleFilterChange = (item, list, type) => {
console.log(item, list, type)
getCclList()
};
watch(viewNew, (newValue) => {
getCclList();
});
watch(currentCCLType, (newValue) => {
console.log(newValue)
getCclList()
})
// const searchDebounceTimer = ref(null);
// watch(searchKeyword, () => {
// if (searchDebounceTimer.value) {
// clearTimeout(searchDebounceTimer.value);
// }
// searchDebounceTimer.value = setTimeout(() => {
// currentPage.value = 1;
// getExportControlListApi();
// }, 300);
// });
watch(searchKeyword, (newValue) => {
console.log('-----searchKey', newValue)
getCclList()
});
// 模拟清单列表
const cclList = ref([
{
name: '类别 0-核材料、设施和设备、枪支、弹药[以及其他物品]',
desc: 'A."最终产品"、"设备"、"附件"、"附加装置"、"零件"、"组件"和"系统"',
isExpand: true,
list: [
{
code: '0A002',
name: '发电或推进设备,"专门设计"用于与太空、海洋或移动"核反应堆"一起使用。(这些项目"受 ITAR 管辖。"参见 22 CFR 第 120 至 130 部分。)',
isExpand: false,
isDot: false
},
{
code: '0A501',
name: '枪支(不包括 0A502 霰弹枪、0A506 半自动步枪、0A507 半自动手枪和 0A508 半自动霰弹枪)及相关商品(不包括在 Eccn 0A509 中列举或以其他方式描述的与半自动相关的商品,用于 Eccn 0A506、0A507 或 0A508)如下(参见受控物品清单)',
isExpand: true,
isDot: true
},
{
code: '0A501',
name: '枪支(不包括 0A502 霰弹枪、0A506 半自动步枪、0A507 半自动手枪和 0A508 半自动霰弹枪)及相关商品(不包括在 Eccn 0A509 中列举或以其他方式描述的与半自动相关的商品,用于 Eccn 0A506、0A507 或 0A508)如下(参见受控物品清单)',
isExpand: false,
isDot: true
}
]
}
])
onMounted(async () => {
// 获取类别字段
await getTypeList()
// 获取科技领域字典
await getTechFields()
// 获取管控原因字典
await getControlReasonList()
// 获取ccl清单列表
getCclList();
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.list-page {
width: 1601px;
padding-bottom: 50px;
margin: 0 auto;
padding-top: 16px;
.search-box {
margin-bottom: 16px;
display: flex;
justify-content: space-between;
align-items: center;
.search-input {
width: 388px;
height: 32px;
:deep(.el-input__wrapper) {
padding: 0 11px;
}
:deep(.el-input__inner) {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
}
.filters {
display: flex;
align-items: center;
.el-checkbox {
margin-right: 20px;
color: rgb(59, 65, 75);
}
.time-select {
width: 160px;
height: 32px;
}
}
}
.main {
width: 100%;
display: flex;
justify-content: space-between;
align-items: flex-start;
.left {
padding-bottom: 20px;
width: 388px;
height: auto;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.checkbox-group {
display: flex;
flex-wrap: wrap;
padding: 0 0 0 24px;
.el-checkbox {
width: 50%;
margin-right: 0;
margin-bottom: 4px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.custom-date-picker {
width: 100%;
margin-top: 8px;
padding-right: 24px;
box-sizing: border-box;
:deep(.el-date-editor) {
width: 100%;
height: 32px;
box-shadow: none;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 10px;
&:hover {
border-color: #c0c4cc;
}
&.is-active {
border-color: #409eff;
}
.el-range-input {
font-size: 14px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
}
.el-range-separator {
color: rgb(95, 101, 108);
line-height: 30px;
}
.el-input__icon {
line-height: 32px;
color: rgb(95, 101, 108);
}
}
}
}
}
.right {
width: 1196px;
height: auto;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.title {
width: 100%;
height: 56px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 12px 16px 0;
box-sizing: border-box;
.left-wrapper {
display: flex;
align-items: center;
.box {
width: 8px;
height: 20px;
background-color: rgb(5, 95, 194);
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
margin-right: 14px;
}
.text {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
}
.right-wrapper {
display: flex;
align-items: center;
.stats {
display: flex;
align-items: center;
margin-right: 24px;
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
margin-left: 4px;
color: rgb(95, 101, 108);
}
}
.btn {
width: 60px;
height: 28px;
img {
width: 28px;
height: 28px;
cursor: pointer;
}
img:first-child {
margin-right: 4px;
}
}
}
}
.right-table {
padding: 5px 21px 0 21px;
max-height: 1987px;
overflow: auto;
box-sizing: border-size;
// background: red;
.list {
width: 100%;
height: auto;
margin-bottom: 14px;
.list-title {
width: 100%;
height: 54px;
background: rgb(5, 95, 194);
color: white;
padding: 14px 23px 16px 29px;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 4px;
span {
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 18px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
.list-desc {
margin-left: 28px;
margin-top: 14px;
margin-bottom: 16px;
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
color: black;
}
.list-content {
width: 100%;
margin-bottom: 12px;
.content-title {
background: rgb(234, 236, 238);
display: flex;
align-items: flex-start;
justify-content: space-around;
// padding: 9px 0px;
.code-zone {
width: 75px;
display: flex;
margin-top: 11px;
align-items: center;
justify-content: space-around;
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
border: 2px solid rgb(206, 79, 81);
background-color: rgb(206, 79, 81);
z-index: 1;
}
.code {
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 16px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
color: rgba(59, 65, 75, 1);
}
}
.name {
width: 984px;
margin-top: 9px;
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
color: rgba(59, 65, 75, 1);
}
img {
margin-top: 20px;
}
}
.content-body {
margin-left: 90px;
// margin-right: 92px;
img {
width: 984px;
height: 1047px;
}
}
}
}
}
.tight-footer {
padding: 16px 24px;
display: flex;
justify-content: space-between;
align-items: center;
.total-text {
font-size: 14px;
font-weight: 400;
color: #5f656c;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination) {
--el-pagination-button-bg-color: #fff;
--el-pagination-hover-color: #0e78f1;
--el-pagination-font-size: 14px;
.el-pager li {
border: 1px solid #dcdfe6;
border-radius: 4px;
margin: 0 4px;
font-weight: 400;
color: #5f656c;
min-width: 32px;
height: 32px;
line-height: 30px;
&.is-active {
background-color: #0e78f1;
color: #fff;
border-color: #0e78f1;
}
&:hover:not(.is-active) {
color: #0e78f1;
border-color: #0e78f1;
}
}
.btn-prev,
.btn-next {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0;
margin: 0 4px;
min-width: 32px;
height: 32px;
line-height: 30px;
text-align: center;
&:hover {
color: #0e78f1;
border-color: #0e78f1;
}
&[disabled] {
border-color: #e4e7ed;
color: #c0c4cc;
}
}
}
}
}
}
}
.title {
width: 100%;
height: 56px;
display: flex;
align-items: center;
padding: 14px 12px 16px 0;
.box {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-bottom-right-radius: 4px;
border-top-right-radius: 4px;
margin-right: 14px;
}
.text {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
}
}
</style>
<!--
* @Author: lishun
* @Date: 2026-01-07 09:57:54
* @LastEditors: lishun
* @LastEditTime: 2026-01-07 09:58:04
-->
<template>
<div class="sanctions-overview">
<div class="side-nav">
<div v-for="(item, index) in activeTab" :key="index" class="tab-item" :class="{'active': index === activeIndex}" @click="activeIndex = index">
{{item}}
<span v-if="index === activeIndex" class="arrow"></span>
</div>
</div>
<div class="content-box">
<introductionPage v-if="activeIndex === 0"></introductionPage>
<listPage v-if="activeIndex === 1"></listPage>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import introductionPage from "./components/introductionPage/index.vue"
import listPage from "./components/listPage/index.vue"
const activeTab = ref(["CCL清单简介", "CCL清单列表"])
const activeIndex = ref(0)
</script>
<style scoped lang="scss">
*{
margin: 0;
padding: 0;
}
.sanctions-overview{
width: 1601px;
margin: 0 auto;
position: relative;
// min-height: 800px;
.side-nav {
position: absolute;
top: 27px;
right: 100%;
margin-right: 12px;
display: flex;
flex-direction: column;
gap: 16px;
.tab-item {
cursor: pointer;
padding: 4px 20px;
border-radius: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
white-space: nowrap;
display: flex;
align-items: center;
&.active {
background-color: rgb(5, 95, 194);
color: #fff;
.arrow {
display: inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 6px solid #fff;
margin-left: 8px;
}
}
}
}
.content-box {
width: 100%;
}
}
</style>
<template>
<div class="entity-list">
<div class="header">
<div class="header-title">
<img :src="headerTitle.img" alt />
<div>
<div class="title">
{{ headerTitle.title }}
<span>{{ headerTitle.titleEn }}</span>
</div>
<div class="department">{{ headerTitle.department }}</div>
</div>
<div class="btn">
<img :src="icon01" alt />切换
</div>
</div>
<div class="header-nav">
<div
class="nav-item"
v-for="(item, index) in headerNavList"
:key="index"
:class="{ active: activeIndex === index }"
@click="activeIndex = index"
>
<img :src="activeIndex === index ? item.imgActive : item.img" alt />
<span>{{ item.title }}</span>
<div class="active-line" v-if="activeIndex === index"></div>
</div>
</div>
</div>
<div class="main">
<sanctions-overview v-if="activeIndex === 0"></sanctions-overview>
<!-- <data-statistics v-if="activeIndex === 1"></data-statistics>
<deep-mining v-if="activeIndex === 2"></deep-mining>
<impact-analysis v-if="activeIndex === 3"></impact-analysis>-->
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import sanctionsOverview from "./components/sanctionsOverview/index.vue"
// import dataStatistics from "./components/dataStatistics/index.vue"
// import deepMining from "./components/deepMining/index.vue"
// import impactAnalysis from "./components/impactAnalysis/index.vue"
import title from "./assets/title.png"
import icon01 from "./assets/icon01.png"
import icon1 from "../assets/icons/icon1.png";
import icon1Active from "../assets/icons/icon1_active.png";
import icon5 from "../assets/icons/icon5.png";
import icon5Active from "../assets/icons/icon5_active.png";
import icon2 from "../assets/icons/icon2.png";
import icon2Active from "../assets/icons/icon2_active.png";
import icon3 from "../assets/icons/icon3.png";
import icon3Active from "../assets/icons/icon3_active.png";
const headerTitle = ref({
img: title,
title: "商业管制清单(CCL)",
titleEn: "Commercial Control List",
department: "美国商务部工业与安全局"
})
const activeIndex = ref(0)
const headerNavList = ref([
{
img: icon1,
imgActive: icon1Active,
title: "制裁概况"
},
{
img: icon5,
imgActive: icon5Active,
title: "数据统计"
},
{
img: icon2,
imgActive: icon2Active,
title: "深度挖掘"
},
{
img: icon3,
imgActive: icon3Active,
title: "影响分析"
}
])
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.entity-list {
width: 100%;
height: 100%;
overflow-y: auto;
.header {
width: 100%;
height: 148px;
background-color: #fff;
padding-top: 16px;
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05);
.header-title {
width: 1601px;
height: 72px;
background-color: rgba(246, 250, 255, 1);
margin: 0 auto;
border-radius: 10px;
border: 2px solid rgba(174, 214, 255, 1);
display: flex;
align-items: center;
margin-bottom: 12px;
position: relative;
img {
width: 54px;
height: 54px;
margin-left: 15px;
margin-right: 11px;
}
.title {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
margin-left: 11px;
}
}
.department {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.btn {
cursor: pointer;
display: flex;
align-items: center;
position: absolute;
right: 16px;
top: 25px;
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
img {
width: 20px;
height: 20px;
margin-right: 7px;
}
}
}
.header-nav {
width: 1601px;
margin: 0 auto;
height: 48px;
display: flex;
align-items: center;
.nav-item {
display: flex;
align-items: center;
height: 100%;
margin-right: 32px;
cursor: pointer;
position: relative;
font-size: 18px;
font-weight: 400;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
&:last-child {
margin-right: 0;
}
img {
width: 16px;
height: 16px;
margin-right: 4px;
}
&.active {
color: rgb(5, 95, 194);
font-weight: 700;
}
.active-line {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 3px;
background-color: #055fc2;
border-radius: 1.5px;
}
}
}
}
.main {
width: 100%;
height: auto;
min-height: calc(100% - 148px);
background-color: #f7f8f9;
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论