index.vue 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. <template>
  2. <div class="container">
  3. <el-row :gutter="20">
  4. <el-col :span="12">
  5. <div class="accuracy">
  6. <div class="accuracy_t">
  7. <div class="accuracy_t_l">
  8. <h4><span class="title"></span>准确性分析</h4>
  9. <el-select v-model="accuracy.value1" style="width:150px;margin-right: 5px;" class="filter-item" @change="changecattle('1')">
  10. <el-option v-for="item in accuracy.cattleTpyeList" :key="item.value" :label="item.label"
  11. :value="item.value"> </el-option>
  12. </el-select>
  13. <el-select v-model="accuracy.value2" style="width:150px;margin-right: 5px;" class="filter-item" @change="changeformula('1')">
  14. <el-option v-for="item in accuracy.formulaList" :key="item.value" :label="item.label"
  15. :value="item.value"> </el-option>
  16. </el-select>
  17. <el-date-picker v-model="accuracy.inputDatetime" :clearable="false" class="inputDatetime filter-item"
  18. type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
  19. style="width: 250px;" :picker-options="pickerOptions" @change="changeDate('1')" />
  20. </div>
  21. <div class="accuracy_t_r">
  22. <div class="exportTable button" @click="handleChart('accuracy')">切换图表</div>
  23. <div class="exportTable button" @click="handleExport('accuracy')">导出</div>
  24. </div>
  25. </div>
  26. <div class="accuracy_b">
  27. <el-tabs v-model="accuracy.activeName" @tab-click="handleTabClick">
  28. <el-tab-pane label="混料准确率" name="first" />
  29. <el-tab-pane label="混料正确率" name="second" />
  30. <el-tab-pane label="撒料准确率" name="third" />
  31. <el-tab-pane label="撒料正确率" name="fourth" />
  32. </el-tabs>
  33. <el-row :gutter="20">
  34. <el-col :span="6">
  35. <div class="maxdiv">
  36. <div class="title-t">最高</div>
  37. <div class="title-c">{{accuracy.chart1.lineData1.max_value}}%</div>
  38. <div class="title-b">NO.1 {{accuracy.chart1.lineData1.top_one_name}}</div>
  39. </div>
  40. </el-col>
  41. <el-col :span="6">
  42. <div class="mediandiv">
  43. <div class="title-t">中位值</div>
  44. <div class="title-c">{{accuracy.chart1.lineData1.middle_value}}%</div>
  45. <a class="title-b" @click="handleSeeRanking">查看排名</a>
  46. </div>
  47. </el-col>
  48. <el-col :span="6">
  49. <div class="mindiv">
  50. <div class="title-t">最低</div>
  51. <div class="title-c">{{accuracy.chart1.lineData1.min_value}}%</div>
  52. </div>
  53. </el-col>
  54. </el-row>
  55. <div v-if="accuracy.chart1.isChart">
  56. <div id="chartLine1" v-loading="accuracy.chart1.listLoading" style="height:310px;" />
  57. <a class="more" @click="handleMore">更多&gt;</a>
  58. </div>
  59. <div v-else>
  60. <el-table style="width: 100%" :max-height="320" :row-style="rowStyle" :cell-style="cellStyle" border
  61. :data="accuracy.chart1.tableDataList1">
  62. <template v-for="(item,key) in accuracy.chart1.tableTitleList1">
  63. <template>
  64. <el-table-column min-width="30" :key="item.value" :label="item.value" align="center">
  65. <template slot-scope="scope">
  66. <span v-if="key == 0">{{ scope.row[item.name] }}</span>
  67. <span v-else>{{ scope.row[item.name] }}%</span>
  68. </template>
  69. </el-table-column>
  70. </template>
  71. </template>
  72. </el-table>
  73. </div>
  74. </div>
  75. </div>
  76. </el-col>
  77. <el-col :span="12">
  78. <div class="time">
  79. <div class="time_t">
  80. <div class="time_t_l">
  81. <h4><span class="title"></span>执行时间</h4>
  82. <el-select v-model="time.value1" style="width:150px;margin-right: 5px;" class="filter-item" @change="changecattle('2')">
  83. <el-option v-for="item in time.cattleTpyeList" :key="item.value" :label="item.label"
  84. :value="item.value"> </el-option>
  85. </el-select>
  86. <el-select v-model="time.value2" style="width:150px;margin-right: 5px;" class="filter-item" @change="changeformula('2')">
  87. <el-option v-for="item in time.formulaList" :key="item.value" :label="item.label" :value="item.value">
  88. </el-option>
  89. </el-select>
  90. <el-date-picker v-model="time.inputDatetime" :clearable="false" class="inputDatetime filter-item"
  91. type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
  92. style="width: 250px;" :picker-options="pickerOptions" @change="changeDate('2')"/>
  93. </div>
  94. <div class="time_t_r">
  95. <div class="exportTable button" @click="handleChart('time')">切换图表</div>
  96. <div class="exportTable button" @click="handleExport('time')">导出</div>
  97. </div>
  98. </div>
  99. <div v-if="time.chart1.isChart">
  100. <div id="chartLine2" v-loading="time.chart1.listLoading" style="height:420px;" />
  101. </div>
  102. <div v-else style="margin: 10px 10px;">
  103. <el-table :data="time.chart1.tableDataList1" border style="width: 100%;" :max-height="410"
  104. :row-style="rowStyle" :cell-style="cellStyle" class="elTable">
  105. <el-table-column label="类型" min-width="80px" align="center">
  106. <el-table-column label="牧场" min-width="80px" align="center" prop="title" />
  107. </el-table-column>
  108. <el-table-column label="加料时间(分钟)" min-width="80px" align="center">
  109. <el-table-column label="最大值" min-width="80px" align="center" prop="add_feed_time_max_value" />
  110. <el-table-column label="上四分位数" min-width="80px" align="center" prop="add_feed_time_up_middle_value" />
  111. <el-table-column label="中位数" min-width="80px" align="center" prop="add_feed_time_middle_value" />
  112. <el-table-column label="下四分位数" min-width="80px" align="center" prop="add_feed_time_down_middle_value" />
  113. <el-table-column label="最小值" min-width="80px" align="center" prop="add_feed_time_min_value" />
  114. </el-table-column>
  115. <!-- <el-table-column label="搅拌延时(分钟)" min-width="80px" align="center">
  116. <el-table-column label="最大值" min-width="80px" align="center" prop="stir_time_max_value" />
  117. <el-table-column label="上四分位数" min-width="80px" align="center" prop="stir_time_up_middle_value" />
  118. <el-table-column label="中位数" min-width="80px" align="center" prop="stir_time_middle_value" />
  119. <el-table-column label="下四分位数" min-width="80px" align="center" prop="stir_time_down_middle_value" />
  120. <el-table-column label="最小值" min-width="80px" align="center" prop="stir_time_min_value" />
  121. </el-table-column> -->
  122. <el-table-column label="撒料时间(分钟)" min-width="80px" align="center">
  123. <el-table-column label="最大值" min-width="80px" align="center" prop="sprinkle_time_max_value" />
  124. <el-table-column label="上四分位数" min-width="80px" align="center" prop="sprinkle_time_up_middle_value" />
  125. <el-table-column label="中位数" min-width="80px" align="center" prop="sprinkle_time_middle_value" />
  126. <el-table-column label="下四分位数" min-width="80px" align="center" prop="sprinkle_time_down_middle_value" />
  127. <el-table-column label="最小值" min-width="80px" align="center" prop="sprinkle_time_min_value" />
  128. </el-table-column>
  129. </el-table>
  130. </div>
  131. </div>
  132. </el-col>
  133. </el-row>
  134. <el-row :gutter="20">
  135. <el-col :span="24">
  136. <div class="abnormal">
  137. <div class="abnormal_t">
  138. <div class="abnormal_t_l">
  139. <h4>
  140. <span class="title"></span>
  141. 撒料时间统计分析
  142. <el-tooltip class="item" effect="dark" placement="top-start">
  143. <div slot="content">
  144. 按时间段统计各牧场配方的撒料正常次数和异常次数,<br />
  145. 切换图表可查看详细数据
  146. </div>
  147. <span class="el-icon-question"></span>
  148. </el-tooltip>
  149. </h4>
  150. <el-select v-model="abnormal.value2" style="width:150px;margin-right: 5px;" class="filter-item" @change="changeformula('3')">
  151. <el-option v-for="item in abnormal.formulaList" :key="item.value" :label="item.label" :value="item.value">
  152. </el-option>
  153. </el-select>
  154. <el-date-picker v-model="abnormal.inputDatetime" :clearable="false" class="inputDatetime filter-item"
  155. type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
  156. style="width: 250px;" @change="changeDate('3')" />
  157. </div>
  158. <div class="abnormal_t_r">
  159. <div class="exportTable button" @click="handleChart('abnormal')">切换图表</div>
  160. <div class="exportTable button" @click="handleExport('abnormal')">导出</div>
  161. </div>
  162. </div>
  163. <div v-if="abnormal.chart1.isChart">
  164. <div id="chartLine3" v-loading="abnormal.chart1.listLoading" style="height:420px;" />
  165. </div>
  166. <div v-else style="margin: 10px 10px;">
  167. <el-select v-model="abnormal.value3" style="width:150px;margin-right: 5px;margin-bottom:10px;" class="filter-item" @change="changepasture('3')">
  168. <el-option v-for="item in abnormal.pastureList" :key="item.id" :label="item.name" :value="item.id" />
  169. </el-select>
  170. <el-select v-model="abnormal.value4" style="width:150px;margin-right: 5px;margin-bottom:10px;" class="filter-item" @change="changestate('3')">
  171. <el-option v-for="item in abnormal.stateList" :key="item.value" :label="item.label" :value="item.value">
  172. </el-option>
  173. </el-select>
  174. <span style="float: right;">共{{abnormal.chart1.tableDataList1.length}}次</span>
  175. <el-table :data="abnormal.chart1.tableDataList1" border style="width: 100%;" :max-height="310"
  176. :row-style="rowStyle" :cell-style="cellStyle" class="elTable">
  177. <el-table-column label="牧场" min-width="130px" align="center" prop="pasture_name" />
  178. <el-table-column label="栏舍" min-width="130px" align="center" prop="barn_name" />
  179. <el-table-column label="班次" min-width="130px" align="center" prop="class_number" />
  180. <el-table-column label="实际撒料时间" min-width="130px" align="center" prop="reality_sprinkle_feed_time" />
  181. </el-table>
  182. </div>
  183. </div>
  184. </el-col>
  185. </el-row>
  186. <el-dialog :title="textMap[accuracy.dialogStatus]" :visible.sync="accuracy.dialogFormVisible"
  187. :close-on-click-modal="false" width="50%">
  188. <div class="accuracy-content">
  189. <div v-if="accuracy.dialogStatus == 'more'" class="dialogmore" style="min-height: 100px;">
  190. <el-checkbox-group v-model="accuracy.more.checkedPasture">
  191. <el-checkbox border v-for="(item,index) in accuracy.more.pastureList" :label="item.id"
  192. :key="index">{{item.name}}</el-checkbox>
  193. </el-checkbox-group>
  194. </div>
  195. <div v-else class="seeRanking" style="min-height: 300px;">
  196. <el-tabs v-model="accuracy.seeRanking.activeName" @tab-click="handleSeeTabClick">
  197. <el-tab-pane label="混料准确率" name="first" />
  198. <el-tab-pane label="混料正确率" name="second" />
  199. <el-tab-pane label="撒料准确率" name="third" />
  200. <el-tab-pane label="撒料正确率" name="fourth" />
  201. </el-tabs>
  202. <div class="search">
  203. <el-input v-model="accuracy.seeRanking.top_rand_start" placeholder="准确率" style="width: 180px;" class="filter-item"
  204. type="number" clearable />
  205. <span style="margin-right: 5px;">-</span>
  206. <el-input v-model="accuracy.seeRanking.top_rand_end" placeholder="准确率" style="width: 180px;" class="filter-item"
  207. type="number" clearable />
  208. <el-button class="successBorder" @click="handleSearch">查询</el-button>
  209. </div>
  210. <el-table :key="accuracy.seeRanking.tableKey" v-loading="accuracy.seeRanking.listLoading"
  211. element-loading-text="给我一点时间" :data="accuracy.seeRanking.list" border fit highlight-current-row
  212. style="width: 100%;" :row-style="rowStyle" :cell-style="cellStyle" class="elTable">
  213. <el-table-column type="selection" align="center" width="50" />
  214. <el-table-column label="排名" min-width="130px" align="center" type="index"/>
  215. <el-table-column label="牧场名称" min-width="130px" align="center" prop="pasture_name" />
  216. <el-table-column label="准确率" min-width="130px" align="center" prop="ratio" />
  217. </el-table>
  218. </div>
  219. <div slot="footer" class="dialog-footer" style="right:30px;position:absolute;bottom: 40px;">
  220. <el-button v-if="accuracy.dialogStatus == 'more'" class="cancelClose cancelClose"
  221. @click="accuracy.dialogFormVisible = false; ">关闭</el-button>
  222. <el-button v-else class="cancelClose1"
  223. @click="accuracy.dialogFormVisible = false; ">关闭</el-button>
  224. <el-button class="save" :disabled="isokDisable" v-if="accuracy.dialogStatus == 'more'"
  225. @click="createData()">确认</el-button>
  226. </div>
  227. </div>
  228. </el-dialog>
  229. </div>
  230. </template>
  231. <script>
  232. import {
  233. postJson,
  234. getJson
  235. } from '@/api/common'
  236. import {
  237. mapGetters
  238. } from 'vuex'
  239. import {
  240. parseTime
  241. } from '@/utils/index.js'
  242. // import echarts from 'echarts'
  243. import * as echarts from 'echarts';
  244. require('echarts/theme/macarons')
  245. import Cookies from 'js-cookie'
  246. export default {
  247. name: 'Dashboard',
  248. data() {
  249. return {
  250. pickerMinDate: '',
  251. pickerOptions: {
  252. onPick: ({
  253. maxDate,
  254. minDate
  255. }) => {
  256. this.pickerMinDate = minDate.getTime()
  257. if (maxDate) {
  258. this.pickerMinDate = ''
  259. }
  260. },
  261. // 限制不能选择明天之后的日期
  262. disabledDate: (time) => {
  263. if (this.pickerMinDate !== '') {
  264. const one = 31 * 24 * 3600 * 1000
  265. const minTime = this.pickerMinDate - one
  266. let maxTime = this.pickerMinDate + one
  267. if (maxTime > new Date()) {
  268. // maxTime = Date.now() + 8.64e7
  269. maxTime = Date.now()
  270. }
  271. return time.getTime() < minTime || time.getTime() > maxTime
  272. }
  273. return time.getTime() > Date.now()
  274. // return time.getTime() > Date.now() + 8.64e7
  275. }
  276. },
  277. pastureList: JSON.parse(sessionStorage.pastureList),
  278. accuracy: {
  279. value1: '',
  280. value2: '',
  281. inputDatetime: [new Date(), new Date()],
  282. cattleTpyeList: JSON.parse(sessionStorage.downlist).cattle_parent_category,
  283. formulaList: JSON.parse(sessionStorage.downlist).formula_list,
  284. activeName: 'first',
  285. chart1: {
  286. isChart: true,
  287. listLoading: false,
  288. chartLine: null,
  289. allChart1Data: {},
  290. allTable1Data: [],
  291. tableTitleList1: [],
  292. tableDataList1: [],
  293. lineData1: {},
  294. },
  295. dialogStatus: '',
  296. dialogFormVisible: false,
  297. more: {
  298. checkedPasture: [],
  299. pastureList: JSON.parse(sessionStorage.pastureList),
  300. },
  301. seeRanking: {
  302. activeName: 'first',
  303. tableKey: 0,
  304. listLoading: false,
  305. list: [],
  306. allData: {}
  307. },
  308. },
  309. time: {
  310. value1: '',
  311. value2: '',
  312. inputDatetime: [new Date(), new Date()],
  313. cattleTpyeList: JSON.parse(sessionStorage.downlist).cattle_parent_category,
  314. formulaList: JSON.parse(sessionStorage.downlist).formula_list,
  315. chart1: {
  316. isChart: true,
  317. listLoading: false,
  318. chartLine: null,
  319. lineData1: {},
  320. tableDataList1: [],
  321. },
  322. },
  323. abnormal: {
  324. value1: '',
  325. value2: '',
  326. value3:0,
  327. value4:0,
  328. inputDatetime: [new Date(), new Date()],
  329. cattleTpyeList: JSON.parse(sessionStorage.downlist).cattle_parent_category,
  330. formulaList: JSON.parse(sessionStorage.downlist).formula_list,
  331. pastureList:JSON.parse(sessionStorage.pastureList), //牧场
  332. stateList:[{label:'数据状态',value:0},{label:'正常撒料',value:1},{label:'异常撒料',value:2}],
  333. chart1: {
  334. isChart: true,
  335. listLoading: false,
  336. chartLine: null,
  337. lineData1: {},
  338. tableDataList1: [],
  339. },
  340. },
  341. textMap: {
  342. seeRanking: '查看排名',
  343. more: '更多'
  344. },
  345. isokDisable: false,
  346. rowStyle: {
  347. maxHeight: 30 + 'px',
  348. height: 30 + 'px'
  349. },
  350. cellStyle: {
  351. padding: 0 + 'px'
  352. },
  353. initData:[],seriesData:[]
  354. }
  355. },
  356. created() {
  357. // accuracy.inputDatetime
  358. this.abnormal.pastureList.unshift({id:0,name:'所有牧场'})
  359. this.accuracy.value1 = this.accuracy.cattleTpyeList[0].value
  360. this.time.value1 = this.time.cattleTpyeList[0].value
  361. this.abnormal.value1 = this.abnormal.cattleTpyeList[0].value
  362. this.accuracy.value2 = this.accuracy.formulaList[0].value
  363. this.time.value2 = this.time.formulaList[0].value
  364. this.abnormal.value2 = this.abnormal.formulaList[0].value
  365. this.getTimeFn()
  366. },
  367. methods: {
  368. getTimeFn() {
  369. const that = this
  370. const start1 = new Date()
  371. const end1 = new Date()
  372. start1.setTime(start1.getTime() - 3600 * 1000 * 24 * 6)
  373. end1.setTime(end1.getTime() - 3600 * 1000 * 24 * 0)
  374. that.accuracy.inputDatetime = [start1, end1]
  375. const start3 = new Date()
  376. const end3 = new Date()
  377. start3.setTime(start3.getTime() - 3600 * 1000 * 24 * 6)
  378. end3.setTime(end3.getTime() - 3600 * 1000 * 24 * 0)
  379. that.time.inputDatetime = [start3, end3]
  380. const start2 = new Date()
  381. const end2 = new Date()
  382. start2.setTime(start2.getTime() - 3600 * 1000 * 24 * 6)
  383. end2.setTime(end2.getTime() - 3600 * 1000 * 24 * 0)
  384. that.abnormal.inputDatetime = [start2, end2]
  385. that.getChart1List()
  386. that.getChart2List()
  387. that.getChart3List()
  388. },
  389. // getFormulaList() {
  390. // let page = 1
  391. // let page_size = 0
  392. // let url = '/api/v1/ops/feed_formula/list' + '?page=' + page + '&page_size=' + page_size
  393. // let data = {}
  394. // postJson(url, data).then(response => {
  395. // if (response.code == 200) {
  396. // this.accuracy.formulaList = response.data.list
  397. // this.time.formulaList = response.data.list
  398. // this.abnormal.formulaList = response.data.list
  399. // } else {
  400. // this.accuracy.formulaList = []
  401. // this.time.formulaList = []
  402. // this.abnormal.formulaList = []
  403. // }
  404. // this.getChart1List()
  405. // this.getChart2List()
  406. // this.getChart3List()
  407. // })
  408. // },
  409. getChart1List() {
  410. let url = '/api/v1/ops/dashboard/accuracy'
  411. let pasture_ids = []
  412. this.pastureList.forEach((item) => {
  413. pasture_ids.push(item.id)
  414. })
  415. let data = {
  416. 'cattle_parent_category_id': this.accuracy.value1,
  417. 'start_date': parseTime(this.accuracy.inputDatetime[0], '{y}-{m}-{d}'),
  418. 'end_date': parseTime(this.accuracy.inputDatetime[1], '{y}-{m}-{d}'),
  419. 'pasture_ids': pasture_ids,
  420. 'feed_formula_id':this.accuracy.value2,
  421. }
  422. if (this.accuracy.value2 == '') {
  423. data.feed_formula_id = 0
  424. }
  425. postJson(url, data).then(response => {
  426. if (response.code == 200) {
  427. this.accuracy.chart1.allChart1Data = response.data.chart
  428. this.accuracy.chart1.allTable1Data = response.data.table.data_list
  429. if (this.accuracy.activeName == 'first') {
  430. this.accuracy.chart1.lineData1 = response.data.chart.mixed_fodder_accurate_ratio
  431. this.accuracy.chart1.tableDataList1 = response.data.table.data_list.mixed_fodder_accurate_ratio
  432. } else if (this.accuracy.activeName == 'second') {
  433. this.accuracy.chart1.lineData1 = response.data.chart.mixed_fodder_correct_ratio
  434. this.accuracy.chart1.tableDataList1 = response.data.table.data_list.mixed_fodder_correct_ratio
  435. } else if (this.accuracy.activeName == 'third') {
  436. this.accuracy.chart1.lineData1 = response.data.chart.sprinkle_fodder_accurate_ratio
  437. this.accuracy.chart1.tableDataList1 = response.data.table.data_list.sprinkle_fodder_accurate_ratio
  438. } else if (this.accuracy.activeName == 'fourth') {
  439. this.accuracy.chart1.lineData1 = response.data.chart.sprinkle_fodder_correct_ratio
  440. this.accuracy.chart1.tableDataList1 = response.data.table.data_list.sprinkle_fodder_correct_ratio
  441. }
  442. this.accuracy.chart1.tableTitleList1 = response.data.table.title_list
  443. console.log(this.accuracy.chart1.allChart1Data, 'allChart1Data')
  444. if (this.accuracy.chart1.isChart) {
  445. this.roadChartLine1(this.accuracy.chart1.lineData1)
  446. }
  447. console.log(this.accuracy.chart1.lineData1, '===')
  448. }
  449. })
  450. },
  451. handleTabClick(tab, event) {
  452. console.log(tab);
  453. if (tab.name == 'first') {
  454. this.accuracy.chart1.lineData1 = this.accuracy.chart1.allChart1Data.mixed_fodder_accurate_ratio
  455. this.accuracy.chart1.tableDataList1 = this.accuracy.chart1.allTable1Data.mixed_fodder_accurate_ratio
  456. } else if (tab.name == 'second') {
  457. this.accuracy.chart1.lineData1 = this.accuracy.chart1.allChart1Data.mixed_fodder_correct_ratio
  458. this.accuracy.chart1.tableDataList1 = this.accuracy.chart1.allTable1Data.mixed_fodder_correct_ratio
  459. } else if (tab.name == 'third') {
  460. this.accuracy.chart1.lineData1 = this.accuracy.chart1.allChart1Data.sprinkle_fodder_accurate_ratio
  461. this.accuracy.chart1.tableDataList1 = this.accuracy.chart1.allTable1Data.sprinkle_fodder_accurate_ratio
  462. } else if (tab.name == 'fourth') {
  463. this.accuracy.chart1.lineData1 = this.accuracy.chart1.allChart1Data.sprinkle_fodder_correct_ratio
  464. this.accuracy.chart1.tableDataList1 = this.accuracy.chart1.allTable1Data.sprinkle_fodder_correct_ratio
  465. }
  466. this.accuracy.chart1.isChart = true
  467. this.roadChartLine1(this.accuracy.chart1.lineData1)
  468. },
  469. handleChart(item) {
  470. if (item == 'accuracy') {
  471. this.accuracy.chart1.isChart = !this.accuracy.chart1.isChart
  472. this.$nextTick(() => {
  473. if (this.accuracy.chart1.isChart) {
  474. this.roadChartLine1(this.accuracy.chart1.lineData1)
  475. }
  476. });
  477. } else if (item == 'time') {
  478. this.time.chart1.isChart = !this.time.chart1.isChart
  479. this.$nextTick(() => {
  480. if (this.time.chart1.isChart) {
  481. this.roadChartLine2(this.time.chart1.lineData1)
  482. }
  483. });
  484. } else {
  485. this.abnormal.chart1.isChart = !this.abnormal.chart1.isChart
  486. this.abnormal.value3 = 0
  487. this.abnormal.value4 = 0
  488. this.getChart3List()
  489. this.$nextTick(() => {
  490. if (this.abnormal.chart1.isChart) {
  491. this.roadChartLine3(this.abnormal.chart1.lineData1)
  492. }
  493. });
  494. }
  495. },
  496. handleExport() {},
  497. handleSeeRanking() {
  498. this.accuracy.dialogStatus = 'seeRanking'
  499. this.accuracy.dialogFormVisible = true
  500. this.getSeeRankingList()
  501. },
  502. getSeeRankingList(item) {
  503. let url = '/api/v1/ops/dashboard/top_pasture'
  504. let pasture_ids = []
  505. this.pastureList.forEach((item) => {
  506. pasture_ids.push(item.id)
  507. })
  508. let dashboard_top_type = 0
  509. if(item){
  510. dashboard_top_type = item
  511. }else{
  512. dashboard_top_type = 0
  513. }
  514. let data = {
  515. 'cattle_parent_category_id': this.accuracy.value1,
  516. 'start_date':parseTime(this.accuracy.inputDatetime[0], '{y}-{m}-{d}'),
  517. 'end_date':parseTime(this.accuracy.inputDatetime[1], '{y}-{m}-{d}'),
  518. 'pasture_ids':pasture_ids,
  519. 'feed_formula_id':this.accuracy.value2,
  520. 'dashboard_top_type':dashboard_top_type
  521. }
  522. if (this.accuracy.value2 == '') {
  523. data.feed_formula_id = 0
  524. }
  525. if (this.accuracy.seeRanking.top_rand_start !== '') {
  526. data.top_rand_start = this.accuracy.seeRanking.top_rand_start
  527. }
  528. if (this.accuracy.seeRanking.top_rand_end !== '') {
  529. data.top_rand_end = this.accuracy.seeRanking.top_rand_end
  530. }
  531. postJson(url, data).then(response => {
  532. if (response.code == 200) {
  533. this.accuracy.seeRanking.allData = response.data
  534. if (this.accuracy.seeRanking.activeName == 'first') {
  535. this.accuracy.seeRanking.list = response.data.mixed_fodder_accurate_ratio
  536. } else if (this.accuracy.seeRanking.activeName == 'second') {
  537. this.accuracy.seeRanking.list = response.data.mixed_fodder_correct_ratio
  538. } else if (this.accuracy.seeRanking.activeName == 'third') {
  539. this.accuracy.seeRanking.list = response.data.sprinkle_fodder_accurate_ratio
  540. } else if (this.accuracy.seeRanking.activeName == 'fourth') {
  541. this.accuracy.seeRanking.list = response.data.sprinkle_fodder_correct_ratio
  542. }
  543. } else {
  544. this.accuracy.seeRanking.list = []
  545. }
  546. })
  547. },
  548. handleSeeTabClick(tab, ) {
  549. console.log(tab);
  550. if (tab.name == 'first') {
  551. this.accuracy.seeRanking.list = this.accuracy.seeRanking.allData.mixed_fodder_accurate_ratio
  552. } else if (tab.name == 'second') {
  553. this.accuracy.seeRanking.list = this.accuracy.seeRanking.allData.mixed_fodder_correct_ratio
  554. } else if (tab.name == 'third') {
  555. this.accuracy.seeRanking.list = this.accuracy.seeRanking.allData.sprinkle_fodder_accurate_ratio
  556. } else if (tab.name == 'fourth') {
  557. this.accuracy.seeRanking.list = this.accuracy.seeRanking.allData.sprinkle_fodder_correct_ratio
  558. }
  559. },
  560. handleSearch() {
  561. let dashboard_top_type = 0
  562. if(this.accuracy.seeRanking.activeName == 'first'){
  563. dashboard_top_type = 1
  564. }else if(this.accuracy.seeRanking.activeName == 'second'){
  565. dashboard_top_type = 2
  566. }else if(this.accuracy.seeRanking.activeName == 'third'){
  567. dashboard_top_type = 3
  568. }else{
  569. dashboard_top_type = 4
  570. }
  571. this.getSeeRankingList(dashboard_top_type)
  572. },
  573. handleMore() {
  574. this.accuracy.dialogStatus = 'more'
  575. this.getPastureList()
  576. },
  577. getPastureList() {
  578. let page = 1
  579. let page_size = 100
  580. let url = 'api/v1/ops/pasture/list' + '?page=' + page + '&page_size=' + page_size
  581. let data = {}
  582. postJson(url, data).then(response => {
  583. if (response.code == 200) {
  584. // this.accuracy.more.pastureList = response.data.list
  585. } else {
  586. // this.accuracy.more.pastureList = []
  587. }
  588. this.accuracy.dialogFormVisible = true
  589. })
  590. },
  591. getChart2List() {
  592. let url = '/api/v1/ops/dashboard/exec_time'
  593. let pasture_ids = []
  594. this.pastureList.forEach((item) => {
  595. pasture_ids.push(item.id)
  596. })
  597. let data = {
  598. 'cattle_parent_category_id': this.time.value1,
  599. 'feed_formula_id':this.time.value2,
  600. 'start_date': parseTime(this.time.inputDatetime[0], '{y}-{m}-{d}'),
  601. 'end_date': parseTime(this.time.inputDatetime[1], '{y}-{m}-{d}'),
  602. 'pasture_ids': pasture_ids,
  603. }
  604. if (this.time.value2 == '') {
  605. data.feed_formula_id = 0
  606. }
  607. postJson(url, data).then(response => {
  608. if (response.code == 200) {
  609. this.time.chart1.lineData1 = response.data.chart
  610. this.time.chart1.tableDataList1 = response.data.table_list
  611. if (this.time.chart1.isChart) {
  612. this.roadChartLine2(this.time.chart1.lineData1)
  613. }
  614. console.log(response.data, '===')
  615. }
  616. })
  617. },
  618. changecattle(item){
  619. if(item == '1'){
  620. this.getChart1List()
  621. }else if(item == '2'){
  622. this.getChart2List()
  623. }else if(item == '3'){
  624. this.getChart3List()
  625. }
  626. },
  627. changeformula(item){
  628. if(item == '1'){
  629. this.getChart1List()
  630. }else if(item == '2'){
  631. this.getChart2List()
  632. }else if(item == '3'){
  633. this.getChart3List()
  634. }
  635. },
  636. changeDate (item){
  637. if(item == '1'){
  638. this.getChart1List()
  639. }else if(item == '2'){
  640. this.getChart2List()
  641. }else if(item == '3'){
  642. if (this.abnormal.inputDatetime) {
  643. const startDate = this.abnormal.inputDatetime[0];
  644. const endDate = this.abnormal.inputDatetime[1];
  645. const days = Math.floor((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1;
  646. console.log('所选天数:', days);
  647. if(days < 7){
  648. this.$message({type: 'error',message: '最少选择7天时间', duration: 2000})
  649. }else if(days > 365){
  650. this.$message({type: 'error',message: '最多选择365天时间', duration: 2000})
  651. }else{
  652. this.getChart3List()
  653. }
  654. }
  655. }
  656. },
  657. changepasture(){
  658. this.getChart3List()
  659. },
  660. changestate(){
  661. this.getChart3List()
  662. },
  663. getChart3List() {
  664. let pasture_ids = []
  665. if(this.abnormal.chart1.isChart){
  666. this.abnormal.value3 == 0
  667. this.abnormal.value4 == 0
  668. }
  669. if(this.abnormal.value3 == 0){
  670. this.pastureList.forEach((item) => {
  671. pasture_ids.push(item.id)
  672. })
  673. }else{
  674. pasture_ids.push(this.abnormal.value3)
  675. }
  676. let url = '/api/v1/ops/dashboard/sprinkle_time'
  677. let data = {
  678. 'start_date': parseTime(this.abnormal.inputDatetime[0], '{y}-{m}-{d}'),
  679. 'end_date': parseTime(this.abnormal.inputDatetime[1], '{y}-{m}-{d}'),
  680. 'pasture_ids': pasture_ids,
  681. 'feed_formula_id':this.abnormal.value2
  682. }
  683. data.state = this.abnormal.value4
  684. console.log(this.abnormal.value2,'====000')
  685. if (this.abnormal.value2 == '') {
  686. data.feed_formula_id = 0
  687. }
  688. postJson(url, data).then(response => {
  689. if (response.code == 200) {
  690. this.abnormal.chart1.lineData1 = response.data.chart
  691. this.abnormal.chart1.tableDataList1 = response.data.table_list
  692. if (this.abnormal.chart1.isChart) {
  693. this.roadChartLine3(this.abnormal.chart1.lineData1)
  694. }
  695. console.log(response.data, '===')
  696. }
  697. })
  698. },
  699. roadChartLine1(chartLine_data) {
  700. if (this.accuracy.chart1.chartLine != null) {
  701. this.accuracy.chart1.chartLine.dispose()
  702. }
  703. this.accuracy.chart1.chartLine = echarts.init(document.getElementById('chartLine1'))
  704. var option = {
  705. animation: false,
  706. tooltip: {
  707. trigger: 'axis'
  708. },
  709. legend: {
  710. data: chartLine_data.pasture_name,
  711. left: 14,
  712. bottom: 0,
  713. },
  714. grid: {
  715. left: '3%',
  716. right: '14%',
  717. // top: '3%',
  718. containLabel: true
  719. },
  720. xAxis: [{
  721. type: 'category',
  722. boundaryGap: false,
  723. data: chartLine_data.date_day,
  724. axisLabel: {
  725. showMinLabel: true,
  726. showMaxLabel: true,
  727. },
  728. axisLine: {
  729. lineStyle: {
  730. color: '#666'
  731. }
  732. },
  733. }],
  734. yAxis: [{
  735. type: 'value',
  736. name: '(%)',
  737. axisLine: {
  738. lineStyle: {
  739. color: '#666'
  740. }
  741. },
  742. }],
  743. color: ['#4b07fa', '#0f96fc', '#ff42a9', '#ff724c', '#05fbf0', '#ffae00', '#b705fa', '#9a60b4', '#3cff00'],
  744. series: function(e) {
  745. var serie = [];
  746. for (var i = 0; i < chartLine_data.pasture_name.length; i++) {
  747. var item = {
  748. name: chartLine_data.pasture_name[i],
  749. data: chartLine_data.data_list[i],
  750. type: 'bar',
  751. // smooth: true,
  752. // itemStyle: {
  753. // borderColor: '#fff',
  754. // borderWidth: 2
  755. // },
  756. label: {
  757. // normal: { show: true },
  758. },
  759. }
  760. serie.push(item);
  761. }
  762. console.log(serie)
  763. return serie;
  764. }()
  765. };
  766. this.accuracy.chart1.chartLine.setOption(option)
  767. if (this.accuracy.chart1.chartLine !== null) {
  768. window.onresize = function() {
  769. this.accuracy.chart1.chartLine.resize()
  770. }
  771. }
  772. },
  773. roadChartLine2(chartLine_data) {
  774. if (this.time.chart1.chartLine != null) {
  775. this.time.chart1.chartLine.dispose()
  776. }
  777. this.time.chart1.chartLine = echarts.init(document.getElementById('chartLine2'))
  778. var option = {
  779. tooltip: {
  780. trigger: `item`,
  781. formatter: this.formatter
  782. }, // formatter可不设置
  783. color: `#8d8d8d`, // 箱线图线框的颜色
  784. grid: {
  785. left: '3%',
  786. right: 10,
  787. bottom: 10,
  788. // top: 20,
  789. containLabel: true,
  790. },
  791. legend: {
  792. // data: ['加料时间', '搅拌时间','撒料时间'],
  793. data: ['加料时间','撒料时间'],
  794. right: 14,
  795. top: 0,
  796. bottom: 10
  797. },
  798. // color: ['#42C7FF', '#20DB7C','#FCC858'],
  799. color: ['#42C7FF', '#FCC858'],
  800. xAxis: { // 此处设置与其他图表类似
  801. type: `category`,
  802. data:chartLine_data.title,
  803. axisLine: {
  804. //坐标轴轴线相关设置
  805. show: false,
  806. },
  807. axisLabel: {
  808. // 坐标轴刻度标签的相关设置
  809. show: true,
  810. showMaxLabel: true,
  811. },
  812. axisTick: {
  813. //刻度相关设置
  814. show: false, //让刻度隐藏
  815. },
  816. },
  817. yAxis: { // 此处设置与其他图表类似
  818. type: `value`,
  819. name:'(分钟)',
  820. splitArea: { show: false },
  821. axisLine: { lineStyle: { color: `#8d8d8d` } },
  822. },
  823. series: [
  824. {
  825. name:'加料时间',
  826. type: `boxplot`,
  827. itemStyle: { color: `#42C7FF` },
  828. data:chartLine_data.add_feed_time
  829. },
  830. // {
  831. // name:'搅拌时间',
  832. // type: `boxplot`,
  833. // itemStyle: { color: `#20DB7C` },
  834. // data:chartLine_data.stir_time
  835. // },
  836. {
  837. name:'撒料时间',
  838. type: `boxplot`,
  839. itemStyle: { color: `#FCC858` },
  840. data:chartLine_data.sprinkle_time
  841. }
  842. ],
  843. }
  844. this.time.chart1.chartLine.setOption(option)
  845. if (this.time.chart1.chartLine !== null) {
  846. window.onresize = function() {
  847. this.time.chart1.chartLine.resize()
  848. }
  849. }
  850. },
  851. formatter(param) {
  852. return [
  853. // '类别名称: ' + param.name,
  854. '最大值: ' + param.data[1],
  855. '上四分位数: ' + param.data[2],
  856. '中位数: ' + param.data[3],
  857. '下四分位数: ' + param.data[4],
  858. '最小值: ' + param.data[5]
  859. ].join('<br/>')
  860. },
  861. roadChartLine3(chartLine_data) {
  862. console.log(chartLine_data,'===999')
  863. if (this.abnormal.chart1.chartLine != null) {
  864. this.abnormal.chart1.chartLine.dispose()
  865. }
  866. this.abnormal.chart1.chartLine = echarts.init(document.getElementById('chartLine3'))
  867. var option = {
  868. animation: false,
  869. tooltip: {
  870. trigger: 'axis',
  871. formatter: function (data) {
  872. console.log(data,'====')
  873. let a = parseFloat(data[0].data)
  874. let b = parseFloat(data[0].data) + parseFloat(data[1].data)
  875. let rate1 = 0
  876. let rate2 = 0
  877. if(data[0].data !== 0 && data[1].data !== 0){
  878. rate1 = (a/b * 100).toFixed(2)
  879. rate2 = 100 - (parseFloat(rate1))
  880. }else{
  881. rate1 = 0
  882. rate2 = 0
  883. }
  884. var res = data[0].marker + data[0].seriesName + '<br/>'
  885. + "总占比"+rate1+"%"+ '<span style="margin-left:10px;color:#ccc;">'+ a + '次'+'</span>'+ '<br/>'
  886. + data[1].marker + data[1].seriesName+':'+'<br/>' + "总占比"+rate2+"%"+ "<span style='margin-left:10px;color:#ccc;'>"+ data[1].data + '次' + "</span>"
  887. return res
  888. }
  889. },
  890. legend: {
  891. data: ['正常撒料次数', '异常撒料次数'],
  892. right: 14,
  893. top: 0,
  894. },
  895. grid: {
  896. // top: '20%',
  897. left: '3%',
  898. right: '14%',
  899. bottom: '13%',
  900. containLabel: true
  901. },
  902. xAxis: [{
  903. type: 'category',
  904. data: chartLine_data.title,
  905. }],
  906. yAxis: [{
  907. type: 'value',
  908. name:'(次)',
  909. axisLine: {
  910. lineStyle: {
  911. color: '#666'
  912. }
  913. },
  914. }],
  915. series: [{
  916. name: '正常撒料次数',
  917. type: 'bar',
  918. barWidth:50,
  919. stack: 'Ad',
  920. data: chartLine_data.sprinkle_number_list[0]
  921. },
  922. {
  923. name: '异常撒料次数',
  924. type: 'bar',
  925. stack: 'Ad',
  926. barWidth:50,
  927. data: chartLine_data.sprinkle_number_list[1]
  928. },
  929. ]
  930. };
  931. this.abnormal.chart1.chartLine.setOption(option)
  932. if (this.abnormal.chart1.chartLine !== null) {
  933. window.onresize = function() {
  934. this.abnormal.chart1.chartLine.resize()
  935. }
  936. }
  937. },
  938. }
  939. }
  940. </script>
  941. <style lang="scss" scoped>
  942. .container {
  943. margin: 10px 10px;
  944. }
  945. .accuracy,
  946. .time,
  947. .abnormal {
  948. background: #fff;
  949. height: 550px;
  950. border-radius: 5px;
  951. border: 2px solid #ededed;
  952. }
  953. .accuracy_t {
  954. margin-left: 10px;
  955. position: relative;
  956. .accuracy_t_l {
  957. h3 {
  958. line-height: 15px;
  959. }
  960. .title {
  961. width: 3px;
  962. height: 15px;
  963. background: red;
  964. display: inline-block;
  965. margin-right: 10px;
  966. }
  967. }
  968. .accuracy_t_r {
  969. position: absolute;
  970. top: 0;
  971. right: 0;
  972. .button {
  973. display: inline-block;
  974. margin-right: 10px;
  975. }
  976. }
  977. }
  978. .accuracy_b {
  979. margin: 0 10px;
  980. /deep/ .el-tabs__item {
  981. font-size: 12px
  982. }
  983. position: relative;
  984. }
  985. .more {
  986. position: absolute;
  987. bottom: -14px;
  988. right: -8px;
  989. color: blue;
  990. font-size: 12px;
  991. }
  992. .maxdiv,
  993. .mediandiv,
  994. .mindiv {
  995. text-align: center;
  996. .title-t {
  997. font-size: 12px;
  998. }
  999. .title-c {
  1000. font-size: 14px;
  1001. font-weight: bold;
  1002. }
  1003. .title-b {
  1004. font-size: 14px;
  1005. color: red;
  1006. font-weight: bold;
  1007. }
  1008. }
  1009. .maxdiv,
  1010. .mediandiv {
  1011. border-right: 2px solid #eee;
  1012. }
  1013. .mediandiv {
  1014. .title-b {
  1015. color: blue;
  1016. }
  1017. }
  1018. .accuracy-content {
  1019. /deep/ .el-checkbox {
  1020. margin: 5px 5px;
  1021. }
  1022. /deep/ .is-bordered {
  1023. margin-left: 5px;
  1024. }
  1025. }
  1026. .time {
  1027. .time_t {
  1028. margin-left: 10px;
  1029. position: relative;
  1030. .time_t_l {
  1031. h3 {
  1032. line-height: 15px;
  1033. }
  1034. .title {
  1035. width: 3px;
  1036. height: 15px;
  1037. background: red;
  1038. display: inline-block;
  1039. margin-right: 10px;
  1040. }
  1041. }
  1042. .time_t_r {
  1043. position: absolute;
  1044. top: 0;
  1045. right: 0;
  1046. .button {
  1047. display: inline-block;
  1048. margin-right: 10px;
  1049. }
  1050. }
  1051. }
  1052. }
  1053. .abnormal {
  1054. background: #fff;
  1055. margin-top: 10px;
  1056. .abnormal_t {
  1057. margin-left: 10px;
  1058. position: relative;
  1059. .abnormal_t_l {
  1060. h3 {
  1061. line-height: 15px;
  1062. }
  1063. .title {
  1064. width: 3px;
  1065. height: 15px;
  1066. background: red;
  1067. display: inline-block;
  1068. margin-right: 10px;
  1069. }
  1070. }
  1071. .abnormal_t_r {
  1072. position: absolute;
  1073. top: 0;
  1074. right: 0;
  1075. .button {
  1076. display: inline-block;
  1077. margin-right: 10px;
  1078. }
  1079. }
  1080. }
  1081. }
  1082. .container {
  1083. background: #fff;
  1084. }
  1085. </style>