index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. <template>
  2. <view class="content">
  3. <scrollView ref="scrollViewComponent"></scrollView>
  4. <view class="chart-con">
  5. <view class="cartsList-all">
  6. <view class="cartsList-name">
  7. 消耗数据趋势
  8. </view>
  9. <view class="select-button">
  10. <view :style="{
  11. border: flagE === index + 1 ? '1px solid #90ffe4' : '1px solid #808080',
  12. color: flagE === index + 1 ? '#90ffe4' : '#808080',
  13. height: '40rpx',
  14. width: '100rpx',
  15. display: 'inline-block',
  16. cursor: 'pointer',
  17. textAlign: 'center',
  18. fontSize: '24rpx',
  19. fontFamily: '微软雅黑',
  20. lineHeight: '40rpx',
  21. }" v-for="(item, index) in navList" :key="item.id" @click="handleClickBtnE(index)">
  22. {{ item.name }}
  23. </view>
  24. </view>
  25. <view class="cartsList-seleven">
  26. <uni-data-select v-model="valueList" :localdata="rangelineChart" @change="changelineChart"
  27. :clear="false"></uni-data-select>
  28. </view>
  29. </view>
  30. <view class="chart-wrap">
  31. <view class="line-chart-con">
  32. <Lechart class="line-chart" ref="lineChart"></Lechart>
  33. </view>
  34. </view>
  35. </view>
  36. <!-- 药耗服务费逐月趋势统计卡片和折线图 -->
  37. <view class="chart-con">
  38. <view class="cartsList-all">
  39. <view class="cartsList-name">
  40. 耗材服务费逐月趋势
  41. </view>
  42. <view class="cartsList-seleven">
  43. <uni-data-select v-model="fwfTrendType" :localdata="rangelineChart" @change="changeFwfTrendType" :clear="false"></uni-data-select>
  44. </view>
  45. </view>
  46. <view class="trend-summary-wrap">
  47. <view class="trend-summary-item">
  48. <view class="trend-summary-title">耗材总服务费</view>
  49. <view class="trend-summary-value">¥{{ supplierSummary.totalFwf }}</view>
  50. </view>
  51. </view>
  52. <view class="chart-wrap">
  53. <view class="line-chart-con">
  54. <Lechart class="line-chart" ref="fwfTrendChart"></Lechart>
  55. </view>
  56. </view>
  57. </view>
  58. <view class="chart-con">
  59. <view class="cartsList-all">
  60. <view class="cartsList-name">
  61. 各供应商贡献度
  62. </view>
  63. </view>
  64. <view class="supplier-summary-wrap">
  65. <view class="supplier-summary-item">
  66. <view style="color:#008080; font-size:22rpx;">总服务费</view>
  67. <view style="font-size:32rpx; font-weight:bold; color:#333; margin-top:8rpx;">¥{{ supplierSummary.totalFwf }}</view>
  68. </view>
  69. <view class="supplier-summary-item">
  70. <view style="color:#008080; font-size:22rpx;">合作供应商</view>
  71. <view style="font-size:32rpx; font-weight:bold; color:#333; margin-top:8rpx;">{{ supplierSummary.supplierCount }}家</view>
  72. </view>
  73. </view>
  74. <view class="supplier-list-scroll supplier-list-border">
  75. <view
  76. v-for="(item, idx) in supplierList"
  77. :key="item.id"
  78. class="supplier-list-item"
  79. >
  80. <view
  81. :style="{
  82. width: '40rpx',
  83. textAlign: 'center',
  84. fontSize: '28rpx',
  85. fontWeight: 'bold',
  86. color:
  87. idx === 0
  88. ? '#ff4d4f'
  89. : idx === 1
  90. ? '#faad14'
  91. : idx === 2
  92. ? '#36cfc9'
  93. : '#008080'
  94. }"
  95. >
  96. {{ idx + 1 }}
  97. </view>
  98. <view style="flex:1; margin-left:16rpx;">
  99. <view style="font-size:26rpx; color:#333; font-weight:bold;">{{ item.name }}</view>
  100. <view style="display:flex; gap:24rpx; margin-top:6rpx;">
  101. <view style="color:#008080; font-size:20rpx;">贡献度 {{ item.rate }}</view>
  102. <view style="color:#333; font-size:20rpx;">服务费 ¥{{ item.fwf }}</view>
  103. </view>
  104. </view>
  105. </view>
  106. <view v-if="supplierList.length > 8" style="text-align:center; color:#999; font-size:20rpx; margin:18rpx 0;">上拉加载更多</view>
  107. </view>
  108. </view>
  109. <PieCharts ref="PieChartsComponent"></PieCharts>
  110. <view class="chart-con">
  111. <view class="cartsList-all">
  112. <view class="cartsList-name">
  113. 分类消耗占比
  114. </view>
  115. <view class="cartsList-seleven">
  116. <uni-data-select v-model="valueTimeType" :localdata="rangeringChart" @change="changeringChart"
  117. :clear="false"></uni-data-select>
  118. </view>
  119. </view>
  120. <view class=".chart-wrap-bing">
  121. <view class="ring-chart">
  122. <Lechart ref="ringChart"></Lechart>
  123. </view>
  124. </view>
  125. </view>
  126. <tiewk ref="tiewkComponent"></tiewk>
  127. <enterprise ref="enterpriseComponent"></enterprise>
  128. </view>
  129. </template>
  130. <script>
  131. import * as echarts from '@/subpkg/uni_modules/lime-echart/static/echarts.min.js';
  132. import scrollView from './scrollView/scrollView.vue';
  133. import PieCharts from './PieCharts/PieCharts.vue';
  134. import enterprise from './enterprise/enterprise.vue';
  135. import tiewk from './tiewk/tiewk.vue';
  136. import Lechart from '@/subpkg/uni_modules/lime-echart/components/l-echart/l-echart.vue';
  137. import {
  138. mapState
  139. } from 'vuex';
  140. export default {
  141. components: {
  142. scrollView,
  143. PieCharts,
  144. tiewk,
  145. enterprise,
  146. Lechart
  147. },
  148. data() {
  149. return {
  150. navList: [
  151. // {
  152. // name: "按科室"
  153. // },
  154. {
  155. name: "按种类"
  156. }, {
  157. name: "集采"
  158. }
  159. ],
  160. statType: "mcsType",
  161. LineData: [], //折线图数据
  162. EllData: [], //总汇折线图
  163. AllData: [], //存放全部数据
  164. yearl: [], //切换年月的数组
  165. pieData: [], //饼图
  166. AdList: null, //main实例
  167. type: 1, //交易分析模块里的类型
  168. valueList: 'Y',
  169. valueTimeType: "Y",
  170. flagE: 1,
  171. rangelineChart: [{
  172. value: 'Y',
  173. text: "年"
  174. },
  175. {
  176. value: 'M',
  177. text: "月"
  178. },
  179. ],
  180. rangeringChart: [{
  181. value: 'Y',
  182. text: "年",
  183. }, {
  184. value: 'M',
  185. text: "月",
  186. }, {
  187. value: 'W',
  188. text: "周",
  189. }, {
  190. value: 'D',
  191. text: "日",
  192. }],
  193. fwfTrendType: 'Y', // 药耗服务费趋势时间类型
  194. fwfTrendData: [], // 药耗服务费折线图数据
  195. fwfTrendYearl: [], // x轴数据
  196. supplierSummary: {
  197. totalFwf: 0,
  198. supplierCount: 0
  199. },
  200. supplierList: []
  201. }
  202. },
  203. computed: {
  204. ...mapState(['instData'])
  205. },
  206. created() {
  207. this.listData();
  208. this.Listson();
  209. this.loadSupplierSummary();
  210. this.loadSupplierList();
  211. },
  212. mounted() {
  213. console.log('页面加载了没有');
  214. //加载饼环数据
  215. this.loadRingData();
  216. //加载折线图数据
  217. this.loadLineData();
  218. this.loadFwfTrendData();
  219. },
  220. methods: {
  221. onPullDownRefresh() {
  222. this.listData();
  223. this.Listson();
  224. this.$refs.enterpriseComponent.getData();
  225. this.$refs.tiewkComponent.listData();
  226. this.$refs.scrollViewComponent.listData();
  227. this.$refs.PieChartsComponent.listData();
  228. setTimeout(function() {
  229. uni.stopPullDownRefresh(); //停止下拉刷新动画
  230. }, 1000);
  231. },
  232. Listson() {
  233. this.$http('homePage.amtCosm', {
  234. timeType: this.valueTimeType
  235. }, '加载中').then((res) => {
  236. this.pieData = res.data;
  237. this.pieData = res.data.map((item) => {
  238. return {
  239. value: item.mcsAmt,
  240. name: item.mcsType,
  241. };
  242. });
  243. // 获取饼图的图例数据
  244. this.pieName = res.data.map((item) => item.mcsType);
  245. this.loadRingData();
  246. });
  247. },
  248. listData() {
  249. this.AllData = [];
  250. // 获取每个月的天数;
  251. const getDaysInMonth = (year, month) => {
  252. return new Date(year, month, 0).getDate();
  253. };
  254. this.$http('homePage.statCosm', {
  255. timeType: this.valueList,
  256. statType: this.statType
  257. }, '加载中').then((res) => {
  258. const year = new Date().getFullYear(); // 获取当前年份
  259. if (this.valueList === "M") {
  260. const daysInMonth = getDaysInMonth(year, new Date().getMonth() + 1); // 获取当前月份的天数
  261. this.yearl = Array.from({
  262. length: daysInMonth
  263. }, (_, i) => i + 1).map(
  264. (day) => `${day}`
  265. );
  266. } else {
  267. this.yearl = Array.from({
  268. length: 12
  269. }, (_, i) => i + 1).map(
  270. (month) => `${month}月`
  271. );
  272. }
  273. this.LineData = res.data.deptCosmList;
  274. this.EllData = res.data.totalCosm;
  275. const ellSeries = {
  276. name: "全部",
  277. data: this.EllData,
  278. smooth: true,
  279. type: "line",
  280. };
  281. this.AllData.push(ellSeries);
  282. const lineSeries = this.LineData.map((item) => ({
  283. name: item.type,
  284. data: item.cnt,
  285. smooth: true,
  286. type: "line",
  287. }));
  288. this.AllData = this.AllData.concat(lineSeries);
  289. this.loadLineData();
  290. })
  291. },
  292. changelineChart(e) {
  293. this.valueList = e
  294. this.updateListData();
  295. },
  296. // 消耗数据统计
  297. handleClickBtnE(index) {
  298. this.flagE = index + 1;
  299. if (index === 0) {
  300. // this.handleQuery("dept");
  301. // this.updateListData();
  302. this.handleQuery("mcsType");
  303. this.updateListData();
  304. } else if (index === 1) {
  305. this.handleQuery("isFas");
  306. this.updateListData();
  307. } else if (index === 2) {
  308. }
  309. },
  310. handleQuery(param) {
  311. this.statType = param;
  312. },
  313. updateListData() {
  314. this.listData({
  315. mcsType: this.valueList,
  316. timeType: this.value
  317. });
  318. },
  319. changeringChart(e) {
  320. this.valueTimeType = e
  321. this.Listson({
  322. timeType: this.valueTimeType
  323. })
  324. },
  325. loadRingData() {
  326. //这里请求服务器得到数据
  327. let data = this.pieData
  328. //这里option配置参考文档:https://echarts.apache.org/zh/option.html
  329. this.$refs.ringChart.init(echarts, chart => {
  330. chart.setOption({
  331. legend: {
  332. data: this.pieData.map((item) => item.name),
  333. left: "3%",
  334. top: "30%",
  335. orient: "vertical",
  336. },
  337. tooltip: {
  338. trigger: "item",
  339. position: ['30%', '30%'],
  340. axisPointer: {
  341. type: "shadow",
  342. },
  343. backgroundColor: "#fff", // 悬浮框背景色
  344. // borderColor: "#000", // 悬浮框边框颜色
  345. borderWidth: 1, // 悬浮框边框宽度
  346. textStyle: {
  347. // 悬浮框文字样式
  348. color: "#000",
  349. fontSize: '10rpx',
  350. },
  351. formatter: "{b} : {c}万元: {d}%", //鼠标移入提示框显示内容
  352. },
  353. series: [{
  354. type: 'pie',
  355. // selectedMode: 'single',
  356. // selectedOffset: 0,
  357. // hoverAnimation: false,
  358. radius: [40, 65],
  359. left: 'center',
  360. width: '98%',
  361. //隐藏默认白边
  362. itemStyle: {
  363. borderColor: '#fff',
  364. borderWidth: 0
  365. },
  366. //格式化label显示
  367. label: {
  368. alignTo: 'edge',
  369. show: true,
  370. formatter: "{b} : {c}万元: {d}%",
  371. minMargin: 5,
  372. edgeDistance: 20,
  373. lineHeight: 24,
  374. rich: {
  375. time: {
  376. fontSize: 10,
  377. color: '#999'
  378. }
  379. }
  380. },
  381. //指向label的线设置
  382. labelLine: {
  383. length: 15,
  384. length2: 0,
  385. maxSurfaceAngle: 80
  386. },
  387. //布局样式
  388. labelLayout: function(params) {
  389. const isLeft = params.labelRect.x < chart.getWidth() / 2;
  390. const points = params.labelLinePoints;
  391. points[2][0] = isLeft ?
  392. params.labelRect.x :
  393. params.labelRect.x + params.labelRect.width;
  394. return {
  395. labelLinePoints: points
  396. };
  397. },
  398. //数据
  399. data: this.pieData
  400. }]
  401. });
  402. //默认突出高亮显示,可以放开下面注释
  403. // chart.dispatchAction({
  404. // type: 'highlight',
  405. // seriesIndex: 0,
  406. // dataIndex: 0
  407. // });
  408. //监听图标项点击事件
  409. chart.on("click", function(e) {
  410. for (var i = 0; i < data.length; i++) {
  411. if (i != e.dataIndex) {
  412. chart.dispatchAction({
  413. type: 'downplay', //取消高亮显示;
  414. seriesIndex: 0,
  415. dataIndex: i
  416. });
  417. } else {
  418. chart.dispatchAction({
  419. type: 'highlight', //突出高亮显示;
  420. seriesIndex: 0,
  421. dataIndex: i
  422. });
  423. }
  424. }
  425. });
  426. });
  427. },
  428. //加载折线图数据
  429. loadLineData() {
  430. let chartColors = [
  431. '#FF6B6B', // 红
  432. '#4ECDC4', // 青绿
  433. '#FFD93B', // 黄
  434. '#1A535C', // 深青
  435. '#FF8C42', // 橙
  436. '#6A4C93', // 紫
  437. '#00B8A9', // 蓝绿
  438. '#F6416C', // 粉
  439. '#43DDE6', // 浅蓝
  440. '#3D5A80', // 蓝
  441. '#EE6C4D', // 橙红
  442. '#FFB400', // 金黄
  443. '#8D8741', // 棕
  444. ];
  445. let option = {
  446. legend: {
  447. data: this.AllData.map((item) => item.name),
  448. },
  449. dataZoom: [{
  450. bottom: 10,
  451. height: 20,
  452. type: 'inside',
  453. show: true,
  454. xAxisIndex: [0],
  455. start: this.valueList === "M" ? 10 : 120,
  456. end: this.valueList === "M" ? 35 : 350
  457. }],
  458. xAxis: {
  459. type: 'category',
  460. axisLabel: { color: '#a7a7a7' },
  461. axisLine: { lineStyle: { color: '#f1f1f1' } },
  462. axisTick: { show: false },
  463. data: this.yearl,
  464. },
  465. grid: { top: 40, bottom: 30 },
  466. yAxis: {
  467. type: 'value',
  468. axisLabel: { color: '#a7a7a7' },
  469. splitLine: { show: true, lineStyle: { type: 'dashed' } }
  470. },
  471. tooltip: {
  472. trigger: 'axis',
  473. triggerOn: 'click',
  474. formatter: '{b}: \n {a0}: {c0} \n {a1}: {c1} \n {a2}: {c2} \n {a3}: {c3}'
  475. },
  476. color: chartColors,
  477. series: this.AllData
  478. };
  479. this.$refs.lineChart.init(echarts, chart => {
  480. chart.setOption(option);
  481. });
  482. },
  483. changeFwfTrendType(e) {
  484. this.fwfTrendType = e;
  485. this.loadFwfTrendData();
  486. },
  487. loadFwfTrendData() {
  488. // 获取每个月的天数
  489. const getDaysInMonth = (year, month) => {
  490. return new Date(year, month, 0).getDate();
  491. };
  492. this.$http('homePage.statFwfCosm', {
  493. timeType: this.fwfTrendType
  494. }, '加载中').then((res) => {
  495. const year = new Date().getFullYear();
  496. if (this.fwfTrendType === "M") {
  497. const daysInMonth = getDaysInMonth(year, new Date().getMonth() + 1);
  498. this.fwfTrendYearl = Array.from({ length: daysInMonth }, (_, i) => i + 1).map(day => `${day}`);
  499. } else {
  500. this.fwfTrendYearl = Array.from({ length: 12 }, (_, i) => i + 1).map(month => `${month}月`);
  501. }
  502. this.fwfTrendData = [{
  503. name: "服务费",
  504. data: res.data.fwfAmt || [],
  505. smooth: true,
  506. type: "line",
  507. }];
  508. this.loadFwfTrendChart();
  509. });
  510. },
  511. loadFwfTrendChart() {
  512. let option = {
  513. legend: {
  514. data: this.fwfTrendData.map(item => item.name),
  515. },
  516. xAxis: {
  517. type: 'category',
  518. axisLabel: { color: '#a7a7a7' },
  519. axisLine: { lineStyle: { color: '#f1f1f1' } },
  520. axisTick: { show: false },
  521. data: this.fwfTrendYearl,
  522. },
  523. grid: { top: 40, bottom: 30 },
  524. yAxis: {
  525. type: 'value',
  526. axisLabel: { color: '#a7a7a7' },
  527. splitLine: { show: true, lineStyle: { type: 'dashed' } }
  528. },
  529. tooltip: {
  530. trigger: 'axis',
  531. triggerOn: 'click',
  532. formatter: '{b}: \n {a0}: {c0}'
  533. },
  534. color: ['#4e9d77'],
  535. series: this.fwfTrendData
  536. };
  537. this.$refs.fwfTrendChart.init(echarts, chart => {
  538. chart.setOption(option);
  539. });
  540. },
  541. loadSupplierSummary() {
  542. this.$http('homePage.mcsTotalFwf', {
  543. spdId: this.instData.spdId
  544. }, '加载中').then(res => {
  545. this.supplierSummary.totalFwf = res.data.totalFwf || 0;
  546. this.supplierSummary.supplierCount = res.data.splerSum || 0;
  547. });
  548. },
  549. // 各供应商贡献度列表
  550. loadSupplierList() {
  551. this.$http('homePage.mcsSplerFwfBl', {
  552. spdId: this.instData.spdId
  553. }, '加载中').then(res => {
  554. this.supplierList = (res.data || []).map(item => ({
  555. id: item.splerId,
  556. name: item.splerName,
  557. rate: item.gxd,
  558. fwf: item.splerAmt != null ? item.splerAmt : '--'
  559. }));
  560. });
  561. },
  562. }
  563. }
  564. </script>
  565. <style lang="scss" scoped>
  566. @import './h1z1.css';
  567. </style>