修改官网governance和新闻,改从接口获取数据,并修改列表展示及分页、触底加载更多;处理滚动条美化

This commit is contained in:
wangyifeng 2025-06-13 12:06:12 +08:00
parent 0b000f2eb0
commit 9fb3db0ced
20 changed files with 1081 additions and 401 deletions

3
env/.env.prod vendored
View File

@ -5,3 +5,6 @@ VITE_DELETE_CONSOLE = true
# 是否开启sourcemap
VITE_SHOW_SOURCEMAP = false
VITE_BASEURL = '//appointteam.szjixun.cn'
# 文档查看
VITE_PAGE_URL="http://172.16.100.22:8045"

4
env/.env.test vendored
View File

@ -3,3 +3,7 @@ NODE_ENV = 'test'
# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false
VITE_BASEURL = '//kid-art-test.szjixun.cn'
# 文档查看
# VITE_PAGE_URL="http://172.16.100.22:8045"
VITE_PAGE_URL="http://192.168.88.50:5878"

View File

@ -12,6 +12,7 @@
},
"dependencies": {
"@fingerprintjs/fingerprintjs": "^4.4.3",
"@onlyoffice/document-editor-vue": "^1.5.0",
"@unocss/reset": "^0.61.9",
"@vicons/ionicons5": "^0.13.0",
"@vicons/utils": "^0.1.4",

View File

@ -11,6 +11,9 @@ importers:
'@fingerprintjs/fingerprintjs':
specifier: ^4.4.3
version: 4.4.3
'@onlyoffice/document-editor-vue':
specifier: ^1.5.0
version: 1.5.0(vue@3.4.35)
'@unocss/reset':
specifier: ^0.61.9
version: 0.61.9
@ -1279,6 +1282,11 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@onlyoffice/document-editor-vue@1.5.0':
resolution: {integrity: sha512-HZEebUhBloP4LomspI5BddgoQdhtPq91h57yA9K/Lk70MMc1vgOTQ4Wq+N5TZYXNxdDTv+TSsEVFLnBCl1Y71A==}
peerDependencies:
vue: ^3.0.0
'@polka/url@1.0.0-next.25':
resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
@ -5536,6 +5544,11 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.17.1
'@onlyoffice/document-editor-vue@1.5.0(vue@3.4.35)':
dependencies:
lodash: 4.17.21
vue: 3.4.35
'@polka/url@1.0.0-next.25': {}
'@rollup/plugin-babel@6.0.4(@babel/core@7.25.2)(rollup@4.20.0)':

View File

@ -143,6 +143,11 @@ const routes = [
},
],
},
{
path: '/office',
name: 'office',
component: () => import('@/views/office/index.vue'),
},
// {
// path: '/companyprofil',

View File

@ -44,10 +44,10 @@
</div>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
style="font-size: 16px"
style="font-size: 16px; cursor: pointer;"
@click="handleViewDocument(item)"
>
View Document
<svg
@ -72,46 +72,83 @@
</template>
<script setup>
import { reactive } from "vue";
import quarterlyPdfone from "@/assets/file/FiEE, Inc._Audit Committee Charter.pdf";
import quarterlyPdftwo from "@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf";
import { reactive, onMounted } from 'vue'
import axios from 'axios'
import quarterlyPdfthree from "@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf";
import quarterlyPdfone from '@/assets/file/FiEE, Inc._Audit Committee Charter.pdf'
import quarterlyPdftwo from '@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf'
import quarterlyPdffour from "@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf";
import quarterlyPdfthree from '@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf'
import quarterlyPdffour from '@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf'
const state = reactive({
list: [
{
title: "AUDIT COMMITTEE CHARTER",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: quarterlyPdfone,
date: "May 30, 2025",
},
{
title: "CODE OF BUSINESS CONDUCT AND ETHICS",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: quarterlyPdftwo,
date: "May 30, 2025",
},
{
title: "COMPENSATION COMMITTEE CHARTER",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: quarterlyPdfthree,
date: "May 30, 2025",
},
{
title: "NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: quarterlyPdffour,
date: "May 30, 2025",
},
// {
// title: 'AUDIT COMMITTEE CHARTER',
// description:
// 'Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.',
// url: quarterlyPdfone,
// date: 'May 30, 2025',
// },
// {
// title: 'CODE OF BUSINESS CONDUCT AND ETHICS',
// description:
// 'Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.',
// url: quarterlyPdftwo,
// date: 'May 30, 2025',
// },
// {
// title: 'COMPENSATION COMMITTEE CHARTER',
// description:
// 'Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.',
// url: quarterlyPdfthree,
// date: 'May 30, 2025',
// },
// {
// title: 'NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER',
// description:
// 'Provides the framework for director nominations and corporate governance matters.',
// url: quarterlyPdffour,
// date: 'May 30, 2025',
// },
],
});
})
onMounted(() => {
getGovernanceDisplay()
})
//
const getGovernanceDisplay = () => {
// let url = 'https://common.szjixun.cn/api/fiee/governance/display'
let url = 'http://172.16.100.93:9020/api/fiee/governance/display'
let params = {}
axios
.get(url, { params })
.then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
state.list = res.data.data.data || []
}
}
})
.catch((err) => {
// console.log(err)
})
}
//
const handleViewDocument = (item) => {
// console.log(item)
window.open(
`${import.meta.env.VITE_PAGE_URL}/office?url=${
item.attachment
}&attachmentName=${item.attachmentName}`,
'_blank',
)
}
</script>
<style scoped lang="scss">

