Compare commits

...

8 Commits

49 changed files with 1283 additions and 2182 deletions

View File

@ -3,9 +3,9 @@
<div class="custom-footer"> <div class="custom-footer">
<div class="custom-footer-box"> <div class="custom-footer-box">
<div class="footer-links"> <div class="footer-links">
<span @click="handleLink('privacyPolicy')">Privacy Policy</span> <span @click="handleLink('privacyPolicy')">{{ $t("footer.privacy_policy") }}</span>
<span @click="handleLink('termsOfUse')">Terms of use</span> <span @click="handleLink('termsOfUse')">{{ $t("footer.terms_of_use") }}</span>
<span @click="handleLink('siteMap')">Site Map</span> <span @click="handleLink('siteMap')">{{ $t("footer.site_map") }}</span>
</div> </div>
<span>&copy; 2025 FiEEHKLimited. All Rights Reserved.</span> <span>&copy; 2025 FiEEHKLimited. All Rights Reserved.</span>
</div> </div>

View File

@ -3,9 +3,9 @@
<div class="custom-footer"> <div class="custom-footer">
<div class="custom-footer-box"> <div class="custom-footer-box">
<div class="footer-links"> <div class="footer-links">
<span @click="handleLink('privacyPolicy')">Privacy Policy</span> <span @click="handleLink('privacyPolicy')">{{ $t("footer.privacy_policy") }}</span>
<span @click="handleLink('termsOfUse')">Terms of use</span> <span @click="handleLink('termsOfUse')">{{ $t("footer.terms_of_use") }}</span>
<span @click="handleLink('siteMap')">Site Map</span> <span @click="handleLink('siteMap')">{{ $t("footer.site_map") }}</span>
</div> </div>
<span>&copy; 2025 FiEEHKLimited. All Rights Reserved.</span> <span>&copy; 2025 FiEEHKLimited. All Rights Reserved.</span>
</div> </div>

View File

@ -3,9 +3,9 @@
<div class="custom-footer"> <div class="custom-footer">
<div class="footer-links-box"> <div class="footer-links-box">
<div class="footer-links"> <div class="footer-links">
<span @click="handleLink('privacyPolicy')">Privacy Policy</span> <span @click="handleLink('privacyPolicy')">{{ $t("footer.privacy_policy") }}</span>
<span @click="handleLink('termsOfUse')">Terms of use</span> <span @click="handleLink('termsOfUse')">{{ $t("footer.terms_of_use") }}</span>
<span @click="handleLink('siteMap')">Site Map</span> <span @click="handleLink('siteMap')">{{ $t("footer.site_map") }}</span>
</div> </div>
</div> </div>
<div class="footer-copyright"> <div class="footer-copyright">

View File

@ -2,9 +2,9 @@
<!-- 通用页脚 --> <!-- 通用页脚 -->
<div class="custom-footer"> <div class="custom-footer">
<div class="footer-links"> <div class="footer-links">
<span @click="handleLink('privacyPolicy')">Privacy Policy</span> <span @click="handleLink('privacyPolicy')">{{ $t("footer.privacy_policy") }}</span>
<span @click="handleLink('termsOfUse')">Terms of use</span> <span @click="handleLink('termsOfUse')">{{ $t("footer.terms_of_use") }}</span>
<span @click="handleLink('siteMap')">Site Map</span> <span @click="handleLink('siteMap')">{{ $t("footer.site_map") }}</span>
</div> </div>
<div>&copy; 2025 FiEEHKLimited. All Rights Reserved.</div> <div>&copy; 2025 FiEEHKLimited. All Rights Reserved.</div>
</div> </div>

View File

@ -97,8 +97,8 @@ const selectedLanguage = ref(
); );
const languageOptions = computed(() => [ const languageOptions = computed(() => [
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.en"), value: "en", key: "en" }, { label: t("language.en"), value: "en", key: "en" },
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.zh"), value: "zh", key: "zh" }, { label: t("language.zh"), value: "zh", key: "zh" },
{ label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" }, { label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" },
]); ]);

View File

@ -94,8 +94,8 @@ const selectedLanguage = ref(
); );
const languageOptions = computed(() => [ const languageOptions = computed(() => [
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.en"), value: "en", key: "en" }, { label: t("language.en"), value: "en", key: "en" },
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.zh"), value: "zh", key: "zh" }, { label: t("language.zh"), value: "zh", key: "zh" },
{ label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" }, { label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" },
]); ]);

View File

@ -107,8 +107,8 @@ const selectedLanguage = ref(
localStorage.getItem("language") || locale.value || "en" localStorage.getItem("language") || locale.value || "en"
); );
const languageOptions = computed(() => [ const languageOptions = computed(() => [
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.en"), value: "en", key: "en" }, { label: t("language.en"), value: "en", key: "en" },
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.zh"), value: "zh", key: "zh" }, { label: t("language.zh"), value: "zh", key: "zh" },
{ label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" }, { label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" },
]); ]);

View File

