639 lines
15 KiB
Vue
639 lines
15 KiB
Vue
<template>
|
||
<div class="page-container relative overflow-hidden z-[11] bg-[#ffffff]">
|
||
<div
|
||
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-[0]"
|
||
style="width: 900px; pointer-events: none; mix-blend-mode: multiply"
|
||
>
|
||
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||
</div>
|
||
<div class="fixed z-[-1] top-[50%] translate-y-[-50%]">
|
||
<img
|
||
src="@/assets/image/content/bg_29.png"
|
||
class="w-[100vw] h-[445PX]"
|
||
alt=""
|
||
/>
|
||
</div>
|
||
<div class="sec-filings-container relative z-10 !w-[900PX] !p-0 !pb-[60PX]">
|
||
<!-- 标题 -->
|
||
<div class="page-title ml-[30PX] mt-[50PX]">{{ $t("SECFILINGS.TITLE") }}</div>
|
||
|
||
<!-- 筛选器 -->
|
||
<div class="filters flex px-[30PX]">
|
||
<div class="filter-group flex-1 flex">
|
||
<label class="filter-label">{{ $t("SECFILINGS.FILTERlABEL1") }}</label>
|
||
<n-select
|
||
v-model:value="state.selectedYear"
|
||
:options="state.yearOptions"
|
||
placeholder="- Any -"
|
||
style="flex: 1"
|
||
clearable
|
||
@update:value="handleYearChange"
|
||
/>
|
||
</div>
|
||
|
||
<div class="filter-group flex-1 flex">
|
||
<label class="filter-label">{{ $t("SECFILINGS.FILTERlABEL2") }}</label>
|
||
<n-select
|
||
v-model:value="state.pageSize"
|
||
:options="state.pageSizeOptions"
|
||
style="flex: 1"
|
||
@update:value="handlePageSizeChange"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 表格 -->
|
||
<div
|
||
class="table-container p-[16PX]"
|
||
style="
|
||
border-radius: 16px;
|
||
background: #fff;
|
||
box-shadow: 0 3px 14px 0 rgba(0, 0, 0, 0.16);
|
||
"
|
||
>
|
||
<n-data-table
|
||
:columns="columns"
|
||
:loading="state.tableLoading"
|
||
:data="state.tableData"
|
||
:pagination="false"
|
||
:bordered="false"
|
||
:size="'medium'"
|
||
:row-key="(row) => row.idx"
|
||
@update:sorter="handleSort"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 分页器 -->
|
||
<div
|
||
class="pagination-container flex items-center justify-center mt-[15PX]"
|
||
>
|
||
<div class="pagination-info text-[#455363] mr-[15PX]">
|
||
Displaying {{ startIndex }} - {{ endIndex }} of
|
||
{{ state.total }} results
|
||
</div>
|
||
<n-pagination
|
||
v-model:page="state.currentPage"
|
||
v-model:page-size="state.pageSize"
|
||
show-size-picker
|
||
show-quick-jumper
|
||
:item-count="state.total"
|
||
:page-sizes="[10, 25, 50]"
|
||
@update:page="handlePageChange"
|
||
@update:page-size="handlePageSizeChange"
|
||
>
|
||
<!-- <template #prev>
|
||
<span>‹ Previous</span>
|
||
</template>
|
||
<template #next>
|
||
<span>Next ›</span>
|
||
</template> -->
|
||
</n-pagination>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="jsx">
|
||
import { reactive, computed, h, onMounted, render } from "vue";
|
||
import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui";
|
||
import { useI18n } from "vue-i18n";
|
||
import { useRouter } from "vue-router";
|
||
|
||
const { t } = useI18n();
|
||
const router = useRouter();
|
||
import pdfFile from "@/assets/image/icon/icon-pdf.png";
|
||
import wordFile from "@/assets/image/icon/icon-word.png";
|
||
import excelFile from "@/assets/image/icon/icon-excel.png";
|
||
import fileLink from "@/assets/image/content/icon-link.png";
|
||
// 使用 reactive 管理所有状态
|
||
const state = reactive({
|
||
selectedYear: null,
|
||
pageSize: 10,
|
||
currentPage: 1,
|
||
tableData: [],
|
||
tableLoading: false,
|
||
total: 0,
|
||
sortParams: {},
|
||
|
||
// 年份选项
|
||
yearOptions: [
|
||
{ label: "- Any -", value: null },
|
||
{
|
||
label: "2025",
|
||
value: "2025",
|
||
},
|
||
{
|
||
label: "2024",
|
||
value: "2024",
|
||
},
|
||
{
|
||
label: "2023",
|
||
value: "2023",
|
||
},
|
||
{
|
||
label: "2022",
|
||
value: "2022",
|
||
},
|
||
{
|
||
label: "2021",
|
||
value: "2021",
|
||
},
|
||
{
|
||
label: "2020",
|
||
value: "2020",
|
||
},
|
||
{
|
||
label: "2019",
|
||
value: "2019",
|
||
},
|
||
{
|
||
label: "2018",
|
||
value: "2018",
|
||
},
|
||
{
|
||
label: "2017",
|
||
value: "2017",
|
||
},
|
||
{
|
||
label: "2016",
|
||
value: "2016",
|
||
},
|
||
{
|
||
label: "2015",
|
||
value: "2015",
|
||
},
|
||
{
|
||
label: "2014",
|
||
value: "2014",
|
||
},
|
||
{
|
||
label: "2013",
|
||
value: "2013",
|
||
},
|
||
{
|
||
label: "2012",
|
||
value: "2012",
|
||
},
|
||
{
|
||
label: "2011",
|
||
value: "2011",
|
||
},
|
||
{
|
||
label: "2010",
|
||
value: "2010",
|
||
},
|
||
{
|
||
label: "2009",
|
||
value: "2009",
|
||
},
|
||
],
|
||
|
||
// 每页条数选项
|
||
pageSizeOptions: [
|
||
{ label: "10", value: 10 },
|
||
{ label: "25", value: 25 },
|
||
{ label: "50", value: 50 },
|
||
],
|
||
});
|
||
|
||
const monthNames = [
|
||
"Jan",
|
||
"Feb",
|
||
"Mar",
|
||
"Apr",
|
||
"May",
|
||
"Jun",
|
||
"Jul",
|
||
"Aug",
|
||
"Sep",
|
||
"Oct",
|
||
"Nov",
|
||
"Dec",
|
||
];
|
||
onMounted(() => {
|
||
getListData();
|
||
});
|
||
import axios from "axios";
|
||
const getListData = async () => {
|
||
state.tableData = [];
|
||
let url = "https://erpapi.fiee.com/api/fiee/sec-filing/web/list";
|
||
let params = {
|
||
page: state.currentPage,
|
||
pageSize: state.pageSize,
|
||
year: state.selectedYear,
|
||
};
|
||
Object.assign(params, state.sortParams);
|
||
state.tableLoading = true;
|
||
const res = await axios.post(url, params);
|
||
if (res.data.status === 0) {
|
||
let resData = res.data.data?.data || [];
|
||
resData.forEach((item) => {
|
||
if (item.filingDate) {
|
||
let year = null;
|
||
let filingDate = item.filingDate;
|
||
if (item.filingDate.includes(", ")) {
|
||
// "Feb 04, 2019" 格式,已经是英文格式,保持不变
|
||
year = parseInt(item.filingDate.split(", ")[1]);
|
||
} else if (item.filingDate.includes("-")) {
|
||
// "2025-10-24" 格式,转换为 "Oct 24, 2025" 英文格式
|
||
const dateParts = item.filingDate.split("-");
|
||
const yearPart = parseInt(dateParts[0]);
|
||
const monthPart = parseInt(dateParts[1]);
|
||
const dayPart = parseInt(dateParts[2]);
|
||
|
||
year = yearPart;
|
||
const monthName = monthNames[monthPart - 1]; // 月份从1开始,数组从0开始
|
||
const dayFormatted = dayPart.toString().padStart(2, "0");
|
||
filingDate = `${monthName} ${dayFormatted}, ${yearPart}`;
|
||
item.year = year;
|
||
item.filingDate = filingDate;
|
||
item.filing_date = filingDate;
|
||
}
|
||
}
|
||
});
|
||
state.tableData = resData;
|
||
state.total = res.data.data?.total;
|
||
}
|
||
state.tableLoading = false;
|
||
};
|
||
const handleSort = (sortData) => {
|
||
state.sortParams = {};
|
||
if (sortData.order !== false) {
|
||
state.sortParams["sortField"] = sortData.columnKey;
|
||
state.sortParams["sortOrder"] = sortData.order.replace("end", "");
|
||
}
|
||
getListData();
|
||
};
|
||
// 表格列定义
|
||
const columns = [
|
||
{
|
||
title: "Filing Date",
|
||
key: "filing_date",
|
||
sorter: "default",
|
||
width: 150,
|
||
render: (row) => (
|
||
<div style={{ borderRight: "1px dashed #E7E7E7" }}>{row.filing_date}</div>
|
||
),
|
||
},
|
||
{
|
||
title: "Form",
|
||
key: "form",
|
||
width: 150,
|
||
align: "left",
|
||
render: (row) => {
|
||
return h(
|
||
"div",
|
||
{
|
||
href: "javascript:void(0)",
|
||
style: {
|
||
color: "#FF7BAC",
|
||
textDecoration: "none",
|
||
cursor: "pointer",
|
||
borderRight: "1px dashed #E7E7E7",
|
||
},
|
||
onClick: (e) => {
|
||
e.preventDefault();
|
||
router.push({
|
||
path: "/secfilingsDefail",
|
||
query: {
|
||
filingKey: row.filingKey,
|
||
},
|
||
});
|
||
},
|
||
onMouseover: (e) => {
|
||
e.target.style.textDecoration = "underline";
|
||
},
|
||
onMouseout: (e) => {
|
||
e.target.style.textDecoration = "none";
|
||
},
|
||
},
|
||
row.form
|
||
);
|
||
},
|
||
},
|
||
{
|
||
title: "Description",
|
||
key: "description",
|
||
// ellipsis: {
|
||
// tooltip: true,
|
||
// },
|
||
render: (row) => (
|
||
<div style={{ borderRight: "1px dashed #E7E7E7" }}>{row.description}</div>
|
||
),
|
||
},
|
||
{
|
||
title: "View",
|
||
key: "fileLink",
|
||
width: 150,
|
||
render: (row) => {
|
||
return h(
|
||
"div",
|
||
{
|
||
style: {
|
||
display: "flex",
|
||
gap: "8px",
|
||
},
|
||
},
|
||
[
|
||
row.pdfFile
|
||
? h(
|
||
"a",
|
||
{
|
||
href: "javascript:void(0)",
|
||
style: {
|
||
color: "#FF7BAC",
|
||
textDecoration: "none",
|
||
fontSize: "12px",
|
||
},
|
||
onClick: (e) => {
|
||
e.preventDefault();
|
||
handleViewDocument(row.pdfFile, "pdf");
|
||
},
|
||
onMouseover: (e) => {
|
||
e.target.style.textDecoration = "underline";
|
||
},
|
||
onMouseout: (e) => {
|
||
e.target.style.textDecoration = "none";
|
||
},
|
||
},
|
||
h("img", {
|
||
src: pdfFile,
|
||
alt: "link",
|
||
style: {
|
||
width: "24px",
|
||
height: "24px",
|
||
},
|
||
})
|
||
)
|
||
: null,
|
||
row.wordFile
|
||
? h(
|
||
"a",
|
||
{
|
||
href: "javascript:void(0)",
|
||
style: {
|
||
color: "#0078d7",
|
||
textDecoration: "none",
|
||
fontSize: "12px",
|
||
},
|
||
onClick: (e) => {
|
||
e.preventDefault();
|
||
handleViewDocument(row.wordFile, "word");
|
||
},
|
||
onMouseover: (e) => {
|
||
e.target.style.textDecoration = "underline";
|
||
},
|
||
onMouseout: (e) => {
|
||
e.target.style.textDecoration = "none";
|
||
},
|
||
},
|
||
h("img", {
|
||
src: wordFile,
|
||
alt: "link",
|
||
style: {
|
||
width: "24px",
|
||
height: "24px",
|
||
},
|
||
})
|
||
)
|
||
: null,
|
||
row.excelFile
|
||
? h(
|
||
"a",
|
||
{
|
||
href: "javascript:void(0)",
|
||
style: {
|
||
color: "#0078d7",
|
||
textDecoration: "none",
|
||
fontSize: "12px",
|
||
},
|
||
onClick: (e) => {
|
||
e.preventDefault();
|
||
handleViewDocument(row.excelFile, "excel");
|
||
},
|
||
onMouseover: (e) => {
|
||
e.target.style.textDecoration = "underline";
|
||
},
|
||
onMouseout: (e) => {
|
||
e.target.style.textDecoration = "none";
|
||
},
|
||
},
|
||
h("img", {
|
||
src: excelFile,
|
||
alt: "link",
|
||
style: {
|
||
width: "24px",
|
||
height: "24px",
|
||
},
|
||
})
|
||
)
|
||
: null,
|
||
row.fileLink
|
||
? h(
|
||
"a",
|
||
{
|
||
href: row.fileLink,
|
||
style: {
|
||
color: "#0078d7",
|
||
textDecoration: "none",
|
||
fontSize: "12px",
|
||
},
|
||
onMouseover: (e) => {
|
||
e.target.style.textDecoration = "underline";
|
||
},
|
||
onMouseout: (e) => {
|
||
e.target.style.textDecoration = "none";
|
||
},
|
||
},
|
||
h("img", {
|
||
src: fileLink,
|
||
alt: "link",
|
||
style: {
|
||
width: "24px",
|
||
height: "24px",
|
||
},
|
||
})
|
||
)
|
||
: null,
|
||
]
|
||
);
|
||
},
|
||
},
|
||
];
|
||
|
||
// 当前页起始索引
|
||
const startIndex = computed(() => {
|
||
return (state.currentPage - 1) * state.pageSize + 1;
|
||
});
|
||
|
||
// 当前页结束索引
|
||
const endIndex = computed(() => {
|
||
const end = state.currentPage * state.pageSize;
|
||
return Math.min(end, state.total);
|
||
});
|
||
|
||
// 处理年份变化
|
||
const handleYearChange = (value) => {
|
||
state.selectedYear = value;
|
||
state.currentPage = 1;
|
||
getListData();
|
||
};
|
||
|
||
// 处理页码变化
|
||
const handlePageChange = (page) => {
|
||
state.currentPage = page;
|
||
getListData();
|
||
};
|
||
|
||
// 处理每页条数变化
|
||
const handlePageSizeChange = (size) => {
|
||
state.pageSize = size;
|
||
state.currentPage = 1;
|
||
getListData();
|
||
};
|
||
// 查看文档
|
||
const handleViewDocument = (val, type) => {
|
||
window.open(
|
||
`${import.meta.env.VITE_PAGE_URL}/office?url=${val}&attachmentName=${type}`,
|
||
"_blank"
|
||
);
|
||
};
|
||
</script>
|
||
<!-- <style lang="scss">
|
||
tr {
|
||
td {
|
||
&:not(:first-child) {
|
||
border-left: 1px dashed #0078d7 !important;
|
||
}
|
||
}
|
||
}
|
||
</style> -->
|
||
|
||
<style scoped lang="scss">
|
||
:deep(
|
||
.n-data-table
|
||
.n-data-table-tr:not(.n-data-table-tr--summary):hover
|
||
> .n-data-table-td
|
||
) {
|
||
background-color: #fff8fb !important;
|
||
}
|
||
:deep(.n-data-table-th) {
|
||
background: #fff0f5 !important;
|
||
&:first-child {
|
||
border-top-left-radius: 8px;
|
||
border-bottom-left-radius: 8px;
|
||
}
|
||
&:last-child {
|
||
border-top-right-radius: 8px;
|
||
border-bottom-right-radius: 8px;
|
||
}
|
||
}
|
||
:deep(.n-data-table-thead) {
|
||
background-color: none;
|
||
}
|
||
:deep(.n-data-table-td) {
|
||
border: none;
|
||
}
|
||
:deep(.n-data-table-th) {
|
||
border: none;
|
||
}
|
||
:deep(.n-data-table-tr) {
|
||
> td {
|
||
&:first-child {
|
||
border-top-left-radius: 8px;
|
||
border-bottom-left-radius: 8px;
|
||
}
|
||
&:last-child {
|
||
border-top-right-radius: 8px;
|
||
border-bottom-right-radius: 8px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.page-container {
|
||
background-size: 100% 100%;
|
||
background-position: center;
|
||
background-repeat: no-repeat;
|
||
min-height: 100vh;
|
||
// padding: 20px;
|
||
}
|
||
|
||
.sec-filings-container {
|
||
width: 900px;
|
||
margin: 0 auto;
|
||
padding: 40px;
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 32px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
margin-bottom: 40px;
|
||
position: relative;
|
||
&::before {
|
||
position: absolute;
|
||
content: "";
|
||
width: 60px;
|
||
top: -10px;
|
||
height: 4px;
|
||
background-color: #ff7bac;
|
||
left: 0;
|
||
}
|
||
}
|
||
|
||
.filters {
|
||
display: flex;
|
||
gap: 40px;
|
||
margin-bottom: 30px;
|
||
align-items: end;
|
||
}
|
||
|
||
.filter-group {
|
||
display: flex;
|
||
// flex-direction: column;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.filter-label {
|
||
font-size: 14PX;
|
||
color: #000;
|
||
font-weight: 500;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
:deep(.n-data-table-tr:hover .n-data-table-td) {
|
||
background-color: #f9f9f9;
|
||
}
|
||
|
||
:deep(.n-select) {
|
||
// .n-base-selection {
|
||
// border: 1px solid #ccc;
|
||
// border-radius: 4px;
|
||
// }
|
||
}
|
||
|
||
// :deep(.n-pagination) {
|
||
// .n-pagination-item {
|
||
// border: 1px solid #ccc;
|
||
|
||
// &.n-pagination-item--active {
|
||
// background-color: #969696;
|
||
// border-color: #969696;
|
||
// color: white;
|
||
// }
|
||
// }
|
||
|
||
// .n-pagination-quick-jumper {
|
||
// font-size: 14px;
|
||
// }
|
||
|
||
// .n-pagination-sizes {
|
||
// font-size: 14px;
|
||
// }
|
||
// }
|
||
:deep(.n-base-loading__icon) {
|
||
color: #ff7bac;
|
||
}
|
||
</style>
|