View File

@ -44,10 +44,10 @@
</div>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
style="font-size: 16px"
style="font-size: 16px; cursor: pointer;"
@click="handleViewDocument(item)"
>
View Document
<svg
@ -72,46 +72,83 @@
</template>
<script setup>
import { reactive } from "vue";
import quarterlyPdfone from "@/assets/file/FiEE, Inc._Audit Committee Charter.pdf";
import quarterlyPdftwo from "@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf";
import { reactive, onMounted } from 'vue'
import axios from 'axios'
import quarterlyPdfthree from "@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf";
import quarterlyPdfone from '@/assets/file/FiEE, Inc._Audit Committee Charter.pdf'
import quarterlyPdftwo from '@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf'
import quarterlyPdffour from "@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf";
import quarterlyPdfthree from '@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf'
import quarterlyPdffour from '@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf'
const state = reactive({
list: [
{
title: "AUDIT COMMITTEE CHARTER",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: quarterlyPdfone,
date: "May 30, 2025",
},
{
title: "CODE OF BUSINESS CONDUCT AND ETHICS",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: quarterlyPdftwo,
date: "May 30, 2025",
},
{
title: "COMPENSATION COMMITTEE CHARTER",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: quarterlyPdfthree,
date: "May 30, 2025",
},
{
title: "NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: quarterlyPdffour,
date: "May 30, 2025",
},
// {
// title: 'AUDIT COMMITTEE CHARTER',
// description:
// 'Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.',
// url: quarterlyPdfone,
// date: 'May 30, 2025',
// },
// {
// title: 'CODE OF BUSINESS CONDUCT AND ETHICS',
// description:
// 'Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.',
// url: quarterlyPdftwo,
// date: 'May 30, 2025',
// },
// {
// title: 'COMPENSATION COMMITTEE CHARTER',
// description:
// 'Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.',
// url: quarterlyPdfthree,
// date: 'May 30, 2025',
// },
// {
// title: 'NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER',
// description:
// 'Provides the framework for director nominations and corporate governance matters.',
// url: quarterlyPdffour,
// date: 'May 30, 2025',
// },
],
});
})
onMounted(() => {
getGovernanceDisplay()
})
//
const getGovernanceDisplay = () => {
// let url = 'https://common.szjixun.cn/api/fiee/governance/display'
let url = 'http://172.16.100.93:9020/api/fiee/governance/display'
let params = {}
axios
.get(url, { params })
.then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
state.list = res.data.data.data || []
}
}
})
.catch((err) => {
// console.log(err)
})
}
//
const handleViewDocument = (item) => {
// console.log(item)
window.open(
`${import.meta.env.VITE_PAGE_URL}/office?url=${
item.attachment
}&attachmentName=${item.attachmentName}`,
'_blank',
)
}
</script>
<style scoped lang="scss">

View File

@ -41,9 +41,10 @@
</div>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
style="cursor: pointer;"
@click="handleViewDocument(item)"
>
View Document
<svg
@ -68,46 +69,83 @@
</template>
<script setup>
import { reactive } from "vue";
import quarterlyPdfone from "@/assets/file/FiEE, Inc._Audit Committee Charter.pdf";
import quarterlyPdftwo from "@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf";
import { reactive, onMounted } from 'vue'
import axios from 'axios'
import quarterlyPdfthree from "@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf";
import quarterlyPdfone from '@/assets/file/FiEE, Inc._Audit Committee Charter.pdf'
import quarterlyPdftwo from '@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf'
import quarterlyPdffour from "@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf";
import quarterlyPdfthree from '@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf'
import quarterlyPdffour from '@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf'
const state = reactive({
list: [
{
title: "AUDIT COMMITTEE CHARTER",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: quarterlyPdfone,
date: "May 30, 2025",
},
{
title: "CODE OF BUSINESS CONDUCT AND ETHICS",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: quarterlyPdftwo,
date: "May 30, 2025",
},
{
title: "COMPENSATION COMMITTEE CHARTER",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: quarterlyPdfthree,
date: "May 30, 2025",
},
{
title: "NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: quarterlyPdffour,
date: "May 30, 2025",
},
// {
// title: 'AUDIT COMMITTEE CHARTER',
// description:
// 'Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.',
// url: quarterlyPdfone,
// date: 'May 30, 2025',
// },
// {
// title: 'CODE OF BUSINESS CONDUCT AND ETHICS',
// description:
// 'Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.',
// url: quarterlyPdftwo,
// date: 'May 30, 2025',
// },
// {
// title: 'COMPENSATION COMMITTEE CHARTER',
// description:
// 'Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.',
// url: quarterlyPdfthree,
// date: 'May 30, 2025',
// },
// {
// title: 'NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER',
// description:
// 'Provides the framework for director nominations and corporate governance matters.',
// url: quarterlyPdffour,
// date: 'May 30, 2025',
// },
],
});
})
onMounted(() => {
getGovernanceDisplay()
})
//
const getGovernanceDisplay = () => {
// let url = 'https://common.szjixun.cn/api/fiee/governance/display'
let url = 'http://172.16.100.93:9020/api/fiee/governance/display'
let params = {}
axios
.get(url, { params })
.then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
state.list = res.data.data.data || []
}
}
})
.catch((err) => {
// console.log(err)
})
}
//
const handleViewDocument = (item) => {
// console.log(item)
window.open(
`${import.meta.env.VITE_PAGE_URL}/office?url=${
item.attachment
}&attachmentName=${item.attachmentName}`,
'_blank',
)
}
</script>
<style scoped lang="scss">