@ -103,8 +103,8 @@ const selectedLanguage = ref(
localStorage.getItem("language") || locale.value || "en" localStorage.getItem("language") || locale.value || "en"
); );
const languageOptions = computed(() => [ const languageOptions = computed(() => [
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.en"), value: "en", key: "en" }, { label: t("language.en"), value: "en", key: "en" },
{ label: t("language.ja"), value: "ja", key: "ja" },
{ label: t("language.zh"), value: "zh", key: "zh" }, { label: t("language.zh"), value: "zh", key: "zh" },
{ label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" }, { label: t("language.zhTW"), value: "zh-TW", key: "zh-TW" },
]); ]);

View File

@ -1,4 +1,9 @@
export default { export default {
footer: {
site_map: "Site Map",
privacy_policy: "Privacy Policy",
terms_of_use:"Terms of use"
},
language: { language: {
zh: "Simplified Chinese", zh: "Simplified Chinese",
zhTW: "Traditional Chinese", zhTW: "Traditional Chinese",
@ -9,6 +14,7 @@ export default {
value: "View Press Release", value: "View Press Release",
view_document: "View Document", view_document: "View Document",
}, },
home: { home: {
nav: { nav: {
home: "Home", home: "Home",
@ -259,8 +265,8 @@ export default {
week_range: "52-Week Range", week_range: "52-Week Range",
days_range: "Day's Range", days_range: "Day's Range",
market_cap: "Market Cap", market_cap: "Market Cap",
dollar: 'USD', dollar: "USD",
million: 'Million', million: "Million",
}, },
historic_stock: { historic_stock: {
title: "Historical Data", title: "Historical Data",

View File

@ -1,4 +1,9 @@
export default { export default {
footer: {
site_map: "サイトマップ",
privacy_policy: "プライバシーポリシー",
terms_of_use: "利用規約",
},
language: { language: {
zh: "簡体中国語", zh: "簡体中国語",
zhTW: "繁体中国語", zhTW: "繁体中国語",

View File

@ -1,4 +1,9 @@
export default { export default {
footer: {
site_map: "網站地圖",
privacy_policy: "隱私政策",
terms_of_use:"使用條款"
},
language: { language: {
zh: "簡體中文", zh: "簡體中文",
zhTW: "繁體中文", zhTW: "繁體中文",

View File

@ -1,4 +1,9 @@
export default { export default {
footer: {
site_map: "网站地图",
privacy_policy: "隐私政策",
terms_of_use: "使用条款"
},
language: { language: {
zh: "简体中文", zh: "简体中文",
zhTW: "繁體中文", zhTW: "繁體中文",

View File

@ -49,16 +49,25 @@
<script setup lang="jsx"> <script setup lang="jsx">
import { NDataTable } from "naive-ui"; import { NDataTable } from "naive-ui";
import { committeeManagement } from "@/api/auth"; import { committeeManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const committeeData = ref([]); const committeeData = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await committeeManagement({}); const res = await committeeManagement(params);
committeeData.value = res.data?.item || []; committeeData.value = res.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const columns = [ const columns = [
{ {

View File

@ -49,16 +49,25 @@
<script setup lang="jsx"> <script setup lang="jsx">
import { NDataTable } from "naive-ui"; import { NDataTable } from "naive-ui";
import { committeeManagement } from "@/api/auth"; import { committeeManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const committeeData = ref([]); const committeeData = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await committeeManagement({}); const res = await committeeManagement(params);
committeeData.value = res.data?.item || []; committeeData.value = res.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const columns = [ const columns = [
{ {

View File

@ -49,16 +49,25 @@
<script setup lang="jsx"> <script setup lang="jsx">
import { NDataTable } from "naive-ui"; import { NDataTable } from "naive-ui";
import { committeeManagement } from "@/api/auth"; import { committeeManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const committeeData = ref([]); const committeeData = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await committeeManagement({}); const res = await committeeManagement(params);
committeeData.value = res.data?.item || []; committeeData.value = res.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const columns = [ const columns = [
{ {

View File

@ -49,16 +49,25 @@
<script setup lang="jsx"> <script setup lang="jsx">
import { NDataTable } from "naive-ui"; import { NDataTable } from "naive-ui";
import { committeeManagement } from "@/api/auth"; import { committeeManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const committeeData = ref([]); const committeeData = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await committeeManagement({}); const res = await committeeManagement(params);
committeeData.value = res.data?.item || []; committeeData.value = res.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const columns = [ const columns = [
{ {

View File

@ -34,16 +34,25 @@
<script setup> <script setup>
import { boardManagement } from "@/api/auth"; import { boardManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await boardManagement({}); const res = await boardManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const otherDirectors = [ const otherDirectors = [
{ {

View File

@ -34,16 +34,25 @@
<script setup> <script setup>
import { boardManagement } from "@/api/auth"; import { boardManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await boardManagement({}); const res = await boardManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const otherDirectors = [ const otherDirectors = [
{ {

View File

@ -34,16 +34,25 @@
<script setup> <script setup>
import { boardManagement } from "@/api/auth"; import { boardManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await boardManagement({}); const res = await boardManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const otherDirectors = [ const otherDirectors = [
{ {
name: "Hu Bin", name: "Hu Bin",

View File

@ -34,16 +34,25 @@
<script setup> <script setup>
import { boardManagement } from "@/api/auth"; import { boardManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await boardManagement({}); const res = await boardManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const otherDirectors = [ const otherDirectors = [
{ {
name: "Hu Bin", name: "Hu Bin",

View File

@ -125,13 +125,20 @@
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import { reactive, ref } from "vue"; import { reactive, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui"; import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui";
import fileLink from "@/assets/image/content/icon-link.png"; import fileLink from "@/assets/image/content/icon-link.png";
import { annualReport } from "@/api/auth"; import { annualReport } from "@/api/auth";
import dayjs from 'dayjs' import dayjs from 'dayjs'
const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const state = reactive({ const state = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -155,11 +162,17 @@ const getListData = async () => {
const res = await annualReport({ const res = await annualReport({
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}); });
state.total = res.data.total; state.total = res.data.total;
annualReportsData.value = res?.data?.Item || []; annualReportsData.value = res?.data?.Item || [];
}; };
getListData(); getListData();
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
const columns = [ const columns = [
{ {
// title: "File Name", // title: "File Name",
@ -209,7 +222,6 @@ const columns = [
}, },
]; ];
const { t } = useI18n();
// //
const annualReports = ref([ const annualReports = ref([
{ {

View File

@ -125,13 +125,20 @@
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import { reactive, ref } from "vue"; import { reactive, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui"; import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui";
import fileLink from "@/assets/image/content/icon-link.png"; import fileLink from "@/assets/image/content/icon-link.png";
import { annualReport } from "@/api/auth"; import { annualReport } from "@/api/auth";
import dayjs from 'dayjs' import dayjs from 'dayjs'
const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const state = reactive({ const state = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -155,11 +162,18 @@ const getListData = async () => {
const res = await annualReport({ const res = await annualReport({
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}); });
state.total = res.data.total; state.total = res.data.total;
annualReportsData.value = res?.data?.Item || []; annualReportsData.value = res?.data?.Item || [];
}; };
getListData(); getListData();
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
const columns = [ const columns = [
{ {
// title: "File Name", // title: "File Name",
@ -209,7 +223,6 @@ const columns = [
}, },
]; ];
const { t } = useI18n();
// //
const annualReports = ref([ const annualReports = ref([
{ {

View File

@ -127,13 +127,20 @@
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import { reactive, ref } from "vue"; import { reactive, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui"; import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui";
import fileLink from "@/assets/image/content/icon-link.png"; import fileLink from "@/assets/image/content/icon-link.png";
import { annualReport } from "@/api/auth"; import { annualReport } from "@/api/auth";
import dayjs from 'dayjs' import dayjs from 'dayjs'
const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const state = reactive({ const state = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -156,11 +163,18 @@ const getListData = async () => {
const res = await annualReport({ const res = await annualReport({
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}); });
state.total = res.data.total; state.total = res.data.total;
annualReportsData.value = res?.data?.Item || []; annualReportsData.value = res?.data?.Item || [];
}; };
getListData(); getListData();
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
const columns = [ const columns = [
{ {
// title: "File Name", // title: "File Name",
@ -213,7 +227,6 @@ const columns = [
}, },
]; ];
const { t } = useI18n();
// //
const annualReports = ref([ const annualReports = ref([
{ {

View File

@ -125,13 +125,20 @@
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
import { reactive, ref } from "vue"; import { reactive, ref, watch } from "vue";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui"; import { NSelect, NDataTable, NPagination, NButton, NIcon } from "naive-ui";
import fileLink from "@/assets/image/content/icon-link.png"; import fileLink from "@/assets/image/content/icon-link.png";
import { annualReport } from "@/api/auth"; import { annualReport } from "@/api/auth";
import dayjs from 'dayjs' import dayjs from 'dayjs'
const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const state = reactive({ const state = reactive({
currentPage: 1, currentPage: 1,
pageSize: 10, pageSize: 10,
@ -155,11 +162,18 @@ const getListData = async () => {
const res = await annualReport({ const res = await annualReport({
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}); });
state.total = res.data.total; state.total = res.data.total;
annualReportsData.value = res?.data?.Item || []; annualReportsData.value = res?.data?.Item || [];
}; };
getListData(); getListData();
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
const columns = [ const columns = [
{ {
// title: "File Name", // title: "File Name",
@ -209,7 +223,6 @@ const columns = [
}, },
]; ];
const { t } = useI18n();
// //
const annualReports = ref([ const annualReports = ref([
{ {

View File

@ -162,7 +162,13 @@ import { useI18n } from "vue-i18n";
// import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf"; // import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf";
// import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf"; // import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf";
import axios from "axios"; import axios from "axios";
const { t } = useI18n(); const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const searchQuery = ref(""); const searchQuery = ref("");
const state = reactive({ const state = reactive({
@ -171,7 +177,7 @@ const state = reactive({
total: 0, total: 0,
gotoPage: 1, gotoPage: 1,
listConfig: { listConfig: {
url: "http://erpapi.test.fontree.cn:8081/api/fiee/reports/quarterly/display", url: `${import.meta.env.VITE_API_BASE_URL}/fiee/reports/quarterly/display`,
// url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display", // url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display",
params: { params: {
filtrate: { filtrate: {
@ -215,6 +221,7 @@ const getListData = async () => {
...state.listConfig.params, ...state.listConfig.params,
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}; };
const res = await axios.post(state.listConfig.url, params); const res = await axios.post(state.listConfig.url, params);
console.log(res); console.log(res);
@ -230,6 +237,11 @@ const getListData = async () => {
state.total = res.data.data.total || 0; state.total = res.data.data.total || 0;
} }
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
// //
const totalPages = computed(() => { const totalPages = computed(() => {

View File

@ -162,7 +162,13 @@ import { useI18n } from "vue-i18n";
// import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf"; // import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf";
// import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf"; // import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf";
import axios from "axios"; import axios from "axios";
const { t } = useI18n(); const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const searchQuery = ref(""); const searchQuery = ref("");
const state = reactive({ const state = reactive({
@ -171,7 +177,7 @@ const state = reactive({
total: 0, total: 0,
gotoPage: 1, gotoPage: 1,
listConfig: { listConfig: {
url: "http://erpapi.test.fontree.cn:8081/api/fiee/reports/quarterly/display", url: `${import.meta.env.VITE_API_BASE_URL}/fiee/reports/quarterly/display`,
// url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display", // url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display",
params: { params: {
filtrate: { filtrate: {
@ -215,6 +221,7 @@ const getListData = async () => {
...state.listConfig.params, ...state.listConfig.params,
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}; };
const res = await axios.post(state.listConfig.url, params); const res = await axios.post(state.listConfig.url, params);
console.log(res); console.log(res);
@ -230,6 +237,11 @@ const getListData = async () => {
state.total = res.data.data.total || 0; state.total = res.data.data.total || 0;
} }
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
// //
const totalPages = computed(() => { const totalPages = computed(() => {

View File

@ -146,7 +146,13 @@ import { useI18n } from "vue-i18n";
// import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf"; // import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf";
// import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf"; // import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf";
import axios from "axios"; import axios from "axios";
const { t } = useI18n(); const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const searchQuery = ref(""); const searchQuery = ref("");
const state = reactive({ const state = reactive({
@ -155,7 +161,7 @@ const state = reactive({
total: 0, total: 0,
gotoPage: 1, gotoPage: 1,
listConfig: { listConfig: {
url: "http://erpapi.test.fontree.cn:8081/api/fiee/reports/quarterly/display", url: `${import.meta.env.VITE_API_BASE_URL}/fiee/reports/quarterly/display`,
// url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display", // url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display",
params: { params: {
filtrate: { filtrate: {
@ -199,6 +205,7 @@ const getListData = async () => {
...state.listConfig.params, ...state.listConfig.params,
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}; };
const res = await axios.post(state.listConfig.url, params); const res = await axios.post(state.listConfig.url, params);
console.log(res); console.log(res);
@ -214,6 +221,11 @@ const getListData = async () => {
state.total = res.data.data.total || 0; state.total = res.data.data.total || 0;
} }
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
// //
const totalPages = computed(() => { const totalPages = computed(() => {

View File

@ -160,7 +160,13 @@ import { useI18n } from "vue-i18n";
// import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf"; // import quarterlyPdf2025Q2 from "@/assets/file/quarterly/10Q 2025-Q2.pdf";
// import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf"; // import quarterlyPdf2025Q3N from "@/assets/file/quarterly/10Q 2025-Q1-No1.pdf";
import axios from "axios"; import axios from "axios";
const { t } = useI18n(); const { t, locale } = useI18n();
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const searchQuery = ref(""); const searchQuery = ref("");
const state = reactive({ const state = reactive({
@ -169,7 +175,7 @@ const state = reactive({
total: 0, total: 0,
gotoPage: 1, gotoPage: 1,
listConfig: { listConfig: {
url: "http://erpapi.test.fontree.cn:8081/api/fiee/reports/quarterly/display", url: `${import.meta.env.VITE_API_BASE_URL}/fiee/reports/quarterly/display`,
// url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display", // url: "https://erpapi.fiee.com/api/fiee/reports/quarterly/display",
params: { params: {
filtrate: { filtrate: {
@ -213,6 +219,7 @@ const getListData = async () => {
...state.listConfig.params, ...state.listConfig.params,
page: state.currentPage, page: state.currentPage,
pageSize: state.pageSize, pageSize: state.pageSize,
langType: map[locale.value],
}; };
const res = await axios.post(state.listConfig.url, params); const res = await axios.post(state.listConfig.url, params);
console.log(res); console.log(res);
@ -228,6 +235,11 @@ const getListData = async () => {
state.total = res.data.data.total || 0; state.total = res.data.data.total || 0;
} }
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getListData();
});
// //
const totalPages = computed(() => { const totalPages = computed(() => {

View File

@ -2,7 +2,7 @@
import customHeader from "@/components/customHeader/index.vue"; import customHeader from "@/components/customHeader/index.vue";
import customFooter from "@/components/customFooter/index.vue"; import customFooter from "@/components/customFooter/index.vue";
import { NScrollbar } from "naive-ui"; import { NScrollbar } from "naive-ui";
import { computed } from "vue"; import { computed, watch, ref } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
@ -55,12 +55,18 @@ const currentBg = computed(() => {
// //
return { background: value }; return { background: value };
}); });
const scrollbarRef = ref(null);
watch(route, () => {
scrollbarRef.value?.scrollTo({ top: 0 });
})
</script> </script>
<template> <template>
<div class="flex flex-col h-screen"> <div class="flex flex-col h-screen">
<customHeader></customHeader> <customHeader></customHeader>
<n-scrollbar <n-scrollbar
ref="scrollbarRef"
class="bg-cover bg-center bg-no-repeat flex-1" class="bg-cover bg-center bg-no-repeat flex-1"
style="background-size: 100% 100%; background-attachment: fixed" style="background-size: 100% 100%; background-attachment: fixed"
:style="currentBg" :style="currentBg"

View File

@ -103,16 +103,25 @@
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed } from "vue"; import { computed } from "vue";
import { departmentManagement } from "@/api/auth"; import { departmentManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await departmentManagement({}); const res = await departmentManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const { t } = useI18n(); const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const leadershipTeam = computed(() => [ const leadershipTeam = computed(() => [
{ {
@ -132,10 +141,11 @@ const leadershipTeam = computed(() => [
]); ]);
const getInitials = (name) => { const getInitials = (name) => {
return name // return name
.split(" ") // .split(" ")
.map((n) => n[0]) // .map((n) => n[0])
.join(""); // .join("");
return name?.slice(0, 2) || "";
}; };
</script> </script>

View File

@ -104,16 +104,25 @@
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed } from "vue"; import { computed } from "vue";
import { departmentManagement } from "@/api/auth"; import { departmentManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await departmentManagement({}); const res = await departmentManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const { t } = useI18n(); const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const leadershipTeam = computed(() => [ const leadershipTeam = computed(() => [
{ {
@ -133,10 +142,11 @@ const leadershipTeam = computed(() => [
]); ]);
const getInitials = (name) => { const getInitials = (name) => {
return name // return name
.split(" ") // .split(" ")
.map((n) => n[0]) // .map((n) => n[0])
.join(""); // .join("");
return name?.slice(0, 2) || "";
}; };
</script> </script>

View File

@ -102,16 +102,25 @@
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed } from "vue"; import { computed } from "vue";
import { departmentManagement } from "@/api/auth"; import { departmentManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await departmentManagement({}); const res = await departmentManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const { t } = useI18n(); const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const leadershipTeam = computed(() => [ const leadershipTeam = computed(() => [
{ {
@ -131,10 +140,11 @@ const leadershipTeam = computed(() => [
]); ]);
const getInitials = (name) => { const getInitials = (name) => {
return name // return name
.split(" ") // .split(" ")
.map((n) => n[0]) // .map((n) => n[0])
.join(""); // .join("");
return name?.slice(0, 2) || "";
}; };
</script> </script>

View File

@ -102,16 +102,25 @@
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed } from "vue"; import { computed } from "vue";
import { departmentManagement } from "@/api/auth"; import { departmentManagement } from "@/api/auth";
import { ref } from "vue"; import { ref, watch } from "vue";
const { t, locale } = useI18n();
const data = ref([]); const data = ref([]);
const getData = async () => { const getData = async (params) => {
const res = await departmentManagement({}); const res = await departmentManagement(params);
data.value = res?.data?.item || []; data.value = res?.data?.item || [];
}; };
getData(); watch(locale, (newLocale, oldLocale) => {
console.log("语言已切换:", newLocale);
const { t } = useI18n(); const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
getData({ langType: map[newLocale] });
}, { immediate: true });
const leadershipTeam = computed(() => [ const leadershipTeam = computed(() => [
{ {
@ -131,10 +140,11 @@ const leadershipTeam = computed(() => [
]); ]);
const getInitials = (name) => { const getInitials = (name) => {
return name // return name
.split(" ") // .split(" ")
.map((n) => n[0]) // .map((n) => n[0])
.join(""); // .join("");
return name?.slice(0, 2) || "";
}; };
</script> </script>

View File

@ -580,6 +580,13 @@ const newList = ref([
// }, // },
]); ]);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// () // ()
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`; let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`;
@ -587,6 +594,7 @@ const getPressReleasesDisplay = () => {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
display: 2, // 1: 2: display: 2, // 1: 2:
langType: map[locale.value],
}; };
// console.log(params) // console.log(params)
axios.post(url, params).then((res) => { axios.post(url, params).then((res) => {
@ -594,7 +602,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString("en-US", { item.time = new Date(item.date).toLocaleDateString("en-US", {
month: "long", month: "long",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -606,7 +614,7 @@ const getPressReleasesDisplay = () => {
}); });
}; };
const { t: $t } = useI18n(); const { t: $t, locale } = useI18n();
const contentRef = ref(null); const contentRef = ref(null);
const isInView = ref(false); const isInView = ref(false);
let observer = null; let observer = null;
@ -641,6 +649,11 @@ onMounted(() => {
}); });
}); });
//
watch(locale, (newLocale) => {
getPressReleasesDisplay();
});
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -680,7 +693,7 @@ const handleLink = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };

View File

@ -580,6 +580,13 @@ const newList = ref([
// }, // },
]); ]);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// () // ()
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`; let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`;
@ -587,6 +594,7 @@ const getPressReleasesDisplay = () => {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
display: 2, // 1: 2: display: 2, // 1: 2:
langType: map[locale.value],
}; };
// console.log(params) // console.log(params)
axios.post(url, params).then((res) => { axios.post(url, params).then((res) => {
@ -594,7 +602,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString("en-US", { item.time = new Date(item.date).toLocaleDateString("en-US", {
month: "long", month: "long",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -606,7 +614,7 @@ const getPressReleasesDisplay = () => {
}); });
}; };
const { t: $t } = useI18n(); const { t: $t, locale } = useI18n();
const contentRef = ref(null); const contentRef = ref(null);
const isInView = ref(false); const isInView = ref(false);
let observer = null; let observer = null;
@ -641,6 +649,11 @@ onMounted(() => {
}); });
}); });
//
watch(locale, (newLocale) => {
getPressReleasesDisplay();
});
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -680,7 +693,7 @@ const handleLink = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };

View File

@ -369,6 +369,13 @@ const newList = ref([
// }, // },
]); ]);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// () // ()
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`; let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`;
@ -376,6 +383,7 @@ const getPressReleasesDisplay = () => {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
display: 2, // 1: 2: display: 2, // 1: 2:
langType: map[locale.value],
}; };
// console.log(params) // console.log(params)
axios.post(url, params).then((res) => { axios.post(url, params).then((res) => {
@ -383,7 +391,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString("en-US", { item.time = new Date(item.date).toLocaleDateString("en-US", {
month: "long", month: "long",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -395,7 +403,7 @@ const getPressReleasesDisplay = () => {
}); });
}; };
const { t: $t } = useI18n(); const { t: $t, locale } = useI18n();
const contentRef = ref(null); const contentRef = ref(null);
const isInView = ref(false); const isInView = ref(false);
let observer = null; let observer = null;
@ -430,6 +438,11 @@ onMounted(() => {
}); });
}); });
//
watch(locale, (newLocale) => {
getPressReleasesDisplay();
});
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -469,7 +482,7 @@ const handleLink = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };

View File

@ -540,6 +540,12 @@ const newList = ref([
// }, // },
]); ]);
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// () // ()
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`; let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases/display`;
@ -547,6 +553,7 @@ const getPressReleasesDisplay = () => {
page: 1, page: 1,
pageSize: 10, pageSize: 10,
display: 2, // 1: 2: display: 2, // 1: 2:
langType: map[locale.value],
}; };
// console.log(params) // console.log(params)
axios.post(url, params).then((res) => { axios.post(url, params).then((res) => {
@ -554,7 +561,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.time = new Date(item.createdAt).toLocaleDateString("en-US", { item.time = new Date(item.date).toLocaleDateString("en-US", {
month: "long", month: "long",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -566,7 +573,7 @@ const getPressReleasesDisplay = () => {
}); });
}; };
const { t: $t } = useI18n(); const { t: $t, locale } = useI18n();
const contentRef = ref(null); const contentRef = ref(null);
const isInView = ref(false); const isInView = ref(false);
let observer = null; let observer = null;
@ -601,6 +608,11 @@ onMounted(() => {
}); });
}); });
//
watch(locale, (newLocale) => {
getPressReleasesDisplay();
});
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -640,7 +652,7 @@ const handleLink = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="relative"> <div class="relative">
<div <div
class="w-[100vw] bg-[#ffffff] z-[1] top-0 left-0 bottom-0 right-0 absolute" class="w-[100vw] min-h-[100vh] bg-[#ffffff] z-[1] top-0 left-0 bottom-0 right-0 absolute"
></div> ></div>
<div <div
class="page-container overflow-hidden z-10 relative" class="page-container overflow-hidden z-10 relative"
@ -19,15 +19,21 @@
</template> </template>
<script setup> <script setup>
import { reactive, onMounted } from "vue"; import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui"; import { NSelect, NInput, NButton } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
import axios from "axios"; import axios from "axios";
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
const state = reactive({ const state = reactive({
id: "", // id id: "", // id
}); });
@ -40,19 +46,23 @@ onMounted(() => {
// //
const getPressReleasesInfo = () => { const getPressReleasesInfo = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?id=${ let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?uuid=${
state.id state.id
}`; }&langType=${map[locale.value]}`;
axios.get(url).then((res) => { axios.get(url).then((res) => {
// console.log(res) // console.log(res)
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
const myRichText = document.getElementById("my-richText"); const myRichText = document.getElementById("my-richText");
myRichText.innerHTML = res.data.data.content; myRichText.innerHTML = res?.data?.data?.data?.content || "";
} }
} }
}); });
}; };
watch(locale, (newLocale, oldLocale) => {
getPressReleasesInfo();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.page-container { .page-container {

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="relative"> <div class="relative">
<div <div
class="w-[100vw] bg-[#ffffff] z-[1] top-0 left-0 bottom-0 right-0 absolute" class="w-[100vw] min-h-[100vh] bg-[#ffffff] z-[1] top-0 left-0 bottom-0 right-0 absolute"
></div> ></div>
<div <div
class="page-container overflow-hidden z-10 relative" class="page-container overflow-hidden z-10 relative"
@ -19,11 +19,11 @@
</template> </template>
<script setup> <script setup>
import { reactive, onMounted } from "vue"; import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui"; import { NSelect, NInput, NButton } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
import axios from "axios"; import axios from "axios";
@ -38,21 +38,34 @@ onMounted(() => {
getPressReleasesInfo(); getPressReleasesInfo();
}); });
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesInfo = () => { const getPressReleasesInfo = () => {
let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?id=${ let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?uuid=${
state.id state.id
}`; }&langType=${map[locale.value]}`;
axios.get(url).then((res) => { axios.get(url).then((res) => {
// console.log(res) // console.log(res)
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
const myRichText = document.getElementById("my-richText"); const myRichText = document.getElementById("my-richText");
myRichText.innerHTML = res.data.data.content; console.log(res?.data?.data?.data?.content,res);
myRichText.innerHTML = res?.data?.data?.data?.content || "";
} }
} }
}); });
}; };
//
watch(locale, (newLocale, oldLocale) => {
getPressReleasesInfo();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.page-container { .page-container {

View File

@ -5,11 +5,11 @@
</template> </template>
<script setup> <script setup>
import { reactive, onMounted } from "vue"; import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui"; import { NSelect, NInput, NButton } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
import axios from 'axios' import axios from 'axios'
@ -24,19 +24,33 @@ onMounted(() => {
getPressReleasesInfo(); getPressReleasesInfo();
}); });
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesInfo = () => { const getPressReleasesInfo = () => {
let url = 'https://erpapi.fiee.com/api/fiee/pressreleases?id=' + state.id let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?uuid=${
state.id
}&langType=${map[locale.value]}`;
axios.get(url).then((res) => { axios.get(url).then((res) => {
// console.log(res) // console.log(res)
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
const myRichText = document.getElementById('my-richText') const myRichText = document.getElementById('my-richText')
myRichText.innerHTML = res.data.data.content myRichText.innerHTML = res?.data?.data?.data?.content || "";
} }
} }
}) })
} }
//
watch(locale, (newLocale, oldLocale) => {
getPressReleasesInfo();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -5,11 +5,11 @@
</template> </template>
<script setup> <script setup>
import { reactive, onMounted } from "vue"; import { reactive, onMounted, watch } from "vue";
import { NSelect, NInput, NButton } from "naive-ui"; import { NSelect, NInput, NButton } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
const { t } = useI18n(); const { t, locale } = useI18n();
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
const route = useRoute(); const route = useRoute();
import axios from 'axios' import axios from 'axios'
@ -24,19 +24,35 @@ onMounted(() => {
getPressReleasesInfo(); getPressReleasesInfo();
}); });
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesInfo = () => { const getPressReleasesInfo = () => {
let url = 'https://erpapi.fiee.com/api/fiee/pressreleases?id=' + state.id let url = `${import.meta.env.VITE_API_BASE_URL}/fiee/pressreleases?uuid=${
state.id
}&langType=${map[locale.value]}`;
axios.get(url).then((res) => { axios.get(url).then((res) => {
// console.log(res) // console.log(res)
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
const myRichText = document.getElementById('my-richText') const myRichText = document.getElementById('my-richText')
myRichText.innerHTML = res.data.data.content myRichText.innerHTML = res?.data?.data?.data?.content || "";
} }
} }
}) })
} }
//
watch(locale, (newLocale, oldLocale) => {
getPressReleasesInfo();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -99,93 +99,40 @@
<!-- 分页器 --> <!-- 分页器 -->
<div class="pagination-container" v-if="state.total > 0"> <div class="pagination-container" v-if="state.total > 0">
<div class="pagination-info"> <div class="pagination-info text-[#455363] mr-[15PX]">
Displaying {{ displayRange.start }} - {{ displayRange.end }} of {{ t("financialinformation.quarterlyreports.pagination.displaying", {
{{ state.total }} results start: (state.currentPage - 1) * state.pageSize + 1,
end: Math.min(state.currentPage * state.pageSize, state.total),
total: state.total,
}) }}
</div> </div>
<div class="pagination-controls"> <NPagination
<div class="pagination-buttons"> v-model:page="state.currentPage"
<button v-model:page-size="state.pageSize"
class="page-btn-prev prev-btn" show-size-picker
:disabled="state.currentPage === 1" show-quick-jumper
@click="goToPrevPage" :item-count="state.total"
:page-sizes="[
{
label: t('historic_stock.pagination.perPage', { size: 10 }),
value: 10,
},
{
label: t('historic_stock.pagination.perPage', { size: 25 }),
value: 25,
},
{
label: t('historic_stock.pagination.perPage', { size: 50 }),
value: 50,
},
]"
@update:page="getPressReleasesDisplay"
@update:page-size="getPressReleasesDisplay"
> >
<svg width="5" height="9" viewBox="0 0 5 9" fill="none"> <template #goto>{{
<path t("financialinformation.quarterlyreports.pagination.goto")
d="M4 1L1 4.5L4 8" }}</template>
stroke="#455363" </NPagination>
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<template v-for="page in getVisiblePages()" :key="page">
<button
v-if="page !== '...'"
class="page-btn-page"
:class="{ active: page === state.currentPage }"
@click="goToPage(page)"
>
{{ page }}
</button>
<button v-else class="page-btn-page disabled" disabled>
...
</button>
</template>
<button
class="page-btn-next next-btn"
:disabled="state.currentPage === totalPages"
@click="goToNextPage"
>
<svg width="5" height="9" viewBox="0 0 5 9" fill="none">
<path
d="M1 1L4 5L1 8"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="page-size-selector" @click="togglePageSizeMenu">
<span>{{ state.pageSize }}/page</span>
<svg width="10" height="5" viewBox="0 0 10 5" fill="none">
<path
d="M1 1L5 4L9 1"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<div v-if="showPageSizeMenu" class="page-size-menu">
<div
v-for="size in [10, 20, 50]"
:key="size"
class="page-size-option"
:class="{ active: state.pageSize === size }"
@click="changePageSize(size)"
>
{{ size }}/page
</div>
</div>
</div>
<div class="goto-section">
<span>Goto</span>
<input
type="number"
v-model="state.gotoPage"
class="goto-input"
:min="1"
:max="totalPages"
@keyup.enter="handleGoto"
/>
</div>
</div>
</div> </div>
</main> </main>
</div> </div>
@ -200,16 +147,14 @@ import {
watch, watch,
nextTick, nextTick,
ref, ref,
computed,
onUnmounted,
} from "vue"; } from "vue";
import { NTooltip } from "naive-ui"; import { NTooltip, NPagination } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import axios from "axios"; import axios from "axios";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t, locale } = useI18n();
const state = reactive({ const state = reactive({
selectedValue: "all_years", // selectedValue: "all_years", //
@ -229,11 +174,8 @@ const state = reactive({
currentPage: 1, // currentPage: 1, //
pageSize: 10, pageSize: 10,
total: 0, total: 0,
gotoPage: 1,
}); });
const showPageSizeMenu = ref(false);
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -254,17 +196,12 @@ const checkAllTitleOverflow = () => {
onMounted(() => { onMounted(() => {
getPressReleasesDisplay(); getPressReleasesDisplay();
document.addEventListener("click", handleClickOutside);
nextTick(() => { nextTick(() => {
checkAllTitleOverflow(); checkAllTitleOverflow();
}); });
}); });
onUnmounted(() => {
document.removeEventListener("click", handleClickOutside);
});
watch( watch(
() => state.filterNewsData, () => state.filterNewsData,
() => { () => {
@ -275,6 +212,13 @@ watch(
{ deep: true } { deep: true }
); );
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
state.loading = true; state.loading = true;
@ -288,6 +232,7 @@ const getPressReleasesDisplay = () => {
? null ? null
: new Date(state.selectedValue).getTime() : new Date(state.selectedValue).getTime()
: null, : null,
langType: map[locale.value],
}; };
axios axios
.post(url, params) .post(url, params)
@ -295,7 +240,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString("en-US", { item.date = new Date(item.date).toLocaleDateString("en-US", {
month: "short", month: "short",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -311,6 +256,11 @@ const getPressReleasesDisplay = () => {
}); });
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getPressReleasesDisplay();
});
// watcher // watcher
watch( watch(
() => [state.selectedValue, state.inputValue], () => [state.selectedValue, state.inputValue],
@ -331,7 +281,6 @@ watch(
watch( watch(
() => state.currentPage, () => state.currentPage,
(newPage) => { (newPage) => {
state.gotoPage = newPage;
getPressReleasesDisplay(); getPressReleasesDisplay();
} }
); );
@ -345,97 +294,10 @@ const handleNewClick = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };
const totalPages = computed(() => {
return Math.ceil(state.total / state.pageSize) || 1;
});
const displayRange = computed(() => {
if (state.total === 0) return { start: 0, end: 0 };
const start = (state.currentPage - 1) * state.pageSize + 1;
const end = Math.min(state.currentPage * state.pageSize, state.total);
return { start, end };
});
const goToPage = (page) => {
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const goToPrevPage = () => {
if (state.currentPage > 1) {
state.currentPage--;
}
};
const goToNextPage = () => {
if (state.currentPage < totalPages.value) {
state.currentPage++;
}
};
const changePageSize = (size) => {
state.pageSize = size;
};
const handleGoto = () => {
const page = parseInt(state.gotoPage);
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const togglePageSizeMenu = () => {
showPageSizeMenu.value = !showPageSizeMenu.value;
};
const getVisiblePages = () => {
const current = state.currentPage;
const total = totalPages.value;
const pages = [];
if (total <= 7) {
for (let i = 1; i <= total; i++) {
pages.push(i);
}
} else {
pages.push(1);
if (current <= 4) {
for (let i = 2; i <= 5; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
} else if (current >= total - 3) {
pages.push("...");
for (let i = total - 4; i <= total; i++) {
pages.push(i);
}
} else {
pages.push("...");
for (let i = current - 1; i <= current + 1; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
}
}
return pages;
};
//
const handleClickOutside = (event) => {
if (!event.target.closest || !event.target.closest(".page-size-selector")) {
showPageSizeMenu.value = false;
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -641,8 +503,8 @@ const handleClickOutside = (event) => {
.pagination-container { .pagination-container {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: center;
margin-top: 20px; margin-top: 15px;
margin-bottom: 30px; margin-bottom: 30px;
gap: 21px; gap: 21px;
} }
@ -656,179 +518,7 @@ const handleClickOutside = (event) => {
text-align: right; text-align: right;
} }
.pagination-controls { :deep(.n-base-loading__icon) {
display: flex;
align-items: center;
gap: 8px;
}
.pagination-buttons {
display: flex;
align-items: center;
gap: 8px;
}
.page-btn-prev,
.page-btn-next {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: 1px solid #e0e0e6;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac; color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
background: #fff0f5;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-btn-page {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
border: none;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
border: 1px solid #e0e0e6;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-size-selector {
position: relative;
display: flex;
align-items: center;
gap: 18px;
padding: 4px 12px;
height: 28px;
border: 1px solid #e0e0e6;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
&:hover {
border-color: #ff7bac;
}
}
.page-size-menu {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background: #ffffff;
border: 1px solid #e0e0e6;
border-radius: 3px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-bottom: 2px;
}
.page-size-option {
padding: 8px 12px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background: #fff0f5;
}
&.active {
background: #fff0f5;
color: #ff7bac;
}
}
.goto-section {
display: flex;
align-items: center;
gap: 8px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
margin-right: 16px;
}
.goto-input {
width: 60px;
height: 28px;
padding: 4px 12px;
border: 1px solid #e0e0e6;
border-radius: 3px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
text-align: center;
&:focus {
outline: none;
border-color: #ff7bac;
}
} }
</style> </style>

View File

@ -99,93 +99,40 @@
<!-- 分页器 --> <!-- 分页器 -->
<div class="pagination-container" v-if="state.total > 0"> <div class="pagination-container" v-if="state.total > 0">
<div class="pagination-info"> <div class="pagination-info text-[#455363] mr-[15PX]">
Displaying {{ displayRange.start }} - {{ displayRange.end }} of {{ t("financialinformation.quarterlyreports.pagination.displaying", {
{{ state.total }} results start: (state.currentPage - 1) * state.pageSize + 1,
end: Math.min(state.currentPage * state.pageSize, state.total),
total: state.total,
}) }}
</div> </div>
<div class="pagination-controls"> <NPagination
<div class="pagination-buttons"> v-model:page="state.currentPage"
<button v-model:page-size="state.pageSize"
class="page-btn-prev prev-btn" show-size-picker
:disabled="state.currentPage === 1" show-quick-jumper
@click="goToPrevPage" :item-count="state.total"
:page-sizes="[
{
label: t('historic_stock.pagination.perPage', { size: 10 }),
value: 10,
},
{
label: t('historic_stock.pagination.perPage', { size: 25 }),
value: 25,
},
{
label: t('historic_stock.pagination.perPage', { size: 50 }),
value: 50,
},
]"
@update:page="getPressReleasesDisplay"
@update:page-size="getPressReleasesDisplay"
> >
<svg width="5" height="9" viewBox="0 0 5 9" fill="none"> <template #goto>{{
<path t("financialinformation.quarterlyreports.pagination.goto")
d="M4 1L1 4.5L4 8" }}</template>
stroke="#455363" </NPagination>
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<template v-for="page in getVisiblePages()" :key="page">
<button
v-if="page !== '...'"
class="page-btn-page"
:class="{ active: page === state.currentPage }"
@click="goToPage(page)"
>
{{ page }}
</button>
<button v-else class="page-btn-page disabled" disabled>
...
</button>
</template>
<button
class="page-btn-next next-btn"
:disabled="state.currentPage === totalPages"
@click="goToNextPage"
>
<svg width="5" height="9" viewBox="0 0 5 9" fill="none">
<path
d="M1 1L4 5L1 8"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="page-size-selector" @click="togglePageSizeMenu">
<span>{{ state.pageSize }}/page</span>
<svg width="10" height="5" viewBox="0 0 10 5" fill="none">
<path
d="M1 1L5 4L9 1"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<div v-if="showPageSizeMenu" class="page-size-menu">
<div
v-for="size in [10, 20, 50]"
:key="size"
class="page-size-option"
:class="{ active: state.pageSize === size }"
@click="changePageSize(size)"
>
{{ size }}/page
</div>
</div>
</div>
<div class="goto-section">
<span>Goto</span>
<input
type="number"
v-model="state.gotoPage"
class="goto-input"
:min="1"
:max="totalPages"
@keyup.enter="handleGoto"
/>
</div>
</div>
</div> </div>
</main> </main>
</div> </div>
@ -203,13 +150,13 @@ import {
computed, computed,
onUnmounted, onUnmounted,
} from "vue"; } from "vue";
import { NTooltip } from "naive-ui"; import { NTooltip, NPagination } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import axios from "axios"; import axios from "axios";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t, locale } = useI18n();
const state = reactive({ const state = reactive({
selectedValue: "all_years", // selectedValue: "all_years", //
@ -229,11 +176,8 @@ const state = reactive({
currentPage: 1, // currentPage: 1, //
pageSize: 10, pageSize: 10,
total: 0, total: 0,
gotoPage: 1,
}); });
const showPageSizeMenu = ref(false);
const titleRefs = ref([]); const titleRefs = ref([]);
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
@ -254,17 +198,12 @@ const checkAllTitleOverflow = () => {
onMounted(() => { onMounted(() => {
getPressReleasesDisplay(); getPressReleasesDisplay();
document.addEventListener("click", handleClickOutside);
nextTick(() => { nextTick(() => {
checkAllTitleOverflow(); checkAllTitleOverflow();
}); });
}); });
onUnmounted(() => {
document.removeEventListener("click", handleClickOutside);
});
watch( watch(
() => state.filterNewsData, () => state.filterNewsData,
() => { () => {
@ -275,6 +214,13 @@ watch(
{ deep: true } { deep: true }
); );
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
state.loading = true; state.loading = true;
@ -288,6 +234,7 @@ const getPressReleasesDisplay = () => {
? null ? null
: new Date(state.selectedValue).getTime() : new Date(state.selectedValue).getTime()
: null, : null,
langType: map[locale.value],
}; };
axios axios
.post(url, params) .post(url, params)
@ -295,7 +242,7 @@ const getPressReleasesDisplay = () => {
if (res.status === 200) { if (res.status === 200) {
if (res.data.status === 0) { if (res.data.status === 0) {
res.data.data?.data?.forEach((item) => { res.data.data?.data?.forEach((item) => {
item.date = new Date(item.createdAt).toLocaleDateString("en-US", { item.date = new Date(item.date).toLocaleDateString("en-US", {
month: "short", month: "short",
day: "numeric", day: "numeric",
year: "numeric", year: "numeric",
@ -311,6 +258,12 @@ const getPressReleasesDisplay = () => {
}); });
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getPressReleasesDisplay();
});
// watcher // watcher
watch( watch(
() => [state.selectedValue, state.inputValue], () => [state.selectedValue, state.inputValue],
@ -331,7 +284,6 @@ watch(
watch( watch(
() => state.currentPage, () => state.currentPage,
(newPage) => { (newPage) => {
state.gotoPage = newPage;
getPressReleasesDisplay(); getPressReleasesDisplay();
} }
); );
@ -345,97 +297,10 @@ const handleNewClick = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };
const totalPages = computed(() => {
return Math.ceil(state.total / state.pageSize) || 1;
});
const displayRange = computed(() => {
if (state.total === 0) return { start: 0, end: 0 };
const start = (state.currentPage - 1) * state.pageSize + 1;
const end = Math.min(state.currentPage * state.pageSize, state.total);
return { start, end };
});
const goToPage = (page) => {
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const goToPrevPage = () => {
if (state.currentPage > 1) {
state.currentPage--;
}
};
const goToNextPage = () => {
if (state.currentPage < totalPages.value) {
state.currentPage++;
}
};
const changePageSize = (size) => {
state.pageSize = size;
};
const handleGoto = () => {
const page = parseInt(state.gotoPage);
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const togglePageSizeMenu = () => {
showPageSizeMenu.value = !showPageSizeMenu.value;
};
const getVisiblePages = () => {
const current = state.currentPage;
const total = totalPages.value;
const pages = [];
if (total <= 7) {
for (let i = 1; i <= total; i++) {
pages.push(i);
}
} else {
pages.push(1);
if (current <= 4) {
for (let i = 2; i <= 5; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
} else if (current >= total - 3) {
pages.push("...");
for (let i = total - 4; i <= total; i++) {
pages.push(i);
}
} else {
pages.push("...");
for (let i = current - 1; i <= current + 1; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
}
}
return pages;
};
//
const handleClickOutside = (event) => {
if (!event.target.closest || !event.target.closest(".page-size-selector")) {
showPageSizeMenu.value = false;
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -637,8 +502,8 @@ const handleClickOutside = (event) => {
.pagination-container { .pagination-container {
display: flex; display: flex;
align-items: center; align-items: center;
margin-top: 20px; justify-content: center;
justify-content: flex-end; margin-top: 15px;
margin-bottom: 30px; margin-bottom: 30px;
gap: 21px; gap: 21px;
} }
@ -652,179 +517,7 @@ const handleClickOutside = (event) => {
text-align: right; text-align: right;
} }
.pagination-controls { :deep(.n-base-loading__icon) {
display: flex;
align-items: center;
gap: 8px;
}
.pagination-buttons {
display: flex;
align-items: center;
gap: 8px;
}
.page-btn-prev,
.page-btn-next {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: 1px solid #e0e0e6;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac; color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
background: #fff0f5;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-btn-page {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
border: none;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
border: 1px solid #e0e0e6;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-size-selector {
position: relative;
display: flex;
align-items: center;
gap: 18px;
padding: 4px 12px;
height: 28px;
border: 1px solid #e0e0e6;
border-radius: 3px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
&:hover {
border-color: #ff7bac;
}
}
.page-size-menu {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background: #ffffff;
border: 1px solid #e0e0e6;
border-radius: 3px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-bottom: 2px;
}
.page-size-option {
padding: 8px 12px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background: #fff0f5;
}
&.active {
background: #fff0f5;
color: #ff7bac;
}
}
.goto-section {
display: flex;
align-items: center;
gap: 8px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
margin-right: 16px;
}
.goto-input {
width: 60px;
height: 28px;
padding: 4px 12px;
border: 1px solid #e0e0e6;
border-radius: 3px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14px;
line-height: 1.428em;
color: #455363;
text-align: center;
&:focus {
outline: none;
border-color: #ff7bac;
}
} }
</style> </style>

View File

@ -1,32 +1,18 @@
<template> <template>
<div class="press-releases-page"> <div class="press-releases-page">
<main class="mx-auto">
<div class="title-section"> <div class="title-section">
<div class="title-decoration"></div> <div class="title-decoration"></div>
<div class="title"> <div class="title mb-[20px]">
{{ t("press_releases.title") }} {{ t("press_releases.title") }}
</div> </div>
</div> </div>
<div class="search-container"> <div class="search-container">
<div class="search-select" @click="openYearPicker"> <custom-select
<div class="search-select-label">Year</div> :options="state.selectOptions"
<div class="search-select-icon"> v-model="state.selectedValue"
<span class="selected-year-label">{{ selectedYearLabel }}</span> class="search-select"
<svg
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
viewBox="0 0 10 10"
fill="none"
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M2.58882 9.69047C2.38633 9.48798 2.36383 9.17365 2.52132 8.9463L2.58882 8.86552L6.45447 5.00022L2.58882 1.13492C2.38633 0.932428 2.36383 0.618098 2.52132 0.390748L2.58882 0.309958C2.79132 0.107469 3.10565 0.0849685 3.33299 0.242458L3.41378 0.309958L7.69156 4.58774C7.89405 4.79023 7.91655 5.10456 7.75906 5.33191L7.69156 5.4127L3.41378 9.69047C3.18597 9.91828 2.81663 9.91828 2.58882 9.69047Z"
fill="black"
/> />
</svg>
</div>
</div>
<input <input
v-model="state.inputValue" v-model="state.inputValue"
type="text" type="text"
@ -88,8 +74,8 @@
style=" style="
word-break: break-all; word-break: break-all;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 1;
line-clamp: 2; line-clamp: 1;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -112,95 +98,49 @@
</div> </div>
<!-- 分页器 --> <!-- 分页器 -->
<div class="pagination-container" v-if="state.total > 0"> <div class="pagination-container" style="flex-direction: column;" v-if="state.total > 0">
<div class="pagination-controls"> <div class="pagination-info text-[#455363] mr-[15PX]">
<div class="pagination-buttons"> {{ t("financialinformation.quarterlyreports.pagination.displaying", {
<button start: (state.currentPage - 1) * state.pageSize + 1,
class="page-btn-prev prev-btn" end: Math.min(state.currentPage * state.pageSize, state.total),
:disabled="state.currentPage === 1" total: state.total,
@click="goToPrevPage" }) }}
</div>
<NPagination
v-model:page="state.currentPage"
v-model:page-size="state.pageSize"
show-size-picker
show-quick-jumper
:item-count="state.total"
:page-sizes="[
{
label: t('historic_stock.pagination.perPage', { size: 10 }),
value: 10,
},
{
label: t('historic_stock.pagination.perPage', { size: 25 }),
value: 25,
},
{
label: t('historic_stock.pagination.perPage', { size: 50 }),
value: 50,
},
]"
@update:page="getPressReleasesDisplay"
@update:page-size="getPressReleasesDisplay"
> >
<svg width="5" height="9" viewBox="0 0 5 9" fill="none"> <template #goto>{{
<path t("financialinformation.quarterlyreports.pagination.goto")
d="M4 1L1 4.5L4 8" }}</template>
stroke="#455363" </NPagination>
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<template v-for="page in getVisiblePages()" :key="page">
<button
v-if="page !== '...'"
class="page-btn-page"
:class="{ active: page === state.currentPage }"
@click="goToPage(page)"
>
{{ page }}
</button>
<button v-else class="page-btn-page disabled" disabled>...</button>
</template>
<button
class="page-btn-next next-btn"
:disabled="state.currentPage === totalPages"
@click="goToNextPage"
>
<svg width="5" height="9" viewBox="0 0 5 9" fill="none">
<path
d="M1 1L4 5L1 8"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div> </div>
<div class="page-size-selector" @click="togglePageSizeMenu"> </main>
<span>{{ state.pageSize }}/page</span>
<svg width="10" height="5" viewBox="0 0 10 5" fill="none">
<path
d="M1 1L5 4L9 1"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<div v-if="showPageSizeMenu" class="page-size-menu">
<div
v-for="size in [10, 20, 50]"
:key="size"
class="page-size-option"
:class="{ active: state.pageSize === size }"
@click="changePageSize(size)"
>
{{ size }}/page
</div> </div>
</div>
</div>
</div>
</div>
<div class="pagination-info" v-if="state.total > 0">
Displaying {{ displayRange.start }} - {{ displayRange.end }} of
{{ state.total }} results
</div>
</div>
<year-wheel-picker
v-if="state.showYearPicker"
v-model="state.selectedValue"
:options="state.selectOptions"
@close="closeYearPicker"
@confirm="onYearConfirm"
></year-wheel-picker>
</template> </template>
<script setup> <script setup>
import customDefaultPage from "@/components/customDefaultPage/index.vue"; import customDefaultPage from "@/components/customDefaultPage/index.vue";
import YearWheelPicker from "@/components/YearWheelPicker.vue"; import customSelect from "@/components/customSelect/index.vue";
import { import {
reactive, reactive,
onMounted, onMounted,
@ -208,15 +148,14 @@ import {
nextTick, nextTick,
ref, ref,
computed, computed,
onUnmounted,
} from "vue"; } from "vue";
import { NInput, NButton, NTooltip } from "naive-ui"; import { NTooltip, NPagination } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import axios from "axios"; import axios from "axios";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t, locale } = useI18n();
const state = reactive({ const state = reactive({
selectedValue: "all_years", // selectedValue: "all_years", //
@ -236,12 +175,9 @@ const state = reactive({
currentPage: 1, // currentPage: 1, //
pageSize: 10, pageSize: 10,
total: 0, total: 0,
gotoPage: 1,
showYearPicker: false, showYearPicker: false,
}); });
const showPageSizeMenu = ref(false);
const titleRefs = ref([]); const titleRefs = ref([]);
const selectedYearLabel = computed(() => { const selectedYearLabel = computed(() => {
@ -282,17 +218,12 @@ const checkAllTitleOverflow = () => {
onMounted(() => { onMounted(() => {
getPressReleasesDisplay(); getPressReleasesDisplay();
document.addEventListener("click", handleClickOutside);
nextTick(() => { nextTick(() => {
checkAllTitleOverflow(); checkAllTitleOverflow();
}); });
}); });
onUnmounted(() => {
document.removeEventListener("click", handleClickOutside);
});
watch( watch(
() => state.filterNewsData, () => state.filterNewsData,
() => { () => {
@ -303,6 +234,13 @@ watch(
{ deep: true } { deep: true }
); );
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
state.loading = true; state.loading = true;
@ -316,6 +254,7 @@ const getPressReleasesDisplay = () => {
? null ? null
: new Date(state.selectedValue).getTime() : new Date(state.selectedValue).getTime()
: null, : null,
langType: map[locale.value],
}; };
axios axios
.post(url, params) .post(url, params)
@ -339,6 +278,12 @@ const getPressReleasesDisplay = () => {
}); });
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getPressReleasesDisplay();
});
// watcher // watcher
watch( watch(
() => [state.selectedValue, state.inputValue], () => [state.selectedValue, state.inputValue],
@ -359,7 +304,6 @@ watch(
watch( watch(
() => state.currentPage, () => state.currentPage,
(newPage) => { (newPage) => {
state.gotoPage = newPage;
getPressReleasesDisplay(); getPressReleasesDisplay();
} }
); );
@ -373,73 +317,10 @@ const handleNewClick = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };
const totalPages = computed(() => {
return Math.ceil(state.total / state.pageSize) || 1;
});
const displayRange = computed(() => {
if (state.total === 0) return { start: 0, end: 0 };
const start = (state.currentPage - 1) * state.pageSize + 1;
const end = Math.min(state.currentPage * state.pageSize, state.total);
return { start, end };
});
const goToPage = (page) => {
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const goToPrevPage = () => {
if (state.currentPage > 1) {
state.currentPage--;
}
};
const goToNextPage = () => {
if (state.currentPage < totalPages.value) {
state.currentPage++;
}
};
const changePageSize = (size) => {
state.pageSize = size;
};
const handleGoto = () => {
const page = parseInt(state.gotoPage);
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const togglePageSizeMenu = () => {
showPageSizeMenu.value = !showPageSizeMenu.value;
};
const getVisiblePages = () => {
const total = totalPages.value;
if (total <= 4) {
const pages = [];
for (let i = 1; i <= total; i++) {
pages.push(i);
}
return pages;
}
return [1, 2, "...", total];
};
//
const handleClickOutside = (event) => {
if (!event.target.closest || !event.target.closest(".page-size-selector")) {
showPageSizeMenu.value = false;
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@ -512,26 +393,6 @@ const handleClickOutside = (event) => {
} }
} }
:deep(.n-input) {
.n-input__input {
padding: 4 * 5.12px 0;
// border: 1*5.12px solid #ccc;
border-radius: 4 * 5.12px;
}
}
:deep(.n-select) {
.n-select__input {
padding: 8 * 5.12px 12 * 5.12px;
border: 1 * 5.12px solid #ccc;
border-radius: 4 * 5.12px;
}
}
:deep(.n-button) {
padding: 20 * 5.12px 16 * 5.12px;
border-radius: 4 * 5.12px;
}
.search-button { .search-button {
width: 104 * 5.12px; width: 104 * 5.12px;
height: 34 * 5.12px; height: 34 * 5.12px;
@ -542,7 +403,7 @@ const handleClickOutside = (event) => {
border-radius: 3 * 5.12px; border-radius: 3 * 5.12px;
cursor: pointer; cursor: pointer;
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 400; font-weight: 500;
font-size: 14 * 5.12px; font-size: 14 * 5.12px;
line-height: 1.375em; line-height: 1.375em;
letter-spacing: 0.48 * 5.12px; letter-spacing: 0.48 * 5.12px;
@ -557,8 +418,6 @@ const handleClickOutside = (event) => {
flex-direction: column; flex-direction: column;
gap: 4 * 5.12px; gap: 4 * 5.12px;
background: #fff; background: #fff;
width: 100%;
margin-top: 40 * 5.12px;
} }
.table-row { .table-row {
@ -566,12 +425,6 @@ const handleClickOutside = (event) => {
flex-direction: column; flex-direction: column;
position: relative; position: relative;
border-radius: 8 * 5.12px; border-radius: 8 * 5.12px;
// &:last-child {
// .separator-line {
// display: none;
// }
// }
} }
.content { .content {
@ -587,6 +440,7 @@ const handleClickOutside = (event) => {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 0; gap: 0;
padding: 0 16 * 5.12px;
&:hover { &:hover {
background: #fff8fb; background: #fff8fb;
} }
@ -597,6 +451,7 @@ const handleClickOutside = (event) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
padding-right: 16 * 5.12px;
} }
.file-info { .file-info {
@ -607,6 +462,13 @@ const handleClickOutside = (event) => {
flex: 1; flex: 1;
} }
.vertical-line {
width: 1 * 5.12px;
height: 20 * 5.12px;
background: #ff7bac;
flex-shrink: 0;
}
.news-item-title { .news-item-title {
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 500; font-weight: 500;
@ -616,30 +478,31 @@ const handleClickOutside = (event) => {
color: #000000; color: #000000;
} }
.arrow-icon { .news-item-content {
margin-right: 16 * 5.12px;
flex-shrink: 0;
cursor: pointer;
}
.vertical-line {
width: 1 * 5.12px;
height: 20 * 5.12px;
background: #ff7bac;
flex-shrink: 0;
}
.file-description {
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 400; font-weight: 400;
font-size: 14 * 5.12px; font-size: 14 * 5.12px;
line-height: 1.375em; line-height: 1.375em;
letter-spacing: 0.48 * 5.12px; letter-spacing: 0.48 * 5.12px;
color: #455363; color: #455363;
margin: 8 * 5.12px 0; margin-top: 4 * 5.12px;
padding: 0 16 * 5.12px; padding: 0 16 * 5.12px;
} }
.arrow-icon {
margin-left: auto;
flex-shrink: 0;
cursor: pointer;
}
.download-section {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 4 * 5.12px 16 * 5.12px;
}
.news-item-date { .news-item-date {
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 400; font-weight: 400;
@ -649,24 +512,15 @@ const handleClickOutside = (event) => {
color: #455363; color: #455363;
} }
.download-section {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 0 16 * 5.12px;
margin-bottom: 8 * 5.12px;
}
.separator-line { .separator-line {
width: 100%; width: 100%;
height: 1 * 5.12px; height: 1 * 5.12px;
background: repeating-linear-gradient( background: repeating-linear-gradient(
to right, to right,
#e6eaee 0 * 5.12px, #e6eaee 0px,
#e6eaee 2 * 5.12px, #e6eaee 4 * 5.12px,
transparent 2 * 5.12px, transparent 4 * 5.12px,
transparent 4 * 5.12px transparent 8 * 5.12px
); );
margin-top: 16 * 5.12px; margin-top: 16 * 5.12px;
} }
@ -675,11 +529,10 @@ const handleClickOutside = (event) => {
.pagination-container { .pagination-container {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 16 * 5.12px 0; justify-content: center;
justify-content: flex-end; margin-top: 15 * 5.12px;
padding: 0 16 * 5.12px; margin-bottom: 30 * 5.12px;
flex-wrap: wrap; gap: 21 * 5.12px;
gap: 16 * 5.12px;
} }
.pagination-info { .pagination-info {
@ -689,201 +542,9 @@ const handleClickOutside = (event) => {
line-height: 1.4375em; line-height: 1.4375em;
color: #455363; color: #455363;
text-align: right; text-align: right;
margin-bottom: 30 * 5.12px;
padding: 0 16 * 5.12px;
width: 100%;
} }
.pagination-controls { :deep(.n-base-loading__icon) {
display: flex;
align-items: center;
gap: 8 * 5.12px;
flex-wrap: wrap;
justify-content: flex-end;
}
.pagination-buttons {
display: flex;
align-items: center;
gap: 8 * 5.12px;
}
.page-btn-prev,
.page-btn-next {
display: flex;
align-items: center;
justify-content: center;
width: 28 * 5.12px;
height: 28 * 5.12px;
border: 1 * 5.12px solid #e0e0e6;
border-radius: 3 * 5.12px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac; color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
background: #fff0f5;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-btn-page {
display: flex;
align-items: center;
justify-content: center;
width: 28 * 5.12px;
height: 28 * 5.12px;
border-radius: 3 * 5.12px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
border: none;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
border: 1 * 5.12px solid #e0e0e6;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-size-selector {
position: relative;
display: flex;
align-items: center;
gap: 18 * 5.12px;
padding: 4 * 5.12px 12 * 5.12px;
height: 28 * 5.12px;
border: 1 * 5.12px solid #e0e0e6;
border-radius: 3 * 5.12px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
&:hover {
border-color: #ff7bac;
}
}
.page-size-menu {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background: #ffffff;
border: 1 * 5.12px solid #e0e0e6;
border-radius: 3 * 5.12px;
box-shadow: 0 2 * 5.12px 8 * 5.12px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-bottom: 2 * 5.12px;
}
.page-size-option {
padding: 8 * 5.12px 12 * 5.12px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background: #fff0f5;
}
&.active {
background: #fff0f5;
color: #ff7bac;
}
}
.goto-section {
display: flex;
align-items: center;
gap: 8 * 5.12px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
}
.goto-input {
width: 60 * 5.12px;
height: 28 * 5.12px;
padding: 4 * 5.12px 12 * 5.12px;
border: 1 * 5.12px solid #e0e0e6;
border-radius: 3 * 5.12px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #455363;
text-align: center;
&:focus {
outline: none;
border-color: #ff7bac;
}
}
.selected-year-label {
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #000;
margin-right: 16 * 5.12px;
}
.search-select-label {
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 5.12px;
line-height: 1.428em;
color: #000;
} }
</style> </style>

View File

@ -3,7 +3,7 @@
<main class="mx-auto"> <main class="mx-auto">
<div class="title-section"> <div class="title-section">
<div class="title-decoration"></div> <div class="title-decoration"></div>
<div class="title"> <div class="title mb-[20px]">
{{ t("press_releases.title") }} {{ t("press_releases.title") }}
</div> </div>
</div> </div>
@ -74,8 +74,8 @@
style=" style="
word-break: break-all; word-break: break-all;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 1;
line-clamp: 2; line-clamp: 1;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@ -99,93 +99,40 @@
<!-- 分页器 --> <!-- 分页器 -->
<div class="pagination-container" v-if="state.total > 0"> <div class="pagination-container" v-if="state.total > 0">
<div class="pagination-controls"> <div class="pagination-info text-[#455363] mr-[15PX]">
<div class="pagination-buttons"> {{ t("financialinformation.quarterlyreports.pagination.displaying", {
<button start: (state.currentPage - 1) * state.pageSize + 1,
class="page-btn-prev prev-btn" end: Math.min(state.currentPage * state.pageSize, state.total),
:disabled="state.currentPage === 1" total: state.total,
@click="goToPrevPage" }) }}
</div>
<NPagination
v-model:page="state.currentPage"
v-model:page-size="state.pageSize"
show-size-picker
show-quick-jumper
:item-count="state.total"
:page-sizes="[
{
label: t('historic_stock.pagination.perPage', { size: 10 }),
value: 10,
},
{
label: t('historic_stock.pagination.perPage', { size: 25 }),
value: 25,
},
{
label: t('historic_stock.pagination.perPage', { size: 50 }),
value: 50,
},
]"
@update:page="getPressReleasesDisplay"
@update:page-size="getPressReleasesDisplay"
> >
<svg width="5" height="9" viewBox="0 0 5 9" fill="none"> <template #goto>{{
<path t("financialinformation.quarterlyreports.pagination.goto")
d="M4 1L1 4.5L4 8" }}</template>
stroke="#455363" </NPagination>
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<template v-for="page in getVisiblePages()" :key="page">
<button
v-if="page !== '...'"
class="page-btn-page"
:class="{ active: page === state.currentPage }"
@click="goToPage(page)"
>
{{ page }}
</button>
<button v-else class="page-btn-page disabled" disabled>
...
</button>
</template>
<button
class="page-btn-next next-btn"
:disabled="state.currentPage === totalPages"
@click="goToNextPage"
>
<svg width="5" height="9" viewBox="0 0 5 9" fill="none">
<path
d="M1 1L4 5L1 8"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</div>
<div class="page-size-selector" @click="togglePageSizeMenu">
<span>{{ state.pageSize }}/page</span>
<svg width="10" height="5" viewBox="0 0 10 5" fill="none">
<path
d="M1 1L5 4L9 1"
stroke="#455363"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<div v-if="showPageSizeMenu" class="page-size-menu">
<div
v-for="size in [10, 20, 50]"
:key="size"
class="page-size-option"
:class="{ active: state.pageSize === size }"
@click="changePageSize(size)"
>
{{ size }}/page
</div>
</div>
</div>
<div class="goto-section">
<span>Goto</span>
<input
type="number"
v-model="state.gotoPage"
class="goto-input"
:min="1"
:max="totalPages"
@keyup.enter="handleGoto"
/>
</div>
</div>
</div>
<div class="pagination-info" v-if="state.total > 0">
Displaying {{ displayRange.start }} - {{ displayRange.end }} of
{{ state.total }} results
</div> </div>
</main> </main>
</div> </div>
@ -201,15 +148,14 @@ import {
nextTick, nextTick,
ref, ref,
computed, computed,
onUnmounted,
} from "vue"; } from "vue";
import { NTooltip } from "naive-ui"; import { NTooltip, NPagination } from "naive-ui";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import axios from "axios"; import axios from "axios";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t, locale } = useI18n();
const state = reactive({ const state = reactive({
selectedValue: "all_years", // selectedValue: "all_years", //
@ -229,13 +175,31 @@ const state = reactive({
currentPage: 1, // currentPage: 1, //
pageSize: 10, pageSize: 10,
total: 0, total: 0,
gotoPage: 1, showYearPicker: false,
}); });
const showPageSizeMenu = ref(false);
const titleRefs = ref([]); const titleRefs = ref([]);
const selectedYearLabel = computed(() => {
const option = state.selectOptions.find(
(opt) => opt.value === state.selectedValue
);
return option ? option.label : "";
});
const openYearPicker = () => {
state.showYearPicker = true;
};
const closeYearPicker = () => {
state.showYearPicker = false;
};
const onYearConfirm = (year) => {
state.selectedValue = year;
closeYearPicker();
};
const setTitleRef = (el, idx) => { const setTitleRef = (el, idx) => {
if (el) titleRefs.value[idx] = el; if (el) titleRefs.value[idx] = el;
}; };
@ -254,17 +218,12 @@ const checkAllTitleOverflow = () => {
onMounted(() => { onMounted(() => {
getPressReleasesDisplay(); getPressReleasesDisplay();
document.addEventListener("click", handleClickOutside);
nextTick(() => { nextTick(() => {
checkAllTitleOverflow(); checkAllTitleOverflow();
}); });
}); });
onUnmounted(() => {
document.removeEventListener("click", handleClickOutside);
});
watch( watch(
() => state.filterNewsData, () => state.filterNewsData,
() => { () => {
@ -275,6 +234,13 @@ watch(
{ deep: true } { deep: true }
); );
const map = {
en: "enUS",
ja: "jaJP",
zh: "zhCN",
"zh-TW": "zhTW",
};
// //
const getPressReleasesDisplay = () => { const getPressReleasesDisplay = () => {
state.loading = true; state.loading = true;
@ -288,6 +254,7 @@ const getPressReleasesDisplay = () => {
? null ? null
: new Date(state.selectedValue).getTime() : new Date(state.selectedValue).getTime()
: null, : null,
langType: map[locale.value],
}; };
axios axios
.post(url, params) .post(url, params)
@ -311,6 +278,12 @@ const getPressReleasesDisplay = () => {
}); });
}; };
watch(locale, (newLocale, oldLocale) => {
//
state.currentPage = 1;
getPressReleasesDisplay();
});
// watcher // watcher
watch( watch(
() => [state.selectedValue, state.inputValue], () => [state.selectedValue, state.inputValue],
@ -331,7 +304,6 @@ watch(
watch( watch(
() => state.currentPage, () => state.currentPage,
(newPage) => { (newPage) => {
state.gotoPage = newPage;
getPressReleasesDisplay(); getPressReleasesDisplay();
} }
); );
@ -345,103 +317,17 @@ const handleNewClick = (item) => {
router.push({ router.push({
path: "/news", path: "/news",
query: { query: {
id: item.id, id: item.uuid,
}, },
}); });
}; };
const totalPages = computed(() => {
return Math.ceil(state.total / state.pageSize) || 1;
});
const displayRange = computed(() => {
if (state.total === 0) return { start: 0, end: 0 };
const start = (state.currentPage - 1) * state.pageSize + 1;
const end = Math.min(state.currentPage * state.pageSize, state.total);
return { start, end };
});
const goToPage = (page) => {
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const goToPrevPage = () => {
if (state.currentPage > 1) {
state.currentPage--;
}
};
const goToNextPage = () => {
if (state.currentPage < totalPages.value) {
state.currentPage++;
}
};
const changePageSize = (size) => {
state.pageSize = size;
};
const handleGoto = () => {
const page = parseInt(state.gotoPage);
if (page >= 1 && page <= totalPages.value) {
state.currentPage = page;
}
};
const togglePageSizeMenu = () => {
showPageSizeMenu.value = !showPageSizeMenu.value;
};
const getVisiblePages = () => {
const current = state.currentPage;
const total = totalPages.value;
const pages = [];
if (total <= 7) {
for (let i = 1; i <= total; i++) {
pages.push(i);
}
} else {
pages.push(1);
if (current <= 4) {
for (let i = 2; i <= 5; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
} else if (current >= total - 3) {
pages.push("...");
for (let i = total - 4; i <= total; i++) {
pages.push(i);
}
} else {
pages.push("...");
for (let i = current - 1; i <= current + 1; i++) {
pages.push(i);
}
pages.push("...");
pages.push(total);
}
}
return pages;
};
//
const handleClickOutside = (event) => {
if (!event.target.closest || !event.target.closest(".page-size-selector")) {
showPageSizeMenu.value = false;
}
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.press-releases-page { .press-releases-page {
width: 650 * 2.5px; width: 650 * 2.5px;
margin: 0 auto; margin: 0 auto;
background: #fff;
} }
.title-section { .title-section {
display: flex; display: flex;
@ -453,7 +339,6 @@ const handleClickOutside = (event) => {
width: 58 * 2.5px; width: 58 * 2.5px;
height: 7 * 2.5px; height: 7 * 2.5px;
background: #ff7bac; background: #ff7bac;
margin: auto 0;
margin-top: 43 * 2.5px; margin-top: 43 * 2.5px;
} }
.title { .title {
@ -462,21 +347,36 @@ const handleClickOutside = (event) => {
} }
.search-container { .search-container {
margin-top: 32 * 2.5px;
margin-bottom: 20 * 2.5px; margin-bottom: 20 * 2.5px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: space-between;
flex-flow: wrap;
gap: 16 * 2.5px; gap: 16 * 2.5px;
padding: 0 16 * 2.5px; padding: 0 16 * 2.5px;
} }
.search-select { .search-select {
width: 134 * 2.5px; width: 201 * 2.5px;
height: 34 * 2.5px;
padding: 0 12 * 2.5px;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
color: #455363;
}
.search-select-icon {
display: flex;
align-items: center;
} }
.search-input { .search-input {
width: 292 * 2.5px; width: 401 * 2.5px;
height: 34 * 2.5px; height: 34 * 2.5px;
padding: 7 * 2.5px 12 * 2.5px; padding: 7 * 2.5px 12 * 2.5px;
border: 1 * 2.5px solid #e0e0e6; border: 1 * 2.5px solid #e0e0e6;
@ -487,7 +387,6 @@ const handleClickOutside = (event) => {
line-height: 1.375em; line-height: 1.375em;
letter-spacing: 0.48 * 2.5px; letter-spacing: 0.48 * 2.5px;
color: #455363; color: #455363;
box-sizing: border-box;
&::placeholder { &::placeholder {
color: #b6b6b6; color: #b6b6b6;
@ -495,20 +394,19 @@ const handleClickOutside = (event) => {
} }
.search-button { .search-button {
width: 201 * 2.5px;
height: 34 * 2.5px; height: 34 * 2.5px;
padding: 7 * 2.5px 12 * 2.5px; padding: 7 * 2.5px 12 * 2.5px;
min-width: 160 * 2.5px;
background: #ff7bac; background: #ff7bac;
color: #fff; color: #fff;
border: none; border: none;
border-radius: 3 * 2.5px; border-radius: 3 * 2.5px;
cursor: pointer; cursor: pointer;
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 400; font-weight: 500;
font-size: 14 * 2.5px; font-size: 14 * 2.5px;
line-height: 1.375em; line-height: 1.375em;
letter-spacing: 0.48 * 2.5px; letter-spacing: 0.48 * 2.5px;
box-sizing: border-box;
&:hover { &:hover {
background: #ff7bac; background: #ff7bac;
color: #fff; color: #fff;
@ -520,7 +418,6 @@ const handleClickOutside = (event) => {
flex-direction: column; flex-direction: column;
gap: 4 * 2.5px; gap: 4 * 2.5px;
background: #fff; background: #fff;
width: 650 * 2.5px;
} }
.table-row { .table-row {
@ -528,12 +425,6 @@ const handleClickOutside = (event) => {
flex-direction: column; flex-direction: column;
position: relative; position: relative;
border-radius: 8 * 2.5px; border-radius: 8 * 2.5px;
// &:last-child {
// .separator-line {
// display: none;
// }
// }
} }
.content { .content {
@ -549,6 +440,7 @@ const handleClickOutside = (event) => {
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 0; gap: 0;
padding: 0 16 * 2.5px;
&:hover { &:hover {
background: #fff8fb; background: #fff8fb;
} }
@ -570,6 +462,13 @@ const handleClickOutside = (event) => {
flex: 1; flex: 1;
} }
.vertical-line {
width: 1 * 2.5px;
height: 20 * 2.5px;
background: #ff7bac;
flex-shrink: 0;
}
.news-item-title { .news-item-title {
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 500; font-weight: 500;
@ -579,29 +478,29 @@ const handleClickOutside = (event) => {
color: #000000; color: #000000;
} }
.arrow-icon { .news-item-content {
margin-left: auto;
flex-shrink: 0;
cursor: pointer;
}
.vertical-line {
width: 1 * 2.5px;
height: 20 * 2.5px;
background: #ff7bac;
flex-shrink: 0;
}
.file-description {
font-family: "PingFang SC", sans-serif; font-family: "PingFang SC", sans-serif;
font-weight: 400; font-weight: 400;
font-size: 14 * 2.5px; font-size: 14 * 2.5px;
line-height: 1.375em; line-height: 1.375em;
letter-spacing: 0.48 * 2.5px; letter-spacing: 0.48 * 2.5px;
color: #455363; color: #455363;
margin: 0; margin-top: 4 * 2.5px;
padding: 0 16 * 2.5px; padding: 0 16 * 2.5px;
margin-top: 8 * 2.5px; }
.arrow-icon {
margin-left: auto;
flex-shrink: 0;
cursor: pointer;
}
.download-section {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 4 * 2.5px 16 * 2.5px;
} }
.news-item-date { .news-item-date {
@ -613,23 +512,15 @@ const handleClickOutside = (event) => {
color: #455363; color: #455363;
} }
.download-section {
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
padding: 4 * 2.5px 16 * 2.5px;
}
.separator-line { .separator-line {
width: 100%; width: 100%;
height: 1 * 2.5px; height: 1 * 2.5px;
background: repeating-linear-gradient( background: repeating-linear-gradient(
to right, to right,
#e6eaee 0 * 2.5px, #e6eaee 0px,
#e6eaee 2 * 2.5px, #e6eaee 4 * 2.5px,
transparent 2 * 2.5px, transparent 4 * 2.5px,
transparent 4 * 2.5px transparent 8 * 2.5px
); );
margin-top: 16 * 2.5px; margin-top: 16 * 2.5px;
} }
@ -638,9 +529,10 @@ const handleClickOutside = (event) => {
.pagination-container { .pagination-container {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 20 * 2.5px 0; justify-content: center;
justify-content: flex-end; margin-top: 15 * 2.5px;
padding: 0 16 * 2.5px; margin-bottom: 30 * 2.5px;
gap: 21 * 2.5px;
} }
.pagination-info { .pagination-info {
@ -650,182 +542,9 @@ const handleClickOutside = (event) => {
line-height: 1.4375em; line-height: 1.4375em;
color: #455363; color: #455363;
text-align: right; text-align: right;
margin-bottom: 30 * 2.5px;
padding: 0 16 * 2.5px;
} }
.pagination-controls { :deep(.n-base-loading__icon) {
display: flex;
align-items: center;
gap: 8 * 2.5px;
}
.pagination-buttons {
display: flex;
align-items: center;
gap: 8 * 2.5px;
}
.page-btn-prev,
.page-btn-next {
display: flex;
align-items: center;
justify-content: center;
width: 28 * 2.5px;
height: 28 * 2.5px;
border: 1 * 2.5px solid #e0e0e6;
border-radius: 3 * 2.5px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac; color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
background: #fff0f5;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-btn-page {
display: flex;
align-items: center;
justify-content: center;
width: 28 * 2.5px;
height: 28 * 2.5px;
border-radius: 3 * 2.5px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: all 0.2s ease;
border: none;
&:hover:not(:disabled) {
border-color: #ff7bac;
color: #ff7bac;
}
&.active {
border-color: #ff7bac;
color: #ff7bac;
border: 1 * 2.5px solid #e0e0e6;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
&.disabled {
cursor: not-allowed;
opacity: 0.5;
}
}
.page-size-selector {
position: relative;
display: flex;
align-items: center;
gap: 18 * 2.5px;
padding: 4 * 2.5px 12 * 2.5px;
height: 28 * 2.5px;
border: 1 * 2.5px solid #e0e0e6;
border-radius: 3 * 2.5px;
background: #ffffff;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
&:hover {
border-color: #ff7bac;
}
}
.page-size-menu {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
background: #ffffff;
border: 1 * 2.5px solid #e0e0e6;
border-radius: 3 * 2.5px;
box-shadow: 0 2 * 2.5px 8 * 2.5px rgba(0, 0, 0, 0.1);
z-index: 1000;
margin-bottom: 2 * 2.5px;
}
.page-size-option {
padding: 8 * 2.5px 12 * 2.5px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background: #fff0f5;
}
&.active {
background: #fff0f5;
color: #ff7bac;
}
}
.goto-section {
display: flex;
align-items: center;
gap: 8 * 2.5px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
}
.goto-input {
width: 60 * 2.5px;
height: 28 * 2.5px;
padding: 4 * 2.5px 12 * 2.5px;
border: 1 * 2.5px solid #e0e0e6;
border-radius: 3 * 2.5px;
font-family: "PingFang SC", sans-serif;
font-weight: 400;
font-size: 14 * 2.5px;
line-height: 1.428em;
color: #455363;
text-align: center;
&:focus {
outline: none;
border-color: #ff7bac;
}
} }
</style> </style>

View File

@ -37,9 +37,7 @@ const trimTrailingLetter = (val) => {
stockQuote.change stockQuote.change
? String(stockQuote.change).includes('-') ? String(stockQuote.change).includes('-')
? 'negative-change' ? 'negative-change'
: String(stockQuote.change).includes('+') : 'positive-change'
? 'positive-change'
: 'neutral-change'
: 'neutral-change' : 'neutral-change'
" "
> >

View File

@ -38,9 +38,7 @@ const trimTrailingLetter = (val) => {
stockQuote.change stockQuote.change
? String(stockQuote.change).includes('-') ? String(stockQuote.change).includes('-')
? 'negative-change' ? 'negative-change'
: String(stockQuote.change).includes('+') : 'positive-change'
? 'positive-change'
: 'neutral-change'
: 'neutral-change' : 'neutral-change'
" "
> >

View File

@ -51,7 +51,7 @@ const trimTrailingLetter = (val) => {
class="detail-value" class="detail-value"
:class="{ :class="{
'text-red': String(stockQuote.change).includes('-'), 'text-red': String(stockQuote.change).includes('-'),
'text-green': String(stockQuote.change).includes('+'), '!text-green': !String(stockQuote.change).includes('-'),
}" }"
> >
{{ stockQuote.change }} {{ stockQuote.change }}

View File

@ -50,7 +50,7 @@ const trimTrailingLetter = (val) => {
class="detail-value" class="detail-value"
:class="{ :class="{
'text-red': String(stockQuote.change).includes('-'), 'text-red': String(stockQuote.change).includes('-'),
'text-green': String(stockQuote.change).includes('+'), '!text-green': !String(stockQuote.change).includes('-'),
}" }"
> >
{{ stockQuote.change }} {{ stockQuote.change }}