index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <template>
  2. <div style="overflow-y: auto;background-color: #F7F7F7;height: 100%;">
  3. <div style="margin-left: 1%;width: 98%;display: flex;margin-top: 1%;height: 15vh;">
  4. <div shadow="always" style="width: 33%;height: 100%;;border-radius: 10px;background-color: white;margin-left: 0%;" class="boxShadow">
  5. <div style="width: 100%;display: flex;align-items: center;justify-content: center;font-size: 35px;font-weight: bold;color: #2DBEA2;;height: 70%">
  6. {{yearAll}}
  7. </div>
  8. <div style="display: flex;align-items: center;justify-content: center;background-color: #2DBEA2;font-size: 20px;width: 100%;color: white;text-align: center;border-radius: 0 0 10px 10px;height: 30%;">
  9. 年调用次数
  10. </div>
  11. </div>
  12. <div shadow="always" style="width: 33%;height: 100%;;border-radius: 10px;background-color: white;margin-left: 1%;" class="boxShadow">
  13. <div style="width: 100%;display: flex;align-items: center;justify-content: center;font-size: 35px;font-weight: bold;color: #40B0D7;;height: 70%">
  14. {{monAll}}
  15. </div>
  16. <div style="display: flex;align-items: center;justify-content: center;background-color: #40B0D7;font-size: 20px;width: 100%;color: white;text-align: center;border-radius: 0 0 10px 10px;height: 30%;">
  17. 月调用次数
  18. </div>
  19. </div>
  20. <div shadow="always" style="width: 33%;margin-left: 1%;height: 100%;;border-radius: 10px;background-color: white;" class="boxShadow">
  21. <div style="width: 100%;display: flex;align-items: center;justify-content: center;font-size: 35px;font-weight: bold;color: #477ACF;;height: 70%">
  22. {{dayAll}}
  23. </div>
  24. <div style="display: flex;align-items: center;justify-content: center;background-color: #477ACF;font-size: 20px;width: 100%;color: white;text-align: center;border-radius: 0 0 10px 10px;height: 30%;">
  25. 日调用次数
  26. </div>
  27. </div>
  28. </div>
  29. <div style="background-color: #F7F7F7;padding-top:1%;">
  30. <div style="margin-left: 1%;width: 98%;display: flex;height: 32vh;">
  31. <div style="width: 100%;height: 100%;">
  32. <el-card shadow="always" class="box-card" style="width:100%;height: 100%;">
  33. <div style="font-weight: bold;font-size: 18px;">
  34. 模型每日服务调度次数统计
  35. </div>
  36. <div style="display: flex;align-items: center;line-height: 1;margin-top: 1%;">
  37. <div style="font-size: 17px;">今日模型服务调度次数</div>
  38. <div style="color: #79bbff;margin-left: 1%;"> {{daySum}} </div>
  39. <div style="margin-left: 1%;"> 次 </div>
  40. <el-date-picker
  41. v-model="valueYue"
  42. type="month"
  43. style="margin-left: 1%;"
  44. @change="getDay"
  45. placeholder="本月"
  46. value-format="YYYY-MM-DD"
  47. />
  48. <el-select
  49. v-model="valueMod"
  50. @change="getDay"
  51. class="m-2"
  52. placeholder="上海市城区洪涝仿真模型"
  53. style="width: 15%;margin-left: 1%;"
  54. >
  55. <el-option
  56. v-for="item in optionsModel"
  57. :key="item.value"
  58. :label="item.label"
  59. :value="item.id"
  60. />
  61. </el-select>
  62. </div>
  63. <div id="top1" style="width: 98%;margin-left: 1%;margin-top: -1%;height:23vh">
  64. </div>
  65. </el-card>
  66. </div>
  67. </div>
  68. <div style="margin-left: 1%;width: 98%;display: flex;margin-top: 1%;height: 45vh;">
  69. <el-card shadow="always" class="box-card" style="width:50%;height: 100%;">
  70. <div style="margin-left: 1%;font-weight: bold;">
  71. 模型每月服务调度次数统计
  72. </div>
  73. <div style="width: 100%;display: flex;margin-top: 2%;">
  74. <el-date-picker
  75. v-model="valueMon"
  76. type="year"
  77. style="margin-left: 1%;"
  78. @change="getMon"
  79. placeholder="本年"
  80. value-format="YYYY-MM-DD"
  81. />
  82. <el-select
  83. v-model="valueModMon"
  84. @change="getMon"
  85. class="m-2"
  86. placeholder=""
  87. style="width: 25%;margin-left: 1%;"
  88. >
  89. <el-option
  90. v-for="item in optionsModel"
  91. :key="item.value"
  92. :label="item.label"
  93. :value="item.id"
  94. />
  95. </el-select>
  96. </div>
  97. <div id="bt1" style="width: 100%;margin-left: 0%;margin-top: -1%;height: 30vh;">
  98. </div>
  99. </el-card>
  100. <el-card shadow="always" class="box-card" style="width:50%;height: 100%;margin-left: 1%;">
  101. <div style="margin-left: 1%;font-weight: bold;">
  102. 模型调用次数年度排名
  103. </div>
  104. <div style="width: 100%;display: flex;margin-top: 2%;">
  105. <el-date-picker
  106. v-model="valuePai"
  107. type="year"
  108. style="margin-left: 1%;"
  109. @change="getPai"
  110. placeholder="本年"
  111. value-format="YYYY-MM-DD"
  112. />
  113. <!-- <el-select
  114. v-model="value"
  115. class="m-2"
  116. placeholder="上海市城区洪涝仿真模型"
  117. style="width:20%;margin-left: 1%;"
  118. >
  119. <el-option
  120. v-for="item in options"
  121. :key="item.value"
  122. :label="item.label"
  123. :value="item.value"
  124. />
  125. </el-select> -->
  126. </div>
  127. <div id="bt2" style="width: 100%;margin-left: 1%;margin-top: -1%;height: 35vh;">
  128. </div>
  129. </el-card>
  130. </div>
  131. </div>
  132. </div>
  133. </template>
  134. <script setup>
  135. import { ref, onMounted } from 'vue';
  136. import * as echarts from 'echarts';
  137. import { modelTreeSelect,getDayChart,getDaySum,getYueChart,getSumAll,getPaihang } from "@/api/service/info";
  138. const listHelp = [
  139. ]
  140. const valuePai = ref()
  141. const modelList = ref([])
  142. const daySum = ref('')
  143. const valueYue = ref('')
  144. const dayAll = ref()
  145. const monAll = ref()
  146. const yearAll = ref()
  147. const valueModMon = ref('')
  148. const valueMon = ref('')
  149. const valueMod = ref('')
  150. const heightAll = window.innerHeight
  151. const seledMo = ['primary','plain','plain','plain','plain','plain','plain']
  152. const optionsModel = ref({})
  153. function getLastDayOfMonth(firstDay) {
  154. // 从第一天字符串解析年月
  155. const [year, month] = firstDay.split('-').map(Number);
  156. // 创建下个月第一天的日期对象
  157. const nextMonthFirstDay = new Date(year, month, 1); // month是1-12,JS会自动处理跨年
  158. // 获取当月最后一天(下个月第一天减1毫秒)
  159. const lastDay = new Date(nextMonthFirstDay - 1);
  160. // 格式化输出
  161. const lastDayYear = lastDay.getFullYear();
  162. const lastDayMonth = (lastDay.getMonth() + 1).toString().padStart(2, '0');
  163. const lastDayDate = lastDay.getDate().toString().padStart(2, '0');
  164. return `${lastDayYear}-${lastDayMonth}-${lastDayDate}`;
  165. }
  166. function getAllDaysInMonth(firstDayOfMonth) {
  167. // 解析输入字符串获取年月
  168. const [year, month] = firstDayOfMonth.split('-').map(Number);
  169. // 创建当月最后一天的日期对象
  170. const lastDay = new Date(year, month, 0); // 月份从0开始,所以month即下个月
  171. // 获取当月天数
  172. const daysCount = lastDay.getDate();
  173. // 生成所有天数的数组
  174. return Array.from({length: daysCount}, (_, i) =>
  175. (i + 1).toString().padStart(2, '0')
  176. );
  177. }
  178. function getLastDayOfYear(firstDay) {
  179. // 从输入字符串中提取年份
  180. const year = parseInt(firstDay.split('-')[0]);
  181. // 计算下一年度的第一天
  182. const nextYearFirstDay = new Date(year + 1, 0, 1); // 月份0代表1月
  183. // 计算本年度的最后一天(下一年第一天减去1毫秒)
  184. const lastDay = new Date(nextYearFirstDay.getTime() - 1);
  185. // 格式化为 YYYY-MM-DD
  186. const lastDayYear = lastDay.getFullYear();
  187. const lastDayMonth = String(lastDay.getMonth() + 1).padStart(2, '0'); // 月份从0开始,需+1
  188. const lastDayDate = String(lastDay.getDate()).padStart(2, '0');
  189. return `${lastDayYear}-${lastDayMonth}-${lastDayDate}`;
  190. }
  191. function getMon(){
  192. var mdName
  193. for(var i = 0;i<optionsModel.value.length;i++){
  194. if(valueModMon.value===optionsModel.value[i].id){
  195. mdName = optionsModel.value[i].label
  196. }
  197. }
  198. console.log(mdName.value)
  199. var par = {
  200. params:{
  201. beginTime:valueMon.value,
  202. endTime:getLastDayOfYear(valueMon.value)
  203. },
  204. mdId:valueModMon.value
  205. }
  206. var x = getMonthsFromJanuaryToCurrent()
  207. var y = []
  208. x.forEach(item=>{
  209. y.push(0)
  210. })
  211. getYueChart(par).then(res=>{
  212. for(var i = 0;i<res.data.length;i++){
  213. for(var i1 = 0;i1<y.length;i1++){
  214. if(Number(res.data[i].statisTm.slice(-5,-3))===i1+1){
  215. y[i1] = res.data[i].statisNum
  216. }
  217. }
  218. }
  219. initChartbt1(y,mdName)
  220. })
  221. }
  222. function getMonthsFromJanuaryToCurrent() {
  223. const today = new Date();
  224. const currentYear = today.getFullYear();
  225. const currentMonth = today.getMonth() + 1; // 获取当前月份 (1-12)
  226. const monthsArray = [];
  227. // 从1月循环到当前月份
  228. for (let month = 1; month <= currentMonth; month++) {
  229. monthsArray.push(month);
  230. }
  231. return monthsArray;
  232. }
  233. function getDaysFromFirstToToday() {
  234. const today = new Date();
  235. const currentYear = today.getFullYear();
  236. const currentMonth = today.getMonth();
  237. const currentDay = today.getDate(); // 获取今天是几号
  238. const daysArray = [];
  239. // 从1号循环到今天
  240. for (let day = 1; day <= currentDay; day++) {
  241. daysArray.push(day);
  242. }
  243. return daysArray;
  244. }
  245. function getDateRangeArray(dateStr) {
  246. const inputDate = new Date(dateStr);
  247. const inputYear = inputDate.getFullYear();
  248. const inputMonth = inputDate.getMonth(); // 0-based
  249. const inputDay = inputDate.getDate();
  250. const currentDate = new Date();
  251. const currentYear = currentDate.getFullYear();
  252. const currentMonth = currentDate.getMonth();
  253. const currentDay = currentDate.getDate();
  254. const daysArray = [];
  255. // 判断是否属于当前月
  256. if (inputYear === currentYear && inputMonth === currentMonth) {
  257. // 若输入日期晚于当前日期,返回空数组
  258. if (inputDay > currentDay) return daysArray;
  259. for (let day = inputDay; day <= currentDay; day++) {
  260. daysArray.push(day);
  261. }
  262. } else {
  263. // 生成传入月份的全部天数
  264. const daysInMonth = new Date(inputYear, inputMonth + 1, 0).getDate();
  265. for (let day = 1; day <= daysInMonth; day++) {
  266. daysArray.push(day);
  267. }
  268. }
  269. return daysArray;
  270. }
  271. function getDay(){
  272. var mdName
  273. for(var i = 0;i<optionsModel.value.length;i++){
  274. if(valueMod.value===optionsModel.value[i].id){
  275. mdName = optionsModel.value[i].label
  276. }
  277. }
  278. var par = {
  279. params:{
  280. beginTime:valueYue.value,
  281. endTime:getLastDayOfMonth(valueYue.value)
  282. },
  283. mdId:valueMod.value
  284. }
  285. var x = getDateRangeArray(valueYue.value)
  286. console.log(x)
  287. var y = []
  288. x.forEach(item=>{
  289. y.push(0)
  290. })
  291. var par1 = {
  292. mdId:valueMod.value
  293. }
  294. getDaySum(par1).then(res=>{
  295. daySum.value = res.data
  296. })
  297. getDayChart(par).then(res=>{
  298. for(var i = 0;i<res.data.length;i++){
  299. for(var i1 = 0;i1<y.length;i1++){
  300. if(Number(res.data[i].statisTm.slice(-2))===i1+1){
  301. y[i1] = res.data[i].statisNum
  302. }
  303. }
  304. }
  305. inintChartTop1(x,y,mdName)
  306. })
  307. }
  308. function inintChartTop1(x,y,mdName){
  309. var chartDom = document.getElementById('top1');
  310. var myChart = echarts.init(chartDom);
  311. var option;
  312. option = {
  313. tooltip: {
  314. trigger: 'axis'
  315. },
  316. legend: {
  317. top:'90%'
  318. },
  319. xAxis: {
  320. splitLine: { show: false },
  321. // type: 'category',
  322. data: x,
  323. axisLabel: {
  324. fontSize: 14, // y轴标签字体大小
  325. color: '#666'
  326. },
  327. },
  328. yAxis: {
  329. type: 'value',
  330. show: true,
  331. axisLabel: {
  332. fontSize: 14, // y轴标签字体大小
  333. color: '#666'
  334. },
  335. splitLine: { show: false },
  336. name: '单位:次',
  337. minInterval: 1,
  338. axisTick: {
  339. show: true // 确保显示刻度线
  340. },
  341. axisLine: {
  342. show: true, // 确保显示轴线
  343. lineStyle: {
  344. color: '#333', // 可以设置轴线的颜色,例如与文字颜色一致
  345. // width: 1 // 可以设置轴线宽度,可选
  346. }
  347. },
  348. },
  349. series: [
  350. {
  351. name: mdName,
  352. type: 'line',
  353. color:'#409EFF',
  354. data: y,
  355. smooth: true
  356. },
  357. ]
  358. };
  359. option && myChart.setOption(option);
  360. }
  361. function initChartbt1(y,mdName){
  362. var chartDom = document.getElementById('bt1');
  363. var myChart = echarts.init(chartDom);
  364. var option;
  365. option = {
  366. tooltip: {
  367. trigger: 'axis'
  368. },
  369. legend: {
  370. data: ['上海市城区洪涝仿真模型', '上海沿海风暴潮预报模型', '黄浦江水系水文分析预报数值模拟模型', '苏州河水系水情预报模型',
  371. '内涝风险实时预警与预报模型','上海市中心城区排水系统模型', '温带风暴潮预报模型',],
  372. top:'90%'
  373. },
  374. xAxis: {
  375. splitLine: { show: false },
  376. // type: 'category',
  377. data: [1,2,3,4,5,6,7,8,9,10,11,12],
  378. axisLabel: {
  379. fontSize: 14, // y轴标签字体大小
  380. color: '#666'
  381. },
  382. },
  383. yAxis: {
  384. type: 'value',
  385. show: true,
  386. name: '单位:次',
  387. axisLabel: {
  388. fontSize: 14, // y轴标签字体大小
  389. color: '#666'
  390. },
  391. minInterval: 1,
  392. splitLine: { show: false },
  393. axisTick: {
  394. show: true // 确保显示刻度线
  395. },
  396. axisLine: {
  397. show: true, // 确保显示轴线
  398. lineStyle: {
  399. color: '#333', // 可以设置轴线的颜色,例如与文字颜色一致
  400. // width: 1 // 可以设置轴线宽度,可选
  401. }
  402. },
  403. },
  404. series: [
  405. {
  406. name: mdName,
  407. type: 'line',
  408. color:'#409EFF',
  409. data: y,
  410. smooth: true
  411. },
  412. ]
  413. };
  414. option && myChart.setOption(option);
  415. }
  416. function initChartbt2(y){
  417. var chartDom = document.getElementById('bt2');
  418. var myChart = echarts.init(chartDom);
  419. var option;
  420. option = {
  421. tooltip: {
  422. trigger: 'axis'
  423. },
  424. xAxis: {
  425. axisLabel: {
  426. fontSize: 14, // y轴标签字体大小
  427. color: '#666'
  428. },
  429. splitLine: { show: false },
  430. type: 'category',
  431. data: modelList.value,
  432. axisLabel: {
  433. interval: 0, // 强制显示所有标签
  434. rotate: -25, // 旋转角度,正值表示顺时针旋转,负值表示逆时针旋转
  435. // 可以设置文字样式,如字体大小、颜色等
  436. textStyle: {
  437. fontSize: 10,
  438. color: '#333'
  439. }
  440. }
  441. },
  442. yAxis: {
  443. type: 'value',
  444. name: '单位:次',
  445. minInterval: 1,
  446. show: true,
  447. nameLocation: 'end',
  448. axisLabel: {
  449. fontSize: 14, // y轴标签字体大小
  450. color: '#666'
  451. },
  452. splitLine: { show: false },
  453. axisTick: {
  454. show: true // 确保显示刻度线
  455. },
  456. axisLine: {
  457. show: true, // 确保显示轴线
  458. lineStyle: {
  459. color: '#333', // 可以设置轴线的颜色,例如与文字颜色一致
  460. // width: 1 // 可以设置轴线宽度,可选
  461. }
  462. },
  463. },
  464. series: [
  465. {
  466. type: 'bar',
  467. color:'#409EFF',
  468. data: y,
  469. smooth: true
  470. },
  471. ]
  472. };
  473. option && myChart.setOption(option);
  474. }
  475. const getFirstDayOfMonthShort = () => {
  476. const now = new Date();
  477. return `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-01`;
  478. };
  479. function getFirstDayOfYear() {
  480. const currentYear = new Date().getFullYear();
  481. const firstDay = new Date(currentYear, 0, 1);
  482. // 格式化为 YYYY-MM-DD
  483. const year = firstDay.getFullYear();
  484. const month = String(firstDay.getMonth() + 1).padStart(2, '0');
  485. const day = String(firstDay.getDate()).padStart(2, '0');
  486. return `${year}-${month}-${day}`;
  487. }
  488. function getPai(){
  489. var par = {
  490. params:{
  491. beginTime:valuePai.value,
  492. endTime:getLastDayOfYear(valueMon.value)
  493. },
  494. }
  495. modelList.value = []
  496. var y = []
  497. getPaihang(par).then(res=>{
  498. res.data.forEach(item=>{
  499. modelList.value.push(item.mdName)
  500. y.push(item.statisNum)
  501. })
  502. initChartbt2(y)
  503. })
  504. }
  505. async function getTreeLeft(){
  506. var par = {
  507. params:{
  508. level:'2',
  509. devkind:'APP'
  510. }
  511. }
  512. await modelTreeSelect(par).then(res=>{
  513. optionsModel.value = res.data[0].children
  514. valueMod.value = optionsModel.value[0].id
  515. valueModMon.value = optionsModel.value[0].id
  516. valueMon.value = getFirstDayOfYear()
  517. valueYue.value = getFirstDayOfMonthShort()
  518. valuePai.value = getFirstDayOfYear()
  519. getDay()
  520. getMon()
  521. // getPai()
  522. })
  523. var par1 = {
  524. params:{
  525. beginTime:valuePai.value,
  526. endTime:getLastDayOfYear(valueMon.value)
  527. },
  528. }
  529. modelList.value = []
  530. var y = []
  531. await getPaihang(par1).then(res=>{
  532. res.data.forEach(item=>{
  533. modelList.value.push(item.mdName)
  534. y.push(item.statisNum)
  535. })
  536. initChartbt2(y)
  537. })
  538. var parDay = {
  539. params:{
  540. beginTime:`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')}`,
  541. endTime:`${new Date().getFullYear()}-${String(new Date().getMonth() + 1).padStart(2, '0')}-${String(new Date().getDate()).padStart(2, '0')}`
  542. },
  543. }
  544. var parMon = {
  545. params:{
  546. beginTime:getFirstDayOfMonthShort(),
  547. endTime:getLastDayOfMonth(valueYue.value)
  548. },
  549. }
  550. var parYear = {
  551. params:{
  552. beginTime:getFirstDayOfYear(),
  553. endTime:getLastDayOfYear(valueMon.value)
  554. },
  555. }
  556. getSumAll(parDay).then(res=>{
  557. dayAll.value = res.data
  558. })
  559. getSumAll(parMon).then(res=>{
  560. monAll.value = res.data
  561. })
  562. getSumAll(parYear).then(res=>{
  563. yearAll.value = res.data
  564. })
  565. }
  566. onMounted(() => {
  567. getTreeLeft()
  568. // inintChartTop1()
  569. // initChartbt1()
  570. });
  571. </script>
  572. <style scoped lang="scss">
  573. .boxShadow{
  574. box-shadow:
  575. -8px 0 15px -10px rgba(0, 0, 0, 0.1), /* 左侧阴影 */
  576. 8px 0 15px -10px rgba(0, 0, 0, 0.1); /* 右侧阴影 */
  577. transition: box-shadow 0.3s ease;
  578. }
  579. </style>