提交 b689b671 authored 作者: liujq23's avatar liujq23

修改冲突

...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
...@@ -4139,7 +4140,7 @@ ...@@ -4139,7 +4140,7 @@
}, },
"node_modules/lodash": { "node_modules/lodash": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "license": "MIT"
}, },
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
......
import request from "@/api/request.js";
import {
ElMessage
} from 'element-plus'
const request200 = (requestP) => {
return requestP.then((data) => {
if (data.code === 200) {
return data.data
}
ElMessage({
message: data.message,
type: 'error',
duration: 3 * 1000
})
return null
})
}
// 实体清单总条数统计
/**
* @returns {Promise<number>}
*/
export function getEntitiesDataCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countData',
}))
}
// 最新实体清单信息查询
/**
* @returns {Promise<{
* chNum: number
* entities:{
* entityNameZh: string
* entityName: string
* }[]
* organization:{
* orgName: string
* }
* domains: string[]
* startTime: string
*}>}
*/
export function getEntitiesDataInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/latestInfoSelect',
}))
}
/**
* 每年最多领域及该领域发布次数
* @returns {Promise<{
* year?: number
* maxDomain: string
* maxCount: number
* }[]>}
*/
export function getIndustryCountByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/industryCountByYear',
}))
}
/**
* 不同领域每年数量
* @returns {Promise<{
* data:{
* year?: number
* domainNum: {
* [ key: string]: number;
* }
* }[]
* domains: string[]
* }>}
*/
export function getCountDomainByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countDomainByYear',
}))
}
/**
* 历次制裁过程(月份统计)
* @returns {Promise<{
* tittle: string
* entitiesChNum: string
* sanReason: string
* }[]>}
*/
export function getSanctionsInfoCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/sanctionsInfoCount',
}))
}
/**
* 查询发布机构
* @returns {Promise<{
* orgName: string //机构名称
* orgIntroduction: string //相关措施
* orgIntroduction: string //机构职责
* }>}
*/
export function getOrganizationInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getOrganizationInfo',
}))
}
/**
* 查询重点人物
* @returns {Promise<{
* name: string
* ename: string
* avatarUrl: string
* positionTitle: string
* }[]>}
*/
export function getPersonList() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getPersonList',
}))
}
/**
* 不同领域实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* domain: string
* count: number
* }[]>}
*/
export function getCountByDomain(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByDomain',
params: {
startTime
}
}))
}
/**
* 不同类型实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountByType(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByType',
params: {
startTime
}
}))
}
/**
* 查询制裁原因
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<string[]>}
*/
export function getSanReasonSelect(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/sanReasonSelect',
params: {
startTime
}
}))
}
/**
* 查询实体清单列表
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* entityNameZh: string
* techDomainList: string[]
* startTime: staring
* }[]>}
*/
export function getSelectEntitiesList(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/selectEntitiesList',
params: {
startTime
}
}))
}
/**
* 数量比对分析
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* countDomainLast: number
* countDomainNow: number
* countSanLast: number
* countSanNow: number
* countTypeLast: number
* countTypeNow: number
* }>}
*/
export function getCompareCountSan(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/compareCountSan',
params: {
startTime
}
}))
}
/**
* 实体清单变化统计
* @param {number} domain
* @param {number} type
* @returns {Promise<{
* year:number
* count:number
* }[]>}
*/
export function getEntitiesChangeCount(domain, type) {
return request200(request({
method: 'GET',
// url: '/api/entitiesDataCount/entitiesChangeCount',
url: '/api/entitiesDataCount/sanCountByYear',
params: {
domain,
type
}
}))
}
/**
* 新增实体数量增长趋势
* @returns {Promise<{
* year: string
* percent: string //百分比'20%'
* }>}
*/
export function getEntitiesGrowthTrend() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesGrowthTrend',
}))
}
/**
* 实体清单更新频率
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesUpdateCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesUpdateCount',
}))
}
/**
* 新增实体领域分布情况
* @param {string} sanTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* value: number
* name: string
* }[]>}
*/
export function getEntitiesAreaCountByYear(sanTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesAreaCountByYear',
params: {
sanTime
}
}))
}
/**
* 历次制裁涉及领域数
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesDomainCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesDomainCount'
}))
}
/**
* 指定领域每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountThisDomain(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisDomain',
params: {
param
}
}))
}
/**
* 历次制裁涉及类别数量
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountTypeByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countTypeByYear',
}))
}
/**
* 新增实体类别统计
* @param {string} startTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountSanTypeByTime(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countSanTypeByTime',
params: {
startTime
}
}))
}
/**
* 指定类别每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: number
* count: number
* }[]>}
*/
export function getCountThisType(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisType',
params: {
param
}
}))
}
import { ref } from 'vue';
export function useRequest(apiFunction, immediate = true) {
const data = ref(null);
const loading = ref(false);
const error = ref(null);
const execute = async (...args) => {
loading.value = true;
error.value = null;
try {
data.value = await apiFunction(...args);
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
};
if (immediate) {
execute(); // 可选:是否立即执行
}
return {
data,
loading,
error,
execute, // 手动触发函数
};
}
\ No newline at end of file
...@@ -6,18 +6,20 @@ ...@@ -6,18 +6,20 @@
<el-select <el-select
:style="{ width: '120px', marginRight: '8px' }" :style="{ width: '120px', marginRight: '8px' }"
size="mini" size="mini"
v-model="value1" v-model="domainValue"
placeholder="领域选择" placeholder="领域选择"
> >
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> <el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select> </el-select>
<el-select <el-select
:style="{ width: '120px', marginRight: '18px' }" :style="{ width: '120px', marginRight: '18px' }"
size="mini" size="mini"
v-model="value2" v-model="typeValue"
placeholder="类型选择" placeholder="类型选择"
> >
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select> </el-select>
</template> </template>
<div class="subPanel1"> <div class="subPanel1">
...@@ -82,28 +84,169 @@ ...@@ -82,28 +84,169 @@
</template> </template>
<script setup> <script setup>
import { ref, shallowRef, onMounted } from "vue"; import { ref, shallowRef, onMounted, watch } from "vue";
import CardCustom from "../../components/CardCustom.vue"; import CardCustom from "../../components/CardCustom.vue";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart } from "../../utils/charts"; import { getBarChart, getLineChart } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
const options = [ import { getEntitiesChangeCount, getEntitiesGrowthTrend, getEntitiesUpdateCount } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const line1Option = shallowRef({});
const bar2Option = shallowRef({});
onMounted(async () => {
try {
const [entitiesGrowthTrendData, entitiesUpdateCountData] = await Promise.all([
getEntitiesGrowthTrend(),
getEntitiesUpdateCount()
]);
const list = _.reverse(entitiesGrowthTrendData);
const xAxisData = _.map(list, "year");
const seriesData = _.map(list, item => {
return parseInt(item.percent);
});
line1Option.value = getLineChart({ xAxisData, seriesData, name: "增长趋势", color: "rgba(146, 84, 222, 1)" }, true);
bar2Option.value = getBarChart(
_.reverse(entitiesUpdateCountData.xAxis),
_.reverse(entitiesUpdateCountData.series),
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
} catch (err) {
console.log(err);
}
});
const domainOptions = [
{ {
value: "1", value: "1",
label: "人工智能" label: "人工智能"
}, },
{ {
value: "2", value: "2",
label: "生物科技"
},
{
value: "3",
label: "新一代信息技术"
},
{
value: "4",
label: "量子科技"
},
{
value: "5",
label: "新能源"
},
{
value: "6",
label: "集成电路"
},
{
value: "7",
label: "海洋"
},
{
value: "8",
label: "先进制造"
},
{
value: "9",
label: "新材料"
},
{
value: "10",
label: "航空航天" label: "航空航天"
},
{
value: "11",
label: "深海"
},
{
value: "12",
label: "极地"
},
{
value: "13",
label: "太空"
},
{
value: "14",
label: "核"
},
{
value: "20",
label: "政治"
},
{
value: "21",
label: "外交"
},
{
value: "22",
label: "经济"
},
{
value: "23",
label: "军事"
},
{
value: "24",
label: "科技"
},
{
value: "25",
label: "安全"
},
{
value: "99",
label: "其他"
} }
]; ];
const value1 = ref(""); const typeOptions = [
const value2 = ref(""); {
const value3 = ref(""); value: "1",
label: "人物"
},
{
value: "2",
label: "机构"
},
{
value: "7",
label: "地址"
}
];
const domainValue = ref(domainOptions[0].value);
const typeValue = ref(typeOptions[0].value);
const bar1Option = shallowRef({}); const bar1Option = shallowRef({});
const bar2Option = shallowRef({}); watch(
const line1Option = shallowRef({}); [domainValue, typeValue],
async ([domain, type]) => {
let EntitiesChangeCount = await getEntitiesChangeCount(domain, type);
EntitiesChangeCount = _.reverse(EntitiesChangeCount);
bar1Option.value = getBarChart(
_.map(EntitiesChangeCount, "year"),
_.map(EntitiesChangeCount, "count"),
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
},
{ immediate: true }
);
// const options = [
// {
// value: "1",
// label: "人工智能"
// },
// {
// value: "2",
// label: "航空航天"
// }
// ];
const subPanel4 = ref([ const subPanel4 = ref([
{ {
name: "中国科学技术大学", name: "中国科学技术大学",
...@@ -141,21 +284,7 @@ const subPanel4 = ref([ ...@@ -141,21 +284,7 @@ const subPanel4 = ref([
] ]
} }
]); ]);
onMounted(() => { const value3 = ref("");
bar1Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[219, 228, 129, 159, 152, 157, 78, 34, 56, 78],
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
line1Option.value = getLineChart();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -121,9 +121,14 @@ onMounted(() => { ...@@ -121,9 +121,14 @@ onMounted(() => {
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], ["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], [39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], ["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率" "市值变化"
); );
line1Option.value = getLineChart(); line1Option.value = getLineChart({
xAxisData: [2013, 2023, 2024, 2015],
seriesData: [434, 24, 453, 322],
name: "融资变化",
color: "rgba(146, 84, 222, 1)"
});
}); });
</script> </script>
......
...@@ -46,30 +46,51 @@ import { Search } from "@element-plus/icons-vue"; ...@@ -46,30 +46,51 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts"; import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
import { getEntitiesAreaCountByYear, getEntitiesDomainCount, getCountThisDomain } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const bar2Option = shallowRef({}); const bar2Option = shallowRef({});
const line1Option = shallowRef({}); const line1Option = shallowRef({});
const line2Option = shallowRef({}); const line2Option = shallowRef({});
onMounted(() => {
pie1Option.value = getPieOption1( onMounted(async () => {
[ try {
{ name: "半导体与集成电路领域", value: 50 }, const [entitiesAreaCountByYearData, countThisDomainData4, entitiesDomainCountData, countThisDomainData10] =
{ name: "生物技术与生命科学领域", value: 46 }, await Promise.all([
{ name: "航天遥感与量子技术领域", value: 12 }, getEntitiesAreaCountByYear(route.query.startTime),
{ name: "航空航天领域", value: 32 }, getCountThisDomain("4"),
{ name: "人工智能领域", value: 31 }, getEntitiesDomainCount(),
{ name: "供应链与物流服务领域", value: 30 }, getCountThisDomain("10")
{ name: "工业软件领域", value: 24 } ]);
]
); pie1Option.value = getPieOption1(entitiesAreaCountByYearData ?? []);
bar2Option.value = getBarChart( const list4 = _.reverse(countThisDomainData4 ?? []);
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], line1Option.value = getLineChart({
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], xAxisData: _.map(list4, "year"),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], seriesData: _.map(list4, "count"),
"更新频率" name: "量子科技领域",
); color: "rgba(255, 149, 77, 1)"
line1Option.value = getLineChart("rgba(255, 149, 77, 1)"); });
line2Option.value = getLineChart("rgba(146, 84, 222, 1)");
bar2Option.value = getBarChart(
_.reverse(entitiesDomainCountData?.xAxis ?? []),
_.reverse(entitiesDomainCountData?.series ?? []),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"领域数"
);
const list10 = _.reverse(countThisDomainData10 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list10, "year"),
seriesData: _.map(list10, "count"),
name: "航空航天领域",
color: "rgba(146, 84, 222, 1)"
});
} catch (err) {
console.log(err);
}
}); });
</script> </script>
......
...@@ -46,28 +46,58 @@ import { Search } from "@element-plus/icons-vue"; ...@@ -46,28 +46,58 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts"; import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
import { getCountSanTypeByTime, getCountTypeByYear, getCountThisType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const bar2Option = shallowRef({}); const bar2Option = shallowRef({});
const line1Option = shallowRef({}); const line1Option = shallowRef({});
const line2Option = shallowRef({}); const line2Option = shallowRef({});
onMounted(() => { onMounted(async () => {
pie1Option.value = getPieOption1( try {
[ const [countSanTypeByTimeData, countThisTypeData1, countTypeByYearData, countThisTypeData2] = await Promise.all([
{ name: "企业", value: 50 }, getCountSanTypeByTime(route.query.startTime),
{ name: "科研院所", value: 40 }, getCountThisType("1"),
{ name: "高校", value: 32 }, getCountTypeByYear(),
{ name: "政府官员", value: 30 }, getCountThisType("2")
{ name: "个人", value: 24}, ]);
]
); pie1Option.value = getPieOption1(
bar2Option.value = getBarChart( _.map(countSanTypeByTimeData ?? [], item => {
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], return {
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], name: item?.type,
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], value: item?.count
"更新频率" };
); })
line1Option.value = getLineChart("rgba(255, 149, 77, 1)"); );
line2Option.value = getLineChart("rgba(146, 84, 222, 1)");
const list1 = _.reverse(countThisTypeData1 ?? []);
line1Option.value = getLineChart({
xAxisData: _.map(list1, "year"),
seriesData: _.map(list1, "count"),
name: "科研院所类",
color: "rgba(255, 149, 77, 1)"
});
const list = _.reverse(countTypeByYearData ?? []);
bar2Option.value = getBarChart(
_.map(list, "year"),
_.map(list, "count"),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"实体数"
);
const list2 = _.reverse(countThisTypeData2 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list2, "year"),
seriesData: _.map(list2, "count"),
name: "企业类",
color: "rgba(117, 29, 219, 1)"
});
} catch (err) {
console.log(err);
}
}); });
</script> </script>
......
...@@ -13,31 +13,70 @@ ...@@ -13,31 +13,70 @@
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getPieOption } from "../../utils/charts"; import { getPieOption } from "../../utils/charts";
import { ref, onMounted, shallowRef } from "vue"; import { ref, onMounted, shallowRef } from "vue";
import { getCountByDomain, getCountByType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const pie2Option = shallowRef({}); const pie2Option = shallowRef({});
onMounted(async () => {
try {
const [countByDomainData, countByTypeData] = await Promise.all([
getCountByDomain(route.query.startTime),
getCountByType(route.query.startTime)
]);
pie1Option.value = getPieOption(
_.chain(countByDomainData)
.filter(item => item.count > 0)
.map(item => {
return {
name: item?.domain,
value: item?.count
};
})
.value(),
"领域分布"
);
pie2Option.value = getPieOption(
_.chain(countByTypeData)
.filter(item => item.count > 0)
.map(item => {
return {
name: item?.type,
value: item?.count
};
})
.value(),
"类型分布"
);
} catch (err) {
console.log(err);
}
});
onMounted(() => { onMounted(() => {
pie1Option.value = getPieOption( // pie1Option.value = getPieOption(
[ // [
{ name: "能源领域", value: 30 }, // { name: "能源领域", value: 30 },
{ name: "集成电路领域", value: 20 }, // { name: "集成电路领域", value: 20 },
{ name: "人工智能领域", value: 12 }, // { name: "人工智能领域", value: 12 },
{ name: "通信网络领域", value: 18 }, // { name: "通信网络领域", value: 18 },
{ name: "量子科技领域", value: 10 }, // { name: "量子科技领域", value: 10 },
{ name: "生物科技领域", value: 10 } // { name: "生物科技领域", value: 10 }
], // ],
"领域分布" // "领域分布"
); // );
pie2Option.value = getPieOption( // pie2Option.value = getPieOption(
[ // [
{ name: "能源领域", value: 30 }, // { name: "能源领域", value: 30 },
{ name: "集成电路领域", value: 20 }, // { name: "集成电路领域", value: 20 },
{ name: "人工智能领域", value: 12 }, // { name: "人工智能领域", value: 12 },
{ name: "通信网络领域", value: 18 }, // { name: "通信网络领域", value: 18 },
{ name: "量子科技领域", value: 10 }, // { name: "量子科技领域", value: 10 },
{ name: "生物科技领域", value: 10 } // { name: "生物科技领域", value: 10 }
], // ],
"类别分布" // "类别分布"
); // );
}); });
</script> </script>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div <div
class="item" class="item"
:class="{ activeItem: activePanelId === item.id }" :class="{ activeItem: activePanelId === item.id }"
v-for="item in panelListData" v-for="item in compareCountSan"
:key="item.id" :key="item.id"
@click="setActivePanelId(item.id)" @click="setActivePanelId(item.id)"
> >
...@@ -44,51 +44,67 @@ ...@@ -44,51 +44,67 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<panel1 v-if="activePanelId === panelListData[0].id"></panel1> <panel1 v-if="activePanelId === compareCountSan[0]?.id"></panel1>
<panel2 v-if="activePanelId === panelListData[1].id"></panel2> <panel2 v-if="activePanelId === compareCountSan[1]?.id"></panel2>
<panel3 v-if="activePanelId === panelListData[2].id"></panel3> <panel3 v-if="activePanelId === compareCountSan[2]?.id"></panel3>
<panel4 v-if="activePanelId === panelListData[3].id"></panel4> <panel4 v-if="activePanelId === compareCountSan[3]?.id"></panel4>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted, shallowRef } from "vue";
import Panel1 from "../components/panel1.vue"; import Panel1 from "../components/panel1.vue";
import Panel2 from "../components/panel2.vue"; import Panel2 from "../components/panel2.vue";
import Panel3 from "../components/panel3.vue"; import Panel3 from "../components/panel3.vue";
import Panel4 from "../components/panel4.vue"; import Panel4 from "../components/panel4.vue";
const panelListData = [ import { getCompareCountSan } from "@/api/exportControl";
{ import { useRoute } from "vue-router";
id: 1, const route = useRoute();
name: "新增实体数量", const compareCountSan = shallowRef([]);
number: "37", const activePanelId = ref(null);
isUp: true, onMounted(async () => {
ComparisonNumber: "31" try {
}, const [compareCountSanData] = await Promise.all([getCompareCountSan(route.query.startTime)]);
{ const { countSanNow, countSanLast, countDomainNow, countDomainLast, countTypeNow, countTypeLast } =
id: 2, compareCountSanData ?? {};
name: "上市企业数量",
number: "6", compareCountSan.value = [
isUp: true, {
ComparisonNumber: "2" id: 1,
}, name: "新增实体数量",
{ number: countSanNow,
id: 3, isUp: countSanNow - countSanLast >= 0,
name: "涉及领域数量", ComparisonNumber: Math.abs(countSanNow - countSanLast)
number: "2", },
isUp: false, {
ComparisonNumber: "1" id: 2,
}, name: "上市企业数量",
{ number: "--",
id: 4, isUp: true,
name: "实体类别数量", ComparisonNumber: "--"
number: "4", },
isUp: true, {
ComparisonNumber: "1" id: 3,
name: "涉及领域数量",
number: countDomainNow,
isUp: countDomainNow - countDomainLast >= 0,
ComparisonNumber: Math.abs(countDomainNow - countDomainLast)
},
{
id: 4,
name: "实体类别数量",
number: countTypeNow,
isUp: countTypeNow - countTypeLast >= 0,
ComparisonNumber: Math.abs(countTypeNow - countTypeLast)
}
];
activePanelId.value = compareCountSan.value[0].id;
} catch (err) {
console.log(err);
} }
]; });
const activePanelId = ref(panelListData[0].id);
const setActivePanelId = id => { const setActivePanelId = id => {
activePanelId.value = id; activePanelId.value = id;
}; };
......
...@@ -3,26 +3,26 @@ ...@@ -3,26 +3,26 @@
<div class="row"> <div class="row">
<CardCustom title="实体清单发布机构" :style="{ width: '984px', height: '284px' }"> <CardCustom title="实体清单发布机构" :style="{ width: '984px', height: '284px' }">
<div class="panel1"> <div class="panel1">
<img :src="panel1.img" alt="" class="img" /> <img :src="organizationInfo.img" alt="" class="img" />
<div class="infoWrap"> <div class="infoWrap">
<div class="item"> <div class="item">
<div class="name">机构名称:</div> <div class="name">机构名称:</div>
<div class="doc">{{ panel1.mingcheng }}</div> <div class="doc">{{ organizationInfo.mingcheng }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="name">相关措施:</div> <div class="name">相关措施:</div>
<div class="doc">{{ panel1.cuoshi }}</div> <div class="doc">{{ organizationInfo.cuoshi }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="name">机构职责:</div> <div class="name">机构职责:</div>
<div class="doc zhize">{{ panel1.zhize }}</div> <div class="doc zhize">{{ organizationInfo.zhize }}</div>
</div> </div>
</div> </div>
</div> </div>
</CardCustom> </CardCustom>
<CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }"> <CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }">
<div class="panel2"> <div class="panel2">
<div class="item" v-for="(item, index) in panel2" :key="index"> <div class="item" v-for="(item, index) in personLis" :key="index">
<img :src="item.img" alt="" class="img" /> <img :src="item.img" alt="" class="img" />
<div class="infoWrap"> <div class="infoWrap">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
</CardCustom> </CardCustom>
<CardCustom title="制裁原因" :style="{ width: '600px', height: '520px' }"> <CardCustom title="制裁原因" :style="{ width: '600px', height: '520px' }">
<div class="panel4"> <div class="panel4">
<div class="item" v-for="(item, index) in panel4" :key="index"> <div class="item" v-for="(item, index) in sanReasonSelect" :key="index">
<div class="icon1">{{ index + 1 }}</div> <div class="icon1">{{ index + 1 }}</div>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<div class="icon2"></div> <div class="icon2"></div>
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
</div> </div>
<div class="tableWrap"> <div class="tableWrap">
<el-table <el-table
:data="panel5MockData" :data="selectEntitiesList"
class="sanction-table" class="sanction-table"
stripe stripe
empty-text="暂无数据" empty-text="暂无数据"
...@@ -106,7 +106,10 @@ ...@@ -106,7 +106,10 @@
<el-table-column prop="name" label="实体清单" min-width="180"> <el-table-column prop="name" label="实体清单" min-width="180">
<template #default="{ row }"> <template #default="{ row }">
<div style="font-weight: 500" class="name"> <div style="font-weight: 500" class="name">
<img :src="row.img" alt="" class="img" /> <img v-if="row.img" :src="row.img" alt="" class="img" />
<div v-else class="imgUndefined">
{{ row.name?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
{{ row.name }} {{ row.name }}
</div> </div>
</template> </template>
...@@ -122,7 +125,7 @@ ...@@ -122,7 +125,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="address" label="上市地点" width="100" align="center"> <el-table-column prop="address" label="上市地点" width="90" align="center">
<template #default="{ row }"> <template #default="{ row }">
{{ row.address }} {{ row.address }}
</template> </template>
...@@ -180,8 +183,7 @@ import PieCharts from "../components/pieCharts.vue"; ...@@ -180,8 +183,7 @@ import PieCharts from "../components/pieCharts.vue";
import MapCharts from "../components/mapCharts.vue"; import MapCharts from "../components/mapCharts.vue";
import ButtonList from "@/components/buttonList/buttonList.vue"; import ButtonList from "@/components/buttonList/buttonList.vue";
import Hint from "../components/hint.vue"; import Hint from "../components/hint.vue";
import { onMounted, reactive, ref, shallowRef } from "vue";
import { onMounted, reactive, ref } from "vue";
import panel1_1 from "../../assets/images/panel1_1.png"; import panel1_1 from "../../assets/images/panel1_1.png";
import panel2_1 from "../../assets/images/panel2_1.png"; import panel2_1 from "../../assets/images/panel2_1.png";
import panel2_2 from "../../assets/images/panel2_2.png"; import panel2_2 from "../../assets/images/panel2_2.png";
...@@ -195,43 +197,39 @@ import panel5_5 from "../../assets/images/panel5_5.png"; ...@@ -195,43 +197,39 @@ import panel5_5 from "../../assets/images/panel5_5.png";
import panel5_6 from "../../assets/images/panel5_6.png"; import panel5_6 from "../../assets/images/panel5_6.png";
import panel5_7 from "../../assets/images/panel5_7.png"; import panel5_7 from "../../assets/images/panel5_7.png";
import panel5_8 from "../../assets/images/panel5_8.png"; import panel5_8 from "../../assets/images/panel5_8.png";
const panel1 = ref({ import { getOrganizationInfo, getPersonList, getSanReasonSelect, getSelectEntitiesList } from "@/api/exportControl";
img: panel1_1, import _ from "lodash";
mingcheng: "美国商务部工业与安全局", import { useRoute } from "vue-router";
cuoshi: "出口管制条例(EAR)、实体清单、商业管制清单(CCL)、232调查等", import { formatAnyDateToChinese } from "../../utils";
zhize: "美国商务部工业与安全局(BIS)是美国商务部下属机构,核心职责围绕国家安全与战略技术管控展开,具体包括:以维护商业管制清单(CCL)和出口管制分类号(ECCN)的方式,对敏感货物及两用技术实施出口管制并确定许可要求;通过出口执行局(OEE)执行出口管制、反抵制等相关法律,对违规行为采取行政、刑事等处罚措施;在出口管制和战略贸易问题上与其他国家合作,参与并领导国际出口管制制度。" const route = useRoute();
}); const organizationInfo = shallowRef({});
const panel2 = ref([ const personLis = shallowRef([
{ // {
name: "吉娜·雷蒙多", // name: "吉娜·雷蒙多",
enName: "Gina Raimondo", // enName: "Gina Raimondo",
party: "美国民主党", // party: "美国民主党",
img: panel2_1 // img: panel2_1
}, // },
{ // {
name: "迈克・约翰逊", // name: "迈克・约翰逊",
enName: "Mike Johnson", // enName: "Mike Johnson",
party: "美国共和党", // party: "美国共和党",
img: panel2_2 // img: panel2_2
}, // },
{ // {
name: "艾伦·埃斯特韦斯", // name: "艾伦·埃斯特韦斯",
enName: "Alan Estevez", // enName: "Alan Estevez",
party: "美国民主党", // party: "美国民主党",
img: panel2_3 // img: panel2_3
}, // },
{ // {
name: "凯・格兰杰", // name: "凯・格兰杰",
enName: "Kay Granger", // enName: "Kay Granger",
party: "美国共和党", // party: "美国共和党",
img: panel2_4 // img: panel2_4
} // }
]); ]);
const panel3ActiveIndex = ref(1); const sanReasonSelect = shallowRef([
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel4 = ref([
{ {
text: "获取美国产物项,以支持中国量子技术;" text: "获取美国产物项,以支持中国量子技术;"
}, },
...@@ -248,6 +246,54 @@ const panel4 = ref([ ...@@ -248,6 +246,54 @@ const panel4 = ref([
text: "将中国定位为“通过强制技术转让获取先进制程的威胁”" text: "将中国定位为“通过强制技术转让获取先进制程的威胁”"
} }
]); ]);
const selectEntitiesList = shallowRef([]);
onMounted(async () => {
try {
const [organizationInfoData, personListData, sanReasonSelectData, selectEntitiesListData] = await Promise.all([
getOrganizationInfo(),
getPersonList(),
getSanReasonSelect(route.query.startTime),
getSelectEntitiesList(route.query.startTime)
]);
organizationInfo.value = {
img: panel1_1,
mingcheng: organizationInfoData?.orgName,
cuoshi: organizationInfoData?.cuoshi || "美国商务部工业与安全局",
zhize: organizationInfoData?.orgIntroduction || "--"
};
personLis.value = _.map(personListData, item => {
return {
name: item.name,
enName: item.enName,
party: item.positionTitle,
img: item.avatarUrl
};
});
sanReasonSelect.value = _.map(sanReasonSelectData, item => {
return { text: item };
});
selectEntitiesList.value = _.map(selectEntitiesListData, item => {
return {
name: item?.entityNameZh,
domains: item.techDomainList,
address: "--",
time: formatAnyDateToChinese(item?.startTime),
isUp: true,
revenue: "--",
subCompany: "--",
img: ""
};
});
} catch (err) {
console.log(err);
}
});
const panel3ActiveIndex = ref(1);
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel5ButtonList = [ const panel5ButtonList = [
{ id: 1, text: "新增实体" }, { id: 1, text: "新增实体" },
...@@ -379,7 +425,7 @@ const panel6 = ref([ ...@@ -379,7 +425,7 @@ const panel6 = ref([
} }
.panel1 { .panel1 {
height: 100%; height: 100%;
padding: 2px 24px 0 24px; padding: 2px 35px 0 24px;
display: flex; display: flex;
.img { .img {
width: 90px; width: 90px;
...@@ -414,6 +460,11 @@ const panel6 = ref([ ...@@ -414,6 +460,11 @@ const panel6 = ref([
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5; /* 控制行数 */
overflow: hidden;
text-overflow: ellipsis;
} }
} }
} }
...@@ -551,6 +602,10 @@ const panel6 = ref([ ...@@ -551,6 +602,10 @@ const panel6 = ref([
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 30px;
flex: 1; flex: 1;
overflow: hidden;
white-space: noWrap;
text-overflow: ellipsis;
min-width: 0;
} }
.icon2 { .icon2 {
width: 16px; width: 16px;
...@@ -605,6 +660,7 @@ const panel6 = ref([ ...@@ -605,6 +660,7 @@ const panel6 = ref([
flex: 1; flex: 1;
margin-top: 14px; margin-top: 14px;
min-height: 0; min-height: 0;
overflow: auto;
} }
.name { .name {
display: flex; display: flex;
...@@ -614,6 +670,20 @@ const panel6 = ref([ ...@@ -614,6 +670,20 @@ const panel6 = ref([
height: 40px; height: 40px;
margin-right: 6px; margin-right: 6px;
margin-left: 6px; margin-left: 6px;
flex-shrink: 0;
}
.imgUndefined {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
color: rgba(5, 95, 194, 1);
background-color: rgb(236, 245, 255);
border-radius: 20px;
margin-right: 6px;
margin-left: 6px;
} }
} }
.subCompany { .subCompany {
......
...@@ -125,7 +125,8 @@ import icon2 from "../assets/icons/icon2.png"; ...@@ -125,7 +125,8 @@ import icon2 from "../assets/icons/icon2.png";
import icon2Active from "../assets/icons/icon2_active.png"; import icon2Active from "../assets/icons/icon2_active.png";
import icon3 from "../assets/icons/icon3.png"; import icon3 from "../assets/icons/icon3.png";
import icon3Active from "../assets/icons/icon3_active.png"; import icon3Active from "../assets/icons/icon3_active.png";
import { useRoute } from "vue-router";
const route = useRoute();
const activeName = ref("分析报告"); const activeName = ref("分析报告");
const handleSwitchActiveName = name => { const handleSwitchActiveName = name => {
...@@ -171,7 +172,12 @@ const activeTitle = ref("制裁概况"); ...@@ -171,7 +172,12 @@ const activeTitle = ref("制裁概况");
const handleClickMainHeaderBtn = item => { const handleClickMainHeaderBtn = item => {
activeTitle.value = item.name; activeTitle.value = item.name;
// window.sessionStorage.setItem('activeTitle', activeTitle.value) // window.sessionStorage.setItem('activeTitle', activeTitle.value)
router.push(item.path); router.push({
path: item.path,
query: {
...route.query
}
});
}; };
const activeNavIndex = ref(0); const activeNavIndex = ref(0);
......
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import chinaJson from './China.json' import chinaJson from './China.json'
import _ from 'lodash';
//饼图 //饼图
export function getPieOption(data, title) { export function getPieOption(data, title) {
let option = { let option = {
...@@ -85,7 +86,7 @@ export function getPieOption1(data, title) { ...@@ -85,7 +86,7 @@ export function getPieOption1(data, title) {
}, },
label: { label: {
alignTo: 'edge', alignTo: 'edge',
formatter: '{b}\n{two|{c}家 {d}%}', formatter: `{b}${data.length < 10 ? '\n' : ''} {two|{c}家 {d}%}`,
fontSize: 17.6, fontSize: 17.6,
fontWeight: 700, fontWeight: 700,
minMargin: 5, minMargin: 5,
...@@ -104,12 +105,13 @@ export function getPieOption1(data, title) { ...@@ -104,12 +105,13 @@ export function getPieOption1(data, title) {
maxSurfaceAngle: 80 maxSurfaceAngle: 80
}, },
labelLayout: function (params) { labelLayout: function (params) {
console.log('labelLayoutparams', params)
const isLeft = params.labelRect.x < 556 / 2; const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints; const points = params.labelLinePoints;
// Update the end point. // Update the end point.
points[2][0] = isLeft points[2][0] = isLeft
? params.labelRect.x ? data.length < 10 ? params.labelRect.x : (params.labelRect.x + params.labelRect.width)
: params.labelRect.x + params.labelRect.width; : data.length < 10 ? (params.labelRect.x + params.labelRect.width) : params.labelRect.x;
return { return {
labelLinePoints: points labelLinePoints: points
}; };
...@@ -600,7 +602,7 @@ export const getBarChart = (nameList, valueList, color = ['rgba(255, 159, 22, 1) ...@@ -600,7 +602,7 @@ export const getBarChart = (nameList, valueList, color = ['rgba(255, 159, 22, 1)
} }
return option return option
} }
export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { export const getLineChart = (object, isPercent) => {
const option = { const option = {
title: { title: {
text: "" text: ""
...@@ -611,11 +613,11 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -611,11 +613,11 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
let result = params[0].name + '<br/>'; let result = params[0].name + '<br/>';
params.forEach(function (item, index) { params.forEach(function (item, index) {
// 自定义颜色数组 // 自定义颜色数组
const customColors = [color]; const customColors = [object.color];
const dotColor = customColors[index % customColors.length]; // 循环取色 const dotColor = customColors[index % customColors.length]; // 循环取色
// 创建彩色圆点图标 // 创建彩色圆点图标
const dot = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${dotColor};"></span>`; const dot = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${dotColor};"></span>`;
result += dot + `${item.seriesName}: ${item.value}<br/>`; result += dot + `${item.seriesName}: ${item.value}${isPercent ? '%' : ''}<br/>`;
}); });
return result; return result;
} }
...@@ -648,7 +650,7 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -648,7 +650,7 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
// fontSize: 22, // fontSize: 22,
// fontWeight: 400 // fontWeight: 400
}, },
data: ["2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023"] data: object.xAxisData
}, },
yAxis: { yAxis: {
type: "value", type: "value",
...@@ -662,7 +664,9 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -662,7 +664,9 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
color: "rgba(95, 101, 108, 1)", color: "rgba(95, 101, 108, 1)",
// fontSize: 22, // fontSize: 22,
// fontWeight: 400 // fontWeight: 400
formatter: `{value} ${isPercent ? '%' : ''}`
}, },
splitNumber: 8, splitNumber: 8,
splitLine: { splitLine: {
lineStyle: { lineStyle: {
...@@ -675,19 +679,19 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -675,19 +679,19 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
}, },
series: [ series: [
{ {
name: "增长趋势", name: object.name,
type: "line", type: "line",
symbolSize: 8, symbolSize: 8,
symbol: 'circle', symbol: 'circle',
itemStyle: { itemStyle: {
color: "#ffffff", color: "#ffffff",
borderColor: color, borderColor: object.color,
borderWidth: 3 borderWidth: 3
}, },
lineStyle: { lineStyle: {
color: color, color: object.color,
}, },
data: [3, 6, 4, 7, 9, 6, 5, 6, 6] data: object.seriesData
} }
] ]
}; };
...@@ -969,4 +973,62 @@ export const getMultipleLineChart = (obj) => { ...@@ -969,4 +973,62 @@ export const getMultipleLineChart = (obj) => {
}; };
return option; return option;
} }
\ No newline at end of file //出口管制主页接口
export const getMultipleBarChart_m = (object) => {
const list = _.chain(object.data).filter('year').orderBy('year', 'asc').value();
const colors = [
['rgba(22, 119, 255, 1)', 'rgba(22, 119, 255, 0)'],
['rgba(206, 79, 81, 1)', 'rgba(206, 79, 81, 0)'],
['rgba(255, 197, 61, 1)', 'rgba(255, 197, 61, 0)'],
['rgba(255, 204, 199, 1)', 'rgba(255, 204, 199, 0)'],
['rgba(179, 127, 235, 1)', 'rgba(179, 127, 235, 0)'],
['rgba(127, 218, 235, 1)', 'rgba(127, 214, 235, 0)'],
];
const names = _.map(list, 'year');
const datas = _.chain(object.domains).splice(0, 6).map((name, index) => {
console.log(_.map(list, name))
return {
name,
data: _.map(list, `domainNum.${name}`),
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[index % colors.length][0] },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: colors[index % colors.length][1] }
]),
borderRadius: [6, 6, 0, 0]
}
}
}).value();
console.log('names', names)
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
top: 50
},
legend: {
// type: "scroll",
// show: true,
// orient: "horizontal",
icon: "circle",
},
xAxis: {
type: "category",
data: names
},
yAxis: {
type: "value"
},
series: datas
}
return option;
}
export function formatAnyDateToChinese(dateStr) {
// 支持多种分隔符
const date = new Date(dateStr.replace(/\//g, '-'));
if (isNaN(date.getTime())) {
return ''
}
// 手动获取各部分,避免Intl可能存在的兼容性考虑
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从0开始,需+1
const day = date.getDate();
return `${year}${month}${day}日`;
}
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论