DashboardView.vue 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665
  1. <script lang="ts" setup>
  2. import { ref, onMounted, reactive } from 'vue'
  3. import QuickCalendarDate from '@/components/DateRange/src/components/QuickCalendarDate.vue'
  4. import { VueDraggable } from 'vue-draggable-plus'
  5. import PieChart from './components/PieChart.vue'
  6. import SellerChart from './components/SellerChart.vue'
  7. import BarChart from './components/BarChart.vue'
  8. import RevenueChart from './components/RevenueChart.vue'
  9. import RecentStatus from './components/RecentStatus.vue'
  10. import ScoringSystem from './components/ScoringSystem.vue'
  11. import TopMap from './components/TopMap.vue'
  12. import DashFilters from './components/DashFiters.vue'
  13. import { useRouter } from 'vue-router'
  14. import { ElMessage } from 'element-plus'
  15. import { formatNumber } from '@/utils/tools'
  16. const router = useRouter()
  17. const activeName = ref('first')
  18. const SaveVisible = ref(false)
  19. // 可拖拽模块的列表
  20. interface ManagementItem {
  21. title: string
  22. switchValue: boolean
  23. isRevenueDisplay: boolean
  24. text: string
  25. id: number
  26. title1: string
  27. title2: string
  28. }
  29. const Management = ref<ManagementItem[]>([])
  30. const changeCancel = (id: any) => {
  31. Management.value[id - 1].switchValue = false
  32. }
  33. //RecentStatusList
  34. const RecentStatusList = ref()
  35. const pageInfo = ref({ pageNo: 1, pageSize: 10, total: 10000 })
  36. const isShowtitle1 = ref(true)
  37. // 点击tab
  38. const handleTabClick = (tab: any) => {
  39. if (tab.props.name == 'first') {
  40. isShowtitle1.value = true
  41. } else {
  42. isShowtitle1.value = false
  43. }
  44. GetTop10ODEcharts(dashboardObj.Top10faultData)
  45. }
  46. const KPIDefaulteData = ref()
  47. const PendingDefaulteData = ref()
  48. const RecentDefaulteData = ref()
  49. const ETDDefaulteData = ref()
  50. const ContainerefaultData = ref()
  51. const Top10DefaultData = ref()
  52. const Co2OriginDefaultData = ref()
  53. const Co2DestinationDefaultData = ref()
  54. const RevenueDefaultData = ref()
  55. // 获取首页数据
  56. let dashboardObj: any = {}
  57. const GetDashboardData = () => {
  58. $api
  59. .getDashboardFilters({})
  60. .then((res: any) => {
  61. if (res.code == 200) {
  62. //给默认筛选条件赋值
  63. KPIDefaulteData.value = res.data.KPIDefaulteData
  64. dashboardObj.KPIDefaulteData = res.data.KPIDefaulteData
  65. PendingDefaulteData.value = res.data.PendingDefaultData
  66. dashboardObj.PendingDefaultData = res.data.PendingDefaultData
  67. RecentDefaulteData.value = res.data.RecentDefaultData
  68. dashboardObj.RecentDefaultData = res.data.RecentDefaultData
  69. ETDDefaulteData.value = res.data.ETDDefaultData
  70. dashboardObj.ETDDefaultData = res.data.ETDDefaultData
  71. ContainerefaultData.value = res.data.ContainerefaultData
  72. dashboardObj.ContainerefaultData = res.data.ContainerefaultData
  73. Top10DefaultData.value = res.data.Top10faultData
  74. dashboardObj.Top10faultData = res.data.Top10faultData
  75. Co2OriginDefaultData.value = res.data.OriginCo2Top10faultData
  76. dashboardObj.OriginCo2Top10faultData = res.data.OriginCo2Top10faultData
  77. Co2DestinationDefaultData.value = res.data.DestinationCo2Top10faultData
  78. dashboardObj.DestinationCo2Top10faultData = res.data.DestinationCo2Top10faultData
  79. RevenueDefaultData.value = res.data.RevenueDefaultData
  80. dashboardObj.RevenueDefaultData = res.data.RevenueDefaultData
  81. }
  82. })
  83. .finally(() => {
  84. nextTick(() => {
  85. GetKpiData(KPIDefaulteData.value)
  86. GetPendingEcharts(PendingDefaulteData.value)
  87. getTableData(false, RecentDefaulteData.value)
  88. GetETDEcharts(ETDDefaulteData.value)
  89. GetContainerCountEcharts(ContainerefaultData.value)
  90. GetTop10ODEcharts(Top10DefaultData.value)
  91. GetCo2EmissionEcharts(Co2OriginDefaultData.value)
  92. GetCo2DestinationEcharts(Co2DestinationDefaultData.value)
  93. GetRevenueEcharts(RevenueDefaultData.value)
  94. })
  95. })
  96. }
  97. // 获取表单数据
  98. const getTableData = (isPage: any, val: any) => {
  99. dashboardObj.RecentDefaultData = val
  100. const rc = isPage ? pageInfo.value.total : -1
  101. $api
  102. .GetDashboardData({
  103. cp: pageInfo.value.pageNo,
  104. ps: pageInfo.value.pageSize,
  105. rc,
  106. ...val
  107. })
  108. .then((res: any) => {
  109. if (res.code === 200) {
  110. pageInfo.value.total = Number(res.data.rc)
  111. Management.value = res.data.Management
  112. RecentStatusList.value = res.data.searchData
  113. }
  114. })
  115. }
  116. const KPIobj = reactive({
  117. ETD_Title: '',
  118. ETDList: [],
  119. ETD_Radius: [],
  120. download_name: ''
  121. })
  122. const Arrivalobj = reactive({
  123. ETD_Title: '',
  124. ETDList: [],
  125. ETD_Radius: [],
  126. download_name: ''
  127. })
  128. const KPILoading = ref(true)
  129. const KPIArrivalLoading = ref(true)
  130. //查询KPI
  131. const GetKpiData = (val: any) => {
  132. dashboardObj.KPIDefaulteData = val
  133. // 获取KPI Departure图表数据
  134. $api
  135. .GetKPIEcharts({
  136. r_type: 'atd_r4',
  137. ...val
  138. })
  139. .then((res: any) => {
  140. if (res.code === 200) {
  141. KPIobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
  142. KPIobj.ETDList = res.data.ETDList
  143. KPIobj.ETD_Radius = res.data.ETD_Radius
  144. KPIobj.download_name = res.data.download_name
  145. }
  146. })
  147. .finally(() => {
  148. KPILoading.value = false
  149. })
  150. // 获取KPI Arrival图表数据
  151. $api
  152. .GetKPIEcharts({
  153. r_type: 'ata_r3',
  154. ...val
  155. })
  156. .then((res: any) => {
  157. if (res.code === 200) {
  158. Arrivalobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
  159. Arrivalobj.ETDList = res.data.ETDList
  160. Arrivalobj.ETD_Radius = res.data.ETD_Radius
  161. Arrivalobj.download_name = res.data.download_name
  162. }
  163. })
  164. .finally(() => {
  165. KPIArrivalLoading.value = false
  166. })
  167. }
  168. const Pendingobj = reactive({
  169. ETD_Title: '',
  170. ETDList: [],
  171. ETD_Radius: [],
  172. download_name: ''
  173. })
  174. const PendingArrivalobj = reactive({
  175. ETD_Title: '',
  176. ETDList: [],
  177. ETD_Radius: [],
  178. download_name: ''
  179. })
  180. const PendingLoading = ref(true)
  181. const PendingArrivalLoading = ref(true)
  182. // 查询Pending
  183. const GetPendingEcharts = (val: any) => {
  184. dashboardObj.PendingDefaultData = val
  185. // 获取Pending Departure图表数据
  186. $api
  187. .GetPendingEcharts({
  188. r_type: 'r4',
  189. ...val
  190. })
  191. .then((res: any) => {
  192. if (res.code === 200) {
  193. Pendingobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
  194. Pendingobj.ETDList = res.data.ETDList
  195. Pendingobj.ETD_Radius = res.data.ETD_Radius
  196. Pendingobj.download_name = res.data.download_name
  197. }
  198. })
  199. .finally(() => {
  200. PendingLoading.value = false
  201. })
  202. // 获取Pending Arrival图表数据
  203. $api
  204. .GetPendingEcharts({
  205. r_type: 'r3',
  206. ...val
  207. })
  208. .then((res: any) => {
  209. if (res.code === 200) {
  210. PendingArrivalobj.ETD_Title = `{a|${res.data.title1}} {b|${res.data.title2}}`
  211. PendingArrivalobj.ETDList = res.data.ETDList
  212. PendingArrivalobj.ETD_Radius = res.data.ETD_Radius
  213. PendingArrivalobj.download_name = res.data.download_name
  214. }
  215. })
  216. .finally(() => {
  217. PendingArrivalLoading.value = false
  218. })
  219. }
  220. const ETDobj = reactive({
  221. ETD_Title: '',
  222. ETDList: [],
  223. ETD_Radius: [],
  224. download_name: ''
  225. })
  226. const ETDLoading = ref(true)
  227. // 获取ETD/ETA 图表数据
  228. const GetETDEcharts = (val: any) => {
  229. dashboardObj.ETDDefaultData = val
  230. $api
  231. .GetETDEcharts({
  232. ...val
  233. })
  234. .then((res: any) => {
  235. if (res.code === 200) {
  236. ETDobj.ETD_Title = `{a|${res.data.ETD_Title}}`
  237. ETDobj.ETDList = res.data.ETDList
  238. ETDobj.ETD_Radius = res.data.ETD_Radius
  239. ETDobj.download_name = res.data.download_name
  240. }
  241. })
  242. .finally(() => {
  243. ETDLoading.value = false
  244. })
  245. }
  246. // 获取ContainerCount
  247. const containerObj = reactive({
  248. bar_title: '',
  249. barList: [],
  250. barSeries: [],
  251. Max: 0,
  252. interval: 0,
  253. download_name: ''
  254. })
  255. const containerLoading = ref(true)
  256. const GetContainerCountEcharts = (val: any) => {
  257. dashboardObj.ContainerefaultData = val
  258. $api
  259. .GetContainerCountEcharts({
  260. ...val
  261. })
  262. .then((res: any) => {
  263. if (res.code === 200) {
  264. containerObj.bar_title = res.data.ContainerCount_Title
  265. containerObj.barList = res.data.ContainerCountList
  266. containerObj.barSeries = res.data.ContainerCounSeries
  267. containerObj.Max = res.data.Max
  268. containerObj.interval = res.data.interval
  269. containerObj.download_name = res.data.download_name
  270. }
  271. })
  272. .finally(() => {
  273. containerLoading.value = false
  274. })
  275. }
  276. const topdestinationinType = ref()
  277. const toporiginType = ref()
  278. //获取Top10 Origin/Destination
  279. const Top10Obj = reactive({
  280. OriginData: [],
  281. DestinationData: []
  282. })
  283. const Top1OInterval = reactive({
  284. Max: 0,
  285. interval: 0
  286. })
  287. const Top1OInterval_dest = reactive({
  288. Max: 0,
  289. interval: 0
  290. })
  291. const TopOriginLoading = ref(true)
  292. const Top10Originref = ref()
  293. const Top10Destinationref = ref()
  294. const GetTop10ODEcharts = (val: any) => {
  295. dashboardObj.Top10faultData = val
  296. $api
  297. .GetTop10ODEcharts({
  298. ...val
  299. })
  300. .then((res: any) => {
  301. if (res.code === 200) {
  302. // Top10Originref.value[0].updataMapObj(dashboardObj.Top10faultData)
  303. if (isShowtitle1.value) {
  304. Top10Originref.value[0].updataMapObj(res.data.toporiginMap)
  305. } else {
  306. Top10Destinationref.value[0].updataMapObj(res.data.topdestinationinMap)
  307. }
  308. Top10Obj.DestinationData = res.data.seller_data_list_destination
  309. Top10Obj.OriginData = res.data.seller_data_list_origin
  310. Top1OInterval.Max = res.data.Max
  311. Top1OInterval.interval = res.data.interval
  312. Top1OInterval_dest.Max = res.data.dest_Max
  313. Top1OInterval_dest.interval = res.data.dest_interval
  314. topdestinationinType.value = res.data.topdestinationinType
  315. toporiginType.value = res.data.toporiginType
  316. }
  317. })
  318. .finally(() => {
  319. TopOriginLoading.value = false
  320. })
  321. }
  322. //获取CO2 Origin
  323. const EmissionLoading = ref(true)
  324. const EmissionObj = reactive({
  325. bar_title: '',
  326. barList: [],
  327. barSeries: [],
  328. Max: 0,
  329. interval: 0,
  330. download_name: ''
  331. })
  332. const GetCo2EmissionEcharts = (val: any) => {
  333. dashboardObj.OriginCo2Top10faultData = val
  334. $api
  335. .GetCo2EmissionEcharts({
  336. ...val
  337. })
  338. .then((res: any) => {
  339. if (res.code === 200) {
  340. EmissionObj.bar_title = res.data.ContainerCount_Title
  341. EmissionObj.barList = res.data.ContainerCountList
  342. EmissionObj.barSeries = res.data.ContainerCounSeries
  343. EmissionObj.Max = res.data.Max
  344. EmissionObj.interval = res.data.interval
  345. EmissionObj.download_name = res.data.download_name
  346. }
  347. })
  348. .finally(() => {
  349. EmissionLoading.value = false
  350. })
  351. }
  352. //获取CO2 Destination
  353. const DestinationObj = reactive({
  354. bar_title: '',
  355. barList: [],
  356. barSeries: [],
  357. Max: 0,
  358. interval: 0,
  359. download_name: ''
  360. })
  361. const DestinationLoading = ref(true)
  362. const GetCo2DestinationEcharts = (val: any) => {
  363. dashboardObj.DestinationCo2Top10faultData = val
  364. $api
  365. .GetCo2DestinationEcharts({
  366. ...val
  367. })
  368. .then((res: any) => {
  369. if (res.code === 200) {
  370. DestinationObj.bar_title = res.data.ContainerCount_Title
  371. DestinationObj.barList = res.data.ContainerCountList
  372. DestinationObj.barSeries = res.data.ContainerCounSeries
  373. DestinationObj.Max = res.data.Max
  374. DestinationObj.interval = res.data.interval
  375. DestinationObj.download_name = res.data.download_name
  376. }
  377. })
  378. .finally(() => {
  379. DestinationLoading.value = false
  380. })
  381. }
  382. //获取Revenue Spent
  383. const RevenueObj = reactive({
  384. bar_title: '',
  385. barList: [],
  386. barSeries: [],
  387. Max: 0,
  388. interval: 0,
  389. download_name: '',
  390. isShowTooltips: true
  391. })
  392. const RevenueLoading = ref(true)
  393. const revenue_date_start = ref()
  394. const revenue_date_end = ref()
  395. const GetRevenueEcharts = (val: any) => {
  396. revenue_date_start.value = val.date_start
  397. revenue_date_end.value = val.date_end
  398. dashboardObj.RevenueDefaultData = val
  399. $api
  400. .GetRevenueEcharts({
  401. ...val
  402. })
  403. .then((res: any) => {
  404. if (res.code === 200) {
  405. RevenueObj.bar_title = res.data.bar_title
  406. RevenueObj.barList = res.data.barList
  407. RevenueObj.barSeries = res.data.barSeries
  408. RevenueObj.Max = res.data.Max
  409. RevenueObj.interval = res.data.interval
  410. RevenueObj.download_name = res.data.download_name
  411. }
  412. })
  413. .finally(() => {
  414. RevenueLoading.value = false
  415. })
  416. }
  417. onMounted(() => {
  418. GetDashboardData()
  419. })
  420. // Save Layout
  421. const SaveLayout = () => {
  422. SaveVisible.value = false
  423. Management.value.forEach((item: any, index: any) => {
  424. item.id = index + 1
  425. })
  426. $api
  427. .SaveLayout({
  428. management: Management.value
  429. })
  430. .then((res: any) => {
  431. if (res.code == 200) {
  432. ElMessage({
  433. message: res.data.msg,
  434. duration: 3000,
  435. type: 'success'
  436. })
  437. }
  438. })
  439. }
  440. //Save Filters
  441. const SaveFilters = () => {
  442. SaveVisible.value = false
  443. Management.value.forEach((item: any, index: any) => {
  444. item.id = index + 1
  445. })
  446. $api
  447. .SaveLayout({
  448. management: Management.value,
  449. dashboardObj
  450. })
  451. .then((res: any) => {
  452. if (res.code == 200) {
  453. ElMessage({
  454. message: res.data.msg,
  455. duration: 3000,
  456. type: 'success'
  457. })
  458. }
  459. })
  460. }
  461. //ETD to ETA(DAYS)点击跳转
  462. const pie_chart_ETD = ref()
  463. const pie_chart_pending_arrival = ref()
  464. const pie_chart_pending_departure = ref()
  465. const pie_chart_kpi_departure = ref()
  466. const pie_chart_kpi_arrival = ref()
  467. const seller_chart_top10_origin = ref()
  468. const seller_chart_top10_destination = ref()
  469. const seller_chart_CO2_origin = ref()
  470. const seller_chart_CO2_destination = ref()
  471. const startyear = ref()
  472. const startmonth = ref()
  473. const startday = ref()
  474. const endyear = ref()
  475. const endmonth = ref()
  476. const endday = ref()
  477. //处理跳转数据
  478. const handleTurnData = (startdate: any, enddata: any, name: any) => {
  479. if (name == 'Container') {
  480. if (startdate != '') {
  481. startmonth.value = startdate.split('/')[0]
  482. startyear.value = startdate.split('/')[1]
  483. }
  484. if (enddata != '') {
  485. endmonth.value = enddata.split('/')[0]
  486. endyear.value = enddata.split('/')[1]
  487. }
  488. } else {
  489. if (startdate != '') {
  490. startmonth.value = startdate.split('/')[0]
  491. startyear.value = startdate.split('/')[2]
  492. startday.value = startdate.split('/')[1]
  493. }
  494. if (enddata != '') {
  495. endmonth.value = enddata.split('/')[0]
  496. endyear.value = enddata.split('/')[2]
  497. endday.value = enddata.split('/')[1]
  498. }
  499. }
  500. }
  501. const ClickParams = (val: any) => {
  502. const currentDate = new Date()
  503. let tenyear = currentDate.getFullYear()
  504. let tenmonth = currentDate.getMonth() - 11
  505. if (tenmonth < 0) {
  506. tenyear -= 1
  507. tenmonth += 11
  508. }
  509. const reportList: any = {}
  510. const handlereportlist = (transportation: any, type: any, name: any) => {
  511. if (transportation.includes('All')) {
  512. reportList.transport_mode = ['All']
  513. } else {
  514. reportList.transport_mode = transportation
  515. }
  516. if (name == 'Container') {
  517. if (type == 'ETA') {
  518. if (startyear.value) {
  519. reportList.eta_start = startmonth.value + '/01/' + startyear.value
  520. reportList.eta_end =
  521. endmonth.value +
  522. '/' +
  523. new Date(endyear.value, endmonth.value, 0).getDate() +
  524. '/' +
  525. endyear.value
  526. }
  527. } else {
  528. if (startyear.value) {
  529. reportList.etd_start = startmonth.value + '/01/' + startyear.value
  530. reportList.etd_end =
  531. endmonth.value +
  532. '/' +
  533. new Date(endyear.value, endmonth.value, 0).getDate() +
  534. '/' +
  535. endyear.value
  536. }
  537. }
  538. } else {
  539. if (type == 'ETA') {
  540. if (startyear.value) {
  541. reportList.eta_start = startmonth.value + '/' + startday.value + '/' + startyear.value
  542. reportList.eta_end = endmonth.value + '/' + endday.value + '/' + endyear.value
  543. }
  544. } else {
  545. if (startyear.value) {
  546. reportList.etd_start = startmonth.value + '/' + startday.value + '/' + startyear.value
  547. reportList.etd_end = endmonth.value + '/' + endday.value + '/' + endyear.value
  548. }
  549. }
  550. }
  551. }
  552. // ETD to ETA(DAYS)点击跳转
  553. if (val == 'ETD to ETA (Days)') {
  554. handleTurnData(
  555. dashboardObj.ETDDefaultData.date_start,
  556. dashboardObj.ETDDefaultData.date_end,
  557. 'Container'
  558. )
  559. reportList._reportRef = pie_chart_ETD.value[0].paramsdata.name
  560. reportList._reportRefe_date = currentDate.getMonth() + 1 + '/' + currentDate.getFullYear()
  561. reportList._reportType = 'r1'
  562. reportList._reportRefb_date = tenmonth + '/' + tenyear
  563. handlereportlist(
  564. dashboardObj.ETDDefaultData.transportation,
  565. dashboardObj.ETDDefaultData.date_type,
  566. 'Container'
  567. )
  568. sessionStorage.setItem('clickParams', 'clickParams')
  569. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  570. let obj: any = {}
  571. obj.title = 'ETD to ETA (Days)'
  572. obj.name = pie_chart_ETD.value[0].paramsdata.name
  573. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  574. router.push({
  575. path: '/tracking'
  576. })
  577. }
  578. // PendingArrival点击跳转
  579. else if (val == 'Pending1') {
  580. handleTurnData('', '', '') // 因为Pending没有时间筛选,所以传空
  581. reportList._reportRef = pie_chart_pending_arrival.value[0].paramsdata.name
  582. reportList._reportType = 'r3'
  583. handlereportlist(
  584. dashboardObj.PendingDefaultData.transportation,
  585. dashboardObj.PendingDefaultData.date_type,
  586. ''
  587. )
  588. sessionStorage.setItem('clickParams', 'clickParams')
  589. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  590. let obj: any = {}
  591. obj.title = 'Pending Arrival'
  592. obj.name = pie_chart_pending_arrival.value[0].paramsdata.name
  593. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  594. router.push({
  595. path: '/tracking'
  596. })
  597. }
  598. // PendingDeparture点击跳转
  599. else if (val == 'Pending0') {
  600. handleTurnData('', '', '') // 因为Pending没有时间筛选,所以传空
  601. reportList._reportType = 'r4'
  602. reportList._reportRef = pie_chart_pending_departure.value[0].paramsdata.name
  603. handlereportlist(
  604. dashboardObj.PendingDefaultData.transportation,
  605. dashboardObj.PendingDefaultData.date_type,
  606. ''
  607. )
  608. sessionStorage.setItem('clickParams', 'clickParams')
  609. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  610. let obj: any = {}
  611. obj.title = 'Pending Departure'
  612. obj.name = pie_chart_pending_departure.value[0].paramsdata.name
  613. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  614. router.push({
  615. path: '/tracking'
  616. })
  617. }
  618. // KPIDeparture点击跳转
  619. else if (val == 'KPI0') {
  620. handleTurnData(
  621. dashboardObj.KPIDefaulteData.date_start,
  622. dashboardObj.KPIDefaulteData.date_end,
  623. ''
  624. )
  625. reportList._reportRef = pie_chart_kpi_departure.value[0].paramsdata.name
  626. reportList._reportType = 'atd_r4'
  627. handlereportlist(
  628. dashboardObj.KPIDefaulteData.transportation,
  629. dashboardObj.KPIDefaulteData.date_type,
  630. ''
  631. )
  632. sessionStorage.setItem('clickParams', 'clickParams')
  633. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  634. let obj: any = {}
  635. obj.title = 'KPI Departure'
  636. obj.name = pie_chart_kpi_departure.value[0].paramsdata.name
  637. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  638. router.push({
  639. path: '/tracking'
  640. })
  641. }
  642. // KPIArrival点击跳转
  643. else if (val == 'KPI1') {
  644. handleTurnData(
  645. dashboardObj.KPIDefaulteData.date_start,
  646. dashboardObj.KPIDefaulteData.date_end,
  647. ''
  648. )
  649. reportList._reportRef = pie_chart_kpi_arrival.value[0]?.paramsdata?.name || ''
  650. reportList._reportType = 'ata_r3'
  651. handlereportlist(
  652. dashboardObj.KPIDefaulteData.transportation,
  653. dashboardObj.KPIDefaulteData.date_type,
  654. ''
  655. )
  656. sessionStorage.setItem('clickParams', 'clickParams')
  657. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  658. let obj: any = {}
  659. obj.title = 'KPI Arrival'
  660. obj.name = pie_chart_kpi_arrival.value[0]?.paramsdata?.name || ''
  661. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  662. router.push({
  663. path: '/tracking'
  664. })
  665. }
  666. // Top10 origin点击跳转
  667. else if (val == 'Top 10 Origin') {
  668. handleTurnData(dashboardObj.Top10faultData.date_start, dashboardObj.Top10faultData.date_end, '')
  669. reportList._reportRef = seller_chart_top10_origin.value[0].paramsdata
  670. reportList._reportType = 'top'
  671. reportList._reportStationType = toporiginType.value
  672. reportList._city_name = seller_chart_top10_origin.value[0].paramscityname
  673. handlereportlist(
  674. dashboardObj.Top10faultData.transportation,
  675. dashboardObj.Top10faultData.date_type,
  676. ''
  677. )
  678. sessionStorage.setItem('clickParams', 'clickParams')
  679. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  680. let obj: any = {}
  681. obj.title = 'Top 10 Origin'
  682. obj.name = seller_chart_top10_origin.value[0].paramsdata
  683. obj.data = seller_chart_top10_origin.value[0].paramscityname
  684. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  685. router.push({
  686. path: '/tracking'
  687. })
  688. }
  689. // Top10 destination点击跳转
  690. else if (val == 'Top 10 Destination') {
  691. handleTurnData(dashboardObj.Top10faultData.date_start, dashboardObj.Top10faultData.date_end, '')
  692. reportList._reportRef = seller_chart_top10_destination.value[0].paramsdata
  693. reportList._reportStationType = topdestinationinType.value
  694. reportList._reportType = 'top'
  695. reportList._city_name = seller_chart_top10_destination.value[0].paramscityname
  696. handlereportlist(
  697. dashboardObj.Top10faultData.transportation,
  698. dashboardObj.Top10faultData.date_type,
  699. ''
  700. )
  701. sessionStorage.setItem('clickParams', 'clickParams')
  702. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  703. let obj: any = {}
  704. obj.title = 'Top 10 Destination'
  705. obj.name = seller_chart_top10_destination.value[0].paramsdata
  706. obj.data = seller_chart_top10_destination.value[0].paramscityname
  707. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  708. router.push({
  709. path: '/tracking'
  710. })
  711. }
  712. // CO2e Emission by Origin (Top 10)点击跳转
  713. else if (val == 'CO2e Emission by Origin (Top 10)') {
  714. handleTurnData(
  715. dashboardObj.OriginCo2Top10faultData.date_start,
  716. dashboardObj.OriginCo2Top10faultData.date_end,
  717. ''
  718. )
  719. reportList._reportRef = seller_chart_CO2_origin.value[0].paramsdata.name
  720. reportList._reportDataType = seller_chart_CO2_origin.value[0].paramsdata.type
  721. reportList._reportStationType = 'origin'
  722. reportList._reportType = 'co2e'
  723. handlereportlist(
  724. dashboardObj.OriginCo2Top10faultData.transportation,
  725. dashboardObj.OriginCo2Top10faultData.date_type,
  726. ''
  727. )
  728. sessionStorage.setItem('clickParams', 'clickParams')
  729. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  730. let obj: any = {}
  731. obj.title = 'CO2e Emission by Origin (Top 10)'
  732. obj.name = seller_chart_CO2_origin.value[0].paramsdata.name
  733. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  734. router.push({
  735. path: '/tracking'
  736. })
  737. }
  738. // CO2e Emission by Origin (Top 10)点击跳转
  739. else if (val == 'CO2e Emission by Destination (Top 10)') {
  740. handleTurnData(
  741. dashboardObj.DestinationCo2Top10faultData.date_start,
  742. dashboardObj.DestinationCo2Top10faultData.date_end,
  743. ''
  744. )
  745. reportList._reportRef = seller_chart_CO2_destination.value[0].paramsdata.name
  746. reportList._reportDataType = seller_chart_CO2_destination.value[0].paramsdata.type
  747. reportList._reportType = 'co2e'
  748. reportList._reportStationType = 'agent'
  749. handlereportlist(
  750. dashboardObj.DestinationCo2Top10faultData.transportation,
  751. dashboardObj.DestinationCo2Top10faultData.date_type,
  752. ''
  753. )
  754. sessionStorage.setItem('clickParams', 'clickParams')
  755. sessionStorage.setItem('reportList', JSON.stringify(reportList))
  756. let obj: any = {}
  757. obj.title = 'CO2e Emission by Destination (Top 10)'
  758. obj.name = seller_chart_CO2_destination.value[0].paramsdata.name
  759. sessionStorage.setItem('tagsList', JSON.stringify(obj))
  760. router.push({
  761. path: '/tracking'
  762. })
  763. }
  764. }
  765. import kpiChartTipLight from './tipsImage/kpi-chart-tip.png'
  766. import kpiChartTipDark from './tipsImage/dark-kpi-chart-tip.png'
  767. import pendingChartTipLight from './tipsImage/pending-chart-tip.png'
  768. import pendingChartTipDark from './tipsImage/dark-pending-chart-tip.png'
  769. import etdToEtaChartsTipLight from './tipsImage/etd-to-eta-chart-tip.png'
  770. import etdToEtaChartsTipDark from './tipsImage/dark-etd-to-eta-chart-tip.png'
  771. import containerChartTipLight from './tipsImage/container-count-chart-tip.png'
  772. import containerChartTipDark from './tipsImage/dark-container-count-chart-tip.png'
  773. import top10ChartTipLight from './tipsImage/top-10-chart-tip.png'
  774. import top10ChartTipDark from './tipsImage/dark-top-10-chart-tip.png'
  775. import co2eChartTipLight from './tipsImage/co2e-chart-tip.png'
  776. import co2eChartTipDark from './tipsImage/dark-co2e-chart-tip.png'
  777. import revenueSpentChartTipLight from './tipsImage/revenue-spent-chart-tip.png'
  778. import revenueSpentChartTipDark from './tipsImage/dark-revenue-spent-chart-tip.png'
  779. import recentStatusChartTipLight from './tipsImage/recent-status-chart-tip.png'
  780. import recentStatusChartTipDark from './tipsImage/dark-recent-status-chart-tip.png'
  781. const kpiChartTip = computed(() => {
  782. return themeStore.theme === 'dark' ? kpiChartTipDark : kpiChartTipLight
  783. })
  784. const pendingChartTip = computed(() => {
  785. return themeStore.theme === 'dark' ? pendingChartTipDark : pendingChartTipLight
  786. })
  787. const etdToEtaChartsTip = computed(() => {
  788. return themeStore.theme === 'dark' ? etdToEtaChartsTipDark : etdToEtaChartsTipLight
  789. })
  790. const containerChartTip = computed(() => {
  791. return themeStore.theme === 'dark' ? containerChartTipDark : containerChartTipLight
  792. })
  793. const top10ChartTip = computed(() => {
  794. return themeStore.theme === 'dark' ? top10ChartTipDark : top10ChartTipLight
  795. })
  796. const co2eChartTip = computed(() => {
  797. return themeStore.theme === 'dark' ? co2eChartTipDark : co2eChartTipLight
  798. })
  799. const revenueSpentChartTip = computed(() => {
  800. return themeStore.theme === 'dark' ? revenueSpentChartTipDark : revenueSpentChartTipLight
  801. })
  802. const recentStatusChartTip = computed(() => {
  803. return themeStore.theme === 'dark' ? recentStatusChartTipDark : recentStatusChartTipLight
  804. })
  805. import DashboardGuide from '../src/components/DashboardGuide.vue'
  806. import { useGuideStore } from '@/stores/modules/guide'
  807. import { useThemeStore } from '@/stores/modules/theme'
  808. import viewManagementLight from './guideImage/view-management.png'
  809. import viewManagementDark from './guideImage/dark-view-management.png'
  810. import saveConfigLight from './guideImage/save-config-guide.png'
  811. import saveConfigDark from './guideImage/dark-save-config-guide.png'
  812. import kpiChartLight from './guideImage/kpi-chart-guide.png'
  813. import kpiChartDark from './guideImage/dark-kpi-chart-guide.png'
  814. const themeStore = useThemeStore()
  815. const viewManagementImg = computed(() => {
  816. return themeStore.theme === 'dark' ? viewManagementDark : viewManagementLight
  817. })
  818. const saveConfigImg = computed(() => {
  819. return themeStore.theme === 'dark' ? saveConfigDark : saveConfigLight
  820. })
  821. const kpiChartImg = computed(() => {
  822. return themeStore.theme === 'dark' ? kpiChartDark : kpiChartLight
  823. })
  824. const guideStore = useGuideStore()
  825. const handleGuide = () => {
  826. dashboardGuideRef.value?.startGuide()
  827. }
  828. const dashboardGuideRef = ref(null)
  829. function handleImageClick(event) {
  830. event.stopPropagation() // 阻止事件冒泡
  831. alert('Image clicked')
  832. }
  833. </script>
  834. <template>
  835. <div class="dashboard">
  836. <!-- 评分 -->
  837. <ScoringSystem></ScoringSystem>
  838. <DashboardGuide ref="dashboardGuideRef"></DashboardGuide>
  839. <!-- Title -->
  840. <div class="Title">
  841. <div>
  842. <span>Dashboard</span>
  843. <VDriverGuide style="margin-top: -1px" @click="handleGuide"></VDriverGuide>
  844. </div>
  845. <div style="position: relative">
  846. <el-popover trigger="click" width="400" popper-style="border-radius: 12px">
  847. <template #reference>
  848. <el-button class="el-button--default">
  849. <span class="iconfont_icon">
  850. <svg class="iconfont" aria-hidden="true">
  851. <use xlink:href="#icon-icon_view__management_b"></use>
  852. </svg>
  853. </span>
  854. View Management
  855. </el-button>
  856. </template>
  857. <div class="Management">
  858. <div class="title">View Management</div>
  859. <div class="management_content" v-for="(item, index) in Management" :key="index">
  860. <div class="management_flex">
  861. <div class="content_title">{{ item.title }}</div>
  862. <div>
  863. <el-switch
  864. v-model="item.switchValue"
  865. :disabled="item.isRevenueDisplay != undefined && item.isRevenueDisplay == false"
  866. />
  867. </div>
  868. </div>
  869. <div class="content_text">{{ item.text }}</div>
  870. <div
  871. class="content_text_warining"
  872. v-if="item.isRevenueDisplay != undefined && item.isRevenueDisplay == false"
  873. >
  874. *To ensure the accuracy of the data display, this report needs to be configured and
  875. displayed after communicating clearly with Sales.
  876. </div>
  877. </div>
  878. <el-divider />
  879. <div class="tips">
  880. <span class="iconfont_icon">
  881. <svg class="iconfont iconfont_tips" aria-hidden="true">
  882. <use xlink:href="#icon-icon_info_b"></use>
  883. </svg>
  884. </span>
  885. <div class="tips_text">
  886. Please remember to click the save button in order to keep the new dashboard layout
  887. and widgets.
  888. </div>
  889. </div>
  890. </div>
  891. </el-popover>
  892. <img
  893. id="view-management-guide"
  894. v-if="guideStore.dashboard.isShowViewManagementGuidePhoto"
  895. class="view-management-guide-class"
  896. :class="{
  897. 'view-management-guide-dark-class': themeStore.theme === 'dark'
  898. }"
  899. :src="viewManagementImg"
  900. alt=""
  901. />
  902. <el-popover
  903. :visible="SaveVisible"
  904. :popper-style="{
  905. display: 'flex',
  906. flexDirection: 'column',
  907. alignItems: 'center',
  908. backgroundColor: 'var(--management-bg-color)'
  909. }"
  910. >
  911. <template #reference>
  912. <el-button
  913. class="el-button--default"
  914. @blur="SaveVisible = false"
  915. @click="SaveVisible = !SaveVisible"
  916. >
  917. <span class="iconfont_icon">
  918. <svg class="iconfont" aria-hidden="true">
  919. <use xlink:href="#icon-icon_save_b"></use>
  920. </svg>
  921. </span>
  922. Save
  923. <span class="iconfont_icon">
  924. <svg class="iconfont" aria-hidden="true">
  925. <use xlink:href="#icon-icon_dropdown_b"></use>
  926. </svg>
  927. </span>
  928. </el-button>
  929. </template>
  930. <div class="Save_filters" @click="SaveFilters">
  931. <span class="iconfont_icon iconfont_icon_save">
  932. <svg class="iconfont" aria-hidden="true">
  933. <use xlink:href="#icon-icon_save_b"></use>
  934. </svg>
  935. </span>
  936. <div>Save Filters</div>
  937. </div>
  938. <div class="Save_filters" @click="SaveLayout">
  939. <span class="iconfont_icon iconfont_icon_save">
  940. <svg class="iconfont" aria-hidden="true">
  941. <use xlink:href="#icon-icon_save_b"></use>
  942. </svg>
  943. </span>
  944. <div>Save Layout</div>
  945. </div>
  946. </el-popover>
  947. <!-- -->
  948. <img
  949. id="save-config-guide"
  950. v-if="guideStore.dashboard.isShowSaveConfigGuidePhoto"
  951. class="save-config-guide-class position-absolute-guide"
  952. :src="saveConfigImg"
  953. :class="{
  954. 'save-config-guide-dark-class': themeStore.theme === 'dark'
  955. }"
  956. alt=""
  957. />
  958. </div>
  959. </div>
  960. <!-- 图表 -->
  961. <div class="echarts">
  962. <VueDraggable
  963. style="
  964. display: flex;
  965. flex-wrap: wrap;
  966. justify-content: space-between;
  967. gap: 8px;
  968. width: 100%;
  969. "
  970. ref="infoContentRef"
  971. ghost-class="ghost-class"
  972. :forceFallback="true"
  973. fallback-class="fallback-class"
  974. v-model="Management"
  975. handle=".handle-draggable"
  976. >
  977. <template v-for="item in Management" :key="item">
  978. <div v-if="item.title === 'KPI' && item.switchValue" class="filters_left">
  979. <!-- KPI -->
  980. <VBox_Dashboard
  981. style="overflow: visible"
  982. @changeCancel="changeCancel(item.id)"
  983. :isShowDragIconGudie="true"
  984. >
  985. <template #header>
  986. <div class="Title_flex" style="position: relative">
  987. <img
  988. id="kpi-chart-guide"
  989. v-if="guideStore.dashboard.isShowKpiChartGuidePhoto"
  990. class="kpi-chart-guide-class position-absolute-guide"
  991. :src="kpiChartImg"
  992. alt=""
  993. />
  994. <div>
  995. {{ item.title }}
  996. <VTipTooltip
  997. :img="kpiChartTip"
  998. :width="410"
  999. :label="'KPI Report:Day difference between actual and estimate.'"
  1000. placement="bottom-start"
  1001. ></VTipTooltip>
  1002. </div>
  1003. <DashFilters
  1004. :defaultData="KPIDefaulteData"
  1005. :isShowTransportModeGuide="true"
  1006. @FilterSearch="GetKpiData"
  1007. ></DashFilters>
  1008. <!-- <el-tooltip
  1009. effect="dark"
  1010. :offset="6"
  1011. :content="item.text"
  1012. placement="bottom-start"
  1013. >
  1014. <span class="iconfont_icon iconfont_icon_tip">
  1015. <svg class="iconfont" aria-hidden="true">
  1016. <use xlink:href="#icon-icon_info_b"></use>
  1017. </svg>
  1018. </span>
  1019. </el-tooltip> -->
  1020. </div>
  1021. </template>
  1022. <template #content>
  1023. <div class="KPI_Pending">
  1024. <div class="kpi">
  1025. <PieChart
  1026. ref="pie_chart_kpi_departure"
  1027. @ClickParams="ClickParams(item.title + '0')"
  1028. :PieData="KPIobj"
  1029. v-vloading="KPILoading"
  1030. style="height: 300px"
  1031. ></PieChart>
  1032. </div>
  1033. <div class="kpi">
  1034. <PieChart
  1035. ref="pie_chart_kpi_arrival"
  1036. :PieData="Arrivalobj"
  1037. v-vloading="KPIArrivalLoading"
  1038. @ClickParams="ClickParams(item.title + '1')"
  1039. style="height: 300px"
  1040. ></PieChart>
  1041. </div>
  1042. </div>
  1043. </template>
  1044. </VBox_Dashboard>
  1045. </div>
  1046. <div v-else-if="item.title === 'Pending' && item.switchValue" class="filters_left">
  1047. <!-- Pending -->
  1048. <VBox_Dashboard @changeCancel="changeCancel(item.id)">
  1049. <template #header>
  1050. <div class="Title_flex">
  1051. <div>
  1052. {{ item.title }}
  1053. <VTipTooltip
  1054. :img="pendingChartTip"
  1055. :width="420"
  1056. :placement="'bottom-start'"
  1057. :label="'Pending Report:Showing shipments which are soon to depart/arrive.'"
  1058. ></VTipTooltip>
  1059. </div>
  1060. <DashFilters
  1061. :defaultData="PendingDefaulteData"
  1062. :radioisDisabled="true"
  1063. :img="'./image/kpi-chart-tip.png'"
  1064. @FilterSearch="GetPendingEcharts"
  1065. ></DashFilters>
  1066. </div>
  1067. </template>
  1068. <template #content>
  1069. <div class="KPI_Pending">
  1070. <div class="kpi">
  1071. <PieChart
  1072. ref="pie_chart_pending_departure"
  1073. :PieData="Pendingobj"
  1074. v-vloading="PendingLoading"
  1075. @ClickParams="ClickParams(item.title + '0')"
  1076. style="height: 300px"
  1077. ></PieChart>
  1078. </div>
  1079. <div class="kpi">
  1080. <PieChart
  1081. ref="pie_chart_pending_arrival"
  1082. @ClickParams="ClickParams(item.title + '1')"
  1083. :PieData="PendingArrivalobj"
  1084. v-vloading="PendingArrivalLoading"
  1085. style="height: 300px"
  1086. ></PieChart>
  1087. </div>
  1088. </div>
  1089. </template>
  1090. </VBox_Dashboard>
  1091. </div>
  1092. <!-- ETD to ETA -->
  1093. <div
  1094. v-else-if="item.title === 'ETD to ETA (Days)' && item.switchValue"
  1095. class="filters_left"
  1096. >
  1097. <VBox_Dashboard @changeCancel="changeCancel(item.id)">
  1098. <template #header>
  1099. <div class="Title_flex">
  1100. <div>
  1101. {{ item.title }}
  1102. <VTipTooltip
  1103. :img="etdToEtaChartsTip"
  1104. :width="430"
  1105. :placement="'bottom-start'"
  1106. :label="'ETD to ETA (Days):Distribution of Transit Time (ETA-ETD) for All Shipments in Last 12 Months.'"
  1107. ></VTipTooltip>
  1108. </div>
  1109. <DashFilters
  1110. :defaultData="ETDDefaulteData"
  1111. @FilterSearch="GetETDEcharts"
  1112. :isETDToETA="true"
  1113. :isContainer="true"
  1114. ></DashFilters>
  1115. </div>
  1116. </template>
  1117. <template #content>
  1118. <PieChart
  1119. ref="pie_chart_ETD"
  1120. @ClickParams="ClickParams(item.title)"
  1121. :PieData="ETDobj"
  1122. v-vloading="ETDLoading"
  1123. style="height: 300px"
  1124. ></PieChart>
  1125. </template>
  1126. </VBox_Dashboard>
  1127. </div>
  1128. <!-- Container Count -->
  1129. <div
  1130. v-else-if="item.title === 'Container Count' && item.switchValue"
  1131. class="filters_left"
  1132. >
  1133. <VBox_Dashboard @changeCancel="changeCancel(item.id)">
  1134. <template #header>
  1135. <div class="Title_flex">
  1136. <div>
  1137. {{ item.title }}
  1138. <VTipTooltip
  1139. :img="containerChartTip"
  1140. :placement="'bottom-start'"
  1141. :label="'Container Count:Total Container Volume by Month (Last 12 Months)'"
  1142. ></VTipTooltip>
  1143. </div>
  1144. <DashFilters
  1145. :defaultData="ContainerefaultData"
  1146. @FilterSearch="GetContainerCountEcharts"
  1147. :isContainer="true"
  1148. ></DashFilters>
  1149. </div>
  1150. </template>
  1151. <template #content>
  1152. <BarChart
  1153. ref="seller_chart_Container_count"
  1154. :BarData="containerObj"
  1155. v-vloading="containerLoading"
  1156. style="height: 300px"
  1157. :isRevenue="true"
  1158. save-image-name="Container Count"
  1159. :barHeight="{ height: '300px' }"
  1160. ></BarChart>
  1161. </template>
  1162. </VBox_Dashboard>
  1163. </div>
  1164. <!-- Top10 Origin/Top 10 Destination -->
  1165. <div
  1166. v-else-if="item.title === 'Top 10 Origin/Destination' && item.switchValue"
  1167. class="KPI_Pending"
  1168. >
  1169. <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
  1170. <template #header>
  1171. <div class="Title_flex" style="height: 48px">
  1172. <div style="display: flex">
  1173. <el-tabs
  1174. v-model="activeName"
  1175. class="demo-tabs"
  1176. style="height: 48px"
  1177. @tab-click="handleTabClick"
  1178. >
  1179. <el-tab-pane :label="item.title1" name="first"></el-tab-pane>
  1180. <el-tab-pane :label="item.title2" name="second"></el-tab-pane>
  1181. </el-tabs>
  1182. <VTipTooltip
  1183. style="margin-left: 4px"
  1184. :img="top10ChartTip"
  1185. :label="'Top 10 Origin & Destination: Last 12 Months Shipment Volume Rankings: Top 10 Origin Cities and Top 10 Destination Cities'"
  1186. :width="700"
  1187. ></VTipTooltip>
  1188. </div>
  1189. <DashFilters
  1190. :defaultData="Top10DefaultData"
  1191. @FilterSearch="GetTop10ODEcharts"
  1192. ></DashFilters>
  1193. </div>
  1194. </template>
  1195. <template v-if="isShowtitle1" #content>
  1196. <div class="KPI_Pending">
  1197. <div class="seller_chart">
  1198. <SellerChart
  1199. ref="seller_chart_top10_origin"
  1200. @clickParams="ClickParams(item.title1)"
  1201. :SellerData="Top10Obj.OriginData"
  1202. v-vloading="TopOriginLoading"
  1203. :Interval="Top1OInterval"
  1204. saveImageName="Top 10 Origin"
  1205. ></SellerChart>
  1206. </div>
  1207. <div class="map">
  1208. <!-- <TopMap :obj="dashboardObj.Top10faultData" ref="Top10Originref"></TopMap> -->
  1209. <TopMap ref="Top10Originref"></TopMap>
  1210. </div>
  1211. </div>
  1212. </template>
  1213. <template v-else #content2>
  1214. <div class="KPI_Pending">
  1215. <div class="seller_chart">
  1216. <SellerChart
  1217. ref="seller_chart_top10_destination"
  1218. @clickParams="ClickParams(item.title2)"
  1219. :SellerData="Top10Obj.DestinationData"
  1220. :Interval="Top1OInterval_dest"
  1221. v-vloading="TopOriginLoading"
  1222. saveImageName="Top 10 Destination"
  1223. style="height: 272px"
  1224. ></SellerChart>
  1225. </div>
  1226. <div class="map" style="height: 272px">
  1227. <!-- <TopMap :obj="dashboardObj.Top10faultData" ref="Top10Destinationref"></TopMap> -->
  1228. <TopMap ref="Top10Destinationref"></TopMap>
  1229. </div>
  1230. </div>
  1231. </template>
  1232. </VBox_Dashboard>
  1233. </div>
  1234. <!-- CO2e Emission by Origin (Top 10) -->
  1235. <div
  1236. v-else-if="item.title === 'CO2e Emission by Origin (Top 10)' && item.switchValue"
  1237. class="filters_left"
  1238. >
  1239. <VBox_Dashboard @changeCancel="changeCancel(item.id)">
  1240. <template #header>
  1241. <div class="Title_flex">
  1242. <div>
  1243. {{ item.title }}
  1244. <VTipTooltip
  1245. :img="co2eChartTip"
  1246. :label="'CO2e Emission by Origin or Destination: Last 12 Months CO2e Emission Rankings: Top 10 Origin Cities and Top 10 Destination Cities'"
  1247. :width="700"
  1248. :placement="'bottom-start'"
  1249. ></VTipTooltip>
  1250. </div>
  1251. <DashFilters
  1252. :defaultData="Co2OriginDefaultData"
  1253. @FilterSearch="GetCo2EmissionEcharts"
  1254. ></DashFilters>
  1255. </div>
  1256. </template>
  1257. <template #content>
  1258. <BarChart
  1259. ref="seller_chart_CO2_origin"
  1260. :BarData="EmissionObj"
  1261. save-image-name="CO2e Emission by Origin (Top 10)"
  1262. @clickParams="ClickParams(item.title)"
  1263. v-vloading="EmissionLoading"
  1264. style="height: 250px"
  1265. :isRevenue="true"
  1266. :barHeight="{ height: '250px' }"
  1267. ></BarChart>
  1268. </template>
  1269. </VBox_Dashboard>
  1270. </div>
  1271. <!-- CO2e Emission by Destination (Top 10) -->
  1272. <div
  1273. v-else-if="item.title === 'CO2e Emission by Destination (Top 10)' && item.switchValue"
  1274. class="filters_left"
  1275. >
  1276. <VBox_Dashboard @changeCancel="changeCancel(item.id)">
  1277. <template #header>
  1278. <div class="Title_flex">
  1279. <div>
  1280. {{ item.title }}
  1281. <!-- <VTipTooltip :img="co2eChartTip"></VTipTooltip> -->
  1282. </div>
  1283. <DashFilters
  1284. :defaultData="Co2DestinationDefaultData"
  1285. @FilterSearch="GetCo2DestinationEcharts"
  1286. ></DashFilters>
  1287. </div>
  1288. </template>
  1289. <template #content>
  1290. <BarChart
  1291. ref="seller_chart_CO2_destination"
  1292. :BarData="DestinationObj"
  1293. v-vloading="DestinationLoading"
  1294. style="height: 250px"
  1295. :isRevenue="true"
  1296. save-image-name="CO2e Emission by Destination (Top 10)"
  1297. @clickParams="ClickParams(item.title)"
  1298. :barHeight="{ height: '250px' }"
  1299. ></BarChart>
  1300. </template>
  1301. </VBox_Dashboard>
  1302. </div>
  1303. <!-- <div
  1304. v-else-if="item.title === 'Revenue' && item.switchValue"
  1305. class="KPI_Pending"
  1306. > -->
  1307. <div
  1308. v-else-if="
  1309. item.title === 'Recent Status' && item.switchValue && RecentStatusList.length != 0
  1310. "
  1311. class="KPI_Pending"
  1312. >
  1313. <!-- Recent Status -->
  1314. <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
  1315. <template #header>
  1316. <div class="Title_flex">
  1317. <div>
  1318. {{ item.title }}
  1319. <VTipTooltip
  1320. :img="recentStatusChartTip"
  1321. :label="'Recent Status: Active shipment list with ETD within the past three months and the next month.'"
  1322. :width="700"
  1323. :placement="'bottom-start'"
  1324. ></VTipTooltip>
  1325. </div>
  1326. <DashFilters
  1327. :defaultData="RecentDefaulteData"
  1328. @FilterSearch="getTableData"
  1329. :isRecent="true"
  1330. ></DashFilters>
  1331. </div>
  1332. </template>
  1333. <template #content>
  1334. <RecentStatus :RecentStatusList="RecentStatusList"></RecentStatus>
  1335. <div class="pagination">
  1336. <span>Total {{ formatNumber(pageInfo.total) }}</span>
  1337. <el-pagination
  1338. v-model:current-page="pageInfo.pageNo"
  1339. v-model:page-size="pageInfo.pageSize"
  1340. :page-sizes="[10, 50, 100, 200]"
  1341. layout="prev, pager, next"
  1342. :pager-count="3"
  1343. :total="pageInfo.total"
  1344. @size-change="getTableData(true, RecentDefaulteData)"
  1345. @current-change="getTableData(true, RecentDefaulteData)"
  1346. />
  1347. </div>
  1348. </template>
  1349. </VBox_Dashboard>
  1350. </div>
  1351. <!-- Revenue -->
  1352. <div v-else-if="item.title === 'Revenue Spent' && item.switchValue" class="KPI_Pending">
  1353. <VBox_Dashboard @changeCancel="changeCancel(item.id)" style="width: 100%">
  1354. <template #header>
  1355. <div class="Title_flex">
  1356. <div>
  1357. Revenue Spent
  1358. <VTipTooltip
  1359. :img="revenueSpentChartTip"
  1360. :label="'Revenue Spent: Based on the billto object, display the corresponding revenue data. '"
  1361. :placement="'bottom-start'"
  1362. :width="700"
  1363. ></VTipTooltip>
  1364. </div>
  1365. <DashFilters
  1366. :defaultData="RevenueDefaultData"
  1367. @FilterSearch="GetRevenueEcharts"
  1368. :isRevenue="true"
  1369. :isContainer="true"
  1370. ></DashFilters>
  1371. </div>
  1372. </template>
  1373. <template #content>
  1374. <RevenueChart
  1375. :BarData="RevenueObj"
  1376. v-vloading="RevenueLoading"
  1377. :RevenueStartDate="revenue_date_start"
  1378. :RevenueEndDate="revenue_date_end"
  1379. style="height: 300px"
  1380. :barHeight="{ height: '300px' }"
  1381. ></RevenueChart>
  1382. </template>
  1383. </VBox_Dashboard>
  1384. </div>
  1385. </template>
  1386. </VueDraggable>
  1387. </div>
  1388. </div>
  1389. </template>
  1390. <style lang="scss" scoped>
  1391. .Title {
  1392. display: flex;
  1393. background-color: var(--color-mode);
  1394. height: 68px;
  1395. font-size: var(--font-size-6);
  1396. font-weight: 700;
  1397. padding: 0 24px;
  1398. align-items: center;
  1399. justify-content: space-between;
  1400. }
  1401. .iconfont {
  1402. vertical-align: -2px;
  1403. }
  1404. .view-management-guide-class {
  1405. position: absolute;
  1406. top: 0px;
  1407. right: 85px;
  1408. width: 437px;
  1409. height: 603px;
  1410. z-index: 1500;
  1411. &.view-management-guide-dark-class {
  1412. width: 439px;
  1413. height: 622px;
  1414. }
  1415. }
  1416. .save-config-guide-class {
  1417. position: absolute;
  1418. top: -1px;
  1419. right: -13px;
  1420. width: 183px;
  1421. height: 160px;
  1422. z-index: 1500;
  1423. transform: translate(-0.8px, 0px);
  1424. &.save-config-guide-dark-class {
  1425. width: 182px;
  1426. height: 157px;
  1427. right: -12px;
  1428. }
  1429. }
  1430. .kpi-chart-guide-class {
  1431. top: -2px;
  1432. left: -50px;
  1433. width: 589px;
  1434. height: 478px;
  1435. z-index: 3500;
  1436. }
  1437. .Management {
  1438. max-height: 640px;
  1439. overflow-y: hidden;
  1440. border-radius: 12px;
  1441. background-color: var(--management-bg-color);
  1442. }
  1443. .Management:hover {
  1444. overflow-y: scroll;
  1445. }
  1446. .title {
  1447. font-weight: 700;
  1448. font-size: var(--font-size-5);
  1449. background-color: var(--color-header-bg);
  1450. height: 48px;
  1451. display: flex;
  1452. align-items: center;
  1453. padding-left: 16px;
  1454. }
  1455. .management_content {
  1456. width: 368px;
  1457. min-height: 54px;
  1458. margin: 10px auto;
  1459. background-color: var(--color-header-bg);
  1460. border-radius: var(--border-radius-6);
  1461. padding: 8px 16px;
  1462. }
  1463. .management_flex {
  1464. display: flex;
  1465. height: 20px;
  1466. justify-content: space-between;
  1467. align-items: center;
  1468. }
  1469. .content_title {
  1470. font-weight: 700;
  1471. font-size: var(--font-size-3);
  1472. }
  1473. .content_text {
  1474. color: var(--color-neutral-2);
  1475. font-size: var(--font-size-2);
  1476. line-height: 16px;
  1477. }
  1478. .content_text_warining {
  1479. color: var(--color-warning);
  1480. font-size: var(--font-size-2);
  1481. line-height: 16px;
  1482. }
  1483. .tips {
  1484. display: flex;
  1485. justify-content: center;
  1486. padding-bottom: 8px;
  1487. }
  1488. .iconfont_tips {
  1489. fill: var(--color-neutral-2);
  1490. }
  1491. .tips_text {
  1492. width: 278.43px;
  1493. text-align: center;
  1494. font-size: var(--font-size-2);
  1495. color: var(--color-neutral-2);
  1496. }
  1497. .el-divider--horizontal {
  1498. margin: 8px 0;
  1499. }
  1500. .Save_filters {
  1501. display: flex;
  1502. align-items: center;
  1503. justify-content: center;
  1504. height: 40px;
  1505. font-size: var(--font-size-3);
  1506. width: 126px;
  1507. margin: 4px 0;
  1508. cursor: pointer;
  1509. }
  1510. .iconfont_icon_save {
  1511. margin-right: 16px;
  1512. fill: var(--color-neutral-1);
  1513. }
  1514. .Save_filters:hover {
  1515. border-color: var(--color-btn-default-bg-hover);
  1516. background-color: var(--color-btn-default-bg-hover);
  1517. .iconfont_icon_save {
  1518. fill: var(--color-theme);
  1519. }
  1520. div {
  1521. color: var(--color-theme);
  1522. }
  1523. }
  1524. .filters {
  1525. display: flex;
  1526. padding: 0 24px;
  1527. height: 32px;
  1528. align-items: center;
  1529. margin-bottom: 8px;
  1530. justify-content: space-between;
  1531. }
  1532. .KPI_Pending {
  1533. display: flex;
  1534. width: 100%;
  1535. }
  1536. .filters_left {
  1537. border-radius: var(--border-radius-6);
  1538. width: calc(50% - 4px);
  1539. flex: 0 0 calc(50% - 4px);
  1540. min-width: 0;
  1541. box-sizing: border-box;
  1542. }
  1543. .KPI_title {
  1544. border-bottom: 1px solid var(--color-border);
  1545. height: 48px;
  1546. line-height: 48px;
  1547. align-items: center;
  1548. justify-content: space-between;
  1549. display: flex;
  1550. padding-left: 16px;
  1551. font-weight: 700;
  1552. font-size: var(--font-size-5);
  1553. }
  1554. .tips_filter {
  1555. margin-right: 8px;
  1556. height: 32px;
  1557. }
  1558. .filters_right {
  1559. width: 251px;
  1560. height: 32px;
  1561. margin-bottom: 8px;
  1562. }
  1563. :deep(.ETD_title) {
  1564. margin-bottom: 0 !important;
  1565. }
  1566. :deep(:where(.css-dev-only-do-not-override-19iuou).ant-picker-range) {
  1567. height: 32px;
  1568. }
  1569. .echarts {
  1570. padding: 0 22px;
  1571. background-color: var(--color-mode);
  1572. :deep(> div) {
  1573. display: flex;
  1574. flex-wrap: wrap;
  1575. justify-content: space-between;
  1576. gap: 8px;
  1577. width: 100%;
  1578. > * {
  1579. box-sizing: border-box;
  1580. }
  1581. }
  1582. }
  1583. .kpi {
  1584. width: 50%;
  1585. border-right: 1px solid var(--color-border);
  1586. }
  1587. .kpi:last-child {
  1588. border-right: none;
  1589. }
  1590. .ghost-class {
  1591. opacity: 0;
  1592. }
  1593. .fallback-class {
  1594. opacity: 1 !important;
  1595. background-color: #fff;
  1596. cursor: move !important;
  1597. box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
  1598. border-radius: 12px;
  1599. }
  1600. .pagination {
  1601. display: flex;
  1602. justify-content: space-between;
  1603. align-items: center;
  1604. border-top: 1px solid var(--color-border);
  1605. padding: 4px 8px;
  1606. }
  1607. .container-type {
  1608. font-size: 14px;
  1609. font-weight: 400;
  1610. margin-right: 4px;
  1611. }
  1612. .seller_chart {
  1613. width: 30%;
  1614. border-right: 1px solid var(--color-border);
  1615. }
  1616. .map {
  1617. width: 70%;
  1618. }
  1619. .Title_flex {
  1620. display: flex;
  1621. align-items: center;
  1622. justify-content: space-between;
  1623. margin-right: 30px;
  1624. }
  1625. .iconfont_icon_tip {
  1626. margin-left: 8px;
  1627. width: 16px;
  1628. height: 16px;
  1629. display: flex;
  1630. align-items: center;
  1631. }
  1632. .dashboard {
  1633. z-index: 2014;
  1634. position: relative;
  1635. background-color: var(--color-mode);
  1636. padding-bottom: 40px;
  1637. }
  1638. :deep(.el-tabs__header) {
  1639. height: 48px;
  1640. margin-bottom: 0;
  1641. }
  1642. </style>
  1643. <style lang="scss">
  1644. :not(body):has(> img.driver-active-element) {
  1645. overflow: visible !important;
  1646. }
  1647. </style>