salesPanel.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <template>
  2. <div>
  3. <borderTemplate borderBox="width: 31.250vw;height: 35.417vw;" title="销售面板" detailTitle="查看详情" @dialog="$emit('dialog')" systemappid="277" push_path="/salesData">
  4. <template slot="content">
  5. <div class="justify-content">
  6. <div class="justify-content-left">
  7. <div class="box-border">
  8. <el-button v-if="typeSelect == '订单'" type="primary" class="btn-select" @click="typeChange('订单')">{{$t(`订单`)}}</el-button>
  9. <el-button type="text" v-else class="btn-unSelect" @click="typeChange('订单')">{{$t(`订单`)}}</el-button>
  10. </div>
  11. <div class="box-border">
  12. <el-button type="primary" v-if="typeSelect == '出货'" class="btn-select" @click="typeChange('出货')">{{$t(`出货`)}}</el-button>
  13. <el-button type="text" class="btn-unSelect" v-else @click="typeChange('出货')">{{$t(`出货`)}}</el-button>
  14. </div>
  15. <div class="box-border">
  16. <el-button type="primary" v-if="typeSelect == '开票'" class="btn-select" @click="typeChange('开票')">{{$t(`开票`)}}</el-button>
  17. <el-button type="text" class="btn-unSelect" v-else @click="typeChange('开票')">{{$t(`开票`)}}</el-button>
  18. </div>
  19. <div class="box-border">
  20. <el-button type="primary" v-if="typeSelect == '回款'" class="btn-select" @click="typeChange('回款')">{{$t(`回款`)}}</el-button>
  21. <el-button type="text" class="btn-unSelect" v-else @click="typeChange('回款')">{{$t(`回款`)}}</el-button>
  22. </div>
  23. </div>
  24. <div>
  25. <el-select v-model="param.content.dateType" class="inline-16" size="small" @change="dateTypeChange" :popper-append-to-body="false">
  26. <el-option :label="$t('去年')" value="去年"></el-option>
  27. <el-option :label="$t('本年')" value="本年"></el-option>
  28. <el-option :label="$t('本季')" value="本季"></el-option>
  29. <el-option :label="$t('本月')" value="本月"></el-option>
  30. <el-option :label="$t('上月')" value="上月"></el-option>
  31. </el-select>
  32. </div>
  33. </div>
  34. <div class="content-style-pie">
  35. <div style="width: 7.292vw;height: 7.292vw;margin: 0.781vw 0 0 1.042vw;">
  36. <el-progress
  37. color="#6395fa"
  38. type="circle"
  39. :percentage="percentage"
  40. :stroke-width="15"
  41. :width="progressWidth"
  42. :format="format"
  43. ></el-progress>
  44. </div>
  45. <div class="content-style-content">
  46. <div class="font1">
  47. {{$t(`实际金额(元)`)}}
  48. </div>
  49. <div>
  50. <span class="font2">
  51. <span v-if="list.amount > 10000">
  52. {{tool.formatAmount(tool.unitConversion(list.amount, 10000), 2)}}
  53. <span class="font3">{{$t(`万`)}}</span>
  54. </span>
  55. <span v-else>
  56. {{tool.formatAmount(tool.unitConversion(list.amount, 10000), 2)}}
  57. </span>
  58. </span>
  59. </div>
  60. <div>
  61. <span class="font4">{{$t(`年同比`)}}:</span>
  62. <span class="font5" style="margin-right: 0.417vw">{{ Math.round(list.tbxsje * 100 * 100) / 100 }}%</span>
  63. <img style="vertical-align: middle" v-if="list.tbxsje > 0" width="8" height="7" src="../../../assets/icons/up.png" alt="">
  64. <img style="vertical-align: middle" v-if="list.tbxsje < 0" width="8" height="7" src="../../../assets/icons/down.png" alt="">
  65. <span class="font4" style="margin-left:1.042vw ">{{$t(`年环比`)}}:</span>
  66. <span class="font5" style="margin-right: 0.417vw">{{ Math.round(list.hbxsje * 100 * 100) / 100 }}%</span>
  67. <img style="vertical-align: middle" v-if="list.hbxsje > 0" width="8" height="7" src="../../../assets/icons/up.png" alt="">
  68. <img style="vertical-align: middle" v-if="list.hbxsje < 0" width="8" height="7" src="../../../assets/icons/down.png" alt="">
  69. </div>
  70. <div class="font1" style="margin-top:1.042vw ">
  71. {{$t(`目标金额(元)`)}}
  72. </div>
  73. <div>
  74. <span class="font6">
  75. <span v-if="list.target_l > 10000">
  76. {{tool.formatAmount(tool.unitConversion(list.target_l, 10000), 2)}}
  77. <span class="font7">{{$t(`万`)}}</span>
  78. </span>
  79. <span v-else>
  80. {{tool.formatAmount(tool.unitConversion(list.target_l, 10000), 2)}}
  81. </span>
  82. </span>
  83. </div>
  84. <div>
  85. <span class="font4">{{$t(`目标达成率`)}}:</span>
  86. <span class="font5">{{ Math.round((list.wcamount * 100)* 100) / 100 }}%</span>
  87. <span class="font4" style="margin-left:0.842vw">{{$t(`实际与目标差额`)}}:</span>
  88. <span class="font5" >
  89. <span v-if="list.unamount > 10000">
  90. {{tool.formatAmount(tool.unitConversion(list.unamount, 10000), 2)}}
  91. <span class="font5">{{$t(`万元`)}}</span>
  92. </span>
  93. <span v-else>
  94. {{tool.formatAmount(tool.unitConversion(list.unamount, 10000), 2)}}
  95. <span class="font5">{{$t(`元`)}}</span>
  96. </span>
  97. </span>
  98. </div>
  99. </div>
  100. </div>
  101. <div style="margin-top: 1.042vw">
  102. <div style="display:flex;justify-content: right">
  103. <datePicker v-show="typeSelect !== '回款'" ref="pickerRef" type="year" @selectTime="pickerChange" format="yyyy" value_format="yyyy"></datePicker>
  104. </div>
  105. <DualAxesCharts v-show="typeSelect == '订单'" :param="paramChart" heightChart="14.0vw" ref-charts="orderPanelChart" ref="orderPanelRef"></DualAxesCharts>
  106. <DualAxesLineCharts v-show="typeSelect == '出货'" :param="paramShipmentChart" heightChart="14.0vw" ref-charts="shipmentPanelChart" ref="shipmentPanelRef"></DualAxesLineCharts>
  107. <DualAxesCharts v-show="typeSelect == '开票'" :param="paramInvoiceChart" heightChart="14.0vw" ref-charts="invoicePanelChart" ref="invoicePanelRef"></DualAxesCharts>
  108. <BarCharts v-show="typeSelect == '回款'" :param="paramRefundChart" heightChart="14.0vw" ref-charts="refundPanelChart" ref="refundPanelRef"></BarCharts>
  109. </div>
  110. </template>
  111. </borderTemplate>
  112. </div>
  113. </template>
  114. <script>
  115. import borderTemplate from '../components/borderTemplate'
  116. import {DualAxes} from "@antv/g2plot";
  117. import datePicker from "../components/datePicker";
  118. import DualAxesCharts from "@/HManagement/serviceDataScreen/components/DualAxesCharts";
  119. import DualAxesLineCharts from "@/HManagement/serviceDataScreen/components/DualAxesLineCharts";
  120. import BarCharts from "@/HManagement/serviceDataScreen/components/BarCharts";
  121. export default {
  122. name: "salesPanel",
  123. components:{borderTemplate,datePicker,DualAxesCharts,DualAxesLineCharts,BarCharts},
  124. data(){
  125. return {
  126. typeSelect:'订单',
  127. chartCustomerLine:null,
  128. param:{
  129. id:20231009125304,
  130. content:{
  131. dataid:'',
  132. datatype:'1',
  133. dateType:'本年',
  134. type:'',
  135. where:{
  136. isleave:''
  137. }
  138. }
  139. },
  140. list:'',
  141. windowWidth: document.documentElement.clientWidth, //实时屏幕宽度
  142. progressWidth: (9.65 * document.documentElement.clientWidth) / 100,
  143. percentage:0,
  144. paramChart:{
  145. "id": 20231012094804,
  146. "content": {
  147. "type": '',
  148. "dataid": '',
  149. "year": 2024,
  150. "where": {
  151. "isleave": "1"
  152. }
  153. }
  154. },
  155. paramShipmentChart:{
  156. "id": 20231012152004,
  157. "content": {
  158. "type": 0,
  159. "dataid": '',
  160. "year": "2023",
  161. "where":{
  162. "isleave":"1"
  163. }
  164. }
  165. },
  166. paramInvoiceChart:{
  167. "id": 20231016095304,
  168. "content": {
  169. "type": 0,
  170. "dataid": 54,
  171. "year": "2023",
  172. "where":{
  173. "isleave":"1"
  174. }
  175. }
  176. },
  177. paramRefundChart:{
  178. "id": 20231016211904,
  179. "content": {
  180. "type": 0,
  181. "dataid": 54,
  182. "where":{
  183. "isleave":"1"
  184. }
  185. }
  186. },
  187. saledateRows:[],
  188. tbzzl:[],
  189. }
  190. },
  191. methods:{
  192. async listData(init,time){
  193. const res = await this.$api.requested(this.param)
  194. this.list = res.data
  195. this.percentage = Math.round(this.list.wcamount * 100 * 100) / 100;
  196. if (init){
  197. this.$refs.orderPanelRef.chartData(true)
  198. this.$refs.shipmentPanelRef.chartData(true)
  199. this.$refs.invoicePanelRef.chartData(true)
  200. this.$refs.refundPanelRef.chartData(true)
  201. }else {
  202. this.$refs.orderPanelRef.chartData(false)
  203. this.$refs.shipmentPanelRef.chartData(false)
  204. this.$refs.invoicePanelRef.chartData(false)
  205. this.$refs.refundPanelRef.chartData(false)
  206. }
  207. },
  208. dateTypeChange(){
  209. this.listData(false,false)
  210. },
  211. pickerChange(val){
  212. this.paramChart.content.year = val
  213. this.paramInvoiceChart.content.year = val
  214. this.paramShipmentChart.content.year = val
  215. this.listData(false,true)
  216. },
  217. typeChange(val){
  218. if (val == '订单'){
  219. this.typeSelect = '订单'
  220. this.param.content.datatype = 1
  221. }else if (val == '出货'){
  222. this.typeSelect = '出货'
  223. this.param.content.datatype = 2
  224. }else if (val == '开票'){
  225. this.typeSelect = '开票'
  226. this.param.content.datatype = 3
  227. }else if (val == '回款'){
  228. this.typeSelect = '回款'
  229. this.param.content.datatype = 4
  230. }
  231. this.listData()
  232. },
  233. format(percentage) {
  234. return this.$t("目标达成率") + '\n\n' + percentage + "%";
  235. },
  236. /*渲染图表*/
  237. async queryModel(){
  238. const res = await this.$api.requested(this.paramChart)
  239. this.saledateRows = res.data.saledateRows
  240. let lastYear = []
  241. let nowYear = []
  242. let k=0
  243. for (var i=0;i<res.data.saledateRows.length;i++){
  244. if (res.data.saledateRows[i].name === '去年同期金额'){
  245. lastYear[k]=res.data.saledateRows[i]
  246. k++
  247. }
  248. }
  249. let x=0
  250. for (var i=0;i<res.data.saledateRows.length;i++){
  251. if (res.data.saledateRows[i].name === '本年金额'){
  252. nowYear[x]=res.data.saledateRows[i]
  253. x++
  254. }
  255. }
  256. let saledateRows = nowYear.concat(lastYear)
  257. this.saledateRows = saledateRows.map((item)=>{
  258. let value = item.value/10000
  259. return {
  260. "date":item.date,
  261. "name":item.name + '(万元)',
  262. "value":value
  263. /*"value":item.value*/
  264. }
  265. })
  266. this.tbzzl = res.data.tbzzlRows.map((item)=>{
  267. return {
  268. "date":item.date,
  269. "name":item.name,
  270. "value":Math.round(((item.value *100)*100)/100)
  271. }
  272. })
  273. this.chartCustomerLine.changeData([this.saledateRows,this.tbzzl])
  274. },
  275. renderPie(){
  276. this.chartCustomerLine = new DualAxes('salesPanelChart', {
  277. data: [this.saledateRows,this.tbzzl],
  278. xField: 'date',
  279. yField: ['value','value'],
  280. xAxis:{
  281. label:{
  282. style:{
  283. fill:'#CFDCE5'
  284. }
  285. }
  286. },
  287. yAxis:{
  288. value:{
  289. label:{
  290. style:{
  291. fill:'#CFDCE5'
  292. }
  293. }
  294. }
  295. },
  296. geometryOptions: [
  297. {
  298. geometry: 'column',
  299. isGroup: true,
  300. seriesField: 'name',
  301. color:['#3685FC','#6CD2A1'],
  302. // label:{
  303. // position:top,
  304. // formatter: (datum) =>{
  305. // return '¥' + this.tool.formatAmount(datum.value,2)
  306. // }
  307. // }
  308. },
  309. {
  310. geometry: 'line',
  311. seriesField: 'name',
  312. color: '#ECB937',
  313. smooth: true,
  314. // label:{
  315. // formatter: (datum) =>{
  316. // return datum.value + '%'
  317. // }
  318. // }
  319. },
  320. ],
  321. tooltip: {
  322. formatter: (datum) => {
  323. return {
  324. name:datum.name,
  325. value:datum.name != '同比增长率'?'¥'+this.tool.formatAmount(datum.value,2):datum.value + '%'
  326. }
  327. },
  328. },
  329. legend:{
  330. itemName:{
  331. style:{
  332. fill:'#CFDCE5'
  333. }
  334. },
  335. }
  336. });
  337. this.chartCustomerLine.render();
  338. this.queryModel()
  339. },
  340. },
  341. }
  342. </script>
  343. <style>
  344. .justify-content{
  345. display: flex;
  346. justify-content: space-between;
  347. margin-top: 1.042vw;
  348. }
  349. .justify-content-left{
  350. display: flex;
  351. justify-content: left;
  352. }
  353. .justify-content-left .box-border{
  354. width: 3.125vw;
  355. height: 1.563vw;
  356. border-radius: 0.104vw 0.104vw 0.104vw 0.104vw;
  357. margin-right: 0.521vw;
  358. text-align: center;
  359. }
  360. .justify-content-left .box-border .btn-select{
  361. font-family: Microsoft YaHei, Microsoft YaHei;
  362. font-weight: 400;
  363. font-size: 0.833vw;
  364. color: #E6F4FF;
  365. font-style: normal;
  366. text-transform: none;
  367. }
  368. .justify-content-left .box-border .btn-unSelect{
  369. font-family: Microsoft YaHei, Microsoft YaHei;
  370. font-weight: 400;
  371. font-size: 0.729vw;
  372. color: #CFDCE5;
  373. font-style: normal;
  374. text-transform: none;
  375. text-align: center;
  376. }
  377. .content-style-pie{
  378. width: 29.167vw;
  379. height: 11.458vw;
  380. background: #001E41;
  381. box-shadow: 0.000vw 0.156vw 0.313vw 0.052vw rgba(0,0,0,0.16);
  382. border-radius: 5.729vw 5.729vw 0.313vw 5.729vw;
  383. border: 0.052vw solid #CFDCE5;
  384. margin-top: 1.042vw;
  385. box-sizing: border-box;
  386. display: flex;
  387. justify-content: left;
  388. }
  389. .content-style-content{
  390. margin-top: 0.717vw;
  391. margin-left: 4.250vw;
  392. }
  393. .content-style-content .font1{
  394. font-family: Microsoft YaHei, Microsoft YaHei;
  395. font-weight: 400;
  396. font-size: 0.938vw;
  397. color: #CFDCE5;
  398. text-align: left;
  399. font-style: normal;
  400. text-transform: none;
  401. }
  402. .content-style-content .font2{
  403. font-family: Microsoft YaHei, Microsoft YaHei;
  404. font-weight: bold;
  405. font-size: 1.250vw;
  406. color: #6CD2A1;
  407. text-align: left;
  408. font-style: normal;
  409. text-transform: none;
  410. }
  411. .content-style-content .font3{
  412. font-family: Microsoft YaHei, Microsoft YaHei;
  413. font-weight: bold;
  414. font-size: 0.625vw;
  415. color: #6CD2A1;
  416. text-align: left;
  417. font-style: normal;
  418. text-transform: none;
  419. }
  420. .content-style-content .font4{
  421. font-family: Microsoft YaHei, Microsoft YaHei;
  422. font-weight: 400;
  423. font-size: 0.625vw;
  424. color: #CFDCE5;
  425. text-align: left;
  426. font-style: normal;
  427. text-transform: none;
  428. }
  429. .content-style-content .font5{
  430. font-family: Microsoft YaHei, Microsoft YaHei;
  431. font-weight: 400;
  432. font-size: 0.625vw;
  433. color: #E6F4FF;
  434. text-align: left;
  435. font-style: normal;
  436. text-transform: none;
  437. }
  438. .content-style-content .font6{
  439. font-family: Microsoft YaHei, Microsoft YaHei;
  440. font-weight: bold;
  441. font-size: 1.250vw;
  442. color: #FFFFFF;
  443. text-align: left;
  444. font-style: normal;
  445. text-transform: none;
  446. }
  447. .content-style-content .font7{
  448. font-family: Microsoft YaHei, Microsoft YaHei;
  449. font-weight: bold;
  450. font-size: 0.625vw;
  451. color: #FFFFFF;
  452. text-align: left;
  453. font-style: normal;
  454. text-transform: none;
  455. }
  456. </style>
  457. <style scoped>
  458. /deep/ .el-progress__text {
  459. position: absolute;
  460. top: 50%; /* 设置垂直居中 */
  461. left: 50%;
  462. transform: translateX(-50%) translateY(-50%); /* 移动到圆环中心 */
  463. font-family: Microsoft YaHei, Microsoft YaHei;
  464. font-weight: bold;
  465. font-size: 0.833vw !important;
  466. color: #E6F4FF !important;
  467. font-style: normal;
  468. text-transform: none;
  469. }
  470. /deep/ .el-button--primary:focus, .el-button--primary:hover {
  471. background: #6090f8;
  472. border-color: #6090f8;
  473. color: #6090f8;
  474. }
  475. /deep/ .element.style {
  476. font-size: 0.830vw;
  477. }
  478. ::v-deep .el-progress__text {
  479. white-space: pre;
  480. }
  481. /deep/ .el-button {
  482. line-height: 0.5;
  483. padding: 0.521vw 0.521vw;
  484. }
  485. </style>