ChartDetail.vue 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. <script setup name="ChartETAChartDetail">
  2. import {nextTick, onMounted,ref,reactive} from 'vue'
  3. import {showDialog, showToast} from 'vant'
  4. import apiChart from '@/api/chart'
  5. import { useRoute, useRouter } from 'vue-router'
  6. import { useWindowSize } from '@vueuse/core'
  7. import {yearSelectOpt,sameOptionType} from '@/hooks/chart/config'
  8. import {useChartRender} from '@/hooks/chart/render'
  9. import { getChartShareExpireToken } from './hooks/useChartSharedToken'
  10. import moment from 'moment'
  11. import EdbInfo from './components/EdbInfo.vue'
  12. import SourceDetail from './components/SourceDetail.vue'
  13. import TreeSelectPop from './components/TreeSelectPop.vue'
  14. import AddChartToMyETA from './components/AddChartToMyETA.vue'
  15. import SetChartEnName from './components/SetChartEnName.vue'
  16. import {useCachedViewsStore} from '@/store/modules/cachedViews'
  17. import { setExtremumDate } from '@/hooks/chart/commonFun.js'
  18. import {chartLibBtn,useAuthBtn} from '@/hooks/useAuthBtn'
  19. import {usePublicSettingStore} from '@/store/modules/publicSetting'
  20. import _ from 'lodash';
  21. import SaveToMaterial from '@/components/SaveToMaterial.vue'
  22. const {checkAuthBtn} = useAuthBtn()
  23. const publicSettingStore = usePublicSettingStore()
  24. const {options,axisLimitState,chartRender,setLimitData,isUseSelfLimit}=useChartRender()
  25. const { width } = useWindowSize()
  26. const cachedViewsStore=useCachedViewsStore()
  27. const route=useRoute()
  28. const router=useRouter()
  29. let routeQueryData=reactive({
  30. chartType:route.query.chartType,
  31. id:route.query.id,
  32. chartClassifyId:route.query.chartClassifyId,
  33. })
  34. let currentLang = ref('')
  35. //获取图详情
  36. let chartInfoData=null
  37. let chartInfo=ref(null)
  38. //highchart图表
  39. let highChart = ref(null)
  40. let edbList=ref([])//指标数据
  41. async function getChartDetail(e){
  42. const params=sameOptionType.includes(Number(routeQueryData.chartType))?{
  43. ChartInfoId:Number(routeQueryData.id),
  44. DateType: chartState.yearVal,
  45. StartDate: chartState.startTime,
  46. EndDate: chartState.endTime,
  47. StartYear:chartState.startYear
  48. }:{
  49. ChartInfoId:Number(routeQueryData.id),
  50. Calendar: chartState.calendarType,//this.calendar_type
  51. DateType: chartState.yearVal,
  52. StartDate: chartState.startTime,
  53. EndDate:chartState.endTime,
  54. StartYear:chartState.startYear
  55. }
  56. const res=await apiChart.chartInfoById(params)
  57. if(res.Ret!==200) return
  58. chartInfoData=res.Data
  59. chartInfo.value=res.Data.ChartInfo
  60. chartActions.value = getChartActions(res.Data.ChartInfo)
  61. if(res.Data.ChartInfo.Source===2){
  62. edbList.value=[res.Data.EdbInfoList[0]]
  63. }else{
  64. edbList.value=res.Data.EdbInfoList
  65. }
  66. if(e==='init'){
  67. chartState.yearVal=res.Data.ChartInfo.DateType
  68. }
  69. // 设置 起始日期 和 最新日期
  70. const extremumDate= setExtremumDate(edbList.value)
  71. minDate = new Date(extremumDate.earliestDate)
  72. earliestDate.value = extremumDate.earliestDate
  73. latestDate.value = extremumDate.latestDate
  74. setDateAppear()
  75. //初始化上下限
  76. isUseSelfLimit.value = true
  77. setLimitData(res.Data)
  78. nextTick(()=>{
  79. highChart.value = chartRender({
  80. data:{
  81. ...res.Data,
  82. ChartInfo:{
  83. ...res.Data.ChartInfo,
  84. Calendar:chartState.calendarType||'公历'
  85. },
  86. },
  87. renderId:'chart-box',
  88. lang:currentLang.value,
  89. changeLangIsCheck:false,
  90. showChartTitle:false,
  91. shouldUseSelfLimit:true,
  92. })
  93. })
  94. }
  95. function setDateAppear() {
  96. if(chartState.yearVal == 20){
  97. let latestYear = parseInt(latestDate.value.substring(0,4))
  98. chartState.startTime = `${latestYear-chartState.startYear+1}-01-01`
  99. chartState.endTime = `${latestYear}-12-31`
  100. }
  101. }
  102. // 是否面积图堆叠百分比
  103. function isChartHeap(info){
  104. let tag=true
  105. if(info.ChartType==3&&info.ExtraConfig){
  106. let ExtraConfig=JSON.parse(info.ExtraConfig)
  107. tag=ExtraConfig.HeapWay==2?false:true
  108. }
  109. return tag
  110. }
  111. onMounted(() => {
  112. currentLang.value = localStorage.getItem('chartETALange')==='EN'?'en':'zh'
  113. initChartState(route.query)
  114. getChartDetail('init')
  115. })
  116. let minDate=new Date(1970, 0, 1)
  117. const maxDate=new Date(2050, 11, 31)
  118. const cYear=moment().format('YYYY')
  119. const cMonth=moment().format('MM')
  120. const cDay=moment().format('dd')
  121. let temStartTime=ref([cYear,cMonth,cDay])
  122. let temEndTime=ref([cYear,cMonth,cDay])
  123. const latestDate = ref('')
  124. const earliestDate = ref('')
  125. let chartState=reactive({
  126. showTimePop:false,
  127. startTime:'',
  128. endTime:'',
  129. yearVal:'',
  130. calendarType:'公历',
  131. startYear:5
  132. })
  133. // 切换年份选项
  134. function handleYearChange(item){
  135. chartState.yearVal=item.value
  136. chartState.startTime=''
  137. chartState.endTime=''
  138. getChartDetail()
  139. }
  140. // 确定日期筛选
  141. function handleTimeChange(){
  142. chartState.startTime=temStartTime.value.join('-')
  143. chartState.endTime=temEndTime.value.join('-')
  144. chartState.yearVal=5
  145. getChartDetail()
  146. chartState.showTimePop=false
  147. }
  148. // 季节图公历\农历切换
  149. function handleSeasonTypeChange(type){
  150. chartState.calendarType=type
  151. getChartDetail()
  152. }
  153. // 上下限调整
  154. let showLimitPop=ref(false)
  155. let axisLimitDataTem=reactive({//左右轴极值
  156. min:'-99999999999999999',
  157. leftMin:0,
  158. leftMax:0,
  159. rightMin:0,
  160. rightMax:0,
  161. rightTwoMin:0,
  162. rightTwoMax:0,
  163. xMin:0,
  164. xMax:0,
  165. })
  166. function handleShowAxisLimitOpt(){
  167. axisLimitDataTem.leftMin=axisLimitState.leftMin
  168. axisLimitDataTem.leftMax=axisLimitState.leftMax
  169. axisLimitDataTem.rightMin=axisLimitState.rightMin
  170. axisLimitDataTem.rightMax=axisLimitState.rightMax
  171. axisLimitDataTem.rightTwoMin=axisLimitState.rightTwoMin
  172. axisLimitDataTem.rightTwoMax=axisLimitState.rightTwoMax
  173. axisLimitDataTem.xMin=axisLimitState.xMin
  174. axisLimitDataTem.xMax=axisLimitState.xMax
  175. showLimitPop.value=true
  176. }
  177. // 极限修改确定
  178. function handleConfirmLimitChange(){
  179. const data=_.cloneDeep(chartInfoData)
  180. // 修改左轴极限
  181. if(axisLimitState.hasLeftAxis){
  182. //基础图
  183. if(axisLimitState.leftIndex!==-1){
  184. axisLimitState.leftMin = axisLimitDataTem.leftMin
  185. axisLimitState.leftMax = axisLimitDataTem.leftMax
  186. }else{
  187. // 柱形图 取的ChartInfo中的极值
  188. if(data.ChartInfo.ChartType ===7){
  189. data.ChartInfo.LeftMin=axisLimitDataTem.leftMin
  190. data.ChartInfo.LeftMax=axisLimitDataTem.leftMax
  191. }
  192. // 商品价格曲线
  193. if(data.ChartInfo.ChartType ===8){
  194. data.ChartInfo.LeftMin=axisLimitDataTem.leftMin
  195. data.ChartInfo.LeftMax=axisLimitDataTem.leftMax
  196. }
  197. // 截面散点 取的DataResp
  198. if(data.ChartInfo.ChartType ===10){
  199. data.DataResp.YMinValue=axisLimitDataTem.leftMin
  200. data.DataResp.YMaxValue=axisLimitDataTem.leftMax
  201. }
  202. }
  203. }
  204. // 修改右轴极限
  205. if(axisLimitState.hasRightAxis){
  206. if(axisLimitState.rightIndex!==-1){
  207. axisLimitState.rightMin = axisLimitDataTem.rightMin
  208. axisLimitState.rightMax = axisLimitDataTem.rightMax
  209. }
  210. }
  211. //修改右2轴极限
  212. if(axisLimitState.hasRightTwoAxis){
  213. if(axisLimitState.rightTwoIndex!==-1){
  214. axisLimitState.rightMin = axisLimitDataTem.rightTwoMin
  215. axisLimitState.rightMax = axisLimitDataTem.rightTwoMax
  216. }
  217. }
  218. // 修改X轴极限
  219. if(axisLimitState.hasXAxis){
  220. // 截面散点 取的DataResp
  221. if(data.ChartInfo.ChartType ===10){
  222. data.DataResp.XMinValue=axisLimitDataTem.xMin
  223. data.DataResp.XMaxValue=axisLimitDataTem.xMax
  224. }
  225. }
  226. highChart.value = chartRender({
  227. data:data,
  228. renderId:'chart-box',
  229. lang:currentLang.value,
  230. changeLangIsCheck:false,
  231. showChartTitle:false,
  232. shouldUseSelfLimit:true,
  233. })
  234. showLimitPop.value=false
  235. }
  236. // 显示指标详情
  237. let showEDB=ref(false)
  238. let showEDBData=ref({})
  239. function handleShowEDBInfo(item){
  240. showEDBData.value=item
  241. showEDB.value=true
  242. }
  243. //显示数据来源详情
  244. let showSourceDetail = ref(false)
  245. function handleShowSourceDetail(){
  246. showSourceDetail.value = true
  247. }
  248. //显示更多操作栏
  249. let showMoreAction = ref(false)
  250. let chartActions = ref([])
  251. function getChartActions(chartInfo){
  252. //加上权限判断
  253. const actionsArr = [
  254. {
  255. type:'refresh',
  256. label:'刷新',
  257. show:true,
  258. btnCode:chartLibBtn.chartLib_refresh
  259. },
  260. {
  261. type:'share',
  262. label:'分享',
  263. show:!Boolean(chartInfo.Disabled),
  264. btnCode:chartLibBtn.chartLib_share
  265. },
  266. {
  267. type:'save',
  268. label:'保存',
  269. show:true,
  270. btnCode:chartLibBtn.chartLib_save
  271. },
  272. {
  273. type:'saveOther',
  274. label:'另存为',
  275. show:true,
  276. btnCode:chartLibBtn.chartLib_otherSave
  277. },
  278. {
  279. type:'savePic',
  280. label:'保存至相册',
  281. show:true,
  282. },
  283. {
  284. type:'saveToMaterial',
  285. label:'保存为素材',
  286. show:true,
  287. btnCode:chartLibBtn.chartLib_saveToMaterial
  288. },
  289. {
  290. type:'setEnName',
  291. label:'设置英文名称',
  292. show:true,
  293. btnCode:chartLibBtn.chartLib_enNameSetting
  294. },
  295. {
  296. type:'addToMyETA',
  297. label:'加入我的图库',
  298. show:true,
  299. btnCode:chartLibBtn.chartLib_addMy
  300. },
  301. {
  302. type:'delete',
  303. label:'删除',
  304. show:chartInfo.IsEdit,
  305. btnCode:chartLibBtn.chartLib_del
  306. }
  307. ]
  308. let currentArr=[]
  309. actionsArr.forEach(item=>{
  310. if(item.btnCode&&checkAuthBtn(item.btnCode)){
  311. currentArr.push(item)
  312. }
  313. if(item.type==='savePic'){
  314. if(checkAuthBtn(chartLibBtn.chartLib_copyWechat)&&checkAuthBtn(chartLibBtn.chartLib_copyOffice)){
  315. currentArr.push(item)
  316. }
  317. }
  318. })
  319. return currentArr
  320. }
  321. function handleActionClick(action){
  322. const eventMap = {
  323. 'refresh':refreshChart,
  324. 'share':getShareLink,
  325. 'saveOther':openSaveChartOtherDialog,
  326. 'savePic':saveChartPic,
  327. 'setEnName':openSetChartEnNameDialog,
  328. 'addToMyETA':openAddToMyETADialog,
  329. 'delete':deleteChart,
  330. 'save':saveChart,
  331. 'saveToMaterial':handleShowSaveToMaterial
  332. }
  333. eventMap[action.type]()
  334. //showMoreAction.value = false
  335. }
  336. //刷新图表
  337. function refreshChart(){
  338. apiChart.chartRefresh({
  339. ChartInfoId:chartInfo.value.ChartInfoId
  340. }).then(res=>{
  341. if(res.Ret!==200) return
  342. getChartDetail()
  343. showToast({message:'刷新成功',type:'success'})
  344. })
  345. }
  346. let confirmFlag = ref(true)
  347. //获取分享链接
  348. async function getShareLink(){
  349. const currentLang = localStorage.getItem('chartETALange')==='EN'?'en':'ch'
  350. //若当前语言设置为英文,则检测图表
  351. if(currentLang==='en') {
  352. !checkChartEnOption()&&(
  353. await showDialog({
  354. title: '提示',
  355. message: '英文名称未输入完整,分享图表上可能出现空名称的情况,确定继续分享吗?',
  356. showCancelButton:true
  357. }).then(() => {
  358. confirmFlag.value = true
  359. }).catch(()=>{
  360. confirmFlag.value = false
  361. })
  362. )
  363. }
  364. if(!confirmFlag.value) return
  365. // const linkUrl = `${import.meta.env.VITE_CHART_LINK}?code=${chartInfo.value.UniqueCode}&fromType=share&lang=${currentLang}`
  366. //临时权限token
  367. const res = await getChartShareExpireToken(chartInfo.value.UniqueCode);
  368. if(res.Ret !== 200) return
  369. const linkUrl = `${publicSettingStore.publicSetting.ChartViewUrl}/chartshow?code=${chartInfo.value.UniqueCode}&fromType=share&lang=${currentLang}&authToken=${res.Data}`
  370. //console.log('url',linkUrl)
  371. if(navigator.clipboard&&window.isSecureContext){
  372. try{
  373. await navigator.clipboard.writeText(linkUrl)
  374. showToast({message:'复制链接成功',type:'success'})
  375. }catch(err){
  376. console.log(err);
  377. showToast({message:'复制链接失败',type:'fail'})
  378. }
  379. }else{
  380. const input = document.createElement('input')
  381. input.setAttribute('readonly','readonly')
  382. input.value = linkUrl
  383. document.body.appendChild(input)
  384. input.select();
  385. document.execCommand('copy');
  386. document.body.removeChild(input);
  387. showToast({message:'复制链接成功',type:'success'})
  388. }
  389. }
  390. function checkChartEnOption(){
  391. if(!chartInfo.value.ChartNameEn) return false
  392. for(const data of chartInfoData.EdbInfoList){
  393. if(data.EdbNameEn==""||(data.UnitEn==""&&data.Unit!="")){
  394. return false
  395. }
  396. }
  397. return true
  398. }
  399. //保存图表
  400. function saveChart(){
  401. //获取每条线的指标配置
  402. let arr = edbList.value.map((item)=>{
  403. return {
  404. ChartColor: item.ChartColor,
  405. PredictChartColor: item.PredictChartColor,
  406. ChartStyle: item.ChartStyle,
  407. ChartWidth: Number(item.ChartWidth),
  408. EdbInfoId: item.EdbInfoId,
  409. EdbInfoType: item.EdbInfoType,
  410. IsAxis: item.IsAxis,
  411. IsOrder: item.IsOrder,
  412. LeadUnit: item.EdbInfoType ? '' : item.LeadUnit,
  413. LeadValue: item.EdbInfoType ? 0 : Number(item.LeadValue),
  414. MaxData: Number(item.MaxData),
  415. MinData: Number(item.MinData),
  416. }
  417. })
  418. //所有图表的公共参数
  419. let public_param = {
  420. ChartClassifyId: chartInfo.value.ChartClassifyId,
  421. ChartInfoId: chartInfo.value.ChartInfoId,
  422. ChartEdbInfoList: arr,
  423. }
  424. //根据ChartType决定剩余参数
  425. let type_param = {}
  426. switch(chartInfo.value.ChartType){
  427. case 2:
  428. type_param = {
  429. DateType: chartState.yearVal,
  430. StartYear:chartState.startYear || 0,
  431. Calendar: chartState.calendarType,
  432. StartDate: chartState.startTime||'',
  433. EndDate: chartState.endTime||'',
  434. }
  435. break
  436. case 7:
  437. case 11:
  438. type_param = {
  439. DateType: 6,
  440. LeftMin: String(axisLimitState.leftMin),
  441. LeftMax: String(axisLimitState.leftMax),
  442. }
  443. break
  444. case 10:
  445. type_param = {
  446. DateType: 6,
  447. Calendar: "公历",
  448. ExtraConfig: JSON.stringify({
  449. ...JSON.parse(chartInfo.value.ExtraConfig),
  450. XMinValue: String(axisLimitState.xMin),
  451. XMaxValue: String(axisLimitState.xMax),
  452. YMinValue: String(axisLimitState.leftMin),
  453. YMaxValue: String(axisLimitState.leftMax),
  454. })
  455. }
  456. break
  457. }
  458. if(sameOptionType.includes(chartInfo.value.ChartType)){
  459. type_param = {
  460. DateType: chartState.yearVal,
  461. StartYear:chartState.startYear || 0,
  462. StartDate:chartState.yearVal === 5 || chartState.yearVal === 6
  463. ? chartState.startTime
  464. : '',
  465. EndDate: chartState.yearVal === 5 ? chartState.endTime : '',
  466. }
  467. }
  468. let params = {...public_param,...type_param}
  469. if(![7,10,11].includes(chartInfo.value.ChartType)){
  470. params = {
  471. ...params,
  472. LeftMin:axisLimitState.leftMin+'',
  473. LeftMax:axisLimitState.leftMax+'',
  474. RightMin:axisLimitState.rightMin+'',
  475. RightMax:axisLimitState.rightMax+'',
  476. Right2Min:axisLimitState.rightTwoMin+'',
  477. Right2Max:axisLimitState.rightTwoMax+'',
  478. //手动保存视为更改过上下限
  479. MinMaxSave:1
  480. }
  481. }
  482. //保存
  483. apiChart.chartSave(params).then(async res=>{
  484. if(res.Ret!==200) return
  485. showToast("保存成功")
  486. //更新缩略图
  487. setChartImage()
  488. //保存成功后修改route.query防止刷新后请求旧参数
  489. router.replace({
  490. path:'/chartETA/chartdetail',
  491. query:{
  492. id:route.query.id,
  493. chartType:route.query.chartType,
  494. chartClassifyId:route.query.chartClassifyId,
  495. DateType:params.DateType,
  496. StartDate:chartState.startTime,
  497. EndDate:chartState.endTime,
  498. Calendar:chartState.calendarType,
  499. SeasonStartDate:chartState.startTime,
  500. SeasonEndDate:chartState.endTime,
  501. StartYear:chartState.startYear
  502. }
  503. })
  504. })
  505. }
  506. async function setChartImage(){
  507. const svgData = highChart.value.getSVG({
  508. chart: {
  509. width: 340,
  510. height: 230,
  511. }
  512. })
  513. let form = new FormData();
  514. form.append('Img', svgData);
  515. let {Data,Ret} = await apiChart.uploadChartImg(form)
  516. if(Ret!==200||!Data) return
  517. await apiChart.setChartImg({
  518. ChartInfoId:Number(route.query.id),
  519. ImageUrl:Data.ResourceUrl
  520. })
  521. }
  522. let isShowSaveOtherDialog = ref(false)
  523. let catalogNodes = ref([])
  524. //另存为
  525. async function openSaveChartOtherDialog(){
  526. const res = await apiChart.ETAChartClassifyList()
  527. if(res.Ret!==200) return
  528. catalogNodes.value = res.Data?res.Data.AllNodes:[]||[]
  529. isShowSaveOtherDialog.value = true
  530. }
  531. function saveOther(ClassifyId){
  532. apiChart.ETAChartSaveOther({
  533. ChartInfoId:chartInfo.value.ChartInfoId,
  534. ChartName:chartInfo.value.ChartName+'(1)',
  535. ChartClassifyId:ClassifyId
  536. }).then(res=>{
  537. if(res.Ret!==200) return
  538. showToast({message:'另存为成功',type:'success'})
  539. isShowSaveOtherDialog.value = false
  540. })
  541. }
  542. let savePicDialogShow = ref(false)
  543. let savePicSrc = ref('')
  544. //保存图片
  545. function saveChartPic(){
  546. const {chartWidth,chartHeight} = highChart.value
  547. //打开保存图片弹窗
  548. const svgData = highChart.value.getSVG({
  549. chart: {
  550. width: chartWidth,
  551. height: chartHeight,
  552. }
  553. })
  554. const canvas = document.createElement('canvas')
  555. const ctx = canvas.getContext('2d')
  556. canvas.width = chartWidth*2
  557. canvas.height = chartHeight*2
  558. const image = new Image()
  559. image.src = 'data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgData)
  560. image.onload = ()=>{
  561. ctx.drawImage(image, 0, 0,chartWidth*2,chartHeight*2);
  562. savePicSrc.value = canvas.toDataURL('image/png');
  563. savePicDialogShow.value = true
  564. }
  565. }
  566. let setChartEnDialogShow = ref(false)
  567. //设置英文名称
  568. function openSetChartEnNameDialog(){
  569. setChartEnDialogShow.value = true
  570. }
  571. function closeSetNameDialog(type){
  572. if(type==='save'){
  573. getChartDetail()
  574. }
  575. setChartEnDialogShow.value = false
  576. }
  577. let isShowAddToMyETADialog = ref(false)
  578. //加入我的图库
  579. function openAddToMyETADialog(){
  580. isShowAddToMyETADialog.value = true
  581. }
  582. //删除图表
  583. function deleteChart(){
  584. showDialog({
  585. title: '提示',
  586. message: '删除后该图表将不能再引用,确认删除吗?',
  587. showCancelButton:true
  588. }).then(() => {
  589. apiChart.deleteClassify({
  590. ChartClassifyId:Number(routeQueryData.chartClassifyId),
  591. ChartInfoId:Number(routeQueryData.id),
  592. }).then(res=>{
  593. if(res.Ret===200){
  594. cachedViewsStore.removeCaches('ChartETAList')
  595. cachedViewsStore.removeCaches('ChartETASearch')
  596. showToast('删除成功')
  597. setTimeout(() => {
  598. router.back()
  599. }, 1000);
  600. }
  601. })
  602. }).catch(()=>{
  603. })
  604. }
  605. // 保存至素材库
  606. const showSaveToMaterial=ref(false)
  607. function handleShowSaveToMaterial(){
  608. showSaveToMaterial.value=true
  609. }
  610. //获取图排序列表数据
  611. const chartSortListData=ref([])
  612. async function getChartSortList(){
  613. const res=await apiChart.chartLocate({
  614. KeyWord:route.query.keyword||'',
  615. ChartClassifyId:Number(route.query.chartClassifyId),
  616. IsShowMe:route.query.IsShowMe=='true'?true:false
  617. })
  618. if(res.Ret===200){
  619. chartSortListData.value=res.Data||[]
  620. }
  621. }
  622. getChartSortList()
  623. // 切换图
  624. async function handleSwitchChart(type){
  625. const index=chartSortListData.value.findIndex((item)=>item.ChartInfoId==routeQueryData.id)
  626. let item=null
  627. if(type==='prev'){
  628. item=index===0?chartSortListData.value[chartSortListData.value.length-1]:chartSortListData.value[index-1]
  629. }else{
  630. item=index===chartSortListData.value.length-1?chartSortListData.value[0]:chartSortListData.value[index+1]
  631. }
  632. //切换前重置chartState
  633. routeQueryData.id=item.ChartInfoId
  634. routeQueryData.chartType=item.ChartType
  635. routeQueryData.chartClassifyId=item.ChartClassifyId
  636. initChartState({...item,...routeQueryData})
  637. isUseSelfLimit.value = false
  638. getChartDetail('init')
  639. }
  640. function initChartState(data){
  641. chartState.showTimePop=false
  642. chartState.startTime=sameOptionType.includes(Number(data.chartType))?data.StartDate:data.SeasonStartDate
  643. chartState.endTime=sameOptionType.includes(Number(data.chartType))?data.EndDate:data.SeasonEndDate
  644. chartState.yearVal=data.DateType
  645. chartState.calendarType=data.Calendar
  646. chartState.startYear=Number(data.StartYear)
  647. }
  648. function openDateSelect(){
  649. // 回显
  650. switch (chartState.yearVal) {
  651. case 3:
  652. temStartTime.value = [2015,1,1]
  653. temEndTime.value = latestDate.value.split('-')
  654. break;
  655. case 9:
  656. temStartTime.value = [2020,1,1]
  657. temEndTime.value = latestDate.value.split('-')
  658. break;
  659. case 4:
  660. temStartTime.value = [2021,1,1]
  661. temEndTime.value = latestDate.value.split('-')
  662. break;
  663. case 11:
  664. temStartTime.value = [2022,1,1]
  665. temEndTime.value = latestDate.value.split('-')
  666. break;
  667. case '':
  668. temStartTime.value = earliestDate.value.split('-')
  669. temEndTime.value = latestDate.value.split('-')
  670. break;
  671. default:
  672. temStartTime.value = chartState.startTime.split('-')
  673. temEndTime.value = chartState.endTime.split('-')
  674. break;
  675. }
  676. chartState.showTimePop=true
  677. }
  678. </script>
  679. <template>
  680. <div class="chart-detail-page" v-if="chartInfo">
  681. <div
  682. class="chart-title"
  683. :style="chartInfo.ChartThemeStyle?`
  684. text-align:${JSON.parse(chartInfo.ChartThemeStyle).titleOptions.align};
  685. font-size:${JSON.parse(chartInfo.ChartThemeStyle).titleOptions.style.fontSize}px;
  686. color:${JSON.parse(chartInfo.ChartThemeStyle).titleOptions.style.color}
  687. `:''"
  688. >{{currentLang==='en'?(chartInfo.ChartNameEn||chartInfo.ChartName):chartInfo.ChartName}}</div>
  689. <!-- 一般曲线图选择时间区间或者季节图选择日期 -->
  690. <div
  691. class="select-time-box"
  692. v-if="sameOptionType.includes(chartInfo.ChartType)||chartInfo.ChartType===2"
  693. @click="openDateSelect"
  694. >
  695. <img class="left-icon" src="@/assets/imgs/icon_calendar.png" alt="">
  696. <span :class="['val-box',!chartState.startTime?'val-box_grey':'']">{{chartState.startTime||'开始日期'}} ~ {{chartState.endTime||'结束日期'}}</span>
  697. <van-icon class="right-icon" name="arrow" />
  698. </div>
  699. <!-- pad端时间和操作按钮模块 -->
  700. <div class="pad-time-action-wrap">
  701. <div class="left-time-box">
  702. <template v-if="sameOptionType.includes(chartInfo.ChartType)">
  703. <span :class="['item',chartState.yearVal==''?'active':'']" @click="handleYearChange({value:''})">全部</span>
  704. <span
  705. :class="['item',chartState.yearVal==item.value?'active':'']"
  706. v-for="item in yearSelectOpt"
  707. :key="item.value"
  708. @click="handleYearChange(item)"
  709. >{{item.name}}</span>
  710. </template>
  711. <span
  712. class="time-box"
  713. v-if="sameOptionType.includes(chartInfo.ChartType)||chartInfo.ChartType===2"
  714. @click="openDateSelect"
  715. >
  716. {{chartState.startTime?`${chartState.startTime} ~ ${chartState.endTime||'至今'}`:'请选择时间段'}}
  717. </span>
  718. </div>
  719. <div class="right-action-box">
  720. <div class="item" @click="showMoreAction=true" v-if="chartActions.length">
  721. <img src="@/assets/imgs/chartETA/more-icon.png" alt="">
  722. <span>更多设置</span>
  723. </div>
  724. </div>
  725. </div>
  726. <!-- 图渲染区域 -->
  727. <div class="chart-render-wrap">
  728. <!-- pad 切换上一张\下一张 -->
  729. <img class="pad-change-chart-btn" src="@/assets/imgs/icon_arrow2.png" alt="" @click="handleSwitchChart('prev')" v-if="chartSortListData.length>0">
  730. <img class="pad-change-chart-btn pad-change-chart-next-btn" src="@/assets/imgs/icon_arrow2.png" alt="" @click="handleSwitchChart('next')" v-if="chartSortListData.length>0">
  731. <div class="chart-box" id="chart-box"></div>
  732. <!-- 底部来源,图表说明 -->
  733. <div class="chart-bottom-insruction-info"
  734. v-if="(chartInfo.SourcesFrom&&JSON.parse(chartInfo.SourcesFrom).isShow) || (chartInfo.Instructions&&JSON.parse(chartInfo.Instructions).isShow)">
  735. <div
  736. class="chart-source"
  737. v-if="chartInfo.SourcesFrom&&JSON.parse(chartInfo.SourcesFrom).isShow"
  738. :style="`
  739. color: ${ JSON.parse(chartInfo.SourcesFrom).color };
  740. font-size: ${ JSON.parse(chartInfo.SourcesFrom).fontSize }px;
  741. `"
  742. >
  743. 数据来源:{{JSON.parse(chartInfo.SourcesFrom).text}}
  744. </div>
  745. <!-- 图表说明 -->
  746. <div
  747. class="chart-instruction text_oneLine"
  748. v-if="chartInfo.Instructions&&JSON.parse(chartInfo.Instructions).isShow"
  749. v-text="JSON.parse(chartInfo.Instructions).text"
  750. :style="`
  751. color: ${JSON.parse(chartInfo.Instructions).color};
  752. font-size: ${ JSON.parse(chartInfo.Instructions).fontSize }px
  753. `"
  754. ></div>
  755. </div>
  756. <!-- 作者 -->
  757. <div class="author-box" style="text-align:right">作者:{{chartInfo.SysUserRealName}}</div>
  758. </div>
  759. <!-- 手机端选择时间区间模块 -->
  760. <div class="select-year-box" v-if="sameOptionType.includes(chartInfo.ChartType)">
  761. <span :class="['item',chartState.yearVal==''?'active':'']" @click="handleYearChange({value:''})">全部</span>
  762. <span
  763. :class="['item',chartState.yearVal==item.value?'active':'']"
  764. v-for="item in yearSelectOpt"
  765. :key="item.value"
  766. @click="handleYearChange(item)"
  767. >{{item.name}}</span>
  768. </div>
  769. <!-- 季节图切换公/农历 -->
  770. <div class="calendar-type-box" v-if="chartInfo.ChartType === 2">
  771. <span
  772. :class="chartState.calendarType=='公历'?'active':''"
  773. @click="handleSeasonTypeChange('公历')"
  774. >公历</span>
  775. <span
  776. :class="chartState.calendarType=='农历'?'active':''"
  777. @click="handleSeasonTypeChange('农历')"
  778. >农历</span>
  779. </div>
  780. <!-- 指标模块 -->
  781. <div class="edb-list-box">
  782. <!-- pad 设置上下限按钮 -->
  783. <div class="pad-limit-set-btn" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(chartLibBtn.chartLib_editLimit)&&isChartHeap(chartInfo)">设置上下限</div>
  784. <!-- <div class="list-lable">指标信息</div> -->
  785. <div class="list-box">
  786. <div class="list-item" v-for="item in edbList" :key="item.EdbInfoId" @click="handleShowEDBInfo(item)">
  787. <span class="date">{{item.LatestDate}}</span>
  788. <span class="edb-name van-ellipsis" :style="{color:item.ChartColor}">{{item.EdbName}}</span>
  789. <span class="value">{{item.LatestValue}}</span>
  790. </div>
  791. </div>
  792. </div>
  793. <!-- 底部悬浮操作模块 -->
  794. <div class="fix-bot-action-box">
  795. <div class="item" @click="handleSwitchChart('prev')" v-if="chartSortListData.length>0">
  796. <img class="icon" src="@/assets/imgs/icon_arrow.png" alt="">
  797. <div>上一张</div>
  798. </div>
  799. <div class="item" @click="handleSwitchChart('next')" v-if="chartSortListData.length>0">
  800. <img class="icon" style="transform: rotate(180deg);" src="@/assets/imgs/icon_arrow.png" alt="">
  801. <div>下一张</div>
  802. </div>
  803. <div class="item" @click="handleShowAxisLimitOpt" v-if="![3,4,6,7,8,9].includes(chartInfo.Source)&&checkAuthBtn(chartLibBtn.chartLib_editLimit)&&isChartHeap(chartInfo)">
  804. <img class="icon" src="@/assets/imgs/myETA/icon_limit.png" alt="">
  805. <div>上下限</div>
  806. </div>
  807. <div class="item" @click="showMoreAction=true" v-if="chartActions.length">
  808. <img class="icon" src="@/assets/imgs/myETA/icon_menu.png" alt="">
  809. <div>更多</div>
  810. </div>
  811. </div>
  812. <!-- 选择日期弹窗 -->
  813. <van-popup
  814. v-model:show="chartState.showTimePop"
  815. :position="width>650?'center':'bottom'"
  816. :style="width>650?{ width: '400px'}:''"
  817. round
  818. >
  819. <div class="time-picker-wrap">
  820. <van-picker-group
  821. title="选择起始时间"
  822. :tabs="['开始时间', '结束时间']"
  823. @cancel="chartState.showTimePop=false"
  824. @confirm="handleTimeChange"
  825. >
  826. <van-date-picker
  827. v-model="temStartTime"
  828. :min-date="minDate"
  829. :max-date="maxDate"
  830. :columns-type="['year','month','day']"
  831. />
  832. <van-date-picker
  833. v-model="temEndTime"
  834. :min-date="minDate"
  835. :max-date="maxDate"
  836. :columns-type="['year','month','day']"
  837. />
  838. </van-picker-group>
  839. </div>
  840. </van-popup>
  841. <!-- 指标详情弹窗 -->
  842. <van-popup
  843. v-model:show="showEDB"
  844. :position="width>650?'right':'bottom'"
  845. round
  846. closeable
  847. :style="width>650?{ width: '400px', height: '100%' }:''"
  848. >
  849. <EdbInfo
  850. :show="showEDB"
  851. :data="showEDBData"
  852. :tableData="edbList"
  853. @showSourceDetail="handleShowSourceDetail"
  854. />
  855. </van-popup>
  856. <!-- 数据来源弹窗-->
  857. <van-popup
  858. v-model:show="showSourceDetail"
  859. position="center"
  860. round
  861. closeable
  862. :style="{ width: '400px'}"
  863. >
  864. <SourceDetail
  865. :show="showSourceDetail"
  866. :EdbInfoId="showEDBData.EdbInfoId"
  867. />
  868. </van-popup>
  869. <!-- 上下限调整弹窗 -->
  870. <van-popup
  871. v-model:show="showLimitPop"
  872. :position="width>650?'center':'bottom'"
  873. round
  874. closeable
  875. :style="width>650?{ width: '400px'}:''"
  876. >
  877. <div class="global-pop-wrap_mobile chart-set-limit-wrap">
  878. <div class="head-box">
  879. <div class="title">上下限设置</div>
  880. </div>
  881. <div class="content">
  882. <!-- 左轴 -->
  883. <div class="item-box" v-if="axisLimitState.hasLeftAxis">
  884. <span class="lable-text">左轴</span>
  885. <div class="input-box">
  886. <div class="item">
  887. <div class="type-text">上限</div>
  888. <div class="step-box">
  889. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMax" />
  890. </div>
  891. </div>
  892. <div class="item">
  893. <div class="type-text">下限</div>
  894. <div class="step-box">
  895. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.leftMin" />
  896. </div>
  897. </div>
  898. </div>
  899. </div>
  900. <!-- 右轴 -->
  901. <div class="item-box" v-if="axisLimitState.hasRightAxis">
  902. <span class="lable-text">右轴</span>
  903. <div class="input-box">
  904. <div class="item">
  905. <div class="type-text">上限</div>
  906. <div class="step-box">
  907. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMax" />
  908. </div>
  909. </div>
  910. <div class="item">
  911. <div class="type-text">下限</div>
  912. <div class="step-box">
  913. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightMin" />
  914. </div>
  915. </div>
  916. </div>
  917. </div>
  918. <!-- 右二轴 -->
  919. <div class="item-box" v-if="axisLimitState.hasRightTwoAxis">
  920. <span class="lable-text">右2轴</span>
  921. <div class="input-box">
  922. <div class="item">
  923. <div class="type-text">上限</div>
  924. <div class="step-box">
  925. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMax" />
  926. </div>
  927. </div>
  928. <div class="item">
  929. <div class="type-text">下限</div>
  930. <div class="step-box">
  931. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.rightTwoMin" />
  932. </div>
  933. </div>
  934. </div>
  935. </div>
  936. <!-- x轴 -->
  937. <div class="item-box" v-if="axisLimitState.hasXAxis">
  938. <span class="lable-text">X轴</span>
  939. <div class="input-box">
  940. <div class="item">
  941. <div class="type-text">上限</div>
  942. <div class="step-box">
  943. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMax" />
  944. </div>
  945. </div>
  946. <div class="item">
  947. <div class="type-text">下限</div>
  948. <div class="step-box">
  949. <van-stepper input-width="60px" :min="axisLimitDataTem.min" v-model.number="axisLimitDataTem.xMin" />
  950. </div>
  951. </div>
  952. </div>
  953. </div>
  954. </div>
  955. <div class="bot-btn-box" @click="handleConfirmLimitChange">确定</div>
  956. </div>
  957. </van-popup>
  958. <!-- 更多设置弹窗 -->
  959. <van-popup
  960. v-model:show="showMoreAction"
  961. :position="width>650?'center':'bottom'"
  962. round
  963. closeable
  964. :style="width>650?{ width: '400px'}:''"
  965. >
  966. <div class="global-pop-wrap_mobile chart-more-action-wrap">
  967. <div class="head-box">
  968. <div class="title van-ellipsis">{{chartInfo.ChartName}}</div>
  969. </div>
  970. <div class="action-box">
  971. <template v-for="item in chartActions" :key="item.types">
  972. <div class="action-item" v-if="item.show" @click="handleActionClick(item)">
  973. {{item.label}}
  974. </div>
  975. </template>
  976. </div>
  977. </div>
  978. </van-popup>
  979. <!-- 另存为弹窗 -->
  980. <TreeSelectPop
  981. :isShowDialog="isShowSaveOtherDialog"
  982. :dialogPosition="width>650?'center':'bottom'"
  983. :catalogNodes="catalogNodes"
  984. :chartInfo="chartInfo"
  985. popTitle="另存为"
  986. @close="isShowSaveOtherDialog=false"
  987. @confirmMove="saveOther"
  988. />
  989. <!-- 加入我的图库弹窗 -->
  990. <AddChartToMyETA
  991. :isShowDialog="isShowAddToMyETADialog"
  992. :dialogPosition="width>650?'center':'bottom'"
  993. :chartInfo="chartInfo"
  994. @close="isShowAddToMyETADialog=false"
  995. />
  996. <!--保存图片弹窗 -->
  997. <van-popup
  998. v-model:show="savePicDialogShow"
  999. position="center"
  1000. round
  1001. closeable
  1002. :style="{width:'80%',padding:'30px'}"
  1003. >
  1004. <img :src="savePicSrc" alt="" style="width:100%;box-sizing: border-box;">
  1005. <p style="text-align: center;color:#999;margin-top: 10px;">长按保存图片</p>
  1006. </van-popup>
  1007. <!-- 设置英文名称弹窗 -->
  1008. <van-popup
  1009. v-model:show="setChartEnDialogShow"
  1010. position="bottom"
  1011. :style="{width:'100%',height:'100%'}"
  1012. >
  1013. <SetChartEnName
  1014. :isShow="setChartEnDialogShow"
  1015. :chartInfo="chartInfoData"
  1016. :chartType="Number(route.query.chartType)"
  1017. @close="closeSetNameDialog"
  1018. />
  1019. </van-popup>
  1020. <!-- 保存至素材库 -->
  1021. <SaveToMaterial
  1022. v-model:show="showSaveToMaterial"
  1023. source="chart"
  1024. :sourceId="chartInfo.ChartInfoId"
  1025. :defaultName="chartInfo.ChartName"
  1026. />
  1027. </div>
  1028. </template>
  1029. <style lang="scss">
  1030. .chart-detail-page{
  1031. .rename-wrap{
  1032. padding:48px;
  1033. input{
  1034. padding: 24px 32px;
  1035. border-radius: 12px;
  1036. background-color: #F6F6F6;
  1037. width: 100%;
  1038. }
  1039. .label{
  1040. color: #666666;
  1041. margin-bottom: 32px;
  1042. text-align: center;
  1043. }
  1044. }
  1045. @media screen and (min-width:$media-width){
  1046. .rename-wrap{
  1047. padding:24px;
  1048. input{
  1049. padding: 12px 16px;
  1050. border-radius: 6px;
  1051. background-color: #F6F6F6;
  1052. width: 100%;
  1053. }
  1054. .label{
  1055. margin-bottom: 16px;
  1056. }
  1057. }
  1058. }
  1059. }
  1060. </style>
  1061. <style scoped lang="scss">
  1062. .chart-detail-page{
  1063. padding: $page-padding;
  1064. padding-bottom: 120px;
  1065. .chart-title{
  1066. font-size: 36px;
  1067. margin-bottom: 56px;
  1068. }
  1069. .chart-render-wrap{
  1070. .pad-change-chart-btn{
  1071. display: none;
  1072. }
  1073. }
  1074. .chart-box{
  1075. width: 100%;
  1076. height: 700px;
  1077. }
  1078. .chart-bottom-insruction-info {
  1079. width: 100%;
  1080. margin: 0 auto;
  1081. }
  1082. .select-time-box{
  1083. display: flex;
  1084. align-items: center;
  1085. padding-bottom: 32px;
  1086. border-bottom: 1px solid $border-color;
  1087. .left-icon{
  1088. width: 48px;
  1089. height: 48px;
  1090. }
  1091. .right-icon{
  1092. margin-left: auto;
  1093. }
  1094. .val-box{
  1095. margin-left: 32px;
  1096. font-size: 32px;
  1097. &.val-box_grey{
  1098. color: $font-grey_999;
  1099. }
  1100. }
  1101. }
  1102. .select-year-box{
  1103. width: 100vw;
  1104. position: relative;
  1105. left: -$page-padding;
  1106. margin-top: 30px;
  1107. box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.08);
  1108. height: 88px;
  1109. display: flex;
  1110. align-items: center;
  1111. overflow-y: auto;
  1112. padding: 0 $page-padding;
  1113. &::-webkit-scrollbar{
  1114. height: 0;
  1115. }
  1116. .item{
  1117. line-height: 88px;
  1118. position: relative;
  1119. height: 100%;
  1120. flex-shrink: 0;
  1121. display: inline-block;
  1122. margin-right: 40px;
  1123. font-size: 32px;
  1124. color: $font-grey_999;
  1125. &.active{
  1126. color: #333;
  1127. &::after{
  1128. content: '';
  1129. display: block;
  1130. width: 50px;
  1131. height: 6px;
  1132. border-radius: 3px;
  1133. background-color: $theme-color;
  1134. position: absolute;
  1135. bottom: 0;
  1136. left: 50%;
  1137. transform: translateX(-50%);
  1138. }
  1139. }
  1140. }
  1141. }
  1142. .calendar-type-box{
  1143. width: 404px;
  1144. margin: 30px auto;
  1145. text-align: center;
  1146. border: 1px solid $theme-color;
  1147. border-radius: 12px;
  1148. overflow: hidden;
  1149. span{
  1150. display: inline-block;
  1151. width: 200px;
  1152. height: 80px;
  1153. line-height: 80px;
  1154. color: $theme-color;
  1155. font-weight: bold;
  1156. &.active{
  1157. background-color: $theme-color;
  1158. color: #fff;
  1159. }
  1160. }
  1161. }
  1162. .pad-time-action-wrap{
  1163. display: none;
  1164. }
  1165. .edb-list-box{
  1166. .pad-limit-set-btn{
  1167. display: none;
  1168. }
  1169. .list-lable{
  1170. font-size: 36px;
  1171. color: #000;
  1172. margin-bottom: 20px;
  1173. margin-top: 40px;
  1174. }
  1175. .list-item{
  1176. padding:18px;
  1177. display: flex;
  1178. gap:0 20px;
  1179. border-bottom: 1px solid #DCDFE6;
  1180. &:last-child{
  1181. border-bottom: none;
  1182. }
  1183. .edb-name{
  1184. flex: 1;
  1185. /* text-align: center; */
  1186. }
  1187. }
  1188. }
  1189. .fix-bot-action-box{
  1190. position: fixed;
  1191. left: 0;
  1192. bottom: 0;
  1193. right: 0;
  1194. z-index: 99;
  1195. background-color: #fff;
  1196. border-top: 1px solid $border-color;
  1197. height: 112px;
  1198. display: flex;
  1199. align-items: center;
  1200. .item{
  1201. height: 100%;
  1202. flex: 1;
  1203. display: flex;
  1204. flex-direction: column;
  1205. justify-content: center;
  1206. align-items: center;
  1207. font-size: 20px;
  1208. .icon{
  1209. width: 40px;
  1210. height: 40px;
  1211. margin-bottom: 5px;
  1212. }
  1213. }
  1214. }
  1215. .chart-set-limit-wrap{
  1216. .head-box{
  1217. .title{
  1218. padding: 0 $page-padding;
  1219. font-size: 36px;
  1220. font-weight: 600;
  1221. line-height: 120px;
  1222. }
  1223. }
  1224. .bot-btn-box{
  1225. line-height: 112px;
  1226. text-align: center;
  1227. color: $theme-color;
  1228. font-size: 32px;
  1229. }
  1230. .content{
  1231. padding: $page-padding;
  1232. .item-box{
  1233. display: flex;
  1234. align-items: flex-end;
  1235. margin-bottom: 30px;
  1236. .lable-text{
  1237. width: 100px;
  1238. }
  1239. .input-box{
  1240. flex: 1;
  1241. display: flex;
  1242. .item{
  1243. flex: 1;
  1244. text-align: center;
  1245. .type-text{
  1246. margin-bottom: 40px;
  1247. }
  1248. .step-box{
  1249. display: inline-block;
  1250. :deep(.van-stepper){
  1251. display: flex;
  1252. justify-content: center;
  1253. }
  1254. }
  1255. }
  1256. }
  1257. }
  1258. }
  1259. }
  1260. .chart-more-action-wrap{
  1261. .head-box{
  1262. .title{
  1263. width: 100%;
  1264. padding:34px 100px;
  1265. box-sizing: border-box;
  1266. font-size: 36px;
  1267. font-weight: 600;
  1268. text-align: center;
  1269. }
  1270. }
  1271. .action-box{
  1272. .action-item{
  1273. text-align: center;
  1274. padding:32px 84px;
  1275. border-bottom: 1px solid #DCDFE6;
  1276. &:last-child{
  1277. border-bottom: none;
  1278. }
  1279. }
  1280. }
  1281. }
  1282. @media screen and (min-width:$media-width){
  1283. padding:30px;
  1284. .chart-title{
  1285. font-size: 16px;
  1286. font-weight: bold;
  1287. margin-bottom: 30px;
  1288. }
  1289. .chart-render-wrap{
  1290. position: relative;
  1291. .pad-change-chart-btn{
  1292. display: block;
  1293. width: 48px;
  1294. height: 48px;
  1295. position: absolute;
  1296. top: 50%;
  1297. transform: translateY(-50%);
  1298. left: 0px;
  1299. &.pad-change-chart-next-btn{
  1300. right: 0;
  1301. left: auto;
  1302. transform: translateY(-50%) rotate(180deg);
  1303. }
  1304. }
  1305. }
  1306. .chart-box{
  1307. width: 85%;
  1308. height: 370px;
  1309. margin: 0 auto;
  1310. }
  1311. .chart-bottom-insruction-info {
  1312. width: 85%;
  1313. margin: 0 auto;
  1314. }
  1315. .select-time-box,.select-year-box,.fix-bot-action-box{
  1316. display: none;
  1317. }
  1318. .pad-time-action-wrap{
  1319. display: flex;
  1320. flex-wrap: wrap;
  1321. align-items: center;
  1322. justify-content: space-between;
  1323. .left-time-box{
  1324. flex-shrink: 0;
  1325. margin-bottom: 20px;
  1326. .item{
  1327. display: inline-block;
  1328. width: 80px;
  1329. height: 36px;
  1330. text-align: center;
  1331. line-height: 36px;
  1332. border: 1px solid $theme-color;
  1333. margin-right: 10px;
  1334. border-radius: 3px;
  1335. &.active{
  1336. color: #fff;
  1337. background-color: $theme-color;
  1338. }
  1339. }
  1340. .time-box{
  1341. display: inline-block;
  1342. padding: 0 15px;
  1343. height: 36px;
  1344. line-height: 36px;
  1345. border: 1px solid $theme-color;
  1346. border-radius: 3px;
  1347. background-color: #F2F3FF;
  1348. color: $theme-color;
  1349. }
  1350. }
  1351. .right-action-box{
  1352. display: flex;
  1353. margin-bottom: 20px;
  1354. .item{
  1355. display: flex;
  1356. color: $theme-color;
  1357. margin-left: 20px;
  1358. img{
  1359. width: 15px;
  1360. height: 15px;
  1361. margin-right: 4px;
  1362. }
  1363. }
  1364. }
  1365. }
  1366. .calendar-type-box{
  1367. width: 224px;
  1368. margin: 20px auto;
  1369. border-radius: 4px;
  1370. span{
  1371. width: 111px;
  1372. height: 38px;
  1373. line-height: 38px;
  1374. }
  1375. }
  1376. .edb-list-box{
  1377. position: relative;
  1378. left: -30px;
  1379. border-top: 1px solid $border-color;
  1380. width: 100vw;
  1381. padding: 0 30px;
  1382. margin-top: 20px;
  1383. .pad-limit-set-btn{
  1384. display: block;
  1385. text-align: right;
  1386. margin: 20px 0;
  1387. color: $theme-color;
  1388. }
  1389. .list-lable{
  1390. margin-top: 20px;
  1391. font-size: 16px;
  1392. margin-bottom: 14px;
  1393. }
  1394. .list-box{
  1395. //border: 1px solid $border-color;
  1396. .list-item{
  1397. padding: 18px;
  1398. }
  1399. }
  1400. }
  1401. .chart-set-limit-wrap{
  1402. .head-box{
  1403. .title{
  1404. font-size: 18px;
  1405. line-height: 50px;
  1406. padding-left: 16px;
  1407. }
  1408. }
  1409. .bot-btn-box{
  1410. font-size: 16px;
  1411. line-height: 56px;
  1412. border-top-width: 8px;
  1413. }
  1414. .content{
  1415. max-height: 500px;
  1416. padding: 30px;
  1417. .item-box{
  1418. margin-bottom: 15px;
  1419. .lable-text{
  1420. width: 50px;
  1421. }
  1422. .input-box{
  1423. .item{
  1424. .type-text{
  1425. margin-bottom: 20px;
  1426. }
  1427. }
  1428. }
  1429. }
  1430. }
  1431. }
  1432. .chart-more-action-wrap{
  1433. .head-box{
  1434. .title{
  1435. padding:17px 50px;
  1436. font-size: 18px;
  1437. }
  1438. }
  1439. .action-box{
  1440. .action-item{
  1441. padding:16px 42px;
  1442. }
  1443. }
  1444. }
  1445. }
  1446. }
  1447. </style>