Compare commits
11 Commits
885e95dba0
...
ec3a82faf9
Author | SHA1 | Date | |
---|---|---|---|
ec3a82faf9 | |||
|
3003d33570 | ||
|
7187503fcf | ||
|
a3209aa170 | ||
|
df01e9b81b | ||
|
313ccf7988 | ||
|
be8d2ca4d4 | ||
|
7b4d234c48 | ||
|
318f850885 | ||
|
fd8b03ad3e | ||
|
7a7751567d |
BIN
src/assets/image/1920/bg-contacts.png
Normal file
After Width: | Height: | Size: 590 KiB |
BIN
src/assets/image/1920/bg-events-calendar.png
Normal file
After Width: | Height: | Size: 712 KiB |
BIN
src/assets/image/1920/bg-news.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
src/assets/image/1920/bg-pc.png
Normal file
After Width: | Height: | Size: 712 KiB |
BIN
src/assets/image/1920/bg-stock-quote.png
Normal file
After Width: | Height: | Size: 296 KiB |
BIN
src/assets/image/1920/contacts-bg.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
src/assets/image/1920/email-alerts-submit.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/image/1920/events-calendar-bg.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/image/1920/product-introduction-icon1.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/image/1920/product-introduction-icon2.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
src/assets/image/1920/product-introduction-icon3.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
src/assets/image/1920/product-introduction-img1.png
Normal file
After Width: | Height: | Size: 412 KiB |
BIN
src/assets/image/1920/product-introduction-img2.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
src/assets/image/1920/product-introduction-img3.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
src/assets/image/1920/product-introduction-img4.png
Normal file
After Width: | Height: | Size: 8.0 MiB |
BIN
src/assets/image/1920/product-introduction-img5.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/image/1920/product-introduction-img6.png
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 874 KiB |
BIN
src/assets/image/content/bg_10.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/image/content/bg_11.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
src/assets/image/content/bg_12.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/image/content/bg_3.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/image/content/bg_4.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
src/assets/image/content/bg_5.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
src/assets/image/content/bg_6.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
src/assets/image/content/bg_7.png
Normal file
After Width: | Height: | Size: 424 KiB |
BIN
src/assets/image/content/bg_8.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/image/content/bg_9.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
src/assets/image/content/information1.png
Normal file
After Width: | Height: | Size: 70 KiB |
BIN
src/assets/image/content/switch_left.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/image/content/switch_right.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 36 KiB |
4
src/assets/image/icon-link-svg.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="23" height="22" viewBox="0 0 23 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13.6548 8.9774C13.516 8.84467 13.3681 8.72503 13.2156 8.61409L13.2153 8.61433C13.0584 8.46998 12.8453 8.38107 12.6104 8.38107C12.1283 8.38107 11.7375 8.75491 11.7375 9.21604C11.7375 9.42009 11.8142 9.60698 11.9413 9.75202C11.9413 9.75204 11.9413 9.75208 11.9414 9.75211C12.0024 9.82178 12.0751 9.88184 12.1567 9.92939C12.239 9.99432 12.3198 10.0582 12.3953 10.1305L12.4673 10.1994C13.372 11.0637 13.1019 12.5528 12.1972 13.4182L8.33659 17.1098C7.4319 17.9741 5.96108 17.9741 5.05634 17.1098L4.9838 17.0404C4.07904 16.175 4.07904 14.7671 4.9838 13.9039L6.68938 12.273C6.90822 12.1068 7.0487 11.8504 7.0487 11.5624C7.0487 11.0616 6.62422 10.6556 6.10059 10.6556C5.903 10.6556 5.71958 10.7134 5.5677 10.8123C5.56722 10.8114 5.56671 10.8104 5.56621 10.8095L5.54802 10.8257C5.48089 10.8719 5.42019 10.926 5.36776 10.9871L3.59529 12.5735C1.92917 14.1683 1.92917 16.7766 3.59529 18.3691L3.66726 18.4379C5.33337 20.0305 8.05903 20.0305 9.72514 18.4379L13.5846 14.7452C15.2484 13.1516 15.3895 10.6377 13.7257 9.04513L13.6548 8.9774Z" fill="#FF7BAC"/>
|
||||||
|
<path d="M19.2173 3.56219L19.1454 3.49335C17.4793 1.89968 14.7536 1.89968 13.0875 3.49335L9.22805 7.18608C7.56193 8.77976 7.47018 11.0811 9.1363 12.6758L9.20711 12.7425C9.28278 12.8149 9.36132 12.8831 9.44149 12.9485C9.49952 13.0105 9.56769 13.0636 9.64347 13.1056C9.64405 13.106 9.64465 13.1065 9.64522 13.1069L9.64547 13.1067C9.76626 13.1731 9.90621 13.2113 10.0556 13.2113C10.5107 13.2113 10.8796 12.8584 10.8796 12.4231C10.8796 12.3002 10.8502 12.1839 10.7978 12.0802C10.6888 11.8462 10.4849 11.7038 10.3438 11.5689L10.273 11.5022C9.3683 10.6368 9.71185 9.37962 10.6165 8.51426L14.4783 4.82259C15.3807 3.9572 16.8521 3.9572 17.7568 4.82259L17.8288 4.89033C18.7335 5.75575 18.7335 7.1642 17.8288 8.0285L16.1288 9.65569C15.8975 9.81959 15.7476 10.0825 15.7476 10.3789C15.7476 10.8757 16.1686 11.2785 16.688 11.2785C16.8688 11.2785 17.0376 11.2296 17.1809 11.145C17.182 11.1468 17.183 11.1484 17.1841 11.1502L17.2104 11.1269C17.2917 11.0749 17.3638 11.011 17.4245 10.938L19.2161 9.35669C20.8834 7.76303 20.8835 5.15584 19.2173 3.56219Z" fill="#FF7BAC"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
@ -2,12 +2,16 @@
|
|||||||
<div class="custom-echarts">
|
<div class="custom-echarts">
|
||||||
<div>
|
<div>
|
||||||
<div class="echarts-header">
|
<div class="echarts-header">
|
||||||
<div class="echarts-header-title">
|
<!-- 标题区域 -->
|
||||||
|
<div class="title-section">
|
||||||
|
<div class="title-decoration"></div>
|
||||||
|
<div class="stock-title">
|
||||||
<span>FiEE, Inc. Stock Price History</span>
|
<span>FiEE, Inc. Stock Price History</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="echarts-search-area">
|
<div class="echarts-search-area">
|
||||||
<div class="echarts-search-byRange">
|
<div class="echarts-search-byRange">
|
||||||
<text style="font-size: 0.9rem; font-weight: 400; color: #666666;">
|
<text style="font-size: 0.9rem; font-weight: 400; color: #666666">
|
||||||
Range
|
Range
|
||||||
</text>
|
</text>
|
||||||
<div class="search-range-list">
|
<div class="search-range-list">
|
||||||
@ -15,6 +19,7 @@
|
|||||||
class="search-range-list-each"
|
class="search-range-list-each"
|
||||||
v-for="(item, index) in state.searchRange"
|
v-for="(item, index) in state.searchRange"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
:class="{ activeRange: state.activeRange === item }"
|
||||||
@click="changeSearchRange(item)"
|
@click="changeSearchRange(item)"
|
||||||
>
|
>
|
||||||
<span>{{ item }}</span>
|
<span>{{ item }}</span>
|
||||||
@ -23,21 +28,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="echarts-search-byDate">
|
<div class="echarts-search-byDate">
|
||||||
<n-date-picker
|
<n-date-picker
|
||||||
v-model:value="state.selectHistoricStartDate"
|
v-model:value="state.dateRange"
|
||||||
type="date"
|
type="daterange"
|
||||||
:is-date-disabled="disableAfterDate"
|
:is-date-disabled="isDateDisabled"
|
||||||
@update:value="changeSearchRangeStartDate"
|
@update:value="handleDateRangeChange"
|
||||||
input-readonly
|
|
||||||
/>
|
|
||||||
<!-- <n-icon size="16">
|
|
||||||
<ArrowForwardOutline />
|
|
||||||
</n-icon> -->
|
|
||||||
<span>to</span>
|
|
||||||
<n-date-picker
|
|
||||||
v-model:value="state.selectHistoricEndDate"
|
|
||||||
type="date"
|
|
||||||
:is-date-disabled="disablePreviousDate"
|
|
||||||
@update:value="changeSearchRangeEndDate"
|
|
||||||
input-readonly
|
input-readonly
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -48,40 +42,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, watch, reactive } from 'vue'
|
import { onMounted, watch, reactive } from "vue";
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import markPointerIcon from '@/assets/image/icon/echarts_markPointer.png'
|
import { NDatePicker, NIcon } from "naive-ui";
|
||||||
import axios from 'axios'
|
import { ArrowForwardOutline } from "@vicons/ionicons5";
|
||||||
import { NDatePicker, NIcon } from 'naive-ui'
|
import axios from "axios";
|
||||||
import { ArrowForwardOutline } from '@vicons/ionicons5'
|
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
searchRange: ['1m', '3m', 'YTD', '1Y', '5Y', '10Y', 'Max'],
|
searchRange: ["1m", "3m", "YTD", "1Y", "5Y", "10Y", "Max"],
|
||||||
selectHistoricStartDate: '2009-10-07',
|
dateRange: [new Date("2009-10-07").getTime(), new Date().getTime()],
|
||||||
selectHistoricEndDate: new Date(),
|
activeRange: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
let myCharts = null
|
let myCharts = null;
|
||||||
let historicData = []
|
let historicData = [];
|
||||||
let xAxisData = []
|
let xAxisData = [];
|
||||||
|
|
||||||
//初始化eCharts
|
//初始化eCharts
|
||||||
const initEcharts = (data) => {
|
const initEcharts = (data) => {
|
||||||
historicData = data
|
historicData = data;
|
||||||
xAxisData = data.map((item) => {
|
xAxisData = data.map((item) => {
|
||||||
return new Date(item.date).toLocaleDateString('en-US', {
|
return new Date(item.date).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
const yAxisData = data.map((item) => item.price)
|
const yAxisData = data.map((item) => item.price);
|
||||||
// console.error(xAxisData, yAxisData)
|
// console.error(xAxisData, yAxisData)
|
||||||
// 基于准备好的dom,初始化echarts实例
|
// 基于准备好的dom,初始化echarts实例
|
||||||
myCharts = echarts.init(document.getElementById('myEcharts'), null, {
|
myCharts = echarts.init(document.getElementById("myEcharts"), null, {
|
||||||
renderer: 'canvas',
|
renderer: "canvas",
|
||||||
useDirtyRect: true
|
useDirtyRect: true,
|
||||||
})
|
});
|
||||||
// 绘制图表
|
// 绘制图表
|
||||||
myCharts.setOption({
|
myCharts.setOption({
|
||||||
animation: false,
|
animation: false,
|
||||||
@ -91,68 +83,68 @@ const initEcharts = (data) => {
|
|||||||
// text: 'FiEE, Inc. Stock Price History',
|
// text: 'FiEE, Inc. Stock Price History',
|
||||||
// },
|
// },
|
||||||
grid: {
|
grid: {
|
||||||
left: '8%', // 或 '2%',根据实际情况调整
|
left: "8%", // 或 '2%',根据实际情况调整
|
||||||
right: '12%', // 给右侧y轴留空间,数值可根据y轴label宽度调整
|
right: "12%", // 给右侧y轴留空间,数值可根据y轴label宽度调整
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: "axis",
|
||||||
axisPointer: {
|
axisPointer: {
|
||||||
type: 'line',
|
type: "line",
|
||||||
label: {
|
label: {
|
||||||
backgroundColor: '#6a7985',
|
backgroundColor: "#6a7985",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
formatter: function (params) {
|
formatter: function (params) {
|
||||||
const p = params[0]
|
const p = params[0];
|
||||||
return `<span style="font-size: 1.1rem; font-weight: 600;">${p.axisValue}</span><br/><span style="font-size: 0.9rem; font-weight: 400;">Price: ${p.data}</span>`
|
return `<span style="font-size: 1.1rem; font-weight: 600;">${p.axisValue}</span><br/><span style="font-size: 0.9rem; font-weight: 400;">Price: ${p.data}</span>`;
|
||||||
},
|
},
|
||||||
triggerOn: 'mousemove',
|
triggerOn: "mousemove",
|
||||||
confine: true,
|
confine: true,
|
||||||
hideDelay: 1500
|
hideDelay: 1500,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
data: xAxisData,
|
data: xAxisData,
|
||||||
type: 'category',
|
type: "category",
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
inverse: true,
|
inverse: true,
|
||||||
axisLine: {
|
axisLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: '#CCD6EB',
|
color: "#CCD6EB",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#323232',
|
color: "#323232",
|
||||||
fontWeight: 'bold',
|
fontWeight: "bold",
|
||||||
interval: 'auto',
|
interval: "auto",
|
||||||
hideOverlap: true
|
hideOverlap: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: "value",
|
||||||
position: 'right',
|
position: "right",
|
||||||
interval: 25,
|
interval: 25,
|
||||||
// max: 75.0,
|
// max: 75.0,
|
||||||
show: true,
|
show: true,
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
color: '#323232',
|
color: "#323232",
|
||||||
fontWeight: 'bold',
|
fontWeight: "bold",
|
||||||
formatter: function (value) {
|
formatter: function (value) {
|
||||||
return value > 0 ? value.toFixed(2) : value
|
return value > 0 ? value.toFixed(2) : value;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: yAxisData,
|
data: yAxisData,
|
||||||
type: 'line',
|
type: "line",
|
||||||
sampling: 'lttb',
|
sampling: "lttb",
|
||||||
symbol: 'none',
|
symbol: "none",
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: '#2c6288',
|
color: "#CC346C",
|
||||||
},
|
},
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color: {
|
color: {
|
||||||
type: 'linear',
|
type: "linear",
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
x2: 0,
|
x2: 0,
|
||||||
@ -160,387 +152,391 @@ const initEcharts = (data) => {
|
|||||||
colorStops: [
|
colorStops: [
|
||||||
{
|
{
|
||||||
offset: 0,
|
offset: 0,
|
||||||
color: '#2c6288',
|
color: "#CC346C",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
offset: 1,
|
offset: 1,
|
||||||
color: '#F4F6F8',
|
color: "#F4F6F8",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
markPoint: {
|
markPoint: {
|
||||||
symbol: 'image://' + markPointerIcon,
|
symbol: "circle",
|
||||||
symbolSize: 24,
|
symbolSize: 20,
|
||||||
|
itemStyle: {
|
||||||
|
color: {
|
||||||
|
type: "radial",
|
||||||
|
x: 0.5,
|
||||||
|
y: 0.5,
|
||||||
|
r: 0.5,
|
||||||
|
colorStops: [
|
||||||
|
{ offset: 0, color: "#CC346C" },
|
||||||
|
{ offset: 0.4, color: "white" },
|
||||||
|
{ offset: 0.4, color: "white" },
|
||||||
|
{ offset: 0.6, color: "rgba(204, 52, 108, 0.30)" },
|
||||||
|
{ offset: 0.8, color: "rgba(204, 52, 108, 0.30)" },
|
||||||
|
{ offset: 1, color: "rgba(255, 123, 172, 0)" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
progressive: 500,
|
progressive: 500,
|
||||||
progressiveThreshold: 3000,
|
progressiveThreshold: 3000,
|
||||||
large: true,
|
large: true,
|
||||||
largeThreshold: 2000
|
largeThreshold: 2000,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'slider',
|
type: "slider",
|
||||||
show: true,
|
show: true,
|
||||||
dataBackground: {
|
dataBackground: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: '#2C6288',
|
color: "#CC346C",
|
||||||
},
|
},
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color: {
|
color: {
|
||||||
type: 'linear',
|
type: "linear",
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
x2: 0,
|
x2: 0,
|
||||||
y2: 1,
|
y2: 1,
|
||||||
colorStops: [
|
colorStops: [
|
||||||
{ offset: 1, color: '#2c6288' },
|
{ offset: 1, color: "#CC346C" },
|
||||||
{ offset: 0, color: '#F4F6F8' },
|
{ offset: 0, color: "#F4F6F8" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
selectedDataBackground: {
|
selectedDataBackground: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
color: '#2C6288',
|
color: "#CC346C",
|
||||||
},
|
},
|
||||||
areaStyle: {
|
areaStyle: {
|
||||||
color: {
|
color: {
|
||||||
type: 'linear',
|
type: "linear",
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
x2: 0,
|
x2: 0,
|
||||||
y2: 1,
|
y2: 1,
|
||||||
colorStops: [
|
colorStops: [
|
||||||
{ offset: 1, color: '#2c6288' },
|
{ offset: 1, color: "#CC346C" },
|
||||||
{ offset: 0, color: '#F4F6F8' },
|
{ offset: 0, color: "#F4F6F8" },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fillerColor: 'rgba(44, 98, 136, 0.3)',
|
fillerColor: "rgba(44, 98, 136, 0.3)",
|
||||||
realtime: false,
|
realtime: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
});
|
||||||
|
|
||||||
// 监听 showTip 事件,动态显示 markPoint
|
// 监听 showTip 事件,动态显示 markPoint
|
||||||
myCharts.on('showTip', function (params) {
|
myCharts.on("showTip", function (params) {
|
||||||
if (params) {
|
if (params) {
|
||||||
const dataIndex = params.dataIndex
|
const dataIndex = params.dataIndex;
|
||||||
const x = myCharts.getOption().xAxis[0].data[dataIndex]
|
const x = myCharts.getOption().xAxis[0].data[dataIndex];
|
||||||
const y = myCharts.getOption().series[0].data[dataIndex]
|
const y = myCharts.getOption().series[0].data[dataIndex];
|
||||||
myCharts.setOption({
|
myCharts.setOption({
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
markPoint: {
|
markPoint: {
|
||||||
symbol: 'image://' + markPointerIcon,
|
|
||||||
symbolSize: 24,
|
|
||||||
data: [{ coord: [x, y] }],
|
data: [{ coord: [x, y] }],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
// 鼠标移出时,清除 markPoint
|
// 鼠标移出时,清除 markPoint
|
||||||
myCharts.on('globalout', function () {
|
myCharts.on("globalout", function () {
|
||||||
myCharts.setOption({
|
myCharts.setOption({
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
markPoint: {
|
markPoint: {
|
||||||
symbol: 'image://' + markPointerIcon,
|
|
||||||
symbolSize: 24,
|
|
||||||
data: [],
|
data: [],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
myCharts.on('dataZoom', function (params) {
|
myCharts.on("dataZoom", function (params) {
|
||||||
// 获取当前 dataZoom 范围
|
// 获取当前 dataZoom 范围
|
||||||
const option = myCharts.getOption()
|
const option = myCharts.getOption();
|
||||||
const xAxisData = option.xAxis[0].data
|
const xAxisData = option.xAxis[0].data;
|
||||||
const dataZoom = option.dataZoom[1] || option.dataZoom[0]
|
const dataZoom = option.dataZoom[1] || option.dataZoom[0];
|
||||||
|
|
||||||
// 获取 dataZoom 的 startValue 和 endValue
|
// 获取 dataZoom 的 startValue 和 endValue
|
||||||
let startValue = dataZoom.endValue
|
let startValue = dataZoom.endValue;
|
||||||
let endValue = dataZoom.startValue
|
let endValue = dataZoom.startValue;
|
||||||
|
|
||||||
// 如果是索引,转为日期
|
// 如果是索引,转为日期
|
||||||
if (typeof startValue === 'number') {
|
if (typeof startValue === "number") {
|
||||||
startValue = xAxisData[startValue]
|
startValue = xAxisData[startValue];
|
||||||
}
|
}
|
||||||
if (typeof endValue === 'number') {
|
if (typeof endValue === "number") {
|
||||||
endValue = xAxisData[endValue]
|
endValue = xAxisData[endValue];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新日期选择器
|
// 更新日期选择器
|
||||||
state.selectHistoricStartDate = new Date(startValue)
|
state.dateRange = [
|
||||||
state.selectHistoricEndDate = new Date(endValue)
|
new Date(startValue).getTime(),
|
||||||
})
|
new Date(endValue).getTime(),
|
||||||
}
|
];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getHistoricalData()
|
getHistoricalData();
|
||||||
})
|
});
|
||||||
|
|
||||||
//获取历史数据
|
//获取历史数据
|
||||||
const getHistoricalData = async () => {
|
const getHistoricalData = async () => {
|
||||||
let now = new Date()
|
let now = new Date();
|
||||||
let toDate =
|
let toDate =
|
||||||
now.getFullYear() +
|
now.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getMonth() + 1).padStart(2, '0') +
|
String(now.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getDate()).padStart(2, '0')
|
String(now.getDate()).padStart(2, "0");
|
||||||
let url =
|
let url =
|
||||||
'https://common.szjixun.cn/api/stock/history/base/list?from=2009-10-07&to=' +
|
"https://common.szjixun.cn/api/stock/history/base/list?from=2009-10-07&to=" +
|
||||||
toDate
|
toDate;
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.data.status === 0) {
|
if (res.data.status === 0) {
|
||||||
initEcharts(res.data.data)
|
initEcharts(res.data.data);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 适配倒序数据,返回大于等于目标日期的最近一天索引
|
// 适配倒序数据,返回大于等于目标日期的最近一天索引
|
||||||
function findClosestDateIndex(data, targetDateStr) {
|
function findClosestDateIndex(data, targetDateStr) {
|
||||||
let left = 0,
|
let left = 0,
|
||||||
right = data.length - 1
|
right = data.length - 1;
|
||||||
const target = new Date(targetDateStr).getTime()
|
const target = new Date(targetDateStr).getTime();
|
||||||
let res = data.length - 1 // 默认返回最后一个
|
let res = data.length - 1; // 默认返回最后一个
|
||||||
while (left <= right) {
|
while (left <= right) {
|
||||||
const mid = Math.floor((left + right) / 2)
|
const mid = Math.floor((left + right) / 2);
|
||||||
const midTime = new Date(data[mid].date).getTime()
|
const midTime = new Date(data[mid].date).getTime();
|
||||||
if (midTime > target) {
|
if (midTime > target) {
|
||||||
left = mid + 1
|
left = mid + 1;
|
||||||
} else {
|
} else {
|
||||||
res = mid
|
res = mid;
|
||||||
right = mid - 1
|
right = mid - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 适配倒序数据,返回小于等于目标日期的最近一天索引
|
// 适配倒序数据,返回小于等于目标日期的最近一天索引
|
||||||
function findClosestDateIndexDescLeft(data, targetDateStr) {
|
function findClosestDateIndexDescLeft(data, targetDateStr) {
|
||||||
let left = 0,
|
let left = 0,
|
||||||
right = data.length - 1
|
right = data.length - 1;
|
||||||
const target = new Date(targetDateStr).getTime()
|
const target = new Date(targetDateStr).getTime();
|
||||||
let res = -1
|
let res = -1;
|
||||||
while (left <= right) {
|
while (left <= right) {
|
||||||
const mid = Math.floor((left + right) / 2)
|
const mid = Math.floor((left + right) / 2);
|
||||||
const midTime = new Date(data[mid].date).getTime()
|
const midTime = new Date(data[mid].date).getTime();
|
||||||
if (midTime > target) {
|
if (midTime > target) {
|
||||||
left = mid + 1 // mid 比目标新,往更旧的方向找
|
left = mid + 1; // mid 比目标新,往更旧的方向找
|
||||||
} else {
|
} else {
|
||||||
res = mid // mid <= target,记录下来,继续往更新的方向找
|
res = mid; // mid <= target,记录下来,继续往更新的方向找
|
||||||
right = mid - 1
|
right = mid - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
//点击切换搜索区间
|
//点击切换搜索区间
|
||||||
const changeSearchRange = (range, dateTime) => {
|
const changeSearchRange = (range, dateTime) => {
|
||||||
const now = new Date()
|
state.activeRange = range;
|
||||||
let startDate = ''
|
const now = new Date();
|
||||||
let endDate = ''
|
let startDate = "";
|
||||||
if (range === '1m') {
|
let endDate = "";
|
||||||
const last = new Date(now)
|
if (range === "1m") {
|
||||||
last.setMonth(now.getMonth() - 1)
|
const last = new Date(now);
|
||||||
startDate = last.toLocaleDateString('en-US', {
|
last.setMonth(now.getMonth() - 1);
|
||||||
month: 'short',
|
startDate = last.toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === '3m') {
|
});
|
||||||
const last = new Date(now)
|
} else if (range === "3m") {
|
||||||
last.setMonth(now.getMonth() - 3)
|
const last = new Date(now);
|
||||||
startDate = last.toLocaleDateString('en-US', {
|
last.setMonth(now.getMonth() - 3);
|
||||||
month: 'short',
|
startDate = last.toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === 'YTD') {
|
});
|
||||||
startDate = new Date(now.getFullYear(), 0, 1).toLocaleDateString('en-US', {
|
} else if (range === "YTD") {
|
||||||
month: 'short',
|
startDate = new Date(now.getFullYear(), 0, 1).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === '1Y') {
|
});
|
||||||
const last = new Date(now)
|
} else if (range === "1Y") {
|
||||||
last.setFullYear(now.getFullYear() - 1)
|
const last = new Date(now);
|
||||||
startDate = last.toLocaleDateString('en-US', {
|
last.setFullYear(now.getFullYear() - 1);
|
||||||
month: 'short',
|
startDate = last.toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === '5Y') {
|
});
|
||||||
const last = new Date(now)
|
} else if (range === "5Y") {
|
||||||
last.setFullYear(now.getFullYear() - 5)
|
const last = new Date(now);
|
||||||
startDate = last.toLocaleDateString('en-US', {
|
last.setFullYear(now.getFullYear() - 5);
|
||||||
month: 'short',
|
startDate = last.toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === '10Y') {
|
});
|
||||||
const last = new Date(now)
|
} else if (range === "10Y") {
|
||||||
last.setFullYear(now.getFullYear() - 10)
|
const last = new Date(now);
|
||||||
startDate = last.toLocaleDateString('en-US', {
|
last.setFullYear(now.getFullYear() - 10);
|
||||||
month: 'short',
|
startDate = last.toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
endDate = new Date(new Date()).toLocaleDateString('en-US', {
|
});
|
||||||
month: 'short',
|
endDate = new Date(new Date()).toLocaleDateString("en-US", {
|
||||||
day: 'numeric',
|
month: "short",
|
||||||
year: 'numeric',
|
day: "numeric",
|
||||||
})
|
year: "numeric",
|
||||||
} else if (range === 'Max') {
|
});
|
||||||
startDate = ''
|
} else if (range === "Max") {
|
||||||
endDate = ''
|
startDate = "";
|
||||||
} else if (range === 'startDateTime') {
|
endDate = "";
|
||||||
startDate = dateTime
|
} else if (range === "startDateTime") {
|
||||||
endDate = ''
|
startDate = dateTime;
|
||||||
} else if (range === 'endDateTime') {
|
endDate = "";
|
||||||
startDate = ''
|
} else if (range === "endDateTime") {
|
||||||
endDate = dateTime
|
startDate = "";
|
||||||
|
endDate = dateTime;
|
||||||
}
|
}
|
||||||
if (startDate || endDate) {
|
if (startDate || endDate) {
|
||||||
// historicData 和 xAxisData 需在 initEcharts 作用域可用
|
// historicData 和 xAxisData 需在 initEcharts 作用域可用
|
||||||
if (
|
if (
|
||||||
typeof historicData !== 'undefined' &&
|
typeof historicData !== "undefined" &&
|
||||||
typeof xAxisData !== 'undefined'
|
typeof xAxisData !== "undefined"
|
||||||
) {
|
) {
|
||||||
let startValue = xAxisData[0]
|
const zoomOptions = {};
|
||||||
if (startDate) {
|
let newStartTs = state.dateRange[0];
|
||||||
const idx = findClosestDateIndex(historicData, startDate)
|
let newEndTs = state.dateRange[1];
|
||||||
// 用 historicData[idx].date 格式化为 xAxisData 的格式
|
|
||||||
startValue = new Date(historicData[idx].date).toLocaleDateString(
|
|
||||||
'en-US',
|
|
||||||
{
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
let endValue = endDate
|
|
||||||
if (endDate) {
|
|
||||||
// console.warn(endDate)
|
|
||||||
const idx = findClosestDateIndexDescLeft(historicData, endDate)
|
|
||||||
// console.warn(idx)
|
|
||||||
// 用 historicData[idx].date 格式化为 xAxisData 的格式
|
|
||||||
endValue = new Date(historicData[idx].date).toLocaleDateString(
|
|
||||||
'en-US',
|
|
||||||
{
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
},
|
|
||||||
)
|
|
||||||
// console.warn(endValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startDate) {
|
if (startDate) {
|
||||||
myCharts.setOption({
|
const idx = findClosestDateIndex(historicData, startDate);
|
||||||
dataZoom: {
|
const startValue = new Date(historicData[idx].date).toLocaleDateString(
|
||||||
endValue: startValue,
|
"en-US",
|
||||||
},
|
{
|
||||||
})
|
month: "short",
|
||||||
state.selectHistoricStartDate = new Date(startValue)
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
zoomOptions.endValue = startValue;
|
||||||
|
newStartTs = new Date(startValue).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
if (endDate) {
|
if (endDate) {
|
||||||
myCharts.setOption({
|
const idx = findClosestDateIndexDescLeft(historicData, endDate);
|
||||||
dataZoom: {
|
const endValue = new Date(historicData[idx].date).toLocaleDateString(
|
||||||
startValue: endValue,
|
"en-US",
|
||||||
},
|
{
|
||||||
})
|
month: "short",
|
||||||
state.selectHistoricEndDate = new Date(endValue)
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
zoomOptions.startValue = endValue;
|
||||||
|
newEndTs = new Date(endValue).getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.keys(zoomOptions).length > 0) {
|
||||||
|
myCharts.setOption({ dataZoom: [zoomOptions, zoomOptions] });
|
||||||
|
}
|
||||||
|
|
||||||
|
state.dateRange = [newStartTs, newEndTs];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
myCharts.setOption({
|
myCharts.setOption({
|
||||||
dataZoom: {
|
dataZoom: {
|
||||||
startValue: '',
|
startValue: "",
|
||||||
endValue: '',
|
endValue: "",
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
state.selectHistoricStartDate = new Date('2009-10-07')
|
state.dateRange = [new Date("2009-10-07").getTime(), new Date().getTime()];
|
||||||
state.selectHistoricEndDate = new Date()
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 禁用日期
|
||||||
|
const isDateDisabled = (ts, type, range) => {
|
||||||
|
const minDate = new Date("2009-10-06").getTime();
|
||||||
|
const maxDate = new Date().getTime();
|
||||||
|
|
||||||
|
if (ts < minDate || ts > maxDate) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用2009-10-07之后的日期
|
if (type === "end" && range && range[0]) {
|
||||||
const disableAfterDate = (date) => {
|
return ts < range[0];
|
||||||
return date < new Date('2009-10-06') || date > new Date()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 禁用过去的日期
|
return false;
|
||||||
const disablePreviousDate = (date) => {
|
};
|
||||||
return date < new Date(state.selectHistoricStartDate) || date > new Date()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 切换搜索区间开始日期
|
// 切换搜索区间
|
||||||
const changeSearchRangeStartDate = (date) => {
|
const handleDateRangeChange = (range) => {
|
||||||
// console.error(date)
|
if (range && range[0] && range[1]) {
|
||||||
changeSearchRange(
|
const startDate = new Date(range[0]).toLocaleDateString("en-US", {
|
||||||
'startDateTime',
|
month: "short",
|
||||||
new Date(date).toLocaleDateString('en-US', {
|
day: "numeric",
|
||||||
month: 'short',
|
year: "numeric",
|
||||||
day: 'numeric',
|
});
|
||||||
year: 'numeric',
|
const endDate = new Date(range[1]).toLocaleDateString("en-US", {
|
||||||
}),
|
month: "short",
|
||||||
)
|
day: "numeric",
|
||||||
}
|
year: "numeric",
|
||||||
|
});
|
||||||
|
|
||||||
// 切换搜索区间结束日期
|
changeSearchRange("startDateTime", startDate);
|
||||||
const changeSearchRangeEndDate = (date) => {
|
changeSearchRange("endDateTime", endDate);
|
||||||
// console.error(date)
|
|
||||||
changeSearchRange(
|
|
||||||
'endDateTime',
|
|
||||||
new Date(date).toLocaleDateString('en-US', {
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.custom-echarts {
|
.custom-echarts {
|
||||||
@ -550,15 +546,32 @@ const changeSearchRangeEndDate = (date) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.echarts-header {
|
.echarts-header {
|
||||||
.echarts-header-title {
|
.title-section {
|
||||||
span {
|
display: flex;
|
||||||
font-size: 2rem;
|
flex-direction: column;
|
||||||
font-weight: 600;
|
gap: 16px;
|
||||||
color: #323232;
|
margin-bottom: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stock-title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 1.4em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
.echarts-search-area {
|
.echarts-search-area {
|
||||||
padding: 2rem 0 0;
|
padding: 0 16px 32px 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -586,6 +599,10 @@ const changeSearchRangeEndDate = (date) => {
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.activeRange {
|
||||||
|
color: #fff;
|
||||||
|
background: #ff7bac;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
<!-- 通用页脚 -->
|
<!-- 通用页脚 -->
|
||||||
<div class="custom-footer">
|
<div class="custom-footer">
|
||||||
<div class="custom-footer-box">
|
<div class="custom-footer-box">
|
||||||
<span>© 2025 FiEE, Inc. All Rights Reserved.</span>
|
|
||||||
<div class="footer-links">
|
<div class="footer-links">
|
||||||
<span @click="handleLink('privacyPolicy')">Privacy Policy</span>
|
<span @click="handleLink('privacyPolicy')">Privacy Policy</span>
|
||||||
<span @click="handleLink('termsOfUse')">Terms of use</span>
|
<span @click="handleLink('termsOfUse')">Terms of use</span>
|
||||||
<span @click="handleLink('siteMap')">Site Map</span>
|
<span @click="handleLink('siteMap')">Site Map</span>
|
||||||
</div>
|
</div>
|
||||||
|
<span>© 2025 FiEE, Inc. All Rights Reserved.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -28,19 +28,20 @@ const handleLink = (link) => {
|
|||||||
// } else if (link === "siteMap") {
|
// } else if (link === "siteMap") {
|
||||||
// window.open(siteMap, "_blank");
|
// window.open(siteMap, "_blank");
|
||||||
// }
|
// }
|
||||||
router.push(link)
|
router.push(link);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.custom-footer {
|
.custom-footer {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #f7f8fa;
|
background: #f5f5f5;
|
||||||
border-top: 1px solid #ececec;
|
border-top: 2px solid #dbdbdb;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
height: 80px;
|
||||||
|
|
||||||
.custom-footer-box {
|
.custom-footer-box {
|
||||||
max-width: 1700px;
|
max-width: 932px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -50,12 +51,11 @@ const handleLink = (link) => {
|
|||||||
color: #888;
|
color: #888;
|
||||||
// font-size: 15px;
|
// font-size: 15px;
|
||||||
font-size: 1.05rem;
|
font-size: 1.05rem;
|
||||||
padding: 1rem 40px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-links {
|
.footer-links {
|
||||||
margin: 0.4rem 0 0;
|
|
||||||
span {
|
span {
|
||||||
border-right: 1px solid #d2d2d7;
|
border-right: 1px solid #d2d2d7;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
@ -201,11 +201,12 @@ const handleToHome = () => {
|
|||||||
top: 320px;
|
top: 320px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
background: #fddfea;
|
bottom: 0;
|
||||||
|
background: #fff;
|
||||||
z-index: 1100;
|
z-index: 1100;
|
||||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08);
|
||||||
padding: 40px 0 80px 0;
|
padding: 40px 0 80px 0;
|
||||||
max-height: 1500px;
|
// max-height: 1500px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
// 设置CSS变量,只影响当前组件的菜单
|
// 设置CSS变量,只影响当前组件的菜单
|
||||||
@ -215,6 +216,16 @@ const handleToHome = () => {
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 为n-submenu添加上边虚线边框
|
||||||
|
:deep(.mobile-menu > div) {
|
||||||
|
border-top: 3px dashed #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为最后一个n-submenu额外添加下边框
|
||||||
|
:deep(.mobile-menu > div:last-child) {
|
||||||
|
border-bottom: 3px dashed #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
// // 强制覆盖子菜单激活状态的文字颜色
|
// // 强制覆盖子菜单激活状态的文字颜色
|
||||||
// :deep(
|
// :deep(
|
||||||
// .n-menu
|
// .n-menu
|
||||||
|
@ -118,5 +118,10 @@ export const useHeaderMenuConfig = () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "Product Introduction",
|
||||||
|
key: "product-introduction",
|
||||||
|
href: '/product-introduction',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -648,7 +648,7 @@ export default {
|
|||||||
TWO: "• Signed a merger agreement with e2Companies to broaden its technology and revenue base.",
|
TWO: "• Signed a merger agreement with e2Companies to broaden its technology and revenue base.",
|
||||||
THREE: "",
|
THREE: "",
|
||||||
},
|
},
|
||||||
SUBHEADINGFIVE: "2025 Rebranding & New C-Suite",
|
SUBHEADINGFIVE: "2025: Rebranding & New C-Suite",
|
||||||
paragraphFIVE: {
|
paragraphFIVE: {
|
||||||
ONE: "• Officially rebranded from Minim Inc. to FiEE, Inc.",
|
ONE: "• Officially rebranded from Minim Inc. to FiEE, Inc.",
|
||||||
TWO: "• Appointed Li Wai Chung as CEO and Cao Yu as CFO.",
|
TWO: "• Appointed Li Wai Chung as CEO and Cao Yu as CFO.",
|
||||||
|
@ -30,26 +30,31 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "/stock-quote",
|
path: "/stock-quote",
|
||||||
name: "stock-quote",
|
name: "stock-quote",
|
||||||
|
meta: { bg:'url("@/assets/image/1920/bg-stock-quote.png")' },
|
||||||
component: () => import("@/views/stock-quote/index.vue"),
|
component: () => import("@/views/stock-quote/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/historic-stock",
|
path: "/historic-stock",
|
||||||
name: "historic-stock",
|
name: "historic-stock",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-events-calendar.png")' },
|
||||||
component: () => import("@/views/historic-stock/index.vue"),
|
component: () => import("@/views/historic-stock/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/contacts",
|
path: "/contacts",
|
||||||
name: "contacts",
|
name: "contacts",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-contacts.png")' },
|
||||||
component: () => import("@/views/contacts/index.vue"),
|
component: () => import("@/views/contacts/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/email-alerts",
|
path: "/email-alerts",
|
||||||
name: "email-alerts",
|
name: "email-alerts",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-contacts.png")' },
|
||||||
component: () => import("@/views/email-alerts/index.vue"),
|
component: () => import("@/views/email-alerts/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/quarterlyreports",
|
path: "/quarterlyreports",
|
||||||
name: "quarterlyreports",
|
name: "quarterlyreports",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-events-calendar.png")' },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/views/financialinformation/quarterlyreports/index.vue"),
|
import("@/views/financialinformation/quarterlyreports/index.vue"),
|
||||||
},
|
},
|
||||||
@ -68,22 +73,26 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: "/annualreports",
|
path: "/annualreports",
|
||||||
name: "AnnualReports",
|
name: "AnnualReports",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-events-calendar.png")' },
|
||||||
component: () =>
|
component: () =>
|
||||||
import("@/views/financialinformation/annualreports/index.vue"),
|
import("@/views/financialinformation/annualreports/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/press-releases",
|
path: "/press-releases",
|
||||||
name: "press-releases",
|
name: "press-releases",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-events-calendar.png")' },
|
||||||
component: () => import("@/views/press-releases/index.vue"),
|
component: () => import("@/views/press-releases/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/news",
|
path: "/news",
|
||||||
name: "news",
|
name: "news",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-news.png")' },
|
||||||
component: () => import("@/views/news/index.vue"),
|
component: () => import("@/views/news/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/events-calendar",
|
path: "/events-calendar",
|
||||||
name: "events-calendar",
|
name: "events-calendar",
|
||||||
|
meta: { bg: 'url("@/assets/image/1920/bg-events-calendar.png")' },
|
||||||
component: () => import("@/views/events-calendar/index.vue"),
|
component: () => import("@/views/events-calendar/index.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -141,6 +150,12 @@ const routes = [
|
|||||||
name: "siteMap",
|
name: "siteMap",
|
||||||
component: () => import("@/views/footerLinks/siteMap/index.vue"),
|
component: () => import("@/views/footerLinks/siteMap/index.vue"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/product-introduction",
|
||||||
|
name: "product-introduction",
|
||||||
|
meta: { bg: 'null' },
|
||||||
|
component: () => import("@/views/product-introduction/index.vue"),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page relative bg-[#ffffff]">
|
||||||
|
<div
|
||||||
|
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-1"
|
||||||
|
style="width: 920px; pointer-events: none; mix-blend-mode: multiply"
|
||||||
|
>
|
||||||
|
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="w-[100%] h-[916px] z-[] top-0 absolute">
|
||||||
|
<div class="relative w-[100%] h-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_1.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute top-[-90px]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_2.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute bottom-0 lef-0 right-0 z-99"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="business-page">
|
<div class="business-page">
|
||||||
<!-- 渐变背景标题区 - 增加层次感 -->
|
<!-- 渐变背景标题区 - 增加层次感 -->
|
||||||
<section class="hero-section">
|
<section class="hero-section">
|
||||||
@ -7,7 +27,7 @@
|
|||||||
<h2 class="hero-title">
|
<h2 class="hero-title">
|
||||||
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.TITLE") }}
|
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.TITLE") }}
|
||||||
</h2>
|
</h2>
|
||||||
<div style="font-size: 18px" class="hero-description">
|
<div style="font-size: 16px" class="hero-description">
|
||||||
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENT") }}
|
{{ $t("BusinessiIntroduction.CONTAIN.TITLEONE.CONTENT") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -109,7 +129,7 @@ const solutions = computed(() => [
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
color: black;
|
color: #455363;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
@ -1,16 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page relative overflow-hidden z-99 bg-[#ffffff]">
|
||||||
|
<div
|
||||||
|
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-1"
|
||||||
|
style="width: 900px; pointer-events: none; mix-blend-mode: multiply"
|
||||||
|
>
|
||||||
|
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="w-[100%] h-[700PX] z-[] top-0 absolute">
|
||||||
|
<div class="relative w-[100%] h-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_6.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute top-[-90px]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_7.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] h-[320PX] absolute bottom-0 lef-0 right-0 z-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="company-overview">
|
<div class="company-overview">
|
||||||
<!-- 公司概况 -->
|
<!-- 公司概况 -->
|
||||||
<section
|
<section
|
||||||
class="company-overview"
|
class="company-overview"
|
||||||
style="max-width: 1200px; margin: 60px auto"
|
style="max-width: 900px; margin: 120px auto"
|
||||||
>
|
>
|
||||||
<h1 class="section-title">
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="content-block">
|
<div class="content-block">
|
||||||
<div style="font-size: 18px">
|
<div style="font-size: 16px; color: #455363">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
||||||
@ -20,12 +41,17 @@
|
|||||||
|
|
||||||
<!-- 使命愿景卡片 -->
|
<!-- 使命愿景卡片 -->
|
||||||
<section class="mission-section">
|
<section class="mission-section">
|
||||||
<h1 class="section-title">
|
<!-- <h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
</h1>
|
</h1> -->
|
||||||
<div class="mission-cards">
|
<div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<div>
|
||||||
|
<h1 class="mt-0">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<n-p style="font-size: 16px; color: #455363" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
@ -34,7 +60,7 @@
|
|||||||
|
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<section class="section timeline-section">
|
<section class="section timeline-section mt-[120PX]">
|
||||||
<h1 class="section-title">
|
<h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
@ -43,8 +69,11 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[0] }}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
<n-p style="font-size: 18px" class="timeline-desc">{{
|
<n-p style="font-size: 18px" class="timeline-desc">{{
|
||||||
@ -62,8 +91,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -82,8 +116,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -102,8 +141,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -122,8 +166,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -154,21 +203,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
|
<!-- 成就部分 -->
|
||||||
|
|
||||||
<section class="mission-section">
|
<section
|
||||||
<h1 class="section-title">
|
class="mission-section overflow-hidden relative z-99"
|
||||||
|
style="
|
||||||
|
width: 100vw;
|
||||||
|
/* padding: 0 40px; */
|
||||||
|
/* margin-top: 40px; */
|
||||||
|
background: linear-gradient(180deg, #e5ffff 0%, #fff8fb 100%);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="height: 190px; width: 880px"
|
||||||
|
class="m-[auto] my-[64px] flex flex-col items-center text-center"
|
||||||
|
>
|
||||||
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="mission-cards">
|
<!-- <div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<n-p style="font-size: 18px" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
</div> -->
|
||||||
|
<div class="w-100% flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center mr-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p style="font-size: 14px; width: 439px" class="my-0 text-[#455363]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
|
</p>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center ml-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -184,15 +284,18 @@ const stats = ref([
|
|||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.home-page {
|
.home-page {
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
.company-overview {
|
.company-overview {
|
||||||
max-width: 1200px;
|
width: 900PX;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
z-index: 99;
|
||||||
|
position: relative;
|
||||||
/* padding: 0 20px; */
|
/* padding: 0 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +324,7 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 通用部分样式 */
|
/* 通用部分样式 */
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 80px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
@ -231,14 +334,16 @@ const stats = ref([
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title:after {
|
.section-title::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -10px;
|
top: -10px;
|
||||||
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: linear-gradient(to right, #00ffff, #ff7bac);
|
// background: linear-gradient(to right, #00ffff, #ff7bac);
|
||||||
|
background-color: #ff7bac;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +356,8 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 使命愿景卡片 */
|
/* 使命愿景卡片 */
|
||||||
.mission-section {
|
.mission-section {
|
||||||
margin: 80px 0;
|
// margin: 80px 0;
|
||||||
|
// margin-top: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mission-cards {
|
.mission-cards {
|
||||||
@ -289,16 +395,18 @@ const stats = ref([
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
transform: translateX(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline:before {
|
.timeline:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 2%;
|
||||||
left: 20px;
|
left: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 4px;
|
width: 2px;
|
||||||
background: linear-gradient(to bottom, #00ffff, #ff7bac);
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #ff7bac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-item {
|
.timeline-item {
|
||||||
@ -306,12 +414,25 @@ const stats = ref([
|
|||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
&:last-child:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 2%;
|
||||||
|
left: -40px;
|
||||||
|
height: 110%;
|
||||||
|
width: 2px;
|
||||||
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #E6EAEE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-dot {
|
.timeline-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -50px;
|
left: -50px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
width: 40px;
|
width: 22px;
|
||||||
height: 40px;
|
height: 22px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #ff7bac;
|
background: #ff7bac;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -319,18 +440,20 @@ const stats = ref([
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
box-shadow: 0 0 0 6px rgba(255, 123, 172, 0.2);
|
box-shadow: 0 0 0 7px rgba(255, 123, 172, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-year {
|
.timeline-year {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
color: #1a2a6c;
|
color: #000;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-desc {
|
.timeline-desc {
|
||||||
font-size: 1.05rem;
|
font-size: 16PX !important;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
|
color: #455363;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page relative overflow-hidden z-99 bg-[#ffffff]">
|
||||||
|
<div
|
||||||
|
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-1"
|
||||||
|
style="width: 900px; pointer-events: none; mix-blend-mode: multiply"
|
||||||
|
>
|
||||||
|
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="w-[100%] h-[700PX] z-[] top-0 absolute">
|
||||||
|
<div class="relative w-[100%] h-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_6.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute top-[-90px]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_7.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] h-[320PX] absolute bottom-0 lef-0 right-0 z-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="company-overview">
|
<div class="company-overview">
|
||||||
<!-- 公司概况 -->
|
<!-- 公司概况 -->
|
||||||
<section
|
<section
|
||||||
class="company-overview"
|
class="company-overview"
|
||||||
style="max-width: 1200px; margin: 60px auto"
|
style="max-width: 900px; margin: 120px auto"
|
||||||
>
|
>
|
||||||
<h1 class="section-title">
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="content-block">
|
<div class="content-block">
|
||||||
<div style="font-size: 18px">
|
<div style="font-size: 16px; color: #455363">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
||||||
@ -20,12 +41,17 @@
|
|||||||
|
|
||||||
<!-- 使命愿景卡片 -->
|
<!-- 使命愿景卡片 -->
|
||||||
<section class="mission-section">
|
<section class="mission-section">
|
||||||
<h1 class="section-title">
|
<!-- <h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
</h1>
|
</h1> -->
|
||||||
<div class="mission-cards">
|
<div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<div>
|
||||||
|
<h1 class="mt-0">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<n-p style="font-size: 16px; color: #455363" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
@ -34,7 +60,7 @@
|
|||||||
|
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<section class="section timeline-section">
|
<section class="section timeline-section mt-[120PX]">
|
||||||
<h1 class="section-title">
|
<h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
@ -43,8 +69,11 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[0] }}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
<n-p style="font-size: 18px" class="timeline-desc">{{
|
<n-p style="font-size: 18px" class="timeline-desc">{{
|
||||||
@ -62,8 +91,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -82,8 +116,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -102,8 +141,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -122,8 +166,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -154,23 +203,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
<!-- 成就部分 -->
|
<!-- 成就部分 -->
|
||||||
|
|
||||||
<section class="mission-section">
|
<section
|
||||||
<h1 class="section-title">
|
class="mission-section overflow-hidden relative z-99"
|
||||||
|
style="
|
||||||
|
width: 100vw;
|
||||||
|
/* padding: 0 40px; */
|
||||||
|
/* margin-top: 40px; */
|
||||||
|
background: linear-gradient(180deg, #e5ffff 0%, #fff8fb 100%);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="height: 190px; width: 880px"
|
||||||
|
class="m-[auto] my-[64px] flex flex-col items-center text-center"
|
||||||
|
>
|
||||||
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="mission-cards">
|
<!-- <div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<n-p style="font-size: 18px" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
</div> -->
|
||||||
|
<div class="w-100% flex items-center justify-between">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center mr-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p style="font-size: 14px; width: 439px" class="my-0 text-[#455363]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
|
</p>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center ml-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -186,15 +284,18 @@ const stats = ref([
|
|||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.home-page {
|
.home-page {
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
.company-overview {
|
.company-overview {
|
||||||
max-width: 1200px;
|
width: 900PX;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
z-index: 99;
|
||||||
|
position: relative;
|
||||||
/* padding: 0 20px; */
|
/* padding: 0 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +324,7 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 通用部分样式 */
|
/* 通用部分样式 */
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 80px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
@ -233,14 +334,16 @@ const stats = ref([
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title:after {
|
.section-title::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -10px;
|
top: -10px;
|
||||||
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: linear-gradient(to right, #00ffff, #ff7bac);
|
// background: linear-gradient(to right, #00ffff, #ff7bac);
|
||||||
|
background-color: #ff7bac;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,7 +356,8 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 使命愿景卡片 */
|
/* 使命愿景卡片 */
|
||||||
.mission-section {
|
.mission-section {
|
||||||
margin: 80px 0;
|
// margin: 80px 0;
|
||||||
|
// margin-top: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mission-cards {
|
.mission-cards {
|
||||||
@ -291,16 +395,18 @@ const stats = ref([
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
transform: translateX(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline:before {
|
.timeline:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 2%;
|
||||||
left: 20px;
|
left: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 4px;
|
width: 2px;
|
||||||
background: linear-gradient(to bottom, #00ffff, #ff7bac);
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #ff7bac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-item {
|
.timeline-item {
|
||||||
@ -308,12 +414,25 @@ const stats = ref([
|
|||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
&:last-child:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 2%;
|
||||||
|
left: -40px;
|
||||||
|
height: 110%;
|
||||||
|
width: 2px;
|
||||||
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #E6EAEE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-dot {
|
.timeline-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -50px;
|
left: -50px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
width: 40px;
|
width: 22px;
|
||||||
height: 40px;
|
height: 22px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #ff7bac;
|
background: #ff7bac;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -321,18 +440,20 @@ const stats = ref([
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
box-shadow: 0 0 0 6px rgba(255, 123, 172, 0.2);
|
box-shadow: 0 0 0 7px rgba(255, 123, 172, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-year {
|
.timeline-year {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
color: #1a2a6c;
|
color: #000;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-desc {
|
.timeline-desc {
|
||||||
font-size: 1.05rem;
|
font-size: 16PX !important;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
|
color: #455363;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,37 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page relative overflow-hidden z-99 bg-[#ffffff]">
|
||||||
|
<div
|
||||||
|
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-1"
|
||||||
|
style="width: 586px; pointer-events: none; mix-blend-mode: multiply"
|
||||||
|
>
|
||||||
|
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="w-[100%] h-[720PX] z-[] top-0 absolute">
|
||||||
|
<div class="relative w-[100%] h-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_10.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute top-[-90px]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_11.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] h-[320PX] absolute bottom-0 lef-0 right-0 z-1"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="company-overview">
|
<div class="company-overview">
|
||||||
<!-- 公司概况 -->
|
<!-- 公司概况 -->
|
||||||
<section
|
<section
|
||||||
class="company-overview"
|
class="company-overview"
|
||||||
style="max-width: 1200px; margin: 60px auto"
|
style="max-width: 586px; margin: 120px auto"
|
||||||
>
|
>
|
||||||
<h1 class="section-title">
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="content-block">
|
<div class="content-block">
|
||||||
<div style="font-size: 18px">
|
<div style="font-size: 16px; color: #455363">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}
|
||||||
</div>
|
</div>
|
||||||
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
<!-- <p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTWO") }}</p>
|
||||||
@ -20,12 +41,17 @@
|
|||||||
|
|
||||||
<!-- 使命愿景卡片 -->
|
<!-- 使命愿景卡片 -->
|
||||||
<section class="mission-section">
|
<section class="mission-section">
|
||||||
<h1 class="section-title">
|
<!-- <h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
</h1>
|
</h1> -->
|
||||||
<div class="mission-cards">
|
<div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<div>
|
||||||
|
<h1 class="mt-0">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLETHREE.TITLE") }}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<n-p style="font-size: 16px; color: #455363" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
$t("COMPANYOVERVIEW.TITLETHREE.CONTENTTWO")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
@ -34,7 +60,7 @@
|
|||||||
|
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<!-- 里程碑时间轴 -->
|
<!-- 里程碑时间轴 -->
|
||||||
<section class="section timeline-section">
|
<section class="section timeline-section mt-[120PX]">
|
||||||
<h1 class="section-title">
|
<h1 class="section-title">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
@ -43,8 +69,11 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[0] }}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADING").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
<n-p style="font-size: 18px" class="timeline-desc">{{
|
<n-p style="font-size: 18px" class="timeline-desc">{{
|
||||||
@ -62,8 +91,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTWO").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -82,8 +116,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGTHREE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -102,8 +141,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFOREFF").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -122,8 +166,13 @@
|
|||||||
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
<div class="timeline-item" v-motion-slide-visible-once-bottom>
|
||||||
<div class="timeline-dot"></div>
|
<div class="timeline-dot"></div>
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
|
<div class="text-[#FF7BAC] text-[16PX]">
|
||||||
|
{{
|
||||||
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[0]
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<n-h3 class="timeline-year">{{
|
<n-h3 class="timeline-year">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE")
|
$t("COMPANYOVERVIEW.TITLEFOUR.SUBHEADINGFIVE").split(":")[1]
|
||||||
}}</n-h3>
|
}}</n-h3>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
@ -154,22 +203,72 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
<!-- 成就部分 -->
|
<!-- 成就部分 -->
|
||||||
<section class="mission-section">
|
|
||||||
<h1 class="section-title">
|
<section
|
||||||
|
class="mission-section overflow-hidden relative z-99"
|
||||||
|
style="
|
||||||
|
width: 100vw;
|
||||||
|
/* padding: 0 40px; */
|
||||||
|
/* margin-top: 40px; */
|
||||||
|
background: linear-gradient(180deg, #e5ffff 0%, #fff8fb 100%);
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="height: 190px; width: 500px"
|
||||||
|
class="m-[auto] my-[64px] flex flex-col items-center text-center"
|
||||||
|
>
|
||||||
|
<h1 class="">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="mission-cards">
|
<!-- <div class="mission-cards">
|
||||||
<n-card hoverable class="mission-card" v-motion-pop>
|
<n-card hoverable class="mission-card" v-motion-pop>
|
||||||
<n-p style="font-size: 18px" class="card-content">{{
|
<n-p style="font-size: 18px" class="card-content">{{
|
||||||
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
$t("COMPANYOVERVIEW.TITLEFIVE.CONTENT")
|
||||||
}}</n-p>
|
}}</n-p>
|
||||||
</n-card>
|
</n-card>
|
||||||
|
</div> -->
|
||||||
|
<div class="w-100% flex items-center justify-between">
|
||||||
|
<!-- <div class="flex items-center">
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center mr-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_left.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
</div> -->
|
||||||
|
<p style="font-size: 14px;" class="my-0 text-[#455363]">
|
||||||
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
|
</p>
|
||||||
|
<!-- <div class="flex items-center">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/arrowhead_right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[95px]"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="bg-[#ffffff] rounded-[50%] flex justify-center items-center ml-[8px]"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/right.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[94PX] h-[94PX]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -185,15 +284,19 @@ const stats = ref([
|
|||||||
]);
|
]);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.home-page {
|
.home-page {
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
.company-overview {
|
.company-overview {
|
||||||
max-width: 1200px;
|
width: 586PX;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
z-index: 99;
|
||||||
|
position: relative;
|
||||||
|
/* padding: 0 20px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 顶部大图区域 */
|
/* 顶部大图区域 */
|
||||||
@ -221,7 +324,7 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 通用部分样式 */
|
/* 通用部分样式 */
|
||||||
.section {
|
.section {
|
||||||
margin-bottom: 80px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
@ -231,14 +334,16 @@ const stats = ref([
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-title:after {
|
.section-title::before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -10px;
|
top: -10px;
|
||||||
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
background: linear-gradient(to right, #00ffff, #ff7bac);
|
// background: linear-gradient(to right, #00ffff, #ff7bac);
|
||||||
|
background-color: #ff7bac;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +356,8 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 使命愿景卡片 */
|
/* 使命愿景卡片 */
|
||||||
.mission-section {
|
.mission-section {
|
||||||
margin: 80px 0;
|
// margin: 80px 0;
|
||||||
|
// margin-top: 160px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mission-cards {
|
.mission-cards {
|
||||||
@ -289,16 +395,18 @@ const stats = ref([
|
|||||||
position: relative;
|
position: relative;
|
||||||
padding-left: 50px;
|
padding-left: 50px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
transform: translateX(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline:before {
|
.timeline:before {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 2%;
|
||||||
left: 20px;
|
left: 10px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 4px;
|
width: 2px;
|
||||||
background: linear-gradient(to bottom, #00ffff, #ff7bac);
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #ff7bac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-item {
|
.timeline-item {
|
||||||
@ -306,12 +414,25 @@ const stats = ref([
|
|||||||
margin-bottom: 50px;
|
margin-bottom: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
&:last-child:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 2%;
|
||||||
|
left: -40px;
|
||||||
|
height: 110%;
|
||||||
|
width: 2px;
|
||||||
|
/* background: linear-gradient(to bottom, #00ffff, #ff7bac); */
|
||||||
|
background: #E6EAEE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.timeline-dot {
|
.timeline-dot {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -50px;
|
left: -50px;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
width: 40px;
|
width: 22px;
|
||||||
height: 40px;
|
height: 22px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #ff7bac;
|
background: #ff7bac;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -319,18 +440,20 @@ const stats = ref([
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
box-shadow: 0 0 0 6px rgba(255, 123, 172, 0.2);
|
box-shadow: 0 0 0 7px rgba(255, 123, 172, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-year {
|
.timeline-year {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
color: #1a2a6c;
|
color: #000;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timeline-desc {
|
.timeline-desc {
|
||||||
font-size: 1.05rem;
|
font-size: 16PX !important;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
|
color: #455363;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,30 +511,30 @@ const stats = ref([
|
|||||||
|
|
||||||
/* 响应式设计 */
|
/* 响应式设计 */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.hero-title {
|
// .hero-title {
|
||||||
font-size: 2.5rem;
|
// font-size: 2.5rem;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.hero-subtitle {
|
// .hero-subtitle {
|
||||||
font-size: 1.2rem;
|
// font-size: 1.2rem;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.section-title {
|
// .section-title {
|
||||||
font-size: 1.8rem;
|
// font-size: 1.8rem;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.timeline {
|
// .timeline {
|
||||||
padding-left: 30px;
|
// padding-left: 30px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.timeline-dot {
|
// .timeline-dot {
|
||||||
left: -30px;
|
// left: -30px;
|
||||||
width: 30px;
|
// // width: 30px;
|
||||||
height: 30px;
|
// // height: 30px;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.achievement-section {
|
// .achievement-section {
|
||||||
padding: 40px 20px;
|
// padding: 40px 20px;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,42 +8,125 @@ function copyEmail() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header className="header"></header>
|
<div class="contact-container">
|
||||||
<main
|
<!-- Title Section -->
|
||||||
ref="main"
|
<div class="title-section">
|
||||||
class="flex-center min-h-80vh rounded-3xl to-accent w-100vw animate-fade-in"
|
<div class="title-decoration"></div>
|
||||||
>
|
<div class="contact-title">Investor Contacts</div>
|
||||||
<div class="w-full flex flex-col items-center gap-6 py-16 px-8">
|
|
||||||
<h1
|
|
||||||
class="text-5xl font-bold text-primary animate-fade-in-down animate-delay-0"
|
|
||||||
>
|
|
||||||
Investor Contacts
|
|
||||||
</h1>
|
|
||||||
<div
|
|
||||||
class="text-3xl font-semibold text-gray-800 animate-fade-in-down animate-delay-200"
|
|
||||||
>
|
|
||||||
FiEE Inc.
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-2xl text-#ff7bac animate-fade-in-down animate-delay-400">
|
|
||||||
Investor Relations
|
<!-- Card Section -->
|
||||||
</div>
|
<div class="contact-card">
|
||||||
<div
|
<div class="logo-text">FiEE Inc.</div>
|
||||||
class="text-xl text-gray-600 flex items-center gap-2 animate-fade-in-down animate-delay-600"
|
<div class="relation-text">Investor Relations</div>
|
||||||
>
|
<div class="email-section">
|
||||||
<span>Email:</span>
|
<span>Email:</span>
|
||||||
<span
|
<span class="email-address" @click="copyEmail"
|
||||||
class="transition-colors duration-300 cursor-pointer text-#00baff hover:text-primary active:text-secondary select-all"
|
|
||||||
@click="copyEmail"
|
|
||||||
>fiee@dlkadvisory.com</span
|
>fiee@dlkadvisory.com</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
<footer></footer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
/**** UnoCSS 动画补充(如未全局引入可在 uno.config.js 添加)****/
|
.contact-container {
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 0 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 1.4em;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-card {
|
||||||
|
display: flex;
|
||||||
|
width: 932px;
|
||||||
|
height: 580px;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 1rem;
|
||||||
|
background-image: url("@/assets/image/1920/contacts-bg.png");
|
||||||
|
background-size: 64% auto;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
box-shadow: 0px 0px 30px 0px rgba(0, 0, 0, 0.1);
|
||||||
|
animation: fade-in 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-text {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-size: 128px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
background: linear-gradient(90deg, #ff7bac 0%, #0ff 100%);
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
color: transparent;
|
||||||
|
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.relation-text {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-section {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #4a5568;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
animation-delay: 0.6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-address {
|
||||||
|
color: #ff7bac;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes fade-in-down {
|
@keyframes fade-in-down {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -54,19 +137,4 @@ function copyEmail() {
|
|||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.animate-fade-in-down {
|
|
||||||
animation: fade-in-down 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
|
||||||
}
|
|
||||||
.animate-delay-0 {
|
|
||||||
animation-delay: 0s;
|
|
||||||
}
|
|
||||||
.animate-delay-200 {
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
.animate-delay-400 {
|
|
||||||
animation-delay: 0.4s;
|
|
||||||
}
|
|
||||||
.animate-delay-600 {
|
|
||||||
animation-delay: 0.6s;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,7 +8,6 @@ const form = ref({
|
|||||||
email: "",
|
email: "",
|
||||||
company: "",
|
company: "",
|
||||||
phone: "",
|
phone: "",
|
||||||
alertType: "all",
|
|
||||||
});
|
});
|
||||||
const submitted = ref(false);
|
const submitted = ref(false);
|
||||||
|
|
||||||
@ -26,126 +25,264 @@ async function handleSubmit(e) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header class="header"></header>
|
<div class="alerts-container">
|
||||||
<main ref="main" class="relative min-h-[80vh] flex-center overflow-hidden">
|
<!-- Title Section -->
|
||||||
<!-- 粒子背景 -->
|
<!-- 未提交 -->
|
||||||
<div class="absolute inset-0 z-0 pointer-events-none animate-bg-move"></div>
|
<div v-if="!submitted" class="title-section">
|
||||||
<!-- 表单卡片/提交成功卡片 -->
|
<div class="title-decoration"></div>
|
||||||
<div
|
<div class="title">E-Mail Alerts</div>
|
||||||
class="relative z-10 w-[480px] max-w-[90vw] p-10 bg-white/80 rounded-3xl shadow-2xl backdrop-blur-md animate-bounce-in"
|
<div class="subtitle">* Required Fields</div>
|
||||||
>
|
</div>
|
||||||
|
<!-- 已提交 -->
|
||||||
|
<div v-else class="title-section">
|
||||||
|
<div class="title-decoration"></div>
|
||||||
|
<div class="title">Submitted successfully!</div>
|
||||||
|
<div class="subtitle">The information you submitted is as follows:</div>
|
||||||
|
</div>
|
||||||
|
<!-- Form Card -->
|
||||||
|
<div class="form-card relative">
|
||||||
<template v-if="!submitted">
|
<template v-if="!submitted">
|
||||||
<h2 class="text-3xl font-bold text-#ff7bac mb-2 tracking-wide">
|
<form class="form-content" @submit="handleSubmit">
|
||||||
E-Mail Alerts
|
<div class="form-group">
|
||||||
</h2>
|
<label for="firstName">* First Name</label>
|
||||||
<p class="text-sm text-gray-500 mb-6">* Required Fields</p>
|
|
||||||
<form class="space-y-4" @submit="handleSubmit">
|
|
||||||
<div>
|
|
||||||
<label class="block text-gray-700 font-semibold mb-1"
|
|
||||||
>* First Name</label
|
|
||||||
>
|
|
||||||
<input
|
<input
|
||||||
|
id="firstName"
|
||||||
v-model="form.firstName"
|
v-model="form.firstName"
|
||||||
type="text"
|
type="text"
|
||||||
class="w-full px-4 py-2 rounded-lg ring-2 ring-#ff7bac/20) transition-all duration-300 outline-none bg-white/90 border-none"
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="block text-gray-700 font-semibold mb-1"
|
<label for="lastName">* Last Name</label>
|
||||||
>* Last Name</label
|
<input id="lastName" v-model="form.lastName" type="text" required />
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model="form.lastName"
|
|
||||||
type="text"
|
|
||||||
class="w-full px-4 py-2 rounded-lg ring-2 ring-#ff7bac/20) transition-all duration-300 outline-none bg-white/90 border-none"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="block text-gray-700 font-semibold mb-1"
|
<label for="email">* Email</label>
|
||||||
>* Email</label
|
<input id="email" v-model="form.email" type="email" required />
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model="form.email"
|
|
||||||
type="email"
|
|
||||||
class="w-full px-4 py-2 rounded-lg ring-2 ring-#ff7bac/20) transition-all duration-300 outline-none bg-white/90 border-none"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="block text-gray-700 font-semibold mb-1"
|
<label for="company">* Company</label>
|
||||||
>* Company</label
|
<input id="company" v-model="form.company" type="text" required />
|
||||||
>
|
|
||||||
<input
|
|
||||||
v-model="form.company"
|
|
||||||
type="text"
|
|
||||||
class="w-full px-4 py-2 rounded-lg ring-2 ring-#ff7bac/20) transition-all duration-300 outline-none bg-white/90 border-none"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label class="block text-gray-700 font-semibold mb-1">Phone</label>
|
<label for="phone">Phone</label>
|
||||||
<input
|
<input id="phone" v-model="form.phone" type="tel" />
|
||||||
v-model="form.phone"
|
|
||||||
type="tel"
|
|
||||||
class="w-full px-4 py-2 rounded-lg ring-2 ring-#ff7bac/20) transition-all duration-300 outline-none bg-white/90 border-none"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button type="submit" class="submit-btn">Submit</button>
|
||||||
type="submit"
|
|
||||||
class="w-full py-3 rounded-xl text-white font-bold text-lg active:scale-95 transition-all duration-200 animate-bounce-in animate-delay-200 submit-btn"
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<div class="submitted-data">
|
||||||
class="flex flex-col items-center justify-center min-h-[300px] animate-bounce-in"
|
<div class="submitted-data-content">
|
||||||
>
|
<div class="submitted-row">
|
||||||
<span
|
<span class="label">First Name:</span>
|
||||||
class="i-mdi:check-circle-outline text-green-500 text-5xl mb-4"
|
<span class="value">{{ form.firstName || "Not filled in" }}</span>
|
||||||
></span>
|
|
||||||
<h2 class="text-2xl font-bold text-#ff7bac mb-2">
|
|
||||||
Submitted successfully!
|
|
||||||
</h2>
|
|
||||||
<div class="text-gray-700 text-base mb-4">
|
|
||||||
The information you submitted is as follows:
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="submitted-row">
|
||||||
class="w-full bg-white/80 rounded-xl shadow p-4 space-y-2 text-gray-800"
|
<span class="label">Last Name:</span>
|
||||||
>
|
<span class="value">{{ form.lastName || "Not filled in" }}</span>
|
||||||
<div>
|
|
||||||
<span class="font-semibold">First Name:</span
|
|
||||||
>{{ form.firstName }}
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="submitted-row">
|
||||||
<span class="font-semibold">Last Name:</span>{{ form.lastName }}
|
<span class="label">Email:</span>
|
||||||
|
<span class="value">{{ form.email || "Not filled in" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="submitted-row">
|
||||||
<span class="font-semibold">Email:</span>{{ form.email }}
|
<span class="label">Company:</span>
|
||||||
|
<span class="value">{{ form.company || "Not filled in" }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="submitted-row">
|
||||||
<span class="font-semibold">Company:</span>{{ form.company }}
|
<span class="label">Phone:</span>
|
||||||
</div>
|
<span class="value">{{ form.phone || "Not filled in" }}</span>
|
||||||
<div>
|
|
||||||
<span class="font-semibold">Phone:</span
|
|
||||||
>{{ form.phone || "Not filled in" }}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<span class="font-semibold">Alert Type:</span
|
|
||||||
>{{
|
|
||||||
form.alertType === "all" ? "All Alerts" : "Customize Alerts"
|
|
||||||
}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="submitted-bg"></div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
<footer></footer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
/* 可选:自定义粒子或渐变动画背景 */
|
.alerts-container {
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 0 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 56px;
|
||||||
|
color: #000000;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtitle {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #455363;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-card {
|
||||||
|
width: 100%;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 24px;
|
||||||
|
box-shadow: 0px 3px 14px 0px rgba(0, 0, 0, 0.16);
|
||||||
|
animation: fade-in 0.8s cubic-bezier(0.23, 1, 0.32, 1) both;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #000000;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
height: 38px;
|
||||||
|
border: 1px solid #e0e0e6;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0 12px;
|
||||||
|
font-size: 16px;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.3s;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: #ff7bac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.submit-btn {
|
.submit-btn {
|
||||||
background: linear-gradient(to right, #ff7bac, #00ffff);
|
height: 60px;
|
||||||
|
background: #ff7bac;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: none;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 32px;
|
||||||
|
color: white;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
margin-top: 8px; // 16px (from figma form-group gap) + 8px = 24px
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff7bac;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-info {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
color: #455363;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitted-data {
|
||||||
|
padding: 36px 24px 24px;
|
||||||
|
border-radius: 16px;
|
||||||
|
width: 678px;
|
||||||
|
height: 428px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.submitted-bg {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-image: url("@/assets/image/1920/email-alerts-submit.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: bottom;
|
||||||
|
background-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitted-data-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 16px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitted-row {
|
||||||
|
display: flex;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
width: 280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #000000;
|
||||||
|
width: 110px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
font-weight: 400;
|
||||||
|
color: #455363;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,29 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="events-calendar-page">
|
<div class="events-calendar-page">
|
||||||
<customDefaultPage>
|
<main class="page-container">
|
||||||
<template #content>
|
<div class="events-container">
|
||||||
<main class="p-[35px] max-w-[1200px] mx-auto">
|
<!-- 标题区域 -->
|
||||||
<div class="title mb-[20px]">
|
<div class="title-section">
|
||||||
|
<div class="title-decoration"></div>
|
||||||
|
<div class="events-title">
|
||||||
{{ t("events_calendar.title") }}
|
{{ t("events_calendar.title") }}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 搜索区域 -->
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
|
<div class="date-picker-wrapper">
|
||||||
<n-date-picker
|
<n-date-picker
|
||||||
v-model:value="state.selectedDateValue"
|
v-model:value="state.selectedDateValue"
|
||||||
type="date"
|
type="date"
|
||||||
class="search-date-picker"
|
class="search-date-picker"
|
||||||
></n-date-picker>
|
placeholder="Select Date"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg
|
||||||
|
class="calendar-icon"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
>
|
||||||
|
<g clip-path="url(#clip0_134_3094)">
|
||||||
|
<path
|
||||||
|
d="M17.5 3.33398H2.5C2.08333 3.33398 1.66667 3.66732 1.66667 4.08398V17.5007C1.66667 17.9173 2.08333 18.2507 2.5 18.2507H17.5C17.9167 18.2507 18.3333 17.9173 18.3333 17.5007V4.08398C18.3333 3.66732 17.9167 3.33398 17.5 3.33398Z"
|
||||||
|
stroke="#78777B"
|
||||||
|
stroke-width="1.25"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M13.3333 1.66602V5.00018"
|
||||||
|
stroke="#78777B"
|
||||||
|
stroke-width="1.25"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M6.66669 1.66602V5.00018"
|
||||||
|
stroke="#78777B"
|
||||||
|
stroke-width="1.25"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path>
|
||||||
|
<path
|
||||||
|
d="M1.66669 8.33398H18.3334"
|
||||||
|
stroke="#78777B"
|
||||||
|
stroke-width="1.25"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_134_3094">
|
||||||
|
<rect
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
fill="white"
|
||||||
|
transform="translate(0 0.000976562)"
|
||||||
|
></rect>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
</n-date-picker>
|
||||||
|
</div>
|
||||||
<n-button @click="handleSearch" class="search-button">
|
<n-button @click="handleSearch" class="search-button">
|
||||||
{{ t("events_calendar.search.button") }}
|
{{ t("events_calendar.search.button") }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 背景图片区域 -->
|
||||||
|
<div class="background-image-container">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/events-calendar-bg.png"
|
||||||
|
alt="Events Calendar Background"
|
||||||
|
class="background-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
|
||||||
</customDefaultPage>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import customDefaultPage from "@/components/customDefaultPage/index.vue";
|
|
||||||
import { reactive } from "vue";
|
import { reactive } from "vue";
|
||||||
import { NDatePicker, NButton } from "naive-ui";
|
import { NDatePicker, NButton } from "naive-ui";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
@ -41,42 +107,112 @@ const handleSearch = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.title {
|
.page-container {
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
.events-container {
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.events-title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
color: #333;
|
line-height: 1.4em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
gap: 32px;
|
||||||
gap: 10px;
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-picker-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-date-picker {
|
.search-date-picker {
|
||||||
width: 14rem;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.n-date-picker) {
|
:deep(.n-input) {
|
||||||
width: 14rem;
|
height: 34px;
|
||||||
.n-input__input {
|
border-radius: 3px;
|
||||||
padding: 4px 0;
|
border: 1px solid #e0e0e6;
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.n-button) {
|
|
||||||
padding: 20px 16px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.search-button {
|
|
||||||
background: #ff7bac;
|
|
||||||
color: #fff;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ff7bac;
|
border-color: #ff7bac;
|
||||||
color: #fff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
:deep(.n-input--focus) {
|
||||||
|
border-color: #ff7bac;
|
||||||
|
box-shadow: 0 0 0 2px rgba(255, 123, 172, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-icon {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-button {
|
||||||
|
height: 34px;
|
||||||
|
padding: 7px 12px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff7bac;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
min-width: 201px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e66f9a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-image-container {
|
||||||
|
background: #fff;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
box-shadow: 0px 3px 14px 0px rgba(0, 0, 0, 0.16);
|
||||||
|
border-radius: 16px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 120px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-image {
|
||||||
|
width: 415px;
|
||||||
|
height: 235px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
aspect-ratio: 83/47;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -66,36 +66,12 @@ import { useI18n } from "vue-i18n";
|
|||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// 年度报告数据
|
// 年度报告数据
|
||||||
const annualReports = ref([
|
const annualReports = ref([
|
||||||
{
|
|
||||||
fileName: "2024 Annual Report Amendment No.2",
|
|
||||||
date: "August 20, 2025",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912625006571/fieeinc_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fileName: "2024 Annual Report Amendment No.1",
|
|
||||||
date: "April 30, 2025",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912625003214/fieeinc_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2024 Annual Report",
|
fileName: "2024 Annual Report",
|
||||||
date: "April 10, 2025",
|
date: "April 10, 2025",
|
||||||
downloadUrl:
|
downloadUrl:
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912625002538/fieeinc_10k.htm",
|
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912625002538/fieeinc_10k.htm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fileName: "2023 Annual Report Amendment",
|
|
||||||
date: "July 28, 2025",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912625005429/fieeinc_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fileName: "2023 Annual Report Amendment No.1",
|
|
||||||
date: "April 29, 2024",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000182912624002836/miniminc_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2023 Annual Report",
|
fileName: "2023 Annual Report",
|
||||||
date: "April 12, 2024",
|
date: "April 12, 2024",
|
||||||
@ -108,48 +84,24 @@ const annualReports = ref([
|
|||||||
downloadUrl:
|
downloadUrl:
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000149315223010335/form10-k.htm",
|
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000149315223010335/form10-k.htm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fileName: "2021 Annual Report Amendment No.1",
|
|
||||||
date: "August 19, 2022",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000149315222023610/form10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2021 Annual Report",
|
fileName: "2021 Annual Report",
|
||||||
date: "March 31, 2022",
|
date: "March 31, 2022",
|
||||||
downloadUrl:
|
downloadUrl:
|
||||||
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000149315222008365/form10-k.htm",
|
"https://www.sec.gov/ix?doc=/Archives/edgar/data/1467761/000149315222008365/form10-k.htm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fileName: "2020 Annual Report Amendment No.1",
|
|
||||||
date: "April 29, 2021",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/Archives/edgar/data/1467761/000114036121015017/brhc10023805_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2020 Annual Report",
|
fileName: "2020 Annual Report",
|
||||||
date: "April 13, 2021",
|
date: "April 13, 2021",
|
||||||
downloadUrl:
|
downloadUrl:
|
||||||
"https://www.sec.gov/Archives/edgar/data/1467761/000165495421004133/zmtp_10k.htm",
|
"https://www.sec.gov/Archives/edgar/data/1467761/000165495421004133/zmtp_10k.htm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fileName: "2019 Annual Report Amendment No.1",
|
|
||||||
date: " April 29, 2020",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/Archives/edgar/data/1467761/000165495420004635/zmtp_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2019 Annual Report",
|
fileName: "2019 Annual Report",
|
||||||
date: "April 15, 2020",
|
date: "April 15, 2020",
|
||||||
downloadUrl:
|
downloadUrl:
|
||||||
"https://www.sec.gov/Archives/edgar/data/1467761/000165495420004069/zmtp_10k.htm",
|
"https://www.sec.gov/Archives/edgar/data/1467761/000165495420004069/zmtp_10k.htm",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fileName: "2018 Annual Report Amendment No.1",
|
|
||||||
date: "April 30, 2019",
|
|
||||||
downloadUrl:
|
|
||||||
"https://www.sec.gov/Archives/edgar/data/1467761/000165495419005031/zmtp_10ka.htm",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fileName: "2018 Annual Report",
|
fileName: "2018 Annual Report",
|
||||||
date: "April 1, 2019",
|
date: "April 1, 2019",
|
||||||
@ -215,6 +167,7 @@ const annualReports = ref([
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.page-container {
|
.page-container {
|
||||||
|
background-image: url("@/assets/image/bg.png");
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<header></header>
|
<header></header>
|
||||||
<main class="p-[35px] max-w-[1200px] mx-auto">
|
<main class="mx-auto">
|
||||||
<div class="title mb-[20px]">
|
<div class="title mb-[20px]">
|
||||||
{{ t("financialinformation.quarterlyreports.title") }}
|
{{ t("financialinformation.quarterlyreports.title") }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="historic-data-container" style="margin-bottom: 40px">
|
<div class="historic-data-container" style="margin-bottom: 40px">
|
||||||
<!-- <img
|
|
||||||
src="@/assets/image/historic-stock.png"
|
|
||||||
alt="1"
|
|
||||||
style="max-width: 100%; margin: 0 auto"
|
|
||||||
/> -->
|
|
||||||
<div class="echarts-container">
|
<div class="echarts-container">
|
||||||
<customEcharts></customEcharts>
|
<customEcharts></customEcharts>
|
||||||
</div>
|
</div>
|
||||||
@ -85,202 +80,202 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NDataTable, NButton, NDropdown, NIcon } from 'naive-ui'
|
import { NDataTable, NButton, NDropdown, NIcon } from "naive-ui";
|
||||||
import { reactive, onMounted, h, computed } from 'vue'
|
import { reactive, onMounted, h, computed } from "vue";
|
||||||
import axios from 'axios'
|
import axios from "axios";
|
||||||
import {
|
import {
|
||||||
ChevronDownOutline,
|
ChevronDownOutline,
|
||||||
ChevronBackOutline,
|
ChevronBackOutline,
|
||||||
ChevronForwardOutline,
|
ChevronForwardOutline,
|
||||||
ArrowUpOutline,
|
ArrowUpOutline,
|
||||||
} from '@vicons/ionicons5'
|
} from "@vicons/ionicons5";
|
||||||
import defaultTableData from '../data'
|
import defaultTableData from "../data";
|
||||||
// console.log('defaultTableData', defaultTableData)
|
// console.log('defaultTableData', defaultTableData)
|
||||||
import customEcharts from '@/components/customEcharts/index.vue'
|
import customEcharts from "@/components/customEcharts/index.vue";
|
||||||
|
|
||||||
// 数据筛选选项
|
// 数据筛选选项
|
||||||
const periodOptions = [
|
const periodOptions = [
|
||||||
{ label: 'Daily', key: 'Daily' },
|
{ label: "Daily", key: "Daily" },
|
||||||
{ label: 'Weekly', key: 'Weekly' },
|
{ label: "Weekly", key: "Weekly" },
|
||||||
{ label: 'Monthly', key: 'Monthly' },
|
{ label: "Monthly", key: "Monthly" },
|
||||||
{ label: 'Quarterly', key: 'Quarterly' },
|
{ label: "Quarterly", key: "Quarterly" },
|
||||||
{ label: 'Annual', key: 'Annual' },
|
{ label: "Annual", key: "Annual" },
|
||||||
]
|
];
|
||||||
|
|
||||||
const durationOptions = [
|
const durationOptions = [
|
||||||
{ label: '3 Months', key: '3 Months' },
|
{ label: "3 Months", key: "3 Months" },
|
||||||
{ label: '6 Months', key: '6 Months' },
|
{ label: "6 Months", key: "6 Months" },
|
||||||
{ label: 'Year to Date', key: 'Year to Date' },
|
{ label: "Year to Date", key: "Year to Date" },
|
||||||
{ label: '1 Year', key: '1 Year' },
|
{ label: "1 Year", key: "1 Year" },
|
||||||
{ label: '5 Years', key: '5 Years' },
|
{ label: "5 Years", key: "5 Years" },
|
||||||
{ label: '10 Years', key: '10 Years' },
|
{ label: "10 Years", key: "10 Years" },
|
||||||
// { label: 'Full History', key: 'Full History', disabled: true },
|
// { label: 'Full History', key: 'Full History', disabled: true },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 分页大小选项
|
// 分页大小选项
|
||||||
const pageSizeOptions = [
|
const pageSizeOptions = [
|
||||||
{ label: '50', key: 50 },
|
{ label: "50", key: 50 },
|
||||||
{ label: '100', key: 100 },
|
{ label: "100", key: 100 },
|
||||||
{ label: '500', key: 500 },
|
{ label: "500", key: 500 },
|
||||||
{ label: '1000', key: 1000 },
|
{ label: "1000", key: 1000 },
|
||||||
]
|
];
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedPeriod: 'Daily',
|
selectedPeriod: "Daily",
|
||||||
selectedDuration: '6 Months',
|
selectedDuration: "6 Months",
|
||||||
tableData: [],
|
tableData: [],
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算总页数
|
// 计算总页数
|
||||||
const totalPages = computed(() => {
|
const totalPages = computed(() => {
|
||||||
return Math.ceil(state.tableData.length / state.pageSize)
|
return Math.ceil(state.tableData.length / state.pageSize);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算当前页的数据
|
// 计算当前页的数据
|
||||||
const paginatedData = computed(() => {
|
const paginatedData = computed(() => {
|
||||||
const start = (state.currentPage - 1) * state.pageSize
|
const start = (state.currentPage - 1) * state.pageSize;
|
||||||
const end = start + state.pageSize
|
const end = start + state.pageSize;
|
||||||
return state.tableData.slice(start, end)
|
return state.tableData.slice(start, end);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: 'Date',
|
title: "Date",
|
||||||
key: 'date',
|
key: "date",
|
||||||
align: 'left',
|
align: "left",
|
||||||
fixed: 'left',
|
fixed: "left",
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Open',
|
title: "Open",
|
||||||
key: 'open',
|
key: "open",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'High',
|
title: "High",
|
||||||
key: 'high',
|
key: "high",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Low',
|
title: "Low",
|
||||||
key: 'low',
|
key: "low",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Close',
|
title: "Close",
|
||||||
key: 'close',
|
key: "close",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Adj. Close',
|
title: "Adj. Close",
|
||||||
key: 'adjClose',
|
key: "adjClose",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Change',
|
title: "Change",
|
||||||
key: 'change',
|
key: "change",
|
||||||
align: 'center',
|
align: "center",
|
||||||
render(row) {
|
render(row) {
|
||||||
const value = parseFloat(row.change)
|
const value = parseFloat(row.change);
|
||||||
const color = value < 0 ? '#ff4d4f' : value > 0 ? '#52c41a' : ''
|
const color = value < 0 ? "#ff4d4f" : value > 0 ? "#52c41a" : "";
|
||||||
return h('span', { style: { color } }, row.change)
|
return h("span", { style: { color } }, row.change);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Volume',
|
title: "Volume",
|
||||||
key: 'volume',
|
key: "volume",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
// 处理下拉选项变更
|
// 处理下拉选项变更
|
||||||
const handlePeriodChange = (key) => {
|
const handlePeriodChange = (key) => {
|
||||||
state.selectedPeriod = key
|
state.selectedPeriod = key;
|
||||||
if (key === 'Annual') {
|
if (key === "Annual") {
|
||||||
handleDurationChange('Full History')
|
handleDurationChange("Full History");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Monthly') {
|
if (key === "Monthly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Quarterly') {
|
if (key === "Quarterly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
getPageData()
|
|
||||||
}
|
}
|
||||||
|
getPageData();
|
||||||
|
};
|
||||||
|
|
||||||
const handleDurationChange = (key) => {
|
const handleDurationChange = (key) => {
|
||||||
state.selectedDuration = key
|
state.selectedDuration = key;
|
||||||
state.currentPage = 1
|
state.currentPage = 1;
|
||||||
getPageData()
|
getPageData();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理分页
|
// 处理分页
|
||||||
const handlePrevPage = () => {
|
const handlePrevPage = () => {
|
||||||
if (state.currentPage === 1) {
|
if (state.currentPage === 1) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage--
|
|
||||||
}
|
}
|
||||||
|
state.currentPage--;
|
||||||
|
};
|
||||||
|
|
||||||
const handleNextPage = () => {
|
const handleNextPage = () => {
|
||||||
if (state.currentPage >= totalPages.value) {
|
if (state.currentPage >= totalPages.value) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage++
|
|
||||||
}
|
}
|
||||||
|
state.currentPage++;
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = (size) => {
|
const handlePageSizeChange = (size) => {
|
||||||
state.pageSize = size
|
state.pageSize = size;
|
||||||
state.currentPage = 1 // 重置到第一页
|
state.currentPage = 1; // 重置到第一页
|
||||||
}
|
};
|
||||||
|
|
||||||
// 回到顶部
|
// 回到顶部
|
||||||
const scrollToTop = () => {
|
const scrollToTop = () => {
|
||||||
// 尝试多种方法
|
// 尝试多种方法
|
||||||
// 1. 使用document.body
|
// 1. 使用document.body
|
||||||
document.body.scrollTop = 0
|
document.body.scrollTop = 0;
|
||||||
// 2. 使用document.documentElement (HTML元素)
|
// 2. 使用document.documentElement (HTML元素)
|
||||||
document.documentElement.scrollTop = 0
|
document.documentElement.scrollTop = 0;
|
||||||
// 3. 使用scrollIntoView
|
// 3. 使用scrollIntoView
|
||||||
document.querySelector('.historic-data-container').scrollIntoView({
|
document.querySelector(".historic-data-container").scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: "smooth",
|
||||||
block: 'start',
|
block: "start",
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPageData()
|
getPageData();
|
||||||
})
|
});
|
||||||
|
|
||||||
const getPageDefaultData = async () => {
|
const getPageDefaultData = async () => {
|
||||||
try {
|
try {
|
||||||
let url =
|
let url =
|
||||||
'https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M'
|
"https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M";
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
let originalData = res.data.data
|
let originalData = res.data.data;
|
||||||
|
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let calcApiData = originalData.map((item) => [
|
let calcApiData = originalData.map((item) => [
|
||||||
new Date(item[0]).toLocaleDateString('en-US', {
|
new Date(item[0]).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
item[1],
|
item[1],
|
||||||
])
|
]);
|
||||||
// console.log('接口数据', calcApiData)
|
// console.log('接口数据', calcApiData)
|
||||||
|
|
||||||
// 使用API数据更新defaultTableData中的close和adjClose值
|
// 使用API数据更新defaultTableData中的close和adjClose值
|
||||||
const updatedTableData = defaultTableData.map((tableItem) => {
|
const updatedTableData = defaultTableData.map((tableItem) => {
|
||||||
// 查找对应日期的API数据
|
// 查找对应日期的API数据
|
||||||
const matchedApiData = calcApiData.find(
|
const matchedApiData = calcApiData.find(
|
||||||
(apiItem) => apiItem[0] === tableItem.date,
|
(apiItem) => apiItem[0] === tableItem.date
|
||||||
)
|
);
|
||||||
|
|
||||||
if (matchedApiData) {
|
if (matchedApiData) {
|
||||||
// 更新close和adjClose值
|
// 更新close和adjClose值
|
||||||
@ -288,100 +283,100 @@ const getPageDefaultData = async () => {
|
|||||||
...tableItem,
|
...tableItem,
|
||||||
close: matchedApiData[1].toFixed(2),
|
close: matchedApiData[1].toFixed(2),
|
||||||
adjClose: matchedApiData[1].toFixed(2),
|
adjClose: matchedApiData[1].toFixed(2),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
return tableItem;
|
||||||
return tableItem
|
});
|
||||||
})
|
|
||||||
|
|
||||||
state.tableData = updatedTableData
|
state.tableData = updatedTableData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.error('获取数据失败', error)
|
// console.error('获取数据失败', error)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const getPageData = async () => {
|
const getPageData = async () => {
|
||||||
let range = ''
|
let range = "";
|
||||||
let now = new Date()
|
let now = new Date();
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
let fromDate = last
|
let fromDate = last;
|
||||||
let toDate =
|
let toDate =
|
||||||
now.getFullYear() +
|
now.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getMonth() + 1).padStart(2, '0') +
|
String(now.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getDate()).padStart(2, '0')
|
String(now.getDate()).padStart(2, "0");
|
||||||
if (state.selectedDuration === '3 Months') {
|
if (state.selectedDuration === "3 Months") {
|
||||||
range = '3M'
|
range = "3M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 3)
|
last.setMonth(now.getMonth() - 3);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '6 Months') {
|
} else if (state.selectedDuration === "6 Months") {
|
||||||
range = '6M'
|
range = "6M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Year to Date') {
|
} else if (state.selectedDuration === "Year to Date") {
|
||||||
range = 'YTD'
|
range = "YTD";
|
||||||
fromDate = new Date(now.getFullYear(), 0, 1)
|
fromDate = new Date(now.getFullYear(), 0, 1);
|
||||||
} else if (state.selectedDuration === '1 Year') {
|
} else if (state.selectedDuration === "1 Year") {
|
||||||
range = '1Y'
|
range = "1Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 1)
|
last.setFullYear(now.getFullYear() - 1);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '5 Years') {
|
} else if (state.selectedDuration === "5 Years") {
|
||||||
range = '5Y'
|
range = "5Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 5)
|
last.setFullYear(now.getFullYear() - 5);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '10 Years') {
|
} else if (state.selectedDuration === "10 Years") {
|
||||||
range = '10Y'
|
range = "10Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 10)
|
last.setFullYear(now.getFullYear() - 10);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Full History') {
|
} else if (state.selectedDuration === "Full History") {
|
||||||
range = 'Max'
|
range = "Max";
|
||||||
fromDate = new Date('2009-10-07')
|
fromDate = new Date("2009-10-07");
|
||||||
}
|
}
|
||||||
let finalFromDate =
|
let finalFromDate =
|
||||||
fromDate.getFullYear() +
|
fromDate.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getMonth() + 1).padStart(2, '0') +
|
String(fromDate.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getDate()).padStart(2, '0')
|
String(fromDate.getDate()).padStart(2, "0");
|
||||||
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
||||||
let url =
|
let url =
|
||||||
'https://common.szjixun.cn/api/stock/history/list?from=' +
|
"https://common.szjixun.cn/api/stock/history/list?from=" +
|
||||||
finalFromDate +
|
finalFromDate +
|
||||||
'&to=' +
|
"&to=" +
|
||||||
toDate
|
toDate;
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
// console.error(res)
|
// console.error(res)
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.data.status === 0) {
|
if (res.data.status === 0) {
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let resultData = res.data.data.map((item) => {
|
let resultData = res.data.data.map((item) => {
|
||||||
return {
|
return {
|
||||||
date: new Date(item.date).toLocaleDateString('en-US', {
|
date: new Date(item.date).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
open: item.open != null ? Number(item.open).toFixed(2) : '',
|
open: item.open != null ? Number(item.open).toFixed(2) : "",
|
||||||
high: item.high != null ? Number(item.high).toFixed(2) : '',
|
high: item.high != null ? Number(item.high).toFixed(2) : "",
|
||||||
low: item.low != null ? Number(item.low).toFixed(2) : '',
|
low: item.low != null ? Number(item.low).toFixed(2) : "",
|
||||||
close: item.close != null ? Number(item.close).toFixed(2) : '',
|
close: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
adjClose: item.close != null ? Number(item.close).toFixed(2) : '',
|
adjClose: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
change:
|
change:
|
||||||
item.changePercent != null
|
item.changePercent != null
|
||||||
? Number(item.changePercent).toFixed(2) + '%'
|
? Number(item.changePercent).toFixed(2) + "%"
|
||||||
: '',
|
: "",
|
||||||
volume: item.volume,
|
volume: item.volume,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
state.tableData = resultData
|
state.tableData = resultData;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="historic-data-container" style="margin-bottom: 40px">
|
<div class="historic-data-container" style="margin-bottom: 40px">
|
||||||
<!-- <img
|
|
||||||
src="@/assets/image/historic-stock-375.png"
|
|
||||||
alt="1"
|
|
||||||
style="max-width: 100%; margin: 0 auto"
|
|
||||||
/> -->
|
|
||||||
<div class="echarts-container">
|
<div class="echarts-container">
|
||||||
<customEcharts></customEcharts>
|
<customEcharts></customEcharts>
|
||||||
</div>
|
</div>
|
||||||
@ -83,202 +78,202 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NDataTable, NButton, NDropdown, NIcon } from 'naive-ui'
|
import { NDataTable, NButton, NDropdown, NIcon } from "naive-ui";
|
||||||
import { reactive, onMounted, h, computed } from 'vue'
|
import { reactive, onMounted, h, computed } from "vue";
|
||||||
import axios from 'axios'
|
import axios from "axios";
|
||||||
import {
|
import {
|
||||||
ChevronDownOutline,
|
ChevronDownOutline,
|
||||||
ChevronBackOutline,
|
ChevronBackOutline,
|
||||||
ChevronForwardOutline,
|
ChevronForwardOutline,
|
||||||
ArrowUpOutline,
|
ArrowUpOutline,
|
||||||
} from '@vicons/ionicons5'
|
} from "@vicons/ionicons5";
|
||||||
import defaultTableData from '../data'
|
import defaultTableData from "../data";
|
||||||
// console.log('defaultTableData', defaultTableData)
|
// console.log('defaultTableData', defaultTableData)
|
||||||
import customEcharts from '@/components/customEcharts/index.vue'
|
import customEcharts from "@/components/customEcharts/index.vue";
|
||||||
|
|
||||||
// 数据筛选选项
|
// 数据筛选选项
|
||||||
const periodOptions = [
|
const periodOptions = [
|
||||||
{ label: 'Daily', key: 'Daily' },
|
{ label: "Daily", key: "Daily" },
|
||||||
{ label: 'Weekly', key: 'Weekly' },
|
{ label: "Weekly", key: "Weekly" },
|
||||||
{ label: 'Monthly', key: 'Monthly' },
|
{ label: "Monthly", key: "Monthly" },
|
||||||
{ label: 'Quarterly', key: 'Quarterly' },
|
{ label: "Quarterly", key: "Quarterly" },
|
||||||
{ label: 'Annual', key: 'Annual' },
|
{ label: "Annual", key: "Annual" },
|
||||||
]
|
];
|
||||||
|
|
||||||
const durationOptions = [
|
const durationOptions = [
|
||||||
{ label: '3 Months', key: '3 Months' },
|
{ label: "3 Months", key: "3 Months" },
|
||||||
{ label: '6 Months', key: '6 Months' },
|
{ label: "6 Months", key: "6 Months" },
|
||||||
{ label: 'Year to Date', key: 'Year to Date' },
|
{ label: "Year to Date", key: "Year to Date" },
|
||||||
{ label: '1 Year', key: '1 Year' },
|
{ label: "1 Year", key: "1 Year" },
|
||||||
{ label: '5 Years', key: '5 Years' },
|
{ label: "5 Years", key: "5 Years" },
|
||||||
{ label: '10 Years', key: '10 Years' },
|
{ label: "10 Years", key: "10 Years" },
|
||||||
// { label: 'Full History', key: 'Full History', disabled: true },
|
// { label: 'Full History', key: 'Full History', disabled: true },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 分页大小选项
|
// 分页大小选项
|
||||||
const pageSizeOptions = [
|
const pageSizeOptions = [
|
||||||
{ label: '50', key: 50 },
|
{ label: "50", key: 50 },
|
||||||
{ label: '100', key: 100 },
|
{ label: "100", key: 100 },
|
||||||
{ label: '500', key: 500 },
|
{ label: "500", key: 500 },
|
||||||
{ label: '1000', key: 1000 },
|
{ label: "1000", key: 1000 },
|
||||||
]
|
];
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedPeriod: 'Daily',
|
selectedPeriod: "Daily",
|
||||||
selectedDuration: '6 Months',
|
selectedDuration: "6 Months",
|
||||||
tableData: [],
|
tableData: [],
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算总页数
|
// 计算总页数
|
||||||
const totalPages = computed(() => {
|
const totalPages = computed(() => {
|
||||||
return Math.ceil(state.tableData.length / state.pageSize)
|
return Math.ceil(state.tableData.length / state.pageSize);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算当前页的数据
|
// 计算当前页的数据
|
||||||
const paginatedData = computed(() => {
|
const paginatedData = computed(() => {
|
||||||
const start = (state.currentPage - 1) * state.pageSize
|
const start = (state.currentPage - 1) * state.pageSize;
|
||||||
const end = start + state.pageSize
|
const end = start + state.pageSize;
|
||||||
return state.tableData.slice(start, end)
|
return state.tableData.slice(start, end);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: 'Date',
|
title: "Date",
|
||||||
key: 'date',
|
key: "date",
|
||||||
align: 'left',
|
align: "left",
|
||||||
fixed: 'left',
|
fixed: "left",
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Open',
|
title: "Open",
|
||||||
key: 'open',
|
key: "open",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'High',
|
title: "High",
|
||||||
key: 'high',
|
key: "high",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Low',
|
title: "Low",
|
||||||
key: 'low',
|
key: "low",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Close',
|
title: "Close",
|
||||||
key: 'close',
|
key: "close",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Adj. Close',
|
title: "Adj. Close",
|
||||||
key: 'adjClose',
|
key: "adjClose",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Change',
|
title: "Change",
|
||||||
key: 'change',
|
key: "change",
|
||||||
align: 'center',
|
align: "center",
|
||||||
render(row) {
|
render(row) {
|
||||||
const value = parseFloat(row.change)
|
const value = parseFloat(row.change);
|
||||||
const color = value < 0 ? '#ff4d4f' : value > 0 ? '#52c41a' : ''
|
const color = value < 0 ? "#ff4d4f" : value > 0 ? "#52c41a" : "";
|
||||||
return h('span', { style: { color } }, row.change)
|
return h("span", { style: { color } }, row.change);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Volume',
|
title: "Volume",
|
||||||
key: 'volume',
|
key: "volume",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
// 处理下拉选项变更
|
// 处理下拉选项变更
|
||||||
const handlePeriodChange = (key) => {
|
const handlePeriodChange = (key) => {
|
||||||
state.selectedPeriod = key
|
state.selectedPeriod = key;
|
||||||
if (key === 'Annual') {
|
if (key === "Annual") {
|
||||||
handleDurationChange('Full History')
|
handleDurationChange("Full History");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Monthly') {
|
if (key === "Monthly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Quarterly') {
|
if (key === "Quarterly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
getPageData()
|
|
||||||
}
|
}
|
||||||
|
getPageData();
|
||||||
|
};
|
||||||
|
|
||||||
const handleDurationChange = (key) => {
|
const handleDurationChange = (key) => {
|
||||||
state.selectedDuration = key
|
state.selectedDuration = key;
|
||||||
state.currentPage = 1
|
state.currentPage = 1;
|
||||||
getPageData()
|
getPageData();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理分页
|
// 处理分页
|
||||||
const handlePrevPage = () => {
|
const handlePrevPage = () => {
|
||||||
if (state.currentPage === 1) {
|
if (state.currentPage === 1) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage--
|
|
||||||
}
|
}
|
||||||
|
state.currentPage--;
|
||||||
|
};
|
||||||
|
|
||||||
const handleNextPage = () => {
|
const handleNextPage = () => {
|
||||||
if (state.currentPage >= totalPages.value) {
|
if (state.currentPage >= totalPages.value) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage++
|
|
||||||
}
|
}
|
||||||
|
state.currentPage++;
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = (size) => {
|
const handlePageSizeChange = (size) => {
|
||||||
state.pageSize = size
|
state.pageSize = size;
|
||||||
state.currentPage = 1 // 重置到第一页
|
state.currentPage = 1; // 重置到第一页
|
||||||
}
|
};
|
||||||
|
|
||||||
// 回到顶部
|
// 回到顶部
|
||||||
const scrollToTop = () => {
|
const scrollToTop = () => {
|
||||||
// 尝试多种方法
|
// 尝试多种方法
|
||||||
// 1. 使用document.body
|
// 1. 使用document.body
|
||||||
document.body.scrollTop = 0
|
document.body.scrollTop = 0;
|
||||||
// 2. 使用document.documentElement (HTML元素)
|
// 2. 使用document.documentElement (HTML元素)
|
||||||
document.documentElement.scrollTop = 0
|
document.documentElement.scrollTop = 0;
|
||||||
// 3. 使用scrollIntoView
|
// 3. 使用scrollIntoView
|
||||||
document.querySelector('.historic-data-container').scrollIntoView({
|
document.querySelector(".historic-data-container").scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: "smooth",
|
||||||
block: 'start',
|
block: "start",
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPageData()
|
getPageData();
|
||||||
})
|
});
|
||||||
|
|
||||||
const getPageDefaultData = async () => {
|
const getPageDefaultData = async () => {
|
||||||
try {
|
try {
|
||||||
let url =
|
let url =
|
||||||
'https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M'
|
"https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M";
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
let originalData = res.data.data
|
let originalData = res.data.data;
|
||||||
|
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let calcApiData = originalData.map((item) => [
|
let calcApiData = originalData.map((item) => [
|
||||||
new Date(item[0]).toLocaleDateString('en-US', {
|
new Date(item[0]).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
item[1],
|
item[1],
|
||||||
])
|
]);
|
||||||
// console.log('接口数据', calcApiData)
|
// console.log('接口数据', calcApiData)
|
||||||
|
|
||||||
// 使用API数据更新defaultTableData中的close和adjClose值
|
// 使用API数据更新defaultTableData中的close和adjClose值
|
||||||
const updatedTableData = defaultTableData.map((tableItem) => {
|
const updatedTableData = defaultTableData.map((tableItem) => {
|
||||||
// 查找对应日期的API数据
|
// 查找对应日期的API数据
|
||||||
const matchedApiData = calcApiData.find(
|
const matchedApiData = calcApiData.find(
|
||||||
(apiItem) => apiItem[0] === tableItem.date,
|
(apiItem) => apiItem[0] === tableItem.date
|
||||||
)
|
);
|
||||||
|
|
||||||
if (matchedApiData) {
|
if (matchedApiData) {
|
||||||
// 更新close和adjClose值
|
// 更新close和adjClose值
|
||||||
@ -286,100 +281,100 @@ const getPageDefaultData = async () => {
|
|||||||
...tableItem,
|
...tableItem,
|
||||||
close: matchedApiData[1].toFixed(2),
|
close: matchedApiData[1].toFixed(2),
|
||||||
adjClose: matchedApiData[1].toFixed(2),
|
adjClose: matchedApiData[1].toFixed(2),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
return tableItem;
|
||||||
return tableItem
|
});
|
||||||
})
|
|
||||||
|
|
||||||
state.tableData = updatedTableData
|
state.tableData = updatedTableData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.error('获取数据失败', error)
|
// console.error('获取数据失败', error)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const getPageData = async () => {
|
const getPageData = async () => {
|
||||||
let range = ''
|
let range = "";
|
||||||
let now = new Date()
|
let now = new Date();
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
let fromDate = last
|
let fromDate = last;
|
||||||
let toDate =
|
let toDate =
|
||||||
now.getFullYear() +
|
now.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getMonth() + 1).padStart(2, '0') +
|
String(now.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getDate()).padStart(2, '0')
|
String(now.getDate()).padStart(2, "0");
|
||||||
if (state.selectedDuration === '3 Months') {
|
if (state.selectedDuration === "3 Months") {
|
||||||
range = '3M'
|
range = "3M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 3)
|
last.setMonth(now.getMonth() - 3);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '6 Months') {
|
} else if (state.selectedDuration === "6 Months") {
|
||||||
range = '6M'
|
range = "6M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Year to Date') {
|
} else if (state.selectedDuration === "Year to Date") {
|
||||||
range = 'YTD'
|
range = "YTD";
|
||||||
fromDate = new Date(now.getFullYear(), 0, 1)
|
fromDate = new Date(now.getFullYear(), 0, 1);
|
||||||
} else if (state.selectedDuration === '1 Year') {
|
} else if (state.selectedDuration === "1 Year") {
|
||||||
range = '1Y'
|
range = "1Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 1)
|
last.setFullYear(now.getFullYear() - 1);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '5 Years') {
|
} else if (state.selectedDuration === "5 Years") {
|
||||||
range = '5Y'
|
range = "5Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 5)
|
last.setFullYear(now.getFullYear() - 5);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '10 Years') {
|
} else if (state.selectedDuration === "10 Years") {
|
||||||
range = '10Y'
|
range = "10Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 10)
|
last.setFullYear(now.getFullYear() - 10);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Full History') {
|
} else if (state.selectedDuration === "Full History") {
|
||||||
range = 'Max'
|
range = "Max";
|
||||||
fromDate = new Date('2009-10-07')
|
fromDate = new Date("2009-10-07");
|
||||||
}
|
}
|
||||||
let finalFromDate =
|
let finalFromDate =
|
||||||
fromDate.getFullYear() +
|
fromDate.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getMonth() + 1).padStart(2, '0') +
|
String(fromDate.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getDate()).padStart(2, '0')
|
String(fromDate.getDate()).padStart(2, "0");
|
||||||
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
||||||
let url =
|
let url =
|
||||||
'https://common.szjixun.cn/api/stock/history/list?from=' +
|
"https://common.szjixun.cn/api/stock/history/list?from=" +
|
||||||
finalFromDate +
|
finalFromDate +
|
||||||
'&to=' +
|
"&to=" +
|
||||||
toDate
|
toDate;
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
// console.error(res)
|
// console.error(res)
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.data.status === 0) {
|
if (res.data.status === 0) {
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let resultData = res.data.data.map((item) => {
|
let resultData = res.data.data.map((item) => {
|
||||||
return {
|
return {
|
||||||
date: new Date(item.date).toLocaleDateString('en-US', {
|
date: new Date(item.date).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
open: item.open != null ? Number(item.open).toFixed(2) : '',
|
open: item.open != null ? Number(item.open).toFixed(2) : "",
|
||||||
high: item.high != null ? Number(item.high).toFixed(2) : '',
|
high: item.high != null ? Number(item.high).toFixed(2) : "",
|
||||||
low: item.low != null ? Number(item.low).toFixed(2) : '',
|
low: item.low != null ? Number(item.low).toFixed(2) : "",
|
||||||
close: item.close != null ? Number(item.close).toFixed(2) : '',
|
close: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
adjClose: item.close != null ? Number(item.close).toFixed(2) : '',
|
adjClose: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
change:
|
change:
|
||||||
item.changePercent != null
|
item.changePercent != null
|
||||||
? Number(item.changePercent).toFixed(2) + '%'
|
? Number(item.changePercent).toFixed(2) + "%"
|
||||||
: '',
|
: "",
|
||||||
volume: item.volume,
|
volume: item.volume,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
state.tableData = resultData
|
state.tableData = resultData;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="historic-data-container" style="margin-bottom: 40px">
|
<div class="historic-data-container" style="margin-bottom: 40px">
|
||||||
<!-- <img
|
|
||||||
src="@/assets/image/historic-stock.png"
|
|
||||||
alt="1"
|
|
||||||
style="max-width: 100%; margin: 0 auto"
|
|
||||||
/> -->
|
|
||||||
<div class="echarts-container">
|
<div class="echarts-container">
|
||||||
<customEcharts></customEcharts>
|
<customEcharts></customEcharts>
|
||||||
</div>
|
</div>
|
||||||
@ -85,202 +80,202 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { NDataTable, NButton, NDropdown, NIcon } from 'naive-ui'
|
import { NDataTable, NButton, NDropdown, NIcon } from "naive-ui";
|
||||||
import { reactive, onMounted, h, computed } from 'vue'
|
import { reactive, onMounted, h, computed } from "vue";
|
||||||
import axios from 'axios'
|
import axios from "axios";
|
||||||
import {
|
import {
|
||||||
ChevronDownOutline,
|
ChevronDownOutline,
|
||||||
ChevronBackOutline,
|
ChevronBackOutline,
|
||||||
ChevronForwardOutline,
|
ChevronForwardOutline,
|
||||||
ArrowUpOutline,
|
ArrowUpOutline,
|
||||||
} from '@vicons/ionicons5'
|
} from "@vicons/ionicons5";
|
||||||
import defaultTableData from '../data'
|
import defaultTableData from "../data";
|
||||||
// console.log('defaultTableData', defaultTableData)
|
// console.log('defaultTableData', defaultTableData)
|
||||||
import customEcharts from '@/components/customEcharts/index.vue'
|
import customEcharts from "@/components/customEcharts/index.vue";
|
||||||
|
|
||||||
// 数据筛选选项
|
// 数据筛选选项
|
||||||
const periodOptions = [
|
const periodOptions = [
|
||||||
{ label: 'Daily', key: 'Daily' },
|
{ label: "Daily", key: "Daily" },
|
||||||
{ label: 'Weekly', key: 'Weekly' },
|
{ label: "Weekly", key: "Weekly" },
|
||||||
{ label: 'Monthly', key: 'Monthly' },
|
{ label: "Monthly", key: "Monthly" },
|
||||||
{ label: 'Quarterly', key: 'Quarterly' },
|
{ label: "Quarterly", key: "Quarterly" },
|
||||||
{ label: 'Annual', key: 'Annual' },
|
{ label: "Annual", key: "Annual" },
|
||||||
]
|
];
|
||||||
|
|
||||||
const durationOptions = [
|
const durationOptions = [
|
||||||
{ label: '3 Months', key: '3 Months' },
|
{ label: "3 Months", key: "3 Months" },
|
||||||
{ label: '6 Months', key: '6 Months' },
|
{ label: "6 Months", key: "6 Months" },
|
||||||
{ label: 'Year to Date', key: 'Year to Date' },
|
{ label: "Year to Date", key: "Year to Date" },
|
||||||
{ label: '1 Year', key: '1 Year' },
|
{ label: "1 Year", key: "1 Year" },
|
||||||
{ label: '5 Years', key: '5 Years' },
|
{ label: "5 Years", key: "5 Years" },
|
||||||
{ label: '10 Years', key: '10 Years' },
|
{ label: "10 Years", key: "10 Years" },
|
||||||
// { label: 'Full History', key: 'Full History', disabled: true },
|
// { label: 'Full History', key: 'Full History', disabled: true },
|
||||||
]
|
];
|
||||||
|
|
||||||
// 分页大小选项
|
// 分页大小选项
|
||||||
const pageSizeOptions = [
|
const pageSizeOptions = [
|
||||||
{ label: '50', key: 50 },
|
{ label: "50", key: 50 },
|
||||||
{ label: '100', key: 100 },
|
{ label: "100", key: 100 },
|
||||||
{ label: '500', key: 500 },
|
{ label: "500", key: 500 },
|
||||||
{ label: '1000', key: 1000 },
|
{ label: "1000", key: 1000 },
|
||||||
]
|
];
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedPeriod: 'Daily',
|
selectedPeriod: "Daily",
|
||||||
selectedDuration: '6 Months',
|
selectedDuration: "6 Months",
|
||||||
tableData: [],
|
tableData: [],
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算总页数
|
// 计算总页数
|
||||||
const totalPages = computed(() => {
|
const totalPages = computed(() => {
|
||||||
return Math.ceil(state.tableData.length / state.pageSize)
|
return Math.ceil(state.tableData.length / state.pageSize);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 计算当前页的数据
|
// 计算当前页的数据
|
||||||
const paginatedData = computed(() => {
|
const paginatedData = computed(() => {
|
||||||
const start = (state.currentPage - 1) * state.pageSize
|
const start = (state.currentPage - 1) * state.pageSize;
|
||||||
const end = start + state.pageSize
|
const end = start + state.pageSize;
|
||||||
return state.tableData.slice(start, end)
|
return state.tableData.slice(start, end);
|
||||||
})
|
});
|
||||||
|
|
||||||
// 表格列定义
|
// 表格列定义
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: 'Date',
|
title: "Date",
|
||||||
key: 'date',
|
key: "date",
|
||||||
align: 'left',
|
align: "left",
|
||||||
fixed: 'left',
|
fixed: "left",
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Open',
|
title: "Open",
|
||||||
key: 'open',
|
key: "open",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'High',
|
title: "High",
|
||||||
key: 'high',
|
key: "high",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Low',
|
title: "Low",
|
||||||
key: 'low',
|
key: "low",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Close',
|
title: "Close",
|
||||||
key: 'close',
|
key: "close",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Adj. Close',
|
title: "Adj. Close",
|
||||||
key: 'adjClose',
|
key: "adjClose",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Change',
|
title: "Change",
|
||||||
key: 'change',
|
key: "change",
|
||||||
align: 'center',
|
align: "center",
|
||||||
render(row) {
|
render(row) {
|
||||||
const value = parseFloat(row.change)
|
const value = parseFloat(row.change);
|
||||||
const color = value < 0 ? '#ff4d4f' : value > 0 ? '#52c41a' : ''
|
const color = value < 0 ? "#ff4d4f" : value > 0 ? "#52c41a" : "";
|
||||||
return h('span', { style: { color } }, row.change)
|
return h("span", { style: { color } }, row.change);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Volume',
|
title: "Volume",
|
||||||
key: 'volume',
|
key: "volume",
|
||||||
align: 'center',
|
align: "center",
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
// 处理下拉选项变更
|
// 处理下拉选项变更
|
||||||
const handlePeriodChange = (key) => {
|
const handlePeriodChange = (key) => {
|
||||||
state.selectedPeriod = key
|
state.selectedPeriod = key;
|
||||||
if (key === 'Annual') {
|
if (key === "Annual") {
|
||||||
handleDurationChange('Full History')
|
handleDurationChange("Full History");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Monthly') {
|
if (key === "Monthly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (key === 'Quarterly') {
|
if (key === "Quarterly") {
|
||||||
handleDurationChange('10 Years')
|
handleDurationChange("10 Years");
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
getPageData()
|
|
||||||
}
|
}
|
||||||
|
getPageData();
|
||||||
|
};
|
||||||
|
|
||||||
const handleDurationChange = (key) => {
|
const handleDurationChange = (key) => {
|
||||||
state.selectedDuration = key
|
state.selectedDuration = key;
|
||||||
state.currentPage = 1
|
state.currentPage = 1;
|
||||||
getPageData()
|
getPageData();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 处理分页
|
// 处理分页
|
||||||
const handlePrevPage = () => {
|
const handlePrevPage = () => {
|
||||||
if (state.currentPage === 1) {
|
if (state.currentPage === 1) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage--
|
|
||||||
}
|
}
|
||||||
|
state.currentPage--;
|
||||||
|
};
|
||||||
|
|
||||||
const handleNextPage = () => {
|
const handleNextPage = () => {
|
||||||
if (state.currentPage >= totalPages.value) {
|
if (state.currentPage >= totalPages.value) {
|
||||||
return
|
return;
|
||||||
}
|
|
||||||
state.currentPage++
|
|
||||||
}
|
}
|
||||||
|
state.currentPage++;
|
||||||
|
};
|
||||||
|
|
||||||
const handlePageSizeChange = (size) => {
|
const handlePageSizeChange = (size) => {
|
||||||
state.pageSize = size
|
state.pageSize = size;
|
||||||
state.currentPage = 1 // 重置到第一页
|
state.currentPage = 1; // 重置到第一页
|
||||||
}
|
};
|
||||||
|
|
||||||
// 回到顶部
|
// 回到顶部
|
||||||
const scrollToTop = () => {
|
const scrollToTop = () => {
|
||||||
// 尝试多种方法
|
// 尝试多种方法
|
||||||
// 1. 使用document.body
|
// 1. 使用document.body
|
||||||
document.body.scrollTop = 0
|
document.body.scrollTop = 0;
|
||||||
// 2. 使用document.documentElement (HTML元素)
|
// 2. 使用document.documentElement (HTML元素)
|
||||||
document.documentElement.scrollTop = 0
|
document.documentElement.scrollTop = 0;
|
||||||
// 3. 使用scrollIntoView
|
// 3. 使用scrollIntoView
|
||||||
document.querySelector('.historic-data-container').scrollIntoView({
|
document.querySelector(".historic-data-container").scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: "smooth",
|
||||||
block: 'start',
|
block: "start",
|
||||||
})
|
});
|
||||||
}
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPageData()
|
getPageData();
|
||||||
})
|
});
|
||||||
|
|
||||||
const getPageDefaultData = async () => {
|
const getPageDefaultData = async () => {
|
||||||
try {
|
try {
|
||||||
let url =
|
let url =
|
||||||
'https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M'
|
"https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=Daily&range=3M";
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
let originalData = res.data.data
|
let originalData = res.data.data;
|
||||||
|
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let calcApiData = originalData.map((item) => [
|
let calcApiData = originalData.map((item) => [
|
||||||
new Date(item[0]).toLocaleDateString('en-US', {
|
new Date(item[0]).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
item[1],
|
item[1],
|
||||||
])
|
]);
|
||||||
// console.log('接口数据', calcApiData)
|
// console.log('接口数据', calcApiData)
|
||||||
|
|
||||||
// 使用API数据更新defaultTableData中的close和adjClose值
|
// 使用API数据更新defaultTableData中的close和adjClose值
|
||||||
const updatedTableData = defaultTableData.map((tableItem) => {
|
const updatedTableData = defaultTableData.map((tableItem) => {
|
||||||
// 查找对应日期的API数据
|
// 查找对应日期的API数据
|
||||||
const matchedApiData = calcApiData.find(
|
const matchedApiData = calcApiData.find(
|
||||||
(apiItem) => apiItem[0] === tableItem.date,
|
(apiItem) => apiItem[0] === tableItem.date
|
||||||
)
|
);
|
||||||
|
|
||||||
if (matchedApiData) {
|
if (matchedApiData) {
|
||||||
// 更新close和adjClose值
|
// 更新close和adjClose值
|
||||||
@ -288,100 +283,100 @@ const getPageDefaultData = async () => {
|
|||||||
...tableItem,
|
...tableItem,
|
||||||
close: matchedApiData[1].toFixed(2),
|
close: matchedApiData[1].toFixed(2),
|
||||||
adjClose: matchedApiData[1].toFixed(2),
|
adjClose: matchedApiData[1].toFixed(2),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
return tableItem;
|
||||||
return tableItem
|
});
|
||||||
})
|
|
||||||
|
|
||||||
state.tableData = updatedTableData
|
state.tableData = updatedTableData;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.error('获取数据失败', error)
|
// console.error('获取数据失败', error)
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
const getPageData = async () => {
|
const getPageData = async () => {
|
||||||
let range = ''
|
let range = "";
|
||||||
let now = new Date()
|
let now = new Date();
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
let fromDate = last
|
let fromDate = last;
|
||||||
let toDate =
|
let toDate =
|
||||||
now.getFullYear() +
|
now.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getMonth() + 1).padStart(2, '0') +
|
String(now.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(now.getDate()).padStart(2, '0')
|
String(now.getDate()).padStart(2, "0");
|
||||||
if (state.selectedDuration === '3 Months') {
|
if (state.selectedDuration === "3 Months") {
|
||||||
range = '3M'
|
range = "3M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 3)
|
last.setMonth(now.getMonth() - 3);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '6 Months') {
|
} else if (state.selectedDuration === "6 Months") {
|
||||||
range = '6M'
|
range = "6M";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setMonth(now.getMonth() - 6)
|
last.setMonth(now.getMonth() - 6);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Year to Date') {
|
} else if (state.selectedDuration === "Year to Date") {
|
||||||
range = 'YTD'
|
range = "YTD";
|
||||||
fromDate = new Date(now.getFullYear(), 0, 1)
|
fromDate = new Date(now.getFullYear(), 0, 1);
|
||||||
} else if (state.selectedDuration === '1 Year') {
|
} else if (state.selectedDuration === "1 Year") {
|
||||||
range = '1Y'
|
range = "1Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 1)
|
last.setFullYear(now.getFullYear() - 1);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '5 Years') {
|
} else if (state.selectedDuration === "5 Years") {
|
||||||
range = '5Y'
|
range = "5Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 5)
|
last.setFullYear(now.getFullYear() - 5);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === '10 Years') {
|
} else if (state.selectedDuration === "10 Years") {
|
||||||
range = '10Y'
|
range = "10Y";
|
||||||
const last = new Date(now)
|
const last = new Date(now);
|
||||||
last.setFullYear(now.getFullYear() - 10)
|
last.setFullYear(now.getFullYear() - 10);
|
||||||
fromDate = last
|
fromDate = last;
|
||||||
} else if (state.selectedDuration === 'Full History') {
|
} else if (state.selectedDuration === "Full History") {
|
||||||
range = 'Max'
|
range = "Max";
|
||||||
fromDate = new Date('2009-10-07')
|
fromDate = new Date("2009-10-07");
|
||||||
}
|
}
|
||||||
let finalFromDate =
|
let finalFromDate =
|
||||||
fromDate.getFullYear() +
|
fromDate.getFullYear() +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getMonth() + 1).padStart(2, '0') +
|
String(fromDate.getMonth() + 1).padStart(2, "0") +
|
||||||
'-' +
|
"-" +
|
||||||
String(fromDate.getDate()).padStart(2, '0')
|
String(fromDate.getDate()).padStart(2, "0");
|
||||||
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
// let url = `https://stockanalysis.com/api/symbol/a/OTC-MINM/history?period=${state.selectedPeriod}&range=${range}`
|
||||||
let url =
|
let url =
|
||||||
'https://common.szjixun.cn/api/stock/history/list?from=' +
|
"https://common.szjixun.cn/api/stock/history/list?from=" +
|
||||||
finalFromDate +
|
finalFromDate +
|
||||||
'&to=' +
|
"&to=" +
|
||||||
toDate
|
toDate;
|
||||||
const res = await axios.get(url)
|
const res = await axios.get(url);
|
||||||
// console.error(res)
|
// console.error(res)
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.data.status === 0) {
|
if (res.data.status === 0) {
|
||||||
// 转换为日期格式:"Nov 26, 2024"
|
// 转换为日期格式:"Nov 26, 2024"
|
||||||
let resultData = res.data.data.map((item) => {
|
let resultData = res.data.data.map((item) => {
|
||||||
return {
|
return {
|
||||||
date: new Date(item.date).toLocaleDateString('en-US', {
|
date: new Date(item.date).toLocaleDateString("en-US", {
|
||||||
month: 'short',
|
month: "short",
|
||||||
day: 'numeric',
|
day: "numeric",
|
||||||
year: 'numeric',
|
year: "numeric",
|
||||||
}),
|
}),
|
||||||
open: item.open != null ? Number(item.open).toFixed(2) : '',
|
open: item.open != null ? Number(item.open).toFixed(2) : "",
|
||||||
high: item.high != null ? Number(item.high).toFixed(2) : '',
|
high: item.high != null ? Number(item.high).toFixed(2) : "",
|
||||||
low: item.low != null ? Number(item.low).toFixed(2) : '',
|
low: item.low != null ? Number(item.low).toFixed(2) : "",
|
||||||
close: item.close != null ? Number(item.close).toFixed(2) : '',
|
close: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
adjClose: item.close != null ? Number(item.close).toFixed(2) : '',
|
adjClose: item.close != null ? Number(item.close).toFixed(2) : "",
|
||||||
change:
|
change:
|
||||||
item.changePercent != null
|
item.changePercent != null
|
||||||
? Number(item.changePercent).toFixed(2) + '%'
|
? Number(item.changePercent).toFixed(2) + "%"
|
||||||
: '',
|
: "",
|
||||||
volume: item.volume,
|
volume: item.volume,
|
||||||
}
|
};
|
||||||
})
|
});
|
||||||
state.tableData = resultData
|
state.tableData = resultData;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@ -2,13 +2,68 @@
|
|||||||
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 { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
function resolveAssetUrl(possiblePath) {
|
||||||
|
try {
|
||||||
|
if (possiblePath.startsWith("@/")) {
|
||||||
|
return new URL(possiblePath.replace("@/", "/src/"), import.meta.url).href;
|
||||||
|
}
|
||||||
|
if (possiblePath.startsWith("/src/")) {
|
||||||
|
return new URL(possiblePath, import.meta.url).href;
|
||||||
|
}
|
||||||
|
return possiblePath;
|
||||||
|
} catch (e) {
|
||||||
|
return possiblePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultBgUrl = resolveAssetUrl("@/assets/image/1920/bg-pc.png");
|
||||||
|
|
||||||
|
const currentBg = computed(() => {
|
||||||
|
// 支持三种:
|
||||||
|
// 1) 'url("@/xxx.png") ...' → 解析成真实 URL 并仅设置 backgroundImage,由类控制 cover/center/no-repeat
|
||||||
|
// 2) '@/xxx.png' 或 '/src/xxx.png' → 按图片处理
|
||||||
|
// 3) 纯色 '#xxxxxx' 或 'rgb(...)' → 作为背景色
|
||||||
|
const metaBg = route.meta?.bg;
|
||||||
|
if (!metaBg) return { backgroundImage: `url(${defaultBgUrl})` };
|
||||||
|
const value = String(metaBg).trim();
|
||||||
|
if (value.startsWith("#") || value.startsWith("rgb")) {
|
||||||
|
return { backgroundColor: value };
|
||||||
|
}
|
||||||
|
// 匹配 url("...") 或 url('...') 或 url(...)
|
||||||
|
const urlMatch = value.match(/url\(([^)]+)\)/i);
|
||||||
|
if (urlMatch) {
|
||||||
|
const rawPath = urlMatch[1].replace(/^['\"]|['\"]$/g, "");
|
||||||
|
const resolved = resolveAssetUrl(rawPath);
|
||||||
|
return { backgroundImage: `url(${resolved})` };
|
||||||
|
}
|
||||||
|
// 直接给出资源路径的情况
|
||||||
|
if (
|
||||||
|
value.endsWith(".png") ||
|
||||||
|
value.endsWith(".jpg") ||
|
||||||
|
value.endsWith(".jpeg") ||
|
||||||
|
value.endsWith(".webp") ||
|
||||||
|
value.endsWith(".gif") ||
|
||||||
|
value.endsWith(".svg")
|
||||||
|
) {
|
||||||
|
const resolved = resolveAssetUrl(value);
|
||||||
|
return { backgroundImage: `url(${resolved})` };
|
||||||
|
}
|
||||||
|
// 兜底:当作颜色或直接背景
|
||||||
|
return { background: value };
|
||||||
|
});
|
||||||
</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
|
||||||
class="bg-[url('@/assets/image/bg-pc.png')] bg-cover bg-center flex-1"
|
class="bg-cover bg-center bg-no-repeat flex-1"
|
||||||
|
style="background-size: 100% 100%; background-attachment: fixed"
|
||||||
|
:style="currentBg"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<router-view />
|
<router-view />
|
||||||
|
@ -93,7 +93,8 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="w-[900px] m-[auto] my-[64px] flex flex-col items-center h-[190px] text-center"
|
style="height: 190px; width: 900px"
|
||||||
|
class="m-[auto] my-[64px] flex flex-col items-center text-center"
|
||||||
>
|
>
|
||||||
<h2 class="section-titles">
|
<h2 class="section-titles">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
@ -115,7 +116,7 @@
|
|||||||
class="w-[95px]"
|
class="w-[95px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p style="font-size: 18px" class="w-[438px] my-0">
|
<p style="font-size: 14px; width: 439px" class="my-0 text-[#455363]">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@ -138,9 +139,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- 新闻模块 -->
|
<!-- 新闻模块 -->
|
||||||
<section class="news-section" style="width: 900px; margin: 60px auto">
|
<section class="news-section relative z-99" style="width: 900px; margin: 60px auto">
|
||||||
<h2 class="section-titles">{{ $t("HOME.CONTAINY.NEWS.TITLE") }}</h2>
|
<div class="flex justify-between">
|
||||||
<div class="grid grid-cols-2 gap-[15px]">
|
<h2 class="section-titles section-titles1">
|
||||||
|
{{ $t("HOME.CONTAINY.NEWS.TITLE") }}
|
||||||
|
</h2>
|
||||||
|
<div v-if="totalPages > 1">
|
||||||
|
<!-- 左右切换按钮 -->
|
||||||
|
<img
|
||||||
|
v-if="currentPage === 0"
|
||||||
|
disabled
|
||||||
|
class="w-[38px] h-[38px]"
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="prevPage"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] cursor-pointer"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="currentPage >= totalPages - 1"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] ml-[20px]"
|
||||||
|
disabled
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="nextPage"
|
||||||
|
class="w-[38px] h-[38px] ml-[20px] cursor-pointer"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="grid grid-cols-2 gap-[15px]">
|
||||||
<template v-for="(item, index) in newList" :key="index">
|
<template v-for="(item, index) in newList" :key="index">
|
||||||
<div
|
<div
|
||||||
class="h-[246px] news-card flex flex-col justify-between"
|
class="h-[246px] news-card flex flex-col justify-between"
|
||||||
@ -185,6 +223,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- Grid 布局容器 -->
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="col-span-2 grid grid-cols-2 gap-4">
|
||||||
|
<template v-for="(item, index) in pages" :key="index">
|
||||||
|
<div
|
||||||
|
class="h-[246px] news-card flex flex-col justify-between"
|
||||||
|
:class="{
|
||||||
|
'col-span-2':
|
||||||
|
pages.length % 2 !== 0 && index === pages.length - 1,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="text-[24px] font-600">{{ item.time }}</div>
|
||||||
|
<n-tooltip
|
||||||
|
trigger="hover"
|
||||||
|
:disabled="!item.showTooltip"
|
||||||
|
width="trigger"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div
|
||||||
|
:ref="(el) => setTitleRef(el, index)"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
"
|
||||||
|
class="text-[16px] text-[#455363]"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div slot="content" class="text-[16px] text-[#455363]">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</n-tooltip>
|
||||||
|
<div
|
||||||
|
class="text-[16px] text-[#FF7BAC] font-500 flex items-center cursor-pointer"
|
||||||
|
@click="handleLink(item)"
|
||||||
|
>
|
||||||
|
View Press Release
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/vector.png"
|
||||||
|
alt=""
|
||||||
|
class="ml-[10px] w-[6.5px] h-[13px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="news-card">
|
<!-- <div class="news-card">
|
||||||
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
||||||
@ -263,49 +354,59 @@
|
|||||||
background-color: #e7407e;
|
background-color: #e7407e;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="w-[900px] m-auto">
|
<div style="width: 900px" class="w-[900px] m-auto">
|
||||||
<!-- 股票信息卡片 -->
|
<!-- 股票信息卡片 -->
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
||||||
<div class="stock-data">
|
<div class="stock-data">
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label"> Time </span>
|
<span class="data-label"> Time </span>
|
||||||
<span class="data-value">{{ sampleDate }}</span>
|
<span class="data-value">{{ sampleDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">${{ stockQuote.price }}</span>
|
<span class="data-value">${{ stockQuote.price }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
||||||
<span
|
<span class="data-value">{{ stockQuote.change || "--" }}</span>
|
||||||
class="data-value"
|
|
||||||
:class="
|
|
||||||
stockQuote.change?.includes('-')
|
|
||||||
? 'text-green-500'
|
|
||||||
: 'text-red-500'
|
|
||||||
"
|
|
||||||
>{{ stockQuote.change || "--" }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">NASDAQ: FIEE</span>
|
<span class="data-value">NASDAQ: FIEE</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">{{ stockQuote.volume }}</span>
|
<span class="data-value">{{ stockQuote.volume }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
||||||
}}</span>
|
}}</span>
|
||||||
@ -361,7 +462,7 @@
|
|||||||
class="dual-column-section"
|
class="dual-column-section"
|
||||||
style="width: 100vw; height: 643px; margin: 60px auto; padding: 0 40px"
|
style="width: 100vw; height: 643px; margin: 60px auto; padding: 0 40px"
|
||||||
>
|
>
|
||||||
<div class="w-[900px] m-auto">
|
<div class="w-[900PX] m-auto">
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2 class="card-title1">
|
<h2 class="card-title1">
|
||||||
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
||||||
@ -419,6 +520,42 @@ import { useI18n } from "vue-i18n";
|
|||||||
import { useStockQuote } from "@/store/stock-quote/index.js";
|
import { useStockQuote } from "@/store/stock-quote/index.js";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
||||||
|
|
||||||
|
// 每页显示的项目数 - 最多三行,每行最多2个项目,所以每页最多6个项目
|
||||||
|
const itemsPerPage = 6;
|
||||||
|
|
||||||
|
// 当前页码
|
||||||
|
const currentPage = ref(0);
|
||||||
|
|
||||||
|
// 计算总页数
|
||||||
|
const totalPages = computed(() => {
|
||||||
|
return Math.ceil(newList.value.length / itemsPerPage);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将数据分页,最多返回6个项目
|
||||||
|
const pages = computed(() => {
|
||||||
|
// 使用slice确保只处理前6个项目
|
||||||
|
const limitedItems = newList.value.slice(
|
||||||
|
currentPage.value * itemsPerPage,
|
||||||
|
(currentPage.value + 1) * itemsPerPage
|
||||||
|
);
|
||||||
|
return limitedItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 切换到上一页
|
||||||
|
const prevPage = () => {
|
||||||
|
if (currentPage.value > 0) {
|
||||||
|
currentPage.value--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换到下一页
|
||||||
|
const nextPage = () => {
|
||||||
|
if (currentPage.value < totalPages.value - 1) {
|
||||||
|
currentPage.value++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
getStockQuate();
|
getStockQuate();
|
||||||
// 示例数据
|
// 示例数据
|
||||||
const sampleDate = ref(formatted);
|
const sampleDate = ref(formatted);
|
||||||
@ -614,6 +751,16 @@ const handleLink = (item) => {
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
color: black;
|
color: black;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.section-titles1::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 60px;
|
||||||
|
height: 4px;
|
||||||
|
background: #ff7bac;
|
||||||
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-block {
|
.content-block {
|
||||||
@ -743,8 +890,7 @@ const handleLink = (item) => {
|
|||||||
/* justify-content: space-between; */
|
/* justify-content: space-between; */
|
||||||
margin: 24px 0;
|
margin: 24px 0;
|
||||||
border-left: 2px solid #00ffff;
|
border-left: 2px solid #00ffff;
|
||||||
transform: translateX(-10px);
|
|
||||||
padding-left: 10px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,8 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="w-[900px] m-[auto] my-[64px] flex flex-col items-center h-[190px] text-center"
|
style="height: 190px; width: 900px"
|
||||||
|
class="m-[auto] my-[64px] flex flex-col items-center text-center"
|
||||||
>
|
>
|
||||||
<h2 class="section-titles">
|
<h2 class="section-titles">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
@ -115,7 +116,7 @@
|
|||||||
class="w-[95px]"
|
class="w-[95px]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p style="font-size: 18px" class="w-[438px] my-0">
|
<p style="font-size: 14px; width: 439px" class="my-0 text-[#455363]">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@ -138,9 +139,46 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- 新闻模块 -->
|
<!-- 新闻模块 -->
|
||||||
<section class="news-section" style="width: 900px; margin: 60px auto">
|
<section class="news-section relative z-99" style="width: 900px; margin: 60px auto;">
|
||||||
<h2 class="section-titles">{{ $t("HOME.CONTAINY.NEWS.TITLE") }}</h2>
|
<div class="flex justify-between">
|
||||||
<div class="grid grid-cols-2 gap-[15px]">
|
<h2 class="section-titles section-titles1">
|
||||||
|
{{ $t("HOME.CONTAINY.NEWS.TITLE") }}
|
||||||
|
</h2>
|
||||||
|
<div v-if="totalPages > 1">
|
||||||
|
<!-- 左右切换按钮 -->
|
||||||
|
<img
|
||||||
|
v-if="currentPage === 0"
|
||||||
|
disabled
|
||||||
|
class="w-[38px] h-[38px]"
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="prevPage"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] cursor-pointer"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="currentPage >= totalPages - 1"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] ml-[20px]"
|
||||||
|
disabled
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="nextPage"
|
||||||
|
class="w-[38px] h-[38px] ml-[20px] cursor-pointer"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="grid grid-cols-2 gap-[15px]">
|
||||||
<template v-for="(item, index) in newList" :key="index">
|
<template v-for="(item, index) in newList" :key="index">
|
||||||
<div
|
<div
|
||||||
class="h-[246px] news-card flex flex-col justify-between"
|
class="h-[246px] news-card flex flex-col justify-between"
|
||||||
@ -185,6 +223,59 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- Grid 布局容器 -->
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="col-span-2 grid grid-cols-2 gap-4">
|
||||||
|
<template v-for="(item, index) in pages" :key="index">
|
||||||
|
<div
|
||||||
|
class="h-[246px] news-card flex flex-col justify-between"
|
||||||
|
:class="{
|
||||||
|
'col-span-2':
|
||||||
|
pages.length % 2 !== 0 && index === pages.length - 1,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="text-[24px] font-600">{{ item.time }}</div>
|
||||||
|
<n-tooltip
|
||||||
|
trigger="hover"
|
||||||
|
:disabled="!item.showTooltip"
|
||||||
|
width="trigger"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div
|
||||||
|
:ref="(el) => setTitleRef(el, index)"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
"
|
||||||
|
class="text-[16px] text-[#455363]"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div slot="content" class="text-[16px] text-[#455363]">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</n-tooltip>
|
||||||
|
<div
|
||||||
|
class="text-[16px] text-[#FF7BAC] font-500 flex items-center cursor-pointer"
|
||||||
|
@click="handleLink(item)"
|
||||||
|
>
|
||||||
|
View Press Release
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/vector.png"
|
||||||
|
alt=""
|
||||||
|
class="ml-[10px] w-[6.5px] h-[13px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="news-card">
|
<!-- <div class="news-card">
|
||||||
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
||||||
@ -263,49 +354,59 @@
|
|||||||
background-color: #e7407e;
|
background-color: #e7407e;
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="w-[900px] m-auto">
|
<div style="width: 900px" class="w-[900px] m-auto">
|
||||||
<!-- 股票信息卡片 -->
|
<!-- 股票信息卡片 -->
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
||||||
<div class="stock-data">
|
<div class="stock-data">
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label"> Time </span>
|
<span class="data-label"> Time </span>
|
||||||
<span class="data-value">{{ sampleDate }}</span>
|
<span class="data-value">{{ sampleDate }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">${{ stockQuote.price }}</span>
|
<span class="data-value">${{ stockQuote.price }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
||||||
<span
|
<span class="data-value">{{ stockQuote.change || "--" }}</span>
|
||||||
class="data-value"
|
|
||||||
:class="
|
|
||||||
stockQuote.change?.includes('-')
|
|
||||||
? 'text-green-500'
|
|
||||||
: 'text-red-500'
|
|
||||||
"
|
|
||||||
>{{ stockQuote.change || "--" }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">NASDAQ: FIEE</span>
|
<span class="data-value">NASDAQ: FIEE</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="data-value">{{ stockQuote.volume }}</span>
|
<span class="data-value">{{ stockQuote.volume }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div
|
||||||
|
class="data-row"
|
||||||
|
style="transform: translateX(-10px); padding-left: 10px"
|
||||||
|
>
|
||||||
<span class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
||||||
}}</span>
|
}}</span>
|
||||||
@ -361,7 +462,7 @@
|
|||||||
class="dual-column-section"
|
class="dual-column-section"
|
||||||
style="width: 100vw; height: 643px; margin: 60px auto; padding: 0 40px"
|
style="width: 100vw; height: 643px; margin: 60px auto; padding: 0 40px"
|
||||||
>
|
>
|
||||||
<div class="w-[900px] m-auto">
|
<div class="w-[900PX] m-auto">
|
||||||
<div class="">
|
<div class="">
|
||||||
<h2 class="card-title1">
|
<h2 class="card-title1">
|
||||||
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
||||||
@ -419,6 +520,42 @@ import { useI18n } from "vue-i18n";
|
|||||||
import { useStockQuote } from "@/store/stock-quote/index.js";
|
import { useStockQuote } from "@/store/stock-quote/index.js";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
||||||
|
|
||||||
|
// 每页显示的项目数 - 最多三行,每行最多2个项目,所以每页最多6个项目
|
||||||
|
const itemsPerPage = 6;
|
||||||
|
|
||||||
|
// 当前页码
|
||||||
|
const currentPage = ref(0);
|
||||||
|
|
||||||
|
// 计算总页数
|
||||||
|
const totalPages = computed(() => {
|
||||||
|
return Math.ceil(newList.value.length / itemsPerPage);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将数据分页,最多返回6个项目
|
||||||
|
const pages = computed(() => {
|
||||||
|
// 使用slice确保只处理前6个项目
|
||||||
|
const limitedItems = newList.value.slice(
|
||||||
|
currentPage.value * itemsPerPage,
|
||||||
|
(currentPage.value + 1) * itemsPerPage
|
||||||
|
);
|
||||||
|
return limitedItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 切换到上一页
|
||||||
|
const prevPage = () => {
|
||||||
|
if (currentPage.value > 0) {
|
||||||
|
currentPage.value--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换到下一页
|
||||||
|
const nextPage = () => {
|
||||||
|
if (currentPage.value < totalPages.value - 1) {
|
||||||
|
currentPage.value++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
getStockQuate();
|
getStockQuate();
|
||||||
// 示例数据
|
// 示例数据
|
||||||
const sampleDate = ref(formatted);
|
const sampleDate = ref(formatted);
|
||||||
@ -614,6 +751,16 @@ const handleLink = (item) => {
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
color: black;
|
color: black;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.section-titles1::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 60px;
|
||||||
|
height: 4px;
|
||||||
|
background: #ff7bac;
|
||||||
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-block {
|
.content-block {
|
||||||
@ -743,8 +890,7 @@ const handleLink = (item) => {
|
|||||||
/* justify-content: space-between; */
|
/* justify-content: space-between; */
|
||||||
margin: 24px 0;
|
margin: 24px 0;
|
||||||
border-left: 2px solid #00ffff;
|
border-left: 2px solid #00ffff;
|
||||||
transform: translateX(-10px);
|
|
||||||
padding-left: 10px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page relative overflow-hidden z-10 bg-[#ffffff]">
|
||||||
|
<div
|
||||||
|
class="fixed h-[100vh] left-[50%] translate-x-[-50%] z-1"
|
||||||
|
style="width: 630px; pointer-events: none; mix-blend-mode: multiply"
|
||||||
|
>
|
||||||
|
<img src="@/assets/image/content/line.png" class="w-[100%]" alt="" />
|
||||||
|
</div>
|
||||||
|
<div class="w-[100%] h-[813PX] z-[] top-0 absolute">
|
||||||
|
<div class="relative w-[100%] h-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_3.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] h-[813PX] absolute top-[-90PX]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_4.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[312PX] h-[214PX] absolute top-[108PX] left-[50%] translate-x-[-100%]"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/bg_5.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100vw] absolute bottom-[-80PX] lef-0 right-0 z-99"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<section
|
<section
|
||||||
class="company-overview"
|
class="company-overview"
|
||||||
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
|
style="
|
||||||
|
max-width: 618px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 290px;
|
||||||
|
height: 790px;
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="hero-section">
|
<div class="hero-section">
|
||||||
<transition name="fade-up" appear>
|
<transition name="fade-up" appear>
|
||||||
@ -23,15 +54,14 @@
|
|||||||
<!-- 公司概况 -->
|
<!-- 公司概况 -->
|
||||||
<section
|
<section
|
||||||
class="company-overview"
|
class="company-overview"
|
||||||
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
|
style="max-width: 618px; margin: 0 auto; padding: 0;margin-top: 100px;"
|
||||||
>
|
>
|
||||||
<h1 class="section-titles">Company Profile</h1>
|
|
||||||
|
|
||||||
<h3 class="section-title">{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}</h3>
|
<h3 class="section-title">{{ $t("COMPANYOVERVIEW.TITLETWO.TITLE") }}</h3>
|
||||||
<div class="content-block">
|
<h1 class="section-titles">Company Profile</h1>
|
||||||
|
<div class="content-block text-[#455363]">
|
||||||
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
|
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENT") }}</p>
|
||||||
<p>
|
<p>
|
||||||
<text style="color: black">{{
|
<text class="text-[#455363]">{{
|
||||||
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTWOTITLE")
|
$t("COMPANYOVERVIEW.TITLETWO.CONTENTTWOTITLE")
|
||||||
}}</text>
|
}}</text>
|
||||||
|
|
||||||
@ -39,31 +69,195 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE") }}</p>
|
<p>{{ $t("COMPANYOVERVIEW.TITLETWO.CONTENTTHREE") }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-2 gap-4 w-[100%]">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/profile_1.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[293PX] h-[201PX] mx-auto"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/profile_2.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[293PX] h-[201PX] mx-auto"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/profile_3.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[293PX] h-[201PX] mx-auto"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/profile_4.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[293PX] h-[201PX] mx-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- 突出成就 -->
|
<!-- 突出成就 -->
|
||||||
<section
|
<section
|
||||||
class="achievements"
|
class="achievements overflow-hidden z-99 relative"
|
||||||
style="
|
style="
|
||||||
max-width: 1200px;
|
width: 100vw;
|
||||||
margin: 60px auto;
|
|
||||||
padding: 0 40px;
|
padding: 0 40px;
|
||||||
background: #fff;
|
margin-top: 40px;
|
||||||
|
background: linear-gradient(180deg, #e5ffff 0%, #fff8fb 100%);
|
||||||
"
|
"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style="max-width: 618px; height: 260px; padding: 64px 0"
|
||||||
|
class="m-[auto] flex flex-col items-center text-center"
|
||||||
>
|
>
|
||||||
<h2 class="section-titles">
|
<h2 class="section-titles">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.TITLE") }}
|
||||||
</h2>
|
</h2>
|
||||||
<p style="font-size: 18px">
|
<div class="w-100% flex items-center justify-between">
|
||||||
|
<p style="font-size: 14px" class="my-0 text-[#455363]">
|
||||||
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
{{ $t("COMPANYOVERVIEW.TITLEFIVE.CONTENT").replace("•", "") }}
|
||||||
</p>
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<!-- 新闻模块 -->
|
<!-- 新闻模块 -->
|
||||||
<section
|
<section class="news-section relative z-99" style="width: 618px; margin: 60px auto">
|
||||||
class="news-section"
|
<div class="flex justify-between">
|
||||||
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
|
<h2 class="section-titles section-titles1">
|
||||||
|
{{ $t("HOME.CONTAINY.NEWS.TITLE") }}
|
||||||
|
</h2>
|
||||||
|
<div v-if="totalPages > 1">
|
||||||
|
<!-- 左右切换按钮 -->
|
||||||
|
<img
|
||||||
|
v-if="currentPage === 0"
|
||||||
|
disabled
|
||||||
|
class="w-[38px] h-[38px]"
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="prevPage"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] cursor-pointer"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
|
||||||
|
<img
|
||||||
|
v-if="currentPage >= totalPages - 1"
|
||||||
|
class="transform rotate-180 w-[38px] h-[38px] ml-[20px]"
|
||||||
|
disabled
|
||||||
|
src="@/assets/image/content/switch_right.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
v-else
|
||||||
|
@click="nextPage"
|
||||||
|
class="w-[38px] h-[38px] ml-[20px] cursor-pointer"
|
||||||
|
src="@/assets/image/content/switch_left.png"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div class="grid grid-cols-2 gap-[15px]">
|
||||||
|
<template v-for="(item, index) in newList" :key="index">
|
||||||
|
<div
|
||||||
|
class="h-[246px] news-card flex flex-col justify-between"
|
||||||
|
:class="{ 'col-span-2': index === 4 }"
|
||||||
>
|
>
|
||||||
<h2 class="section-titles">{{ $t("HOME.CONTAINY.NEWS.TITLE") }}</h2>
|
<div class="text-[24px] font-600">{{ item.time }}</div>
|
||||||
<div class="news-card">
|
<n-tooltip
|
||||||
|
trigger="hover"
|
||||||
|
:disabled="!item.showTooltip"
|
||||||
|
width="trigger"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div
|
||||||
|
:ref="(el) => setTitleRef(el, index)"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
"
|
||||||
|
class="text-[16px] text-[#455363]"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div slot="content" class="text-[16px] text-[#455363]">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</n-tooltip>
|
||||||
|
<div
|
||||||
|
class="text-[16px] text-[#FF7BAC] font-500 flex items-center cursor-pointer"
|
||||||
|
@click="handleLink(item)"
|
||||||
|
>
|
||||||
|
View Press Release
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/vector.png"
|
||||||
|
alt=""
|
||||||
|
class="ml-[10px] w-[6.5px] h-[13px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<!-- Grid 布局容器 -->
|
||||||
|
<div class="grid grid-cols-2 gap-4">
|
||||||
|
<div class="col-span-2 grid grid-cols-2 gap-4">
|
||||||
|
<template v-for="(item, index) in pages" :key="index">
|
||||||
|
<div
|
||||||
|
style="height: 232px"
|
||||||
|
class="news-card flex flex-col justify-between"
|
||||||
|
:class="{
|
||||||
|
'col-span-2':
|
||||||
|
pages.length % 2 !== 0 && index === pages.length - 1,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<div class="text-[24PX] font-600">{{ item.time }}</div>
|
||||||
|
<n-tooltip
|
||||||
|
trigger="hover"
|
||||||
|
:disabled="!item.showTooltip"
|
||||||
|
width="trigger"
|
||||||
|
>
|
||||||
|
<template #trigger>
|
||||||
|
<div
|
||||||
|
:ref="(el) => setTitleRef(el, index)"
|
||||||
|
style="
|
||||||
|
word-break: break-word;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
"
|
||||||
|
class="text-[16PX] text-[#455363]"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div slot="content" class="text-[16PX] text-[#455363]">
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</n-tooltip>
|
||||||
|
<div
|
||||||
|
class="text-[16PX] text-[#FF7BAC] font-500 flex items-center cursor-pointer"
|
||||||
|
@click="handleLink(item)"
|
||||||
|
>
|
||||||
|
View Press Release
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/vector.png"
|
||||||
|
alt=""
|
||||||
|
class="ml-[10px] w-[6.5px] h-[13px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="news-card">
|
||||||
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
<div style="margin-bottom: 20px" v-for="(item, index) in newList">
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
@ -74,8 +268,9 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div style="font-size: 18px">{{ item.time }}</div>
|
<div style="font-size: 18px">{{ item.time }}</div>
|
||||||
|
|
||||||
<n-tooltip
|
<n-tooltip
|
||||||
trigger="click"
|
trigger="hover"
|
||||||
:disabled="!item.showTooltip"
|
:disabled="!item.showTooltip"
|
||||||
width="trigger"
|
width="trigger"
|
||||||
>
|
>
|
||||||
@ -102,7 +297,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style="font-size: 18px; flex-shrink: 0; margin: 0 0 0 0.9rem"
|
style="font-size: 18px; flex-shrink: 0; margin: 0 0 0 0.6rem"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@click="handleLink(item)"
|
@click="handleLink(item)"
|
||||||
>
|
>
|
||||||
@ -125,81 +320,121 @@
|
|||||||
style="width: 109px; height: 60px"
|
style="width: 109px; height: 60px"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</section>
|
</section>
|
||||||
<!-- 新增:股票信息与活动预告双栏模块 -->
|
<!-- 新增:股票信息与活动预告双栏模块 -->
|
||||||
<section
|
<section
|
||||||
class="dual-column-section"
|
class="dual-column-section bg-[url('@/assets/image/content/information1.png')]"
|
||||||
style="max-width: 1200px; margin: 60px auto; padding: 0 40px"
|
style="
|
||||||
|
width: 100vw;
|
||||||
|
height: 743px;
|
||||||
|
margin: 60px auto;
|
||||||
|
padding: 0 40px;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-color: #e7407e;
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="grid-container">
|
<div style="width: 618px" class="m-auto">
|
||||||
<!-- 股票信息卡片 -->
|
<!-- 股票信息卡片 -->
|
||||||
<div class="info-card stock-card">
|
<div class="">
|
||||||
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
<h2 class="card-title">{{ $t("HOME.CONTAINY.STOCK_INFO.TITLE") }}</h2>
|
||||||
<div class="stock-data">
|
<div class="stock-data">
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label"> Time </span>
|
<span class="data-label"> Time </span>
|
||||||
<span style="font-size: 18px" class="data-value">{{
|
<span class="data-value">{{ sampleDate }}</span>
|
||||||
formatted
|
|
||||||
}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
$t("HOME.CONTAINY.STOCK_INFO.LAST_PRICE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span style="font-size: 18px" class="data-value"
|
<span class="data-value">${{ stockQuote.price }}</span>
|
||||||
>${{ stockQuote.price }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
$t("HOME.CONTAINY.STOCK_INFO.CHANGE")
|
||||||
}}</span>
|
}}</span>
|
||||||
|
|
||||||
<span
|
<span class="data-value">{{ stockQuote.change || "--" }}</span>
|
||||||
style="font-size: 18px"
|
|
||||||
class="data-value"
|
|
||||||
:class="
|
|
||||||
stockQuote.change?.includes('-')
|
|
||||||
? 'text-green-500'
|
|
||||||
: 'text-red-500'
|
|
||||||
"
|
|
||||||
>{{ stockQuote.change || "--" }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
$t("HOME.CONTAINY.STOCK_INFO.STOCK_CODE")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span style="font-size: 18px" class="data-value"
|
<span class="data-value">NASDAQ: FIEE</span>
|
||||||
>NASDAQ: FIEE</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
$t("HOME.CONTAINY.STOCK_INFO.VOLUME")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span style="font-size: 18px" class="data-value">{{
|
<span class="data-value">{{ stockQuote.volume }}</span>
|
||||||
stockQuote.volume
|
|
||||||
}}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span style="font-size: 18px" class="data-label">{{
|
<span class="data-label">{{
|
||||||
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
$t("HOME.CONTAINY.STOCK_INFO.MARKET_CAP")
|
||||||
}}</span>
|
}}</span>
|
||||||
<span style="font-size: 18px" class="data-value"
|
<span class="data-value">${{ stockQuote.marketCap }}</span>
|
||||||
>${{ stockQuote.marketCap }}</span
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 活动预告卡片 -->
|
<!-- 活动预告卡片 -->
|
||||||
<div class="info-card events-card">
|
<!-- <div class="">
|
||||||
<h2 class="card-title">
|
<h2 class="card-title">
|
||||||
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
||||||
</h2>
|
</h2>
|
||||||
|
<div class="event-item"> -->
|
||||||
|
<!-- <h3 class="event-name">
|
||||||
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.EVENT_NAME") }}
|
||||||
|
</h3> -->
|
||||||
|
<!-- <div class="event-detail">
|
||||||
|
<div class="detail-row">
|
||||||
|
<i class="icon-calendar"></i>
|
||||||
|
<span
|
||||||
|
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.DATE") }}:
|
||||||
|
2025年8月12日(二)-2025年8月14日</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<i class="icon-location"></i>
|
||||||
|
<span
|
||||||
|
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.VENUE") }}:
|
||||||
|
6号馆B厅</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<i class="icon-area"></i>
|
||||||
|
<span
|
||||||
|
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.AREA") }}:
|
||||||
|
约10,000m²</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="detail-row">
|
||||||
|
<i class="icon-booth"></i>
|
||||||
|
<span
|
||||||
|
>{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.BOOTHS") }}:
|
||||||
|
约500个标准展位</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
<!-- </div> -->
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section
|
||||||
|
class="dual-column-section"
|
||||||
|
style="width: 100vw; height: 643px; margin: 60px auto; padding: 0 40px"
|
||||||
|
>
|
||||||
|
<div class="w-[618PX] m-auto">
|
||||||
|
<div class="">
|
||||||
|
<h2 class="card-title1">
|
||||||
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.TITLE") }}
|
||||||
|
</h2>
|
||||||
<div class="event-item">
|
<div class="event-item">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/content/empty.png"
|
||||||
|
alt=""
|
||||||
|
class="w-[100%] h-[540px]"
|
||||||
|
/>
|
||||||
<!-- <h3 class="event-name">
|
<!-- <h3 class="event-name">
|
||||||
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.EVENT_NAME") }}
|
{{ $t("HOME.CONTAINY.UPCOMING_EVENTS.EVENT_NAME") }}
|
||||||
</h3> -->
|
</h3> -->
|
||||||
@ -248,12 +483,44 @@ import { useStockQuote } from "@/store/stock-quote/index.js";
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
||||||
|
|
||||||
getStockQuate();
|
// 每页显示的项目数 - 最多三行,每行最多2个项目,所以每页最多6个项目
|
||||||
|
const itemsPerPage = 6;
|
||||||
|
|
||||||
const { t: $t } = useI18n();
|
// 当前页码
|
||||||
const contentRef = ref(null);
|
const currentPage = ref(0);
|
||||||
const isInView = ref(false);
|
|
||||||
let observer = null;
|
// 计算总页数
|
||||||
|
const totalPages = computed(() => {
|
||||||
|
return Math.ceil(newList.value.length / itemsPerPage);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将数据分页,最多返回6个项目
|
||||||
|
const pages = computed(() => {
|
||||||
|
// 使用slice确保只处理前6个项目
|
||||||
|
const limitedItems = newList.value.slice(
|
||||||
|
currentPage.value * itemsPerPage,
|
||||||
|
(currentPage.value + 1) * itemsPerPage
|
||||||
|
);
|
||||||
|
return limitedItems;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 切换到上一页
|
||||||
|
const prevPage = () => {
|
||||||
|
if (currentPage.value > 0) {
|
||||||
|
currentPage.value--;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 切换到下一页
|
||||||
|
const nextPage = () => {
|
||||||
|
if (currentPage.value < totalPages.value - 1) {
|
||||||
|
currentPage.value++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getStockQuate();
|
||||||
|
// 示例数据
|
||||||
|
const sampleDate = ref(formatted);
|
||||||
|
|
||||||
const newList = ref([
|
const newList = ref([
|
||||||
// {
|
// {
|
||||||
@ -268,6 +535,36 @@ const newList = ref([
|
|||||||
// },
|
// },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// 获取新闻发布(展示在首页的)
|
||||||
|
const getPressReleasesDisplay = () => {
|
||||||
|
let url = "https://erpapi.fiee.com/api/fiee/pressreleases/display";
|
||||||
|
let params = {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
display: 2, // 1: 不展示在首页 2: 展示在首页
|
||||||
|
};
|
||||||
|
// console.log(params)
|
||||||
|
axios.post(url, params).then((res) => {
|
||||||
|
// console.log(res)
|
||||||
|
if (res.status === 200) {
|
||||||
|
if (res.data.status === 0) {
|
||||||
|
res.data.data?.data?.forEach((item) => {
|
||||||
|
item.time = new Date(item.createdAt).toLocaleDateString("en-US", {
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
newList.value = res.data.data?.data || [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const { t: $t } = useI18n();
|
||||||
|
const contentRef = ref(null);
|
||||||
|
const isInView = ref(false);
|
||||||
|
let observer = null;
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (contentRef.value && "IntersectionObserver" in window) {
|
if (contentRef.value && "IntersectionObserver" in window) {
|
||||||
observer = new IntersectionObserver(
|
observer = new IntersectionObserver(
|
||||||
@ -327,32 +624,6 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取新闻发布(展示在首页的)
|
|
||||||
const getPressReleasesDisplay = () => {
|
|
||||||
let url = "https://erpapi.fiee.com/api/fiee/pressreleases/display";
|
|
||||||
let params = {
|
|
||||||
page: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
display: 2, // 1: 不展示在首页 2: 展示在首页
|
|
||||||
};
|
|
||||||
// console.log(params)
|
|
||||||
axios.post(url, params).then((res) => {
|
|
||||||
// console.log(res)
|
|
||||||
if (res.status === 200) {
|
|
||||||
if (res.data.status === 0) {
|
|
||||||
res.data.data?.data?.forEach((item) => {
|
|
||||||
item.time = new Date(item.createdAt).toLocaleDateString("en-US", {
|
|
||||||
month: "long",
|
|
||||||
day: "numeric",
|
|
||||||
year: "numeric",
|
|
||||||
});
|
|
||||||
});
|
|
||||||
newList.value = res.data.data?.data || [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (observer) {
|
if (observer) {
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
@ -370,7 +641,7 @@ const handleLink = (item) => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
.home-page {
|
.home-page {
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@ -384,11 +655,11 @@ const handleLink = (item) => {
|
|||||||
}
|
}
|
||||||
/* 顶部大图区域 */
|
/* 顶部大图区域 */
|
||||||
.hero-section {
|
.hero-section {
|
||||||
background: linear-gradient(135deg, #00ffff, #b21f1f, #ff7bac);
|
/* background: linear-gradient(135deg, #00ffff, #b21f1f, #ff7bac); */
|
||||||
background-size: 400% 400%;
|
background-size: 400% 400%;
|
||||||
animation: gradientBG 15s ease infinite;
|
/* animation: gradientBG 15s ease infinite; */
|
||||||
color: white;
|
color: #000;
|
||||||
padding: 40px 20px;
|
padding: 40px 0px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin-bottom: 60px;
|
margin-bottom: 60px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -407,7 +678,7 @@ const handleLink = (item) => {
|
|||||||
}
|
}
|
||||||
.banner-content {
|
.banner-content {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: white;
|
color: #000;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -434,24 +705,34 @@ const handleLink = (item) => {
|
|||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
font-size: 1.5rem; /* 18px */
|
font-size: 1.5rem; /* 18px */
|
||||||
margin-bottom: 30px;
|
margin-bottom: 0;
|
||||||
color: #ff7bac;
|
color: #ff7bac;
|
||||||
}
|
}
|
||||||
.section-titles {
|
.section-titles {
|
||||||
font-size: 2.5rem;
|
font-size: 2.2rem;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 15px;
|
||||||
|
margin-top: 0;
|
||||||
color: black;
|
color: black;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.section-titles1::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 60px;
|
||||||
|
height: 4px;
|
||||||
|
background: #ff7bac;
|
||||||
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-block {
|
.content-block {
|
||||||
font-size: 1.1rem;
|
font-size: 0.9rem;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
.content-blocks {
|
.content-blocks {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
color: #fff;
|
color: #000;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(-200px);
|
transform: translateX(-200px);
|
||||||
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
|
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
|
||||||
@ -523,20 +804,38 @@ const handleLink = (item) => {
|
|||||||
|
|
||||||
.card-title {
|
.card-title {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
margin-bottom: 25px;
|
padding-top: 88px;
|
||||||
color: #333;
|
color: #ffffff;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-bottom: 10px;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-title::after {
|
.card-title::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
height: 3px;
|
height: 4px;
|
||||||
background: linear-gradient(90deg, #121212, #232330);
|
background: #ffffff;
|
||||||
|
transform: translateY(-20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
padding-top: 88px;
|
||||||
|
color: #000;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title1::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
width: 60px;
|
||||||
|
height: 4px;
|
||||||
|
background: #ff7bac;
|
||||||
|
transform: translateY(-20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 股票信息卡片样式 */
|
/* 股票信息卡片样式 */
|
||||||
@ -550,20 +849,24 @@ const handleLink = (item) => {
|
|||||||
|
|
||||||
.data-row {
|
.data-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
/* justify-content: space-between; */
|
||||||
padding: 12px 0;
|
margin: 24px 0;
|
||||||
border-bottom: 1px solid #f0f0f0;
|
border-left: 2px solid #00ffff;
|
||||||
|
transform: translateX(-10px);
|
||||||
|
padding-left: 30px;
|
||||||
|
font-size: 14PX;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-label {
|
.data-label {
|
||||||
color: #666;
|
// font-weight: 500;
|
||||||
font-weight: 500;
|
width: 150px;
|
||||||
font-size: 18px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.data-value {
|
.data-value {
|
||||||
font-weight: 600;
|
// font-weight: 600;
|
||||||
font-size: 18px;
|
font-family: "PingFang SC";
|
||||||
|
letter-spacing: 0.48px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.positive {
|
.positive {
|
||||||
@ -644,7 +947,7 @@ const handleLink = (item) => {
|
|||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
|
||||||
border-left: 4px solid #ff7bac;
|
border-top: 14px solid #ff7bac;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-date {
|
.news-date {
|
||||||
|
@ -54,8 +54,8 @@ const getPressReleasesInfo = () => {
|
|||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.page-container {
|
.page-container {
|
||||||
// max-width: 900px;
|
width: 900PX;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
// padding: 40px;
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="press-releases-page">
|
<div class="press-releases-page">
|
||||||
<n-infinite-scroll :distance="0" @load="doLoadMore">
|
<n-infinite-scroll :distance="0" @load="doLoadMore">
|
||||||
<main class="p-[35px] max-w-[1200px] mx-auto">
|
<main class="mx-auto">
|
||||||
<div class="title mb-[20px]">
|
<div class="title mb-[20px]">
|
||||||
{{ t("press_releases.title") }}
|
{{ t("press_releases.title") }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,35 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="press-releases-page">
|
<div class="press-releases-page">
|
||||||
<n-infinite-scroll :distance="0" @load="doLoadMore">
|
<main class="mx-auto">
|
||||||
<main class="p-[35px] max-w-[1200px] mx-auto">
|
<div class="title-section">
|
||||||
|
<div class="title-decoration"></div>
|
||||||
<div class="title mb-[20px]">
|
<div class="title mb-[20px]">
|
||||||
{{ t("press_releases.title") }}
|
{{ t("press_releases.title") }}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<n-select
|
<n-select
|
||||||
:options="state.selectOptions"
|
:options="state.selectOptions"
|
||||||
v-model:value="state.selectedValue"
|
v-model:value="state.selectedValue"
|
||||||
class="search-select"
|
class="search-select"
|
||||||
/>
|
/>
|
||||||
<n-input
|
<input
|
||||||
v-model:value="state.inputValue"
|
v-model="state.inputValue"
|
||||||
type="text"
|
type="text"
|
||||||
:placeholder="t('press_releases.search.placeholder')"
|
:placeholder="t('press_releases.search.placeholder')"
|
||||||
class="search-input"
|
class="search-input"
|
||||||
/>
|
/>
|
||||||
<n-button @click="handleSearch" class="search-button w-[60px]">
|
<button @click="handleSearch" class="search-button">
|
||||||
{{ t("press_releases.search.button") }}
|
{{ t("press_releases.search.button") }}
|
||||||
</n-button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="(item, idx) in state.filterNewsData" :key="idx">
|
<div class="reports-list">
|
||||||
<div class="news-item mt-[10px]">
|
|
||||||
<div class="news-item-date">{{ item.date }}</div>
|
|
||||||
<div
|
<div
|
||||||
class="news-item-title text-[#0078d7] cursor-pointer"
|
v-for="(item, idx) in state.filterNewsData"
|
||||||
|
:key="idx"
|
||||||
|
class="news-item table-row"
|
||||||
|
>
|
||||||
|
<div class="content">
|
||||||
|
<div class="file-content">
|
||||||
|
<div class="file-info">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
<div
|
||||||
|
class="news-item-title text-[#000] cursor-pointer"
|
||||||
style="
|
style="
|
||||||
word-break: break-word;
|
word-break: break-all;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 1;
|
||||||
|
line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@ -38,19 +48,34 @@
|
|||||||
>
|
>
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
<n-tooltip
|
<svg
|
||||||
trigger="hover"
|
class="arrow-icon"
|
||||||
:disabled="!item.showTooltip"
|
width="7"
|
||||||
width="trigger"
|
height="14"
|
||||||
|
viewBox="0 0 7 14"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
@click="handleNewClick(item)"
|
||||||
>
|
>
|
||||||
|
<path
|
||||||
|
d="M1 1L6 7L1 13"
|
||||||
|
stroke="#FF7BAC"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<n-tooltip trigger="hover" :disabled="true" width="trigger">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<div
|
<div
|
||||||
:ref="(el) => setTitleRef(el, idx)"
|
:ref="(el) => setTitleRef(el, idx)"
|
||||||
class="news-item-content"
|
class="news-item-content file-description"
|
||||||
style="
|
style="
|
||||||
word-break: break-word;
|
word-break: break-all;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 2;
|
-webkit-line-clamp: 1;
|
||||||
|
line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@ -63,17 +88,119 @@
|
|||||||
{{ item.summary }}
|
{{ item.summary }}
|
||||||
</div>
|
</div>
|
||||||
</n-tooltip>
|
</n-tooltip>
|
||||||
|
<div class="download-section">
|
||||||
|
<div class="news-item-date">{{ item.date }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="separator-line"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 分页器 -->
|
||||||
|
<div class="pagination-container" v-if="state.total > 0">
|
||||||
|
<div class="pagination-info">
|
||||||
|
Displaying {{ displayRange.start }} - {{ displayRange.end }} of
|
||||||
|
{{ state.total }} results
|
||||||
|
</div>
|
||||||
|
<div class="pagination-controls">
|
||||||
|
<div class="pagination-buttons">
|
||||||
|
<button
|
||||||
|
class="page-btn prev-btn"
|
||||||
|
:disabled="state.currentPage === 1"
|
||||||
|
@click="goToPrevPage"
|
||||||
|
>
|
||||||
|
<svg width="5" height="9" viewBox="0 0 5 9" fill="none">
|
||||||
|
<path
|
||||||
|
d="M4 1L1 4.5L4 8"
|
||||||
|
stroke="#455363"
|
||||||
|
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"
|
||||||
|
:class="{ active: page === state.currentPage }"
|
||||||
|
@click="goToPage(page)"
|
||||||
|
>
|
||||||
|
{{ page }}
|
||||||
|
</button>
|
||||||
|
<button v-else class="page-btn disabled" disabled>...</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="page-btn 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>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</n-infinite-scroll>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import customDefaultPage from "@/components/customDefaultPage/index.vue";
|
import customDefaultPage from "@/components/customDefaultPage/index.vue";
|
||||||
import { reactive, onMounted, watch, nextTick, ref } from "vue";
|
import {
|
||||||
import { NSelect, NInput, NButton, NInfiniteScroll, NTooltip } from "naive-ui";
|
reactive,
|
||||||
|
onMounted,
|
||||||
|
watch,
|
||||||
|
nextTick,
|
||||||
|
ref,
|
||||||
|
computed,
|
||||||
|
onUnmounted,
|
||||||
|
} from "vue";
|
||||||
|
import { NSelect, NInput, NButton, NTooltip } from "naive-ui";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
@ -94,32 +221,16 @@ const state = reactive({
|
|||||||
}),
|
}),
|
||||||
], //下拉选项
|
], //下拉选项
|
||||||
inputValue: "", //输入值
|
inputValue: "", //输入值
|
||||||
newsData: [
|
|
||||||
{
|
|
||||||
date: "June 3, 2025",
|
|
||||||
title: "FiEE, Inc. seized market opportunities through 2025 Osaka Expo",
|
|
||||||
content:
|
|
||||||
"Hong Kong, 3 June 2025 — FiEE, Inc. (NASDAQ:FIEE) (“FiEE, Inc.” or the “Company”), a technology company integrating IoT, connectivity and AI to redefine brand management solutions in the digital era, is pleased to announce significant business updates....",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: "June 2, 2025",
|
|
||||||
title: "FiEE, Inc. Closes Its First Day of Trading on NASDAQ",
|
|
||||||
content:
|
|
||||||
"Hong Kong, 2 June 2025 — FiEE, Inc. (NASDAQ:FIEE) (“FiEE, Inc.” or the “Company”), a technology company integrating IoT, connectivity and AI to redefine brand management solutions in the digital era, commenced...",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: "May 30, 2025",
|
|
||||||
title: "FiEE, Inc. Announces Reinitiation of Trading on Nasdaq",
|
|
||||||
content:
|
|
||||||
"Hong Kong, May 30, 2025 — FiEE, Inc. (“FiEE, Inc.” or the “Company”), a technology company integrating IoT, connectivity and AI to redefine brand management solutions...",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
filterNewsData: [],
|
filterNewsData: [],
|
||||||
loading: false, //是否正在加载数据
|
loading: false, //是否正在加载数据
|
||||||
hasMore: true, //是否还有更多数据
|
|
||||||
currentPage: 1, //当前页码
|
currentPage: 1, //当前页码
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
gotoPage: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showPageSizeMenu = ref(false);
|
||||||
|
|
||||||
const titleRefs = ref([]);
|
const titleRefs = ref([]);
|
||||||
|
|
||||||
const setTitleRef = (el, idx) => {
|
const setTitleRef = (el, idx) => {
|
||||||
@ -139,14 +250,18 @@ const checkAllTitleOverflow = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// state.filterNewsData = state.newsData;
|
|
||||||
getPressReleasesDisplay();
|
getPressReleasesDisplay();
|
||||||
|
document.addEventListener("click", handleClickOutside);
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
checkAllTitleOverflow();
|
checkAllTitleOverflow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener("click", handleClickOutside);
|
||||||
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => state.filterNewsData,
|
() => state.filterNewsData,
|
||||||
() => {
|
() => {
|
||||||
@ -159,20 +274,21 @@ watch(
|
|||||||
|
|
||||||
// 获取新闻列表
|
// 获取新闻列表
|
||||||
const getPressReleasesDisplay = () => {
|
const getPressReleasesDisplay = () => {
|
||||||
|
state.loading = true;
|
||||||
let url = "https://erpapi.fiee.com/api/fiee/pressreleases/display";
|
let url = "https://erpapi.fiee.com/api/fiee/pressreleases/display";
|
||||||
let params = {
|
let params = {
|
||||||
query: state.inputValue,
|
query: state.inputValue,
|
||||||
page: state.currentPage,
|
page: state.currentPage,
|
||||||
pageSize: 10,
|
pageSize: state.pageSize,
|
||||||
timeStart: state.selectedValue
|
timeStart: state.selectedValue
|
||||||
? state.selectedValue === "all_years"
|
? state.selectedValue === "all_years"
|
||||||
? null
|
? null
|
||||||
: new Date(state.selectedValue).getTime()
|
: new Date(state.selectedValue).getTime()
|
||||||
: null,
|
: null,
|
||||||
};
|
};
|
||||||
// console.log(params)
|
axios
|
||||||
axios.post(url, params).then((res) => {
|
.post(url, params)
|
||||||
// console.log(res)
|
.then((res) => {
|
||||||
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) => {
|
||||||
@ -182,70 +298,44 @@ const getPressReleasesDisplay = () => {
|
|||||||
year: "numeric",
|
year: "numeric",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (state.currentPage === 1) {
|
|
||||||
state.filterNewsData = res.data.data?.data || [];
|
state.filterNewsData = res.data.data?.data || [];
|
||||||
} else {
|
state.total = res.data.data?.total || 0;
|
||||||
state.filterNewsData = [
|
|
||||||
...state.filterNewsData,
|
|
||||||
...(res.data.data?.data || []),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
if (state.filterNewsData.length < (res.data.data?.total || 0)) {
|
|
||||||
state.hasMore = true;
|
|
||||||
} else {
|
|
||||||
state.hasMore = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
state.loading = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFilter = () => {
|
|
||||||
// 筛选逻辑
|
|
||||||
let filteredData = [...state.newsData];
|
|
||||||
|
|
||||||
// 按年份筛选
|
|
||||||
if (state.selectedValue !== "all_years") {
|
|
||||||
filteredData = filteredData.filter((item) => {
|
|
||||||
// 从日期字符串中提取年份,假设日期格式为 "May 30, 2025"
|
|
||||||
const dateMatch = item.date.match(/\b\d{4}\b/);
|
|
||||||
if (dateMatch) {
|
|
||||||
const year = dateMatch[0];
|
|
||||||
return year === state.selectedValue;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按输入内容进行模糊查询(title 和 content)
|
|
||||||
if (state.inputValue && state.inputValue.trim() !== "") {
|
|
||||||
const searchText = state.inputValue.toLowerCase().trim();
|
|
||||||
filteredData = filteredData.filter((item) => {
|
|
||||||
const titleMatch = item.title.toLowerCase().includes(searchText);
|
|
||||||
const contentMatch = item.content.toLowerCase().includes(searchText);
|
|
||||||
return titleMatch || contentMatch;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
state.filterNewsData = filteredData;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 添加 watcher 来实现自动筛选
|
// 添加 watcher 来实现自动筛选
|
||||||
watch(
|
watch(
|
||||||
() => [state.selectedValue, state.inputValue],
|
() => [state.selectedValue, state.inputValue],
|
||||||
() => {
|
() => {
|
||||||
// handleFilter();
|
|
||||||
state.currentPage = 1;
|
state.currentPage = 1;
|
||||||
getPressReleasesDisplay();
|
getPressReleasesDisplay();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSearch = () => {
|
watch(
|
||||||
// 手动触发筛选(保留这个函数以保持兼容性)
|
() => state.pageSize,
|
||||||
// handleFilter();
|
() => {
|
||||||
|
state.currentPage = 1;
|
||||||
|
getPressReleasesDisplay();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => state.currentPage,
|
||||||
|
(newPage) => {
|
||||||
|
state.gotoPage = newPage;
|
||||||
|
getPressReleasesDisplay();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
state.currentPage = 1;
|
state.currentPage = 1;
|
||||||
getPressReleasesDisplay();
|
getPressReleasesDisplay();
|
||||||
// console.log("筛选结果:", state.filterNewsData);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNewClick = (item) => {
|
const handleNewClick = (item) => {
|
||||||
@ -257,21 +347,112 @@ const handleNewClick = (item) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//加载更多数据
|
const totalPages = computed(() => {
|
||||||
const doLoadMore = () => {
|
return Math.ceil(state.total / state.pageSize) || 1;
|
||||||
if (!state.hasMore || state.loading) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// console.log('触底了')
|
|
||||||
state.loading = true;
|
|
||||||
state.currentPage++;
|
|
||||||
getPressReleasesDisplay().finally(() => {
|
|
||||||
state.loading = false;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
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 {
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.title-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
|
}
|
||||||
.title {
|
.title {
|
||||||
font-size: 40px;
|
font-size: 40px;
|
||||||
color: #333;
|
color: #333;
|
||||||
@ -283,18 +464,31 @@ const doLoadMore = () => {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
gap: 10px;
|
gap: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-select {
|
.search-select {
|
||||||
width: 7rem;
|
width: 201px;
|
||||||
:deep(.n-base-selection) {
|
height: 34px;
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
width: 240px;
|
flex: 1;
|
||||||
|
height: 34px;
|
||||||
|
padding: 7px 12px;
|
||||||
|
border: 1px solid #e0e0e6;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #455363;
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
color: #b6b6b6;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.n-input) {
|
:deep(.n-input) {
|
||||||
@ -318,11 +512,294 @@ const doLoadMore = () => {
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.search-button {
|
.search-button {
|
||||||
|
height: 34px;
|
||||||
|
padding: 7px 12px;
|
||||||
|
min-width: 201px;
|
||||||
background: #ff7bac;
|
background: #ff7bac;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
&:hover {
|
&:hover {
|
||||||
background: #ff7bac;
|
background: #ff7bac;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reports-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
.separator-line {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-row .content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0;
|
||||||
|
&:hover {
|
||||||
|
background: #fff8fb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-item-title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-icon {
|
||||||
|
margin-left: auto;
|
||||||
|
flex-shrink: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-line {
|
||||||
|
width: 1px;
|
||||||
|
height: 20px;
|
||||||
|
background: #ff7bac;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-description {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #455363;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 17px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news-item-date {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.375em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #455363;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
padding: 4px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator-line {
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background: repeating-linear-gradient(
|
||||||
|
to right,
|
||||||
|
#e6eaee 0px,
|
||||||
|
#e6eaee 2px,
|
||||||
|
transparent 2px,
|
||||||
|
transparent 4px
|
||||||
|
);
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页器样式
|
||||||
|
.pagination-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
gap: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-info {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.4375em;
|
||||||
|
color: #455363;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination-buttons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.page-btn {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: #ff7bac;
|
||||||
|
color: #ff7bac;
|
||||||
|
background: #fff0f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&: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>
|
||||||
|
34
src/views/product-introduction/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import { useWindowSize } from "@vueuse/core";
|
||||||
|
|
||||||
|
// import size375 from "./size375/index.vue";
|
||||||
|
// import size768 from "./size768/index.vue";
|
||||||
|
// import size1440 from "./size1440/index.vue";
|
||||||
|
import size1920 from "./size1920/index.vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const { width } = useWindowSize();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const viewComponent = computed(() => {
|
||||||
|
const viewWidth = width.value;
|
||||||
|
// if (viewWidth <= 450) {
|
||||||
|
// return size375;
|
||||||
|
// } else if (viewWidth <= 1100) {
|
||||||
|
// return size768;
|
||||||
|
// } else if (viewWidth <= 1500) {
|
||||||
|
// return size1440;
|
||||||
|
// } else if (viewWidth <= 1920 || viewWidth > 1920) {
|
||||||
|
return size1920;
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="viewComponent" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
0
src/views/product-introduction/size1440/index.vue
Normal file
600
src/views/product-introduction/size1920/index.vue
Normal file
@ -0,0 +1,600 @@
|
|||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="page-container">
|
||||||
|
<div class="grid-lines">
|
||||||
|
<div class="line solid line-1"></div>
|
||||||
|
<div class="line dashed line-2"></div>
|
||||||
|
<div class="line dashed line-3"></div>
|
||||||
|
<div class="line dashed line-4"></div>
|
||||||
|
<div class="line solid line-5"></div>
|
||||||
|
</div>
|
||||||
|
<section class="hero-section relative">
|
||||||
|
<div class="hero-content">
|
||||||
|
<div class="hero-title">
|
||||||
|
More than just a tool——<br />
|
||||||
|
Comprehensive growth solutions, <br />
|
||||||
|
providing a one-stop solution for content creation,<br />
|
||||||
|
publishing, analysis, and monetization
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="core-value-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-title">Core Value</div>
|
||||||
|
<div class="card-text">
|
||||||
|
The FIEE-SAAS platform is a one-stop content operation solution
|
||||||
|
tailored for creators in the digital era. The platform utilizes
|
||||||
|
intelligent distribution technology, A1 empowerment tools, and
|
||||||
|
full-chain services,Assist you in efficiently reaching audiences on
|
||||||
|
global mainstream platforms such as TikTok, YouTube, and Instagram,
|
||||||
|
creating a KOL brand effect, unlocking content value, and achieving
|
||||||
|
sustainable growth.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-img2.png"
|
||||||
|
alt="background"
|
||||||
|
class="hero-bg-img"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="features-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="decorator-bar"></div>
|
||||||
|
<div class="section-title">Product Features</div>
|
||||||
|
</div>
|
||||||
|
<div class="features-list">
|
||||||
|
<div class="feature-item">
|
||||||
|
<div class="feature-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
One-click Synchronous Publishing
|
||||||
|
</div>
|
||||||
|
<div class="feature-description">
|
||||||
|
Synchronize graphic and video content to TikTok, YouTube, and
|
||||||
|
Instagram platforms at once, saving time on repetitive operations.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-item">
|
||||||
|
<div class="feature-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Intelligent Scheduled Publishing
|
||||||
|
</div>
|
||||||
|
<div class="feature-description">
|
||||||
|
Plan the content release time in advance, support batch scheduling,
|
||||||
|
and accurately grasp the optimal release time of each platform.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-item">
|
||||||
|
<div class="feature-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Unified Management of Multiple Accounts
|
||||||
|
</div>
|
||||||
|
<div class="feature-description">
|
||||||
|
Easily manage multiple accounts on one platform without the need for
|
||||||
|
repeated login and switching, improving team collaboration
|
||||||
|
efficiency.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-item">
|
||||||
|
<div class="feature-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Cloud Content Library
|
||||||
|
</div>
|
||||||
|
<div class="feature-description">
|
||||||
|
Safely store and manage all creative materials, access and use them
|
||||||
|
anytime, anywhere, and support quick retrieval and reuse.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="feature-item">
|
||||||
|
<div class="feature-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Basic Data Tracking
|
||||||
|
</div>
|
||||||
|
<div class="feature-description">
|
||||||
|
Visually view the content performance of various platforms,
|
||||||
|
understand core data indicators, and provide a basis for optimizing
|
||||||
|
strategies.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="solutions-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<div class="decorator-bar"></div>
|
||||||
|
<div class="section-title">Value Added Solutions</div>
|
||||||
|
</div>
|
||||||
|
<div class="solutions-content">
|
||||||
|
<div class="solutions-list">
|
||||||
|
<div class="solution-item">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-icon1.png"
|
||||||
|
alt="KOL Brand Promotion"
|
||||||
|
class="solution-icon"
|
||||||
|
/>
|
||||||
|
<div class="solution-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
KOL Brand Promotion Services
|
||||||
|
</div>
|
||||||
|
<div class="solution-description">
|
||||||
|
Efficiently connect high-quality business cooperation
|
||||||
|
opportunities and complete the entire process management from
|
||||||
|
order acceptance to publication within the platform.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="solution-item">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-icon2.png"
|
||||||
|
alt="Content Creation Support"
|
||||||
|
class="solution-icon"
|
||||||
|
/>
|
||||||
|
<div class="solution-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Professional Content Creation Support
|
||||||
|
</div>
|
||||||
|
<div class="solution-description">
|
||||||
|
Connect professional shooting and post production teams for you,
|
||||||
|
create high-quality "art+story" content, and strengthen IP
|
||||||
|
influence.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="solution-item">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-icon3.png"
|
||||||
|
alt="Account Operation"
|
||||||
|
class="solution-icon"
|
||||||
|
/>
|
||||||
|
<div class="solution-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Account Operation and Hosting Services
|
||||||
|
</div>
|
||||||
|
<div class="solution-description">
|
||||||
|
From 0 to 1 account positioning, follower growth strategy to
|
||||||
|
monetization cycle, operation experts provide full cycle running
|
||||||
|
and hosting services.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="solution-image-container">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-img1.png"
|
||||||
|
alt="Value Added Solutions"
|
||||||
|
class="solution-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="advantages-section">
|
||||||
|
<div class="advantages-content">
|
||||||
|
<div class="advantages-header">
|
||||||
|
<div class="decorator-bar"></div>
|
||||||
|
<div class="section-title text-white">Our Advantages</div>
|
||||||
|
</div>
|
||||||
|
<div class="advantages-list">
|
||||||
|
<div class="advantage-item">
|
||||||
|
<div class="advantage-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Time Saving
|
||||||
|
</div>
|
||||||
|
<div class="advantage-description">
|
||||||
|
Multi platform publishing efficiency improvement, allowing you to
|
||||||
|
focus on content creation.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="advantage-item">
|
||||||
|
<div class="advantage-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Safe and Reliable
|
||||||
|
</div>
|
||||||
|
<div class="advantage-description">
|
||||||
|
Enterprise level data encryption and permission control ensure
|
||||||
|
account and content security.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="advantage-item">
|
||||||
|
<div class="advantage-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Maintain Consistency
|
||||||
|
</div>
|
||||||
|
<div class="advantage-description">
|
||||||
|
Ensure that brand information is presented uniformly on all
|
||||||
|
platforms.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="advantage-item">
|
||||||
|
<div class="advantage-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Data Driven
|
||||||
|
</div>
|
||||||
|
<div class="advantage-description">
|
||||||
|
Optimizing Content Strategies Based on Actual Performance.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="advantage-item">
|
||||||
|
<div class="advantage-title">
|
||||||
|
<div class="vertical-line"></div>
|
||||||
|
Easy to Use
|
||||||
|
</div>
|
||||||
|
<div class="advantage-description">
|
||||||
|
Intuitive interface design, no need for professional technical
|
||||||
|
background.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="cta-section">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-img5.png"
|
||||||
|
alt="background"
|
||||||
|
class="cta-bg-img"
|
||||||
|
/>
|
||||||
|
<div class="cta-content">
|
||||||
|
<div class="cta-text">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="60"
|
||||||
|
height="32"
|
||||||
|
viewBox="0 0 60 32"
|
||||||
|
fill="none"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M42.4968 0.636391C43.3437 -0.21213 44.7165 -0.21213 45.5635 0.636391L59.3648 14.4638C60.2117 15.3123 60.2117 16.6877 59.3648 17.5362L45.5635 31.3636C44.7165 32.2121 43.3437 32.2121 42.4968 31.3636C41.6499 30.5151 41.6499 29.1397 42.4968 28.2912L52.5962 18.1728H2.16868C0.970951 18.1728 0 17.2 0 16C0 14.8 0.970951 13.8272 2.16868 13.8272H52.5962L42.4968 3.70883C41.6499 2.86031 41.6499 1.48491 42.4968 0.636391Z"
|
||||||
|
fill="#FF7BAC"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
<div class="cta-title">
|
||||||
|
Get customized <br />
|
||||||
|
solutions for free
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="cta-qr-code">
|
||||||
|
<img
|
||||||
|
src="@/assets/image/1920/product-introduction-img6.png"
|
||||||
|
alt="QR Code"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-container {
|
||||||
|
background-color: #fff;
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
/* max-width: 932px; */
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section {
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
background-image: url("@/assets/image/1920/product-introduction-img3.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% auto;
|
||||||
|
background-position: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 56px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
padding: 153px 0;
|
||||||
|
color: #000;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.hero-bg-img {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -84px;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
/* height: 100%; */
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.core-value-card {
|
||||||
|
width: 932px;
|
||||||
|
padding: 40px 32px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: 0px 3px 14px 0px rgba(0, 0, 0, 0.16);
|
||||||
|
text-align: left;
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 56px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-text {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #455363;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.decorator-bar {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background-color: #ff7bac;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 56px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.features-section {
|
||||||
|
padding-top: 200px;
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.features-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.feature-description {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #455363;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solutions-section {
|
||||||
|
padding-top: 80px;
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.solutions-content {
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
.solutions-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
width: 466px;
|
||||||
|
}
|
||||||
|
.solution-item {
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.solution-icon {
|
||||||
|
width: 92px;
|
||||||
|
height: 76px;
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
.solution-title {
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px; /* 133.333% */
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
.solution-description {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
color: #455363;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
.solution-image-container {
|
||||||
|
width: 434px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
.solution-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advantages-section {
|
||||||
|
margin-top: 80px;
|
||||||
|
padding: 80px 0;
|
||||||
|
background-image: url("@/assets/image/1920/product-introduction-img4.png");
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
color: #fff;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advantages-content {
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.advantages-header {
|
||||||
|
width: 466px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
.advantages-list {
|
||||||
|
width: 466px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
.advantage-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
.advantage-title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
display: flex;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
.advantage-description {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0.48px;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
.text-white {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-section {
|
||||||
|
padding: 80px 0;
|
||||||
|
position: relative;
|
||||||
|
max-width: 932px;
|
||||||
|
margin: 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.cta-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 16px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.cta-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 188px;
|
||||||
|
}
|
||||||
|
.cta-arrow {
|
||||||
|
width: 60px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
.cta-title {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 56px;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
.cta-qr-code {
|
||||||
|
width: 188px;
|
||||||
|
height: 188px;
|
||||||
|
background-color: #90ffff;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
.cta-qr-code img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
.cta-bg-img {
|
||||||
|
position: absolute;
|
||||||
|
top: 80px;
|
||||||
|
left: 201px;
|
||||||
|
width: 530px;
|
||||||
|
height: 268px;
|
||||||
|
opacity: 0.8;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
.vertical-line {
|
||||||
|
width: 1px;
|
||||||
|
height: 20px;
|
||||||
|
background: #ff7bac;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-lines {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 932px;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-lines .line {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-lines .line.solid {
|
||||||
|
width: 1px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-lines .line.dashed {
|
||||||
|
width: 0;
|
||||||
|
border-left: 1px dotted rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-lines .line-1 {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.grid-lines .line-2 {
|
||||||
|
left: 233px;
|
||||||
|
}
|
||||||
|
.grid-lines .line-3 {
|
||||||
|
left: 466px;
|
||||||
|
}
|
||||||
|
.grid-lines .line-4 {
|
||||||
|
left: 699px;
|
||||||
|
}
|
||||||
|
.grid-lines .line-5 {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
</style>
|
0
src/views/product-introduction/size375/index.vue
Normal file
0
src/views/product-introduction/size768/index.vue
Normal file
@ -1,80 +1,216 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { useStockQuote } from "@/store/stock-quote/index.js";
|
import { useStockQuote } from "@/store/stock-quote/index.js";
|
||||||
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
const { getStockQuate, stockQuote, formatted } = useStockQuote();
|
||||||
|
console.log(stockQuote);
|
||||||
getStockQuate();
|
getStockQuate();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main
|
<main ref="main" class="stock-quote-hero">
|
||||||
ref="main"
|
<div class="hero-content">
|
||||||
class="flex pt-100px flex-col md:flex-row justify-center items-center gap-32 rounded-3xl"
|
<!-- 标题区域 -->
|
||||||
>
|
<div class="title-section">
|
||||||
<!-- 左侧大号价格 -->
|
<div class="title-decoration"></div>
|
||||||
<section
|
<div class="stock-title">Stock Quote</div>
|
||||||
class="flex flex-col items-center justify-center glass-card p-32 rounded-2xl shadow-xl"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="text-9xl font-extrabold text-#ff7bac animate-bg-move select-none drop-shadow-lg"
|
|
||||||
>
|
|
||||||
${{ stockQuote.price }}
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<section class="quote-layout">
|
||||||
class="mt-10 text-3xl text-gray-500 font-semibold tracking-widest mb-10px"
|
<div class="price-card">
|
||||||
>
|
<div class="price-value">${{ stockQuote.price }}</div>
|
||||||
NASDAQ: <span class="text-black">FIEE</span>
|
<div class="price-market">NASDAQ: FIEE</div>
|
||||||
|
<div class="price-time">{{ formatted }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-500">{{ formatted }}</div>
|
<div class="stats-table">
|
||||||
</section>
|
<div class="stats-cell">
|
||||||
<!-- 右侧信息卡片 -->
|
<span class="stat-title">Open</span>
|
||||||
<section class="grid grid-cols-2 gap-16">
|
<span class="stat-value">{{ stockQuote.open }}</span>
|
||||||
<div class="info-card">
|
|
||||||
<div class="text-lg text-gray-400">Open</div>
|
|
||||||
<div class="text-3xl font-bold">{{ stockQuote.open }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="stats-cell">
|
||||||
<div class="text-lg text-gray-400">% Change</div>
|
<span class="stat-title">% Change</span>
|
||||||
<!-- <div class="text-3xl font-bold"
|
<span
|
||||||
:class="stockQuote.change?.[1]?.startsWith('-') ? 'text-red-500' : (stockQuote.change?.[1]?.startsWith('+') ? 'text-green-500' : '')">
|
class="stat-value"
|
||||||
{{ stockQuote.change?.join('') }}</div> -->
|
|
||||||
<div
|
|
||||||
class="text-3xl font-bold"
|
|
||||||
:class="
|
:class="
|
||||||
stockQuote.change?.includes('-') ? 'text-green-500' : 'text-red-500'
|
stockQuote.change
|
||||||
|
? String(stockQuote.change).includes('-')
|
||||||
|
? 'negative-change'
|
||||||
|
: String(stockQuote.change).includes('+')
|
||||||
|
? 'positive-change'
|
||||||
|
: 'neutral-change'
|
||||||
|
: 'neutral-change'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
{{ stockQuote.change }}
|
{{ stockQuote.change }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stats-cell">
|
||||||
|
<span class="stat-title">Volume</span>
|
||||||
|
<span class="stat-value">{{ stockQuote.volume }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="stats-cell">
|
||||||
<div class="text-lg text-gray-400">Day's Range</div>
|
<span class="stat-title">52-Week Range</span>
|
||||||
<div class="text-3xl font-bold">{{ stockQuote.daysRange }}</div>
|
<span class="stat-value">{{ stockQuote.week52Range }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="stats-cell">
|
||||||
<div class="text-lg text-gray-400">52-Week Range</div>
|
<span class="stat-title">Day's Range</span>
|
||||||
<div class="text-3xl font-bold">{{ stockQuote.week52Range }}</div>
|
<span class="stat-value">{{ stockQuote.daysRange }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
<div class="stats-cell">
|
||||||
<div class="text-lg text-gray-400">Volume</div>
|
<span class="stat-title">Market Cap</span>
|
||||||
<div class="text-3xl font-bold">{{ stockQuote.volume }}</div>
|
<span class="stat-value">{{ stockQuote.marketCap }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-card">
|
|
||||||
<div class="text-lg text-gray-400">Market Cap</div>
|
|
||||||
<div class="text-3xl font-bold">{{ stockQuote.marketCap }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* 玻璃拟态和卡片动画可用 UnoCSS 快捷方式实现,若未配置可加如下样式 */
|
.stock-quote-hero {
|
||||||
.glass-card {
|
position: relative;
|
||||||
backdrop-filter: blur(16px);
|
|
||||||
background: rgba(255, 255, 255, 0.6);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
||||||
box-shadow: 0 8px 32px 0 rgba(255, 123, 172, 0.18);
|
|
||||||
}
|
}
|
||||||
.info-card {
|
|
||||||
@apply glass-card p-6 rounded-xl flex flex-col items-start gap-1 hover:scale-105 transition-transform duration-300;
|
.hero-content {
|
||||||
|
max-width: 930px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
.title-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-decoration {
|
||||||
|
width: 58px;
|
||||||
|
height: 7px;
|
||||||
|
background: #ff7bac;
|
||||||
|
margin: auto 0;
|
||||||
|
margin-top: 43px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stock-title {
|
||||||
|
font-family: "PingFang SC", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40px;
|
||||||
|
line-height: 1.4em;
|
||||||
|
letter-spacing: 3%;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient-badge {
|
||||||
|
width: 48px;
|
||||||
|
height: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #e62968;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
color: #0d1b2a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quote-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-card {
|
||||||
|
width: 466px;
|
||||||
|
min-height: 466px;
|
||||||
|
border-radius: 32px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #f0f3f8;
|
||||||
|
box-shadow: 0 12px 32px rgba(16, 46, 86, 0.08);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-value {
|
||||||
|
font-size: 110px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
background: linear-gradient(90deg, #ff7bac 0%, #0ff 100%);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-market {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #0d1b2a;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price-time {
|
||||||
|
font-size: 18px;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
color: #5a6775;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-table {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
grid-auto-rows: minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats-cell {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 16px 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-title {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #73849a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
color: #455363;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
color: #000;
|
||||||
|
font-feature-settings: "liga" off, "clig" off;
|
||||||
|
font-family: "PingFang SC";
|
||||||
|
font-size: 26px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 56px; /* 215.385% */
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.positive-change {
|
||||||
|
color: #00c48c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.negative-change {
|
||||||
|
color: #cf3050;
|
||||||
|
}
|
||||||
|
|
||||||
|
.neutral-change {
|
||||||
|
color: #0d1b2a;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|