View File

@ -41,9 +41,10 @@
</div>
<div class="mt-auto">
<a
:href="item.url"
class="inline-flex items-center px-5 py-3 border border-transparent text-base font-medium rounded-md text-white bg-[#895bff] hover:bg-[#7a4de6] transition-all duration-300 transform hover:scale-105 shadow-md"
target="_blank"
style="cursor: pointer;"
@click="handleViewDocument(item)"
>
View Document
<svg
@ -68,46 +69,83 @@
</template>
<script setup>
import { reactive } from "vue";
import quarterlyPdfone from "@/assets/file/FiEE, Inc._Audit Committee Charter.pdf";
import quarterlyPdftwo from "@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf";
import { reactive, onMounted } from 'vue'
import axios from 'axios'
import quarterlyPdfthree from "@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf";
import quarterlyPdfone from '@/assets/file/FiEE, Inc._Audit Committee Charter.pdf'
import quarterlyPdftwo from '@/assets/file/FiEE, Inc. _Code of Business Conduct and Ethics.pdf'
import quarterlyPdffour from "@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf";
import quarterlyPdfthree from '@/assets/file/FiEE, Inc._Compensation Committee Charter.pdf'
import quarterlyPdffour from '@/assets/file/FiEE, Inc. _Nominating and Corporate Governance Committee Charter.pdf'
const state = reactive({
list: [
{
title: "AUDIT COMMITTEE CHARTER",
description:
"Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.",
url: quarterlyPdfone,
date: "May 30, 2025",
},
{
title: "CODE OF BUSINESS CONDUCT AND ETHICS",
description:
"Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.",
url: quarterlyPdftwo,
date: "May 30, 2025",
},
{
title: "COMPENSATION COMMITTEE CHARTER",
description:
"Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.",
url: quarterlyPdfthree,
date: "May 30, 2025",
},
{
title: "NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER",
description:
"Provides the framework for director nominations and corporate governance matters.",
url: quarterlyPdffour,
date: "May 30, 2025",
},
// {
// title: 'AUDIT COMMITTEE CHARTER',
// description:
// 'Defines the purpose, composition, and responsibilities of the Audit Committee in overseeing financial reporting and disclosure.',
// url: quarterlyPdfone,
// date: 'May 30, 2025',
// },
// {
// title: 'CODE OF BUSINESS CONDUCT AND ETHICS',
// description:
// 'Establishes the ethical standards and legal compliance expectations for all directors, officers and employees.',
// url: quarterlyPdftwo,
// date: 'May 30, 2025',
// },
// {
// title: 'COMPENSATION COMMITTEE CHARTER',
// description:
// 'Outlines the duties and responsibilities for overseeing executive compensation and benefit plans.',
// url: quarterlyPdfthree,
// date: 'May 30, 2025',
// },
// {
// title: 'NOMINATING AND CORPORATE GOVERNANCE COMMITTEE CHARTER',
// description:
// 'Provides the framework for director nominations and corporate governance matters.',
// url: quarterlyPdffour,
// date: 'May 30, 2025',
// },
],
});
})
onMounted(() => {
getGovernanceDisplay()
})
//
const getGovernanceDisplay = () => {
// let url = 'https://common.szjixun.cn/api/fiee/governance/display'
let url = 'http://172.16.100.93:9020/api/fiee/governance/display'
let params = {}
axios
.get(url, { params })
.then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
state.list = res.data.data.data || []
}
}
})
.catch((err) => {
// console.log(err)
})
}
//
const handleViewDocument = (item) => {
// console.log(item)
window.open(
`${import.meta.env.VITE_PAGE_URL}/office?url=${
item.attachment
}&attachmentName=${item.attachmentName}`,
'_blank',
)
}
</script>
<style scoped lang="scss">

