index.vue 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <template>
  2. <div class="subPage">
  3. <div class="selectCase">
  4. <el-select v-model="postData.caseid" placeholder="请选择" @change="caseChange">
  5. <el-option
  6. v-for="item in cases"
  7. :key="item.CaseId"
  8. :label="item.CaseName"
  9. :value="item.CaseId">
  10. </el-option>
  11. </el-select>
  12. </div>
  13. <div class="flex-h" v-for="(item,index) in pageData" v-if="pageData.length" :key="index">
  14. <div class="flex-item" v-for="(subItem,subIndex) in item" :key="subIndex" :class="{'listMargin' : subItem.type === 'dashboardList'}">
  15. <div v-if="subItem.type === 'dashboardList'">
  16. <dashboardList :data="subItem" :index="subIndex"></dashboardList>
  17. </div>
  18. <div v-if="subItem.type === 'histogram' && typeof(subItem.value) === 'object' && subItem.value.length">
  19. <histogram :data="subItem" :index="index + '-' + subIndex"></histogram>
  20. </div>
  21. <div v-if="subItem.type === 'pieDiagram' && typeof(subItem.value) === 'object' && subItem.value.length">
  22. <pieDiagram :data="subItem" :index="index + '-' + subIndex"></pieDiagram>
  23. </div>
  24. <div v-if="subItem.type === 'brokenLineGraph' && typeof(subItem.value) === 'object' && subItem.value.length">
  25. <brokenLineGraph :data="subItem" :index="index + '-' + subIndex"></brokenLineGraph>
  26. </div>
  27. <div v-if="subItem.type === 'ringChart' && typeof(subItem.value) === 'object' && subItem.value.length">
  28. <ringChart :data="subItem" :index="index + '-' + subIndex"></ringChart>
  29. </div>
  30. <div v-if="subItem.type === 'dashboard' && typeof(subItem.value) === 'object' && subItem.value.length">
  31. <dashboard :data="subItem" :index="index + '-' + subIndex"></dashboard>
  32. </div>
  33. <div v-if="subItem.type === 'brokenLineGraphGroup' && typeof(subItem.value) === 'object' && subItem.value.length">
  34. <brokenLineGraphGroup :data="subItem" :index="index + '-' + subIndex"></brokenLineGraphGroup>
  35. </div>
  36. </div>
  37. </div>
  38. <div class="bottomData">
  39. <div class="flex-h">
  40. <div class="flex-item">
  41. <h1>数据统计</h1>
  42. </div>
  43. <el-select v-model="bottomSelectValue" placeholder="请选择" @change="bottomChange">
  44. <el-option
  45. v-for="item in bottomSelect"
  46. :key="item.id"
  47. :label="item.value"
  48. :value="item.id">
  49. </el-option>
  50. </el-select>
  51. </div>
  52. <ul>
  53. <li v-for="(item,index) in bottomNav" :key="index" :class="{'active': bottomActive === index}" @click="bottomActive = index">{{item}}</li>
  54. </ul>
  55. <div style="height: 400px;" v-if="bottomData.length">
  56. <div v-for="(item,index) in bottomData" :key="index" v-if="bottomActive === index && bottomData.length">
  57. <brokenLineGraph :data="item.data" :index="'bottomData-' + index"></brokenLineGraph>
  58. </div>
  59. </div>
  60. </div>
  61. </div>
  62. </template>
  63. <script>
  64. import { mapState, createNamespacedHelpers } from 'vuex'
  65. import dashboardList from '../../../components/dashboardList/index'
  66. import histogram from '../../../components/histogram/index'
  67. import pieDiagram from '../../../components/pieDiagram/index'
  68. import brokenLineGraph from '../../../components/brokenLineGraph/index'
  69. import ringChart from '../../../components/ringChart/index'
  70. import dashboard from '../../../components/dashboard/index'
  71. import brokenLineGraphGroup from '../../../components/brokenLineGraphGroup/index'
  72. const { mapActions: mapStaActions } = createNamespacedHelpers('sta')
  73. export default {
  74. name: '',
  75. data () {
  76. return {
  77. postData: {
  78. caseid: ''
  79. },
  80. bottomSelect: [{
  81. value: '最近一周',
  82. id: 'week'
  83. }, {
  84. value: '最近一个月',
  85. id: 'month'
  86. }],
  87. bottomSelectValue: 'week',
  88. bottomActive: 0,
  89. bottomNav: ['推荐会员新增', '排课数', '课程预约量', '饮品下单量', '到场人次'],
  90. bottomData: [],
  91. pageData: [
  92. [
  93. { type: 'dashboardList', remark: '列表面板', data: { title: '', list: [{ name: '会员总数', value: '1000', }, { name: '课程预约总量', value: '1000', }, { name: '饮品下单总量', value: '1000', }] } }
  94. ],
  95. [
  96. { type: 'histogram', remark: '柱状图', data: { title: '今日数据', list: [{ x: '推荐会员新增', y: 38 }, { x: '课程数', y: 52 }, { x: '预约数', y: 61 }, { x: '到场人次', y: 145 }] } },
  97. { type: 'pieDiagram', remark: '扇形图', data: { title: '明日课程预约数据', list: [{ item: '小小体验官', count: 40, percent: 0.4 }, { item: '哈他瑜伽', count: 52, percent: 0.52 }, { item: '小小飞行家', count: 8, percent: 0.08 }] } }
  98. ],
  99. [
  100. { type: 'brokenLineGraph', remark: '折线图', data: { title: '下单饮品数据', list: [{ x: '09/05', y: 3 }, { x: '09/06', y: 4 }, { x: '09/07', y: 3.5 }, { x: '09/08', y: 5 }, { x: '09/09', y: 4.9 }, { x: '09/10', y: 6 }, { x: '09/11', y: 7 }, { x: '09/12', y: 9 }, { x: '09/13', y: 13 }] } },
  101. { type: 'ringChart', remark: '环形图', data: { title: '本月课程预约', list: [{ item: '健身课程', count: 40, percent: 0.4 }, { item: '社交课程', count: 21, percent: 0.21 }, { item: '教育课程', count: 17, percent: 0.17 }, { item: '健康课程', count: 13, percent: 0.13 }, { item: '艺术课程', count: 9, percent: 0.09 }] } },
  102. ],
  103. [
  104. { type: 'dashboard', remark: '仪表盘', data: { title: '参与率', list: [{ value: 5.6 }] } },
  105. { type: 'dashboard', remark: '仪表盘', data: { title: '参与率', list: [{ value: 3.1 }] } },
  106. ],
  107. [
  108. { type: 'brokenLineGraphGroup', remark: '折线图组合', data: { title: '下单饮品数据', list: [{ month: 'Jan', city: 'Tokyo', temperature: 7 }, { month: 'Jan', city: 'London', temperature: 3.9 }, { month: 'Feb', city: 'Tokyo', temperature: 6.9 }, { month: 'Feb', city: 'London', temperature: 4.2 }, { month: 'Mar', city: 'Tokyo', temperature: 9.5 }, { month: 'Mar', city: 'London', temperature: 5.7 }, { month: 'Apr', city: 'Tokyo', temperature: 14.5 }, { month: 'Apr', city: 'London', temperature: 8.5 }, { month: 'May', city: 'Tokyo', temperature: 18.4 }, { month: 'May', city: 'London', temperature: 11.9 }, { month: 'Jun', city: 'Tokyo', temperature: 21.5 }, { month: 'Jun', city: 'London', temperature: 15.2 }, { month: 'Jul', city: 'Tokyo', temperature: 25.2 }, { month: 'Jul', city: 'London', temperature: 17 }, { month: 'Aug', city: 'Tokyo', temperature: 26.5 }, { month: 'Aug', city: 'London', temperature: 16.6 }, { month: 'Sep', city: 'Tokyo', temperature: 23.3 }, { month: 'Sep', city: 'London', temperature: 14.2 }, { month: 'Oct', city: 'Tokyo', temperature: 18.3 }, { month: 'Oct', city: 'London', temperature: 10.3 }, { month: 'Nov', city: 'Tokyo', temperature: 13.9 }, { month: 'Nov', city: 'London', temperature: 6.6 }, { month: 'Dec', city: 'Tokyo', temperature: 9.6 }, { month: 'Dec', city: 'London', temperature: 4.8 }] } },
  109. ],
  110. ],
  111. }
  112. },
  113. components: {
  114. dashboardList,
  115. histogram,
  116. pieDiagram,
  117. brokenLineGraph,
  118. ringChart,
  119. dashboard,
  120. brokenLineGraphGroup,
  121. },
  122. computed: {
  123. ...mapState({
  124. cases: x => x.app.cases.list,
  125. defaultCaseId: x => x.app.cases.belongCase,
  126. user: x => x.app.user
  127. }),
  128. CaseId: {
  129. get () {
  130. return this.postData.caseid || this.defaultCaseId || this.cases[0].CaseId
  131. },
  132. set (val) {
  133. this.postData.caseid = val
  134. }
  135. }
  136. },
  137. watch: {
  138. defaultCaseId: function (val) {
  139. if (!this.postData.caseid) {
  140. this.postData.caseid = val
  141. }
  142. this.getData(val)
  143. this.getBottomData(val, this.bottomSelectValue)
  144. },
  145. },
  146. mounted () {
  147. this.$nextTick(function () {
  148. if (this.defaultCaseId !== null) {
  149. this.getData(this.defaultCaseId)
  150. this.getBottomData(this.defaultCaseId, this.bottomSelectValue)
  151. }
  152. })
  153. },
  154. methods: {
  155. ...mapStaActions([
  156. 'getDashboardData',
  157. 'getDashboardBottomData',
  158. ]),
  159. bottomChange () {
  160. this.getBottomData(this.postData.caseid, this.bottomSelectValue)
  161. },
  162. caseChange () {
  163. this.getData(this.postData.caseid)
  164. this.getBottomData(this.postData.caseid, this.bottomSelectValue)
  165. },
  166. getData (id) {
  167. this.pageData = []
  168. this.getDashboardData({
  169. caseid: id
  170. }).then((res) => {
  171. res = res || []
  172. for (var n = 0; n < res.length; n++) {
  173. this.pageData.push([])
  174. for (var a = 0; a < res[n].length; a++) {
  175. if (res[n][a].type !== 'dashboardList' && res[n][a].value === null) res[n][a].value = []
  176. this.pageData[n].push(res[n][a])
  177. }
  178. }
  179. console.log(JSON.stringify(this.pageData))
  180. })
  181. },
  182. getBottomData (id, type) {
  183. this.bottomData = []
  184. this.getDashboardBottomData({
  185. caseid: id,
  186. statype: type
  187. }).then((res) => {
  188. for (var n = 0; n < res.length; n++) {
  189. this.bottomData.push({
  190. type: 'brokenLineGraph',
  191. remark: '折线图',
  192. data: {
  193. title: '',
  194. value: res[n]
  195. }
  196. })
  197. }
  198. console.log(JSON.stringify(this.bottomData))
  199. })
  200. },
  201. }
  202. }
  203. </script>
  204. <!-- Add "scoped" attribute to limit CSS to this component only -->
  205. <style lang="scss" scoped>
  206. @import "page.scss";
  207. .listMargin {
  208. margin-left: 20px;
  209. &:first-child {
  210. margin-left: 0;
  211. }
  212. }
  213. </style>