View File

@ -1,16 +1,17 @@
<script setup>
import customHeader from '@/components/customHeader/index.vue'
import customFooter from '@/components/customFooter/index.vue'
import { NScrollbar } from 'naive-ui'
</script>
<template>
<div class="flex flex-col h-screen">
<customHeader></customHeader>
<div
class="bg-[url('@/assets/image/bg-pc.png')] bg-cover bg-center flex-1 overflow-auto"
>
<router-view />
</div>
<n-scrollbar class="bg-[url('@/assets/image/bg-pc.png')] bg-cover bg-center flex-1">
<div>
<router-view />
</div>
</n-scrollbar>
<customFooter></customFooter>
</div>
</template>

View File

@ -1,16 +1,19 @@
<script setup>
import customHeader from '@/components/customHeader/index.vue'
import customFooter from '@/components/customFooter/index.vue'
import { NScrollbar } from 'naive-ui'
</script>
<template>
<div class="flex flex-col h-100svh">
<customHeader />
<div
class="bg-[url('@/assets/image/bg-mobile.png')] bg-cover bg-center flex-1 overflow-auto"
<n-scrollbar
class="bg-[url('@/assets/image/bg-mobile.png')] bg-cover bg-center flex-1"
>
<router-view />
</div>
<div>
<router-view />
</div>
</n-scrollbar>
<customFooter />
</div>
</template>

View File

@ -83,7 +83,7 @@
<div
style="font-size: 18px"
class="cursor-pointer"
@click="handleLink(item.router, item.time)"
@click="handleLink(item)"
>
View Press Release<img
class="ml-[10px]"
@ -205,6 +205,7 @@
import { onMounted, ref, onUnmounted, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useStockQuote } from "@/store/stock-quote/index.js";
import axios from 'axios'
const { getStockQuate, stockQuote, formatted } = useStockQuote();
getStockQuate();
@ -214,17 +215,44 @@ const contentRef = ref(null);
const isInView = ref(false);
let observer = null;
const newList = ref([
{
time: "June 3, 2025",
title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
router: "/news",
},
{
time: "June 2, 2025",
title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
router: "/news",
},
// {
// time: "June 3, 2025",
// title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
// router: "/news",
// },
// {
// time: "June 2, 2025",
// title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
// router: "/news",
// },
]);
// ()
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
page: 1,
pageSize: 10,
display: 2, // 1: 2:
}
console.log(params)
axios.post(url, params).then((res) => {
console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
})
newList.value = res.data.data?.data || []
}
}
})
}
onMounted(() => {
if (contentRef.value && "IntersectionObserver" in window) {
observer = new IntersectionObserver(
@ -249,6 +277,7 @@ onMounted(() => {
// 退IntersectionObserver
isInView.value = true;
}
getPressReleasesDisplay()
});
onUnmounted(() => {
@ -258,11 +287,11 @@ onUnmounted(() => {
});
import { useRouter } from "vue-router";
const router = useRouter();
const handleLink = (routers, index) => {
const handleLink = (item) => {
router.push({
path: routers,
path: "/news",
query: {
date: index,
id: item.id,
},
});
};

View File

@ -82,7 +82,7 @@
<div
style="font-size: 18px"
class="cursor-pointer"
@click="handleLink(item.router, item.time)"
@click="handleLink(item)"
>
View Press Release<img
class="ml-[10px]"
@ -194,24 +194,51 @@
import { onMounted, ref, onUnmounted, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useStockQuote } from "@/store/stock-quote/index.js";
import axios from 'axios'
const { getStockQuate, stockQuote, formatted } = useStockQuote();
getStockQuate();
//
const sampleDate = ref(formatted);
const newList = ref([
{
time: "June 3, 2025",
title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
router: "/news",
},
{
time: "June 2, 2025",
title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
router: "/news",
},
// {
// time: "June 3, 2025",
// title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
// router: "/news",
// },
// {
// time: "June 2, 2025",
// title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
// router: "/news",
// },
]);
// ()
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
page: 1,
pageSize: 10,
display: 2, // 1: 2:
}
console.log(params)
axios.post(url, params).then((res) => {
console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
})
newList.value = res.data.data?.data || []
}
}
})
}
const { t: $t } = useI18n();
const contentRef = ref(null);
const isInView = ref(false);
@ -240,6 +267,7 @@ onMounted(() => {
// 退IntersectionObserver
isInView.value = true;
}
getPressReleasesDisplay()
});
onUnmounted(() => {
@ -249,11 +277,11 @@ onUnmounted(() => {
});
import { useRouter } from "vue-router";
const router = useRouter();
const handleLink = (routers, index) => {
const handleLink = (item) => {
router.push({
path: routers,
path: "/news",
query: {
date: index,
id: item.id,
},
});
};

View File

@ -83,7 +83,7 @@
<div
style="font-size: 18px"
class="cursor-pointer"
@click="handleLink(item.router, item.time)"
@click="handleLink(item)"
>
View Press Release<img
class="ml-[10px]"
@ -205,6 +205,7 @@
import { onMounted, ref, onUnmounted, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useStockQuote } from "@/store/stock-quote/index.js";
import axios from 'axios'
const { getStockQuate, stockQuote, formatted } = useStockQuote();
getStockQuate();
const { t: $t } = useI18n();
@ -212,17 +213,44 @@ const contentRef = ref(null);
const isInView = ref(false);
let observer = null;
const newList = ref([
{
time: "June 3, 2025",
title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
router: "/news",
},
{
time: "June 2, 2025",
title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
router: "/news",
},
// {
// time: "June 3, 2025",
// title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
// router: "/news",
// },
// {
// time: "June 2, 2025",
// title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
// router: "/news",
// },
]);
// ()
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
page: 1,
pageSize: 10,
display: 2, // 1: 2:
}
console.log(params)
axios.post(url, params).then((res) => {
console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
})
newList.value = res.data.data?.data || []
}
}
})
}
onMounted(() => {
if (contentRef.value && "IntersectionObserver" in window) {
observer = new IntersectionObserver(
@ -247,6 +275,7 @@ onMounted(() => {
// 退IntersectionObserver
isInView.value = true;
}
getPressReleasesDisplay()
});
onUnmounted(() => {
@ -256,11 +285,11 @@ onUnmounted(() => {
});
import { useRouter } from "vue-router";
const router = useRouter();
const handleLink = (routers, index) => {
const handleLink = (item) => {
router.push({
path: routers,
path: "/news",
query: {
date: index,
id: item.id,
},
});
};

View File

@ -83,7 +83,7 @@
<div
style="font-size: 18px"
class="cursor-pointer"
@click="handleLink(item.router, item.time)"
@click="handleLink(item)"
>
View Press Release<img
class="ml-[10px]"
@ -205,6 +205,7 @@
import { onMounted, ref, onUnmounted, computed } from "vue";
import { useI18n } from "vue-i18n";
import { useStockQuote } from "@/store/stock-quote/index.js";
import axios from 'axios'
const { getStockQuate, stockQuote, formatted } = useStockQuote();
getStockQuate();
@ -238,20 +239,47 @@ onMounted(() => {
// 退IntersectionObserver
isInView.value = true;
}
getPressReleasesDisplay()
});
const newList = ref([
{
time: "June 3, 2025",
title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
router: "/news",
},
{
time: "June 2, 2025",
title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
router: "/news",
},
// {
// time: "June 3, 2025",
// title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
// router: "/news",
// },
// {
// time: "June 2, 2025",
// title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
// router: "/news",
// },
]);
// ()
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
page: 1,
pageSize: 10,
display: 2, // 1: 2:
}
console.log(params)
axios.post(url, params).then((res) => {
console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
})
newList.value = res.data.data?.data || []
}
}
})
}
onUnmounted(() => {
if (observer) {
observer.disconnect();
@ -259,11 +287,11 @@ onUnmounted(() => {
});
import { useRouter } from "vue-router";
const router = useRouter();
const handleLink = (routers, index) => {
const handleLink = (item) => {
router.push({
path: routers,
path: "/news",
query: {
date: index,
id: item.id,
},
});
};

119
src/views/office/index.vue Normal file
View File

@ -0,0 +1,119 @@
<!-- 从chat-PC接入的文档查看 -->
<template>
<DocumentEditor
id="docEditor"
:documentServerUrl="documentServerUrl"
:config="config"
:events_onDocumentReady="onDocumentReady"
:onLoadComponentError="onLoadComponentError"
/>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { DocumentEditor } from "@onlyoffice/document-editor-vue"
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const documentServerUrl = 'https://onlyoffice.fontree.cn'
const route = useRoute()
onMounted(() => {
// Content-Security-Policy meta
if (!document.querySelector('meta[http-equiv="Content-Security-Policy"]')) {
const meta = document.createElement('meta')
meta.httpEquiv = 'Content-Security-Policy'
meta.content = 'upgrade-insecure-requests'
document.head.appendChild(meta)
}
})
//
function getDocumentTypes(url) {
const extension = url.split('.').pop().toLowerCase()
const types = {
'docx': { fileType: 'docx', documentType: 'word' },
'doc': { fileType: 'doc', documentType: 'word' },
'xlsx': { fileType: 'xlsx', documentType: 'cell' },
'xls': { fileType: 'xls', documentType: 'cell' },
'pptx': { fileType: 'pptx', documentType: 'slide' },
'ppt': { fileType: 'ppt', documentType: 'slide' },
'pdf': { fileType: 'pdf', documentType: 'word' }
}
return types[extension] || { fileType: 'docx', documentType: 'word' }
}
const url = route.query.url
if (!url) {
alert(t('PAGES.FiEEInfoManage.document.readFailed'))
}
let attachmentName = route.query.attachmentName
const fileName = attachmentName ? attachmentName : url ? url.split('/').pop() : ''
const { fileType, documentType } = getDocumentTypes(url || '')
const config = {
document: {
fileType,
key: 'doc_' + Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
title: fileName,
url
},
documentType,
editorConfig: {
mode: 'view',
lang: 'en-US',
user: {
id: 'user_' + new Date().getTime(),
name: 'Guest User'
},
customization: {
about: false, //
help: false, //
chat: false,
commentAuthorOnly: false,
compactToolbar: true,
hideRightMenu: false, //
compatibility: true,
showReviewChanges: false,
loaderLogo: '', // logo
logo: {
image: '', //
imageDark: '', //
url: '', //
visible: false // false logo
}
}
}
}
const onDocumentReady = () => {
console.log("文档加载完成")
}
const onLoadComponentError = (errorCode, errorDescription) => {
switch(errorCode) {
case -1: //
console.log(errorDescription)
break
case -2: // DocsAPI
console.log(errorDescription)
break
case -3: // DocsAPI
console.log(errorDescription)
break
}
}
</script>
<style>
iframe[name="frameEditor"] {
width: 100% !important;
height: 100vh !important;
min-height: 100vh !important;
border: none !important;
display: block;
}
</style>

View File

@ -1,56 +1,59 @@
<template>
<div class="press-releases-page">
<main class="p-[35px] max-w-[1200px] mx-auto">
<div class="title mb-[20px]">
{{ t("press_releases.title") }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[80px]"
>
{{ t("press_releases.search.button") }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
<n-infinite-scroll :distance="0" @load="doLoadMore">
<main class="p-[35px] max-w-[1200px] mx-auto">
<div class="title mb-[20px]">
{{ t('press_releases.title') }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[80px]"
>
{{ item.title }}
</div>
<div class="news-item-content">
{{
item.content.length > 230
? item.content.substring(0, 230) + "..."
: item.content
}}
{{ t('press_releases.search.button') }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
>
{{ item.title }}
</div>
<div class="news-item-content" style="word-break: break-all;">
{{
item.summary?.length > 199
? item.summary.substring(0, 199) + '...'
: item.summary
}}
</div>
</div>
</div>
</div>
</main>
</main>
</n-infinite-scroll>
</div>
</template>
<script setup>
import customDefaultPage from "@/components/customDefaultPage/index.vue";
import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui";
import { NSelect, NInput, NButton, NInfiniteScroll } from "naive-ui";
import { useI18n } from "vue-i18n";
import axios from 'axios'
import { useRouter } from "vue-router";
const router = useRouter();
@ -90,12 +93,59 @@ const state = reactive({
},
],
filterNewsData: [],
loading: false, //
hasMore: true, //
currentPage: 1, //
});
onMounted(() => {
state.filterNewsData = state.newsData;
// state.filterNewsData = state.newsData;
getPressReleasesDisplay()
});
//
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
query: state.inputValue,
page: state.currentPage,
pageSize: 10,
timeStart: state.selectedValue
? state.selectedValue === 'all_years'
? null
: new Date(state.selectedValue).getTime()
: null,
}
// console.log(params)
axios.post(url, params).then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
if (state.currentPage === 1) {
state.filterNewsData = res.data.data?.data || []
} else {
state.filterNewsData = [
...state.filterNewsData,
...(res.data.data?.data || []),
]
}
if (state.filterNewsData.length < (res.data.data?.total || 0)) {
state.hasMore = true
} else {
state.hasMore = false
}
}
}
})
}
const handleFilter = () => {
//
let filteredData = [...state.newsData];
@ -130,14 +180,17 @@ const handleFilter = () => {
watch(
() => [state.selectedValue, state.inputValue],
() => {
handleFilter();
},
{ immediate: true }
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
}
);
const handleSearch = () => {
//
handleFilter();
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
// console.log(":", state.filterNewsData);
};
@ -145,10 +198,23 @@ const handleNewClick = (item) => {
router.push({
path: "/news",
query: {
date: item.date,
id: item.id,
},
});
};
//
const doLoadMore = () => {
if (!state.hasMore || state.loading) {
return
}
// console.log('')
state.loading = true
state.currentPage++
getPressReleasesDisplay().finally(() => {
state.loading = false
})
}
</script>
<style scoped lang="scss">

View File

@ -1,56 +1,59 @@
<template>
<div class="press-releases-page">
<main class="p-[35px] max-w-[1200px] mx-auto">
<div class="title mb-[20px]">
{{ t("press_releases.title") }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[60px]"
>
{{ t("press_releases.search.button") }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
<n-infinite-scroll :distance="0" @load="doLoadMore">
<main class="p-[35px] max-w-[1200px] mx-auto">
<div class="title mb-[20px]">
{{ t('press_releases.title') }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[60px]"
>
{{ item.title }}
</div>
<div class="news-item-content">
{{
item.content.length > 230
? item.content.substring(0, 230) + "..."
: item.content
}}
{{ t('press_releases.search.button') }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
>
{{ item.title }}
</div>
<div class="news-item-content" style="word-break: break-all;">
{{
item.summary?.length > 199
? item.summary.substring(0, 199) + '...'
: item.summary
}}
</div>
</div>
</div>
</div>
</main>
</main>
</n-infinite-scroll>
</div>
</template>
<script setup>
import customDefaultPage from "@/components/customDefaultPage/index.vue";
import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui";
import { NSelect, NInput, NButton, NInfiniteScroll } from "naive-ui";
import { useI18n } from "vue-i18n";
import axios from 'axios'
import { useRouter } from "vue-router";
const router = useRouter();
@ -90,12 +93,59 @@ const state = reactive({
},
],
filterNewsData: [],
loading: false, //
hasMore: true, //
currentPage: 1, //
});
onMounted(() => {
state.filterNewsData = state.newsData;
// state.filterNewsData = state.newsData;
getPressReleasesDisplay()
});
//
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
query: state.inputValue,
page: state.currentPage,
pageSize: 10,
timeStart: state.selectedValue
? state.selectedValue === 'all_years'
? null
: new Date(state.selectedValue).getTime()
: null,
}
// console.log(params)
axios.post(url, params).then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
if (state.currentPage === 1) {
state.filterNewsData = res.data.data?.data || []
} else {
state.filterNewsData = [
...state.filterNewsData,
...(res.data.data?.data || []),
]
}
if (state.filterNewsData.length < (res.data.data?.total || 0)) {
state.hasMore = true
} else {
state.hasMore = false
}
}
}
})
}
const handleFilter = () => {
//
let filteredData = [...state.newsData];
@ -130,14 +180,17 @@ const handleFilter = () => {
watch(
() => [state.selectedValue, state.inputValue],
() => {
handleFilter();
},
{ immediate: true }
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
}
);
const handleSearch = () => {
//
handleFilter();
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
// console.log(":", state.filterNewsData);
};
@ -145,10 +198,23 @@ const handleNewClick = (item) => {
router.push({
path: "/news",
query: {
date: item.date,
id: item.id,
},
});
};
//
const doLoadMore = () => {
if (!state.hasMore || state.loading) {
return
}
// console.log('')
state.loading = true
state.currentPage++
getPressReleasesDisplay().finally(() => {
state.loading = false
})
}
</script>
<style scoped lang="scss">

View File

@ -1,62 +1,68 @@
<template>
<div class="press-releases-page">
<main class="p-[80px] mx-auto" style="max-width: 100vw; min-width: 285px">
<div class="title mb-[24px]">
{{ t("press_releases.title") }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
:font-size="72"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
clearable
:font-size="72"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button"
:font-size="72"
>
{{ t("press_releases.search.button") }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
<n-infinite-scroll :distance="0" @load="doLoadMore">
<main
class="p-[80px] mx-auto"
style="max-width: 100vw; min-width: 285px;"
>
<div class="title mb-[24px]">
{{ t('press_releases.title') }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
:font-size="72"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
clearable
:font-size="72"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button"
:font-size="72"
>
{{ item.title }}
</div>
<div class="news-item-content">
{{
item.content.length > 230
? item.content.substring(0, 230) + "..."
: item.content
}}
{{ t('press_releases.search.button') }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
>
{{ item.title }}
</div>
<div class="news-item-content" style="word-break: break-all;">
{{
item.summary?.length > 199
? item.summary.substring(0, 199) + '...'
: item.summary
}}
</div>
</div>
</div>
</div>
</main>
</main>
</n-infinite-scroll>
</div>
</template>
<script setup>
import customDefaultPage from "@/components/customDefaultPage/index.vue";
import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui";
import { NSelect, NInput, NButton, NInfiniteScroll } from "naive-ui";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import axios from 'axios'
import { useRouter } from "vue-router";
const router = useRouter();
const { t } = useI18n();
@ -94,12 +100,59 @@ const state = reactive({
},
],
filterNewsData: [],
loading: false, //
hasMore: true, //
currentPage: 1, //
});
onMounted(() => {
state.filterNewsData = state.newsData;
// state.filterNewsData = state.newsData;
getPressReleasesDisplay()
});
//
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
query: state.inputValue,
page: state.currentPage,
pageSize: 10,
timeStart: state.selectedValue
? state.selectedValue === 'all_years'
? null
: new Date(state.selectedValue).getTime()
: null,
}
// console.log(params)
axios.post(url, params).then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
if (state.currentPage === 1) {
state.filterNewsData = res.data.data?.data || []
} else {
state.filterNewsData = [
...state.filterNewsData,
...(res.data.data?.data || []),
]
}
if (state.filterNewsData.length < (res.data.data?.total || 0)) {
state.hasMore = true
} else {
state.hasMore = false
}
}
}
})
}
const handleFilter = () => {
//
let filteredData = [...state.newsData];
@ -134,14 +187,17 @@ const handleFilter = () => {
watch(
() => [state.selectedValue, state.inputValue],
() => {
handleFilter();
},
{ immediate: true }
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
}
);
const handleSearch = () => {
//
handleFilter();
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
// console.log(":", state.filterNewsData);
};
@ -149,10 +205,23 @@ const handleNewClick = (item) => {
router.push({
path: "/news",
query: {
date: item.date,
id: item.id,
},
});
};
//
const doLoadMore = () => {
if (!state.hasMore || state.loading) {
return
}
// console.log('')
state.loading = true
state.currentPage++
getPressReleasesDisplay().finally(() => {
state.loading = false
})
}
</script>
<style scoped lang="scss">

View File

@ -1,56 +1,59 @@
<template>
<div class="press-releases-page">
<main class="p-[35px] mx-auto" style="max-width: calc(100% - 100px)">
<div class="title mb-[20px]">
{{ t("press_releases.title") }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[120px]"
>
{{ t("press_releases.search.button") }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
<n-infinite-scroll :distance="0" @load="doLoadMore">
<main class="p-[35px] mx-auto" style="max-width: calc(100% - 100px);">
<div class="title mb-[20px]">
{{ t('press_releases.title') }}
</div>
<div class="search-container">
<n-select
:options="state.selectOptions"
v-model:value="state.selectedValue"
class="search-select"
/>
<n-input
v-model:value="state.inputValue"
type="text"
:placeholder="t('press_releases.search.placeholder')"
class="search-input"
/>
<n-button
type="primary"
@click="handleSearch"
class="search-button w-[120px]"
>
{{ item.title }}
</div>
<div class="news-item-content">
{{
item.content.length > 230
? item.content.substring(0, 230) + "..."
: item.content
}}
{{ t('press_releases.search.button') }}
</n-button>
</div>
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
<div class="news-item mt-[10px]">
<div class="news-item-date">{{ item.date }}</div>
<div
class="news-item-title text-[#0078d7] overflow-hidden whitespace-nowrap text-ellipsis cursor-pointer"
@click="handleNewClick(item)"
>
{{ item.title }}
</div>
<div class="news-item-content" style="word-break: break-all;">
{{
item.summary?.length > 199
? item.summary.substring(0, 199) + '...'
: item.summary
}}
</div>
</div>
</div>
</div>
</main>
</main>
</n-infinite-scroll>
</div>
</template>
<script setup>
import customDefaultPage from "@/components/customDefaultPage/index.vue";
import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui";
import { NSelect, NInput, NButton, NInfiniteScroll } from "naive-ui";
import { useI18n } from "vue-i18n";
import axios from 'axios'
import { useRouter } from "vue-router";
const router = useRouter();
@ -90,12 +93,59 @@ const state = reactive({
},
],
filterNewsData: [],
loading: false, //
hasMore: true, //
currentPage: 1, //
});
onMounted(() => {
state.filterNewsData = state.newsData;
// state.filterNewsData = state.newsData;
getPressReleasesDisplay()
});
//
const getPressReleasesDisplay = () => {
let url = 'http://172.16.100.93:9020/api/fiee/pressreleases/display'
let params = {
query: state.inputValue,
page: state.currentPage,
pageSize: 10,
timeStart: state.selectedValue
? state.selectedValue === 'all_years'
? null
: new Date(state.selectedValue).getTime()
: null,
}
// console.log(params)
axios.post(url, params).then((res) => {
// console.log(res)
if (res.status === 200) {
if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
})
})
if (state.currentPage === 1) {
state.filterNewsData = res.data.data?.data || []
} else {
state.filterNewsData = [
...state.filterNewsData,
...(res.data.data?.data || []),
]
}
if (state.filterNewsData.length < (res.data.data?.total || 0)) {
state.hasMore = true
} else {
state.hasMore = false
}
}
}
})
}
const handleFilter = () => {
//
let filteredData = [...state.newsData];
@ -130,14 +180,17 @@ const handleFilter = () => {
watch(
() => [state.selectedValue, state.inputValue],
() => {
handleFilter();
},
{ immediate: true }
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
}
);
const handleSearch = () => {
//
handleFilter();
// handleFilter();
state.currentPage = 1
getPressReleasesDisplay()
// console.log(":", state.filterNewsData);
};
@ -145,15 +198,28 @@ const handleNewClick = (item) => {
router.push({
path: "/news",
query: {
date: item.date,
id: item.id,
},
});
};
//
const doLoadMore = () => {
if (!state.hasMore || state.loading) {
return
}
// console.log('')
state.loading = true
state.currentPage++
getPressReleasesDisplay().finally(() => {
state.loading = false
})
}
</script>
<style scoped lang="scss">
.title {
font-size: 40px;
font-size: 63px;
color: #333;
}