目录

  • 需求
  • 实现效果
  • 主要代码
    • 前端首页
    • 面板组组件:
    • 折线图组件:
  • 详细解释
      • 面板组
      • 折线图
    • 关于他们底下的数据
  • 后端传来的json参考
  • 租户配置的页面
    • 后端,这里做个参考就好,每个项目都不一样,就是把数据返回前端,样子就是json上那个样子

关键词:Vue;若依管理系统;实现管理员配置 首页计数框/折线图 数据

需求

自定义若依首页展示的数据内容,并且每个租户能够自行配置
没实现之前的页面:

实现效果

管理员配置展示信息(计数框选择入库、提交、核销、采集。折线图选发票数/转出数。):

效果(页面展示与用户设置的选择相同):

主要代码

首页+首页中的组件 代码:https://cloud.189.cn/web/share?code=MZfaQnqi6Nbm(访问码:0w36)

前端首页

  1. 主页
<template><div className="dashboard-editor-container"><panel-group @handleSetLineChartData="handleSetLineChartData":count01="countList.count01":count-t0="countList.countT0":count-s0="countList.countS0":count05="countList.count05":count10="countList.count10":count15="countList.count15":count20="countList.count20":count25="countList.count25"/><!--折线图--><el-row style="background:#fff; padding:16px 16px 0; margin-bottom:32px;"><line-chart :chart-data="lineChartData" /></el-row><!--用不到的几个,因为我只用到了计数框和折线图,其他就不让显示了-->
<!--    <el-row :gutter="32">-->
<!--      &lt;!&ndash;雷达图&ndash;&gt;-->
<!--      <el-col :xs="24" :sm="24" :lg="8">-->
<!--        <div class="chart-wrapper">-->
<!--          <raddar-chart />-->
<!--        </div>-->
<!--      </el-col>-->
<!--      &lt;!&ndash;饼状图&ndash;&gt;-->
<!--      <el-col :xs="24" :sm="24" :lg="8">-->
<!--        <div class="chart-wrapper">-->
<!--          <pie-chart />-->
<!--        </div>-->
<!--      </el-col>-->
<!--      &lt;!&ndash;条形图&ndash;&gt;-->
<!--      <el-col :xs="24" :sm="24" :lg="8">-->
<!--        <div class="chart-wrapper">-->
<!--          <bar-chart />-->
<!--        </div>-->
<!--      </el-col>-->
<!--    </el-row>--></div>
</template><script>
import {getConfigInfo,getIndexLinechartData,getIndexLinechartDataByMonth,getIndexSelectBoxCount01,getIndexSelectBoxCount05,getIndexSelectBoxCount10,getIndexSelectBoxCount15,getIndexSelectBoxCount20,getIndexSelectBoxCount25,getIndexSelectBoxCountS0,getIndexSelectBoxCountT0
} from "@/api/index";
// 面板组
import PanelGroup from './dashboard/PanelGroup'
// 折线图
import LineChart from './dashboard/LineChart'
// 雷达图
import RaddarChart from './dashboard/RaddarChart'
// 饼状图
import PieChart from './dashboard/PieChart'
// 条形图
import BarChart from './dashboard/BarChart'export default {name: 'Index',components: {PanelGroup,LineChart,RaddarChart,PieChart,BarChart},data() {return {/** 当前配置信息,这里是存放获取的租户管理员配置的展示信息 */config: {},/** 面板组,该用户配置的计数列表,这里你显示什么需要先定义 */countList: {count01: null,countT0: null,countS0: null,count05: null,count10: null,count15: null,count20: null,count25: null,},// 该用户选择的面板组(数组)selected: null,/** 折线图 */lineChartData: {expectedData: [200, 192, 120, 144, 160, 130, 140],actualData: [180, 160, 151, 106, 145, 150, 130],dateData: ["1", "2", "3", "4", "5", "6", "7"]},}},created() {/** 2022-5-31,初始化租户参数 */this.configInfo();},methods: {/** 2022-5-27,获取接口参数信息,这里是配置的,我做了管理员选项,让每个租户管理自己选要展示的框 */configInfo(){getConfigInfo().then(response => {this.config = response.data;this.selected = this.config.selectBoxCount.split(",");/** 2022-5-31,获取面板组框:获取该租户设置了展示哪几个计数框 */this.check(this.selected);/** 2022-5-31,获取折线图数据 */this.getLinechardData();});},/** 判断当前选中了那些,注:这是面板组的,getIndexSelectBoxCount01-xx,这些方法是每个框各自获取自己的框的数据,因为是配置的,就分别获取的 */check(selected) {for (const s of selected) {switch (s) {case "01":getIndexSelectBoxCount01().then(response => {this.countList.count01 = parseInt(response.data);});break;case "S0":getIndexSelectBoxCountS0().then(response => {this.countList.countT0 = parseInt(response.data);});break;case "T0":getIndexSelectBoxCountT0().then(response => {this.countList.countS0 = parseInt(response.data);});break;case "05":getIndexSelectBoxCount05().then(response => {this.countList.count05 = parseInt(response.data);});break;case "10":getIndexSelectBoxCount10().then(response => {this.countList.count10 = parseInt(response.data)});break;case "15":getIndexSelectBoxCount15().then(response => {this.countList.count15 = parseInt(response.data);});break;case "20":getIndexSelectBoxCount20().then(response => {this.countList.count20 = parseInt(response.data);});break;case "25":getIndexSelectBoxCount25().then(response => {this.countList.count25 = parseInt(response.data);});break;}}},/** 获取折现图的数据,这里也是管理员可配置,所以用到了判断 */getLinechardData() {getIndexLinechartDataByMonth(this.config.selectLine).then(response => {this.lineChartData = response.data;// 当前租户设置中选择展示的折线图(1:第一种,2:第二种)if (this.config.selectLine === '1') {this.lineChartData.selectName = ['发票数','核销数']} else {this.lineChartData.selectName = ['发票数','转出数']}})},// 调用变化线型图,给4个数据卡片调用的,卡片调用的时候就加载卡片传过来的数据handleSetLineChartData(type) {// 根据子集的调用切换对应的数据// this.lineChartData = lineChartData[type]},}
}
</script><style lang="scss" scoped>
.dashboard-editor-container {padding: 32px;background-color: rgb(240, 242, 245);position: relative;.chart-wrapper {background: #fff;padding: 16px 16px 0;margin-bottom: 32px;}
}@media (max-width: 1024px) {.chart-wrapper {padding: 8px;}
}
</style>
  1. 在webStorm找到src/views/dashboard,里面就是首页这几个组件

面板组组件:

<template><el-row :gutter="40" class="panel-group"><el-col v-show="count01 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-people"><svg-icon icon-class="nested" class-name="card-panel-icon"/></div><div class="card-panel-description"><div class="card-panel-text">入库</div><count-to :start-val="0" :end-val="count01" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="countT0 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-message"><svg-icon icon-class="nested" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">提交</div><count-to :start-val="0" :end-val="countT0" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="countS0 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-money"><svg-icon icon-class="post" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">核销</div><count-to :start-val="0" :end-val="countS0" :duration="3200" class="card-panel-num" /></div></div></el-col><el-col v-show="count05 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="xy-choice2" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">采集</div><count-to :start-val="0" :end-val="count05" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="count10 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="nested" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">认证提交</div><count-to :start-val="0" :end-val="count10" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="count15 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="nested" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">验收</div><count-to :start-val="0" :end-val="count15" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="count20 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="nested" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">认证</div><count-to :start-val="0" :end-val="count20" :duration="2600" class="card-panel-num" /></div></div></el-col><el-col v-show="count25 != null" :xs="12" :sm="12" :lg="6" class="card-panel-col"><div class="card-panel"><div class="card-panel-icon-wrapper icon-shopping"><svg-icon icon-class="nested" class-name="card-panel-icon" /></div><div class="card-panel-description"><div class="card-panel-text">转出</div><count-to :start-val="0" :end-val="count25" :duration="2600" class="card-panel-num" /></div></div></el-col></el-row>
</template><script>
import CountTo from 'vue-count-to'export default {props:{count01: {type: Number, default: 0},countT0: {type: Number, default: 0},countS0: {type: Number, default: 0},count05: {type: Number, default: 0},count10: {type: Number, default: 0},count15: {type: Number, default: 0},count20: {type: Number, default: 0},count25: {type: Number, default: 0},},components: {CountTo}
}
</script><style lang="scss" scoped>
.panel-group {margin-top: 18px;.card-panel-col {margin-bottom: 32px;}.card-panel {height: 108px;font-size: 12px;position: relative;overflow: hidden;color: #666;background: #fff;box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);border-color: rgba(0, 0, 0, .05);&:hover {.card-panel-icon-wrapper {color: #fff;}.icon-people {background: #40c9c6;}.icon-message {background: #36a3f7;}.icon-money {background: #f4516c;}.icon-shopping {background: #34bfa3}}.icon-people {color: #40c9c6;}.icon-message {color: #36a3f7;}.icon-money {color: #f4516c;}.icon-shopping {color: #34bfa3}.card-panel-icon-wrapper {float: left;margin: 14px 0 0 14px;padding: 16px;transition: all 0.38s ease-out;border-radius: 6px;}.card-panel-icon {float: left;font-size: 48px;}.card-panel-description {float: right;font-weight: bold;margin: 26px;margin-left: 0px;.card-panel-text {line-height: 18px;color: rgba(0, 0, 0, 0.45);font-size: 16px;margin-bottom: 12px;}.card-panel-num {font-size: 20px;}}}
}@media (max-width:550px) {.card-panel-description {display: none;}.card-panel-icon-wrapper {float: none !important;width: 100%;height: 100%;margin: 0 !important;.svg-icon {display: block;margin: 14px auto !important;float: none !important;}}
}
</style>

折线图组件:

<template><div :class="className" :style="{height:height,width:width}" />
</template><script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'export default {mixins: [resize],props: {className: {type: String,default: 'chart'},width: {type: String,default: '100%'},height: {type: String,default: '350px'},autoResize: {type: Boolean,default: true},chartData: {type: Object,required: true,}},data() {return {chart: null,}},watch: {chartData: {deep: true,handler(val) {// console.log('触发了Line组件调用x轴初始化')this.setOptions(val)}}},mounted() {this.$nextTick(() => {this.initChart()})},created() {this.$nextTick(() => {this.initChart()})},beforeDestroy() {if (!this.chart) {return}this.chart.dispose()this.chart = null},methods: {initChart() {this.chart = echarts.init(this.$el, 'macarons')this.setOptions(this.chartData)},setOptions({ dateData, firstData, secondData, selectName } = {}) {this.chart.setOption({xAxis: {data: dateData,boundaryGap: false,axisTick: {show: false}},grid: {left: 10,right: 10,bottom: 20,top: 30,containLabel: true},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'},padding: [5, 10]},yAxis: {axisTick: {show: false}},legend: {// data: ['发票数', '核销数']data: selectName},// 图表描述series: [{name: selectName?.[0], itemStyle: {normal: {color: '#FF005A',lineStyle: {color: '#FF005A',width: 2}}},// 柔性过过渡smooth: true,type: 'line',data: firstData,animationDuration: 2800,animationEasing: 'cubicInOut'},{name: selectName?.[1],smooth: true,type: 'line',itemStyle: {normal: {color: '#3888fa',lineStyle: {color: '#3888fa',width: 2},areaStyle: {color: '#f3f8ff'}}},data: secondData,animationDuration: 2800,animationEasing: 'quadraticOut'}]})}}
}
</script>

详细解释

面板组

大概说一下,实现面板组的话,需要先在组件里面写好,你都要有哪些框,先在页面写好,通过v-show控制其是否渲染

可以看到这里面都用了v-show,之后如果管理员没有选中的话,返回到前端肯定是null,那样就不会显示了,从而实现根据配置展示

折线图


这个方法,就是对应首页的折线图的标题。data: [‘发票数’, ‘核销数’]这样标题就是固定的,为了实现需求,我们需要通过后端传过来,这个selectName就是折线图的标题数组

首页把这个selectName传递给组件

这是用到了父传子,可以看到:chart-data=“lineChartData”,将父组件的数据传给了折线图组件

关于他们底下的数据

比如折线图,原来的数据如下,这些是写死的,所以通过后端传入的数据改一下就行。折线图不是有两个标题吗,firstData:就是第一个标题的数值;secondData:就是第二个标题的;dateData:就是底下的数(天数)

lineChartData: {firstData: [200, 192, 120, 144, 160, 130, 140],secondData: [180, 160, 151, 106, 145, 150, 130],dateData: ["1", "2", "3", "4", "5", "6", "7"]},

把上面固定的数据通过后端传过来,就能实现租户自定义了

这块就是后端返回的数据,赋值给了这些数据:

后端传来的json参考

面板组
{"msg":"操作成功","code":200,"data":"0"}
折线图
{"msg": "获取数据成功!","code": 200,"data": {"dateData": ["2021-07","2021-08","2021-09","2021-10","2021-11","2021-12","2022-01","2022-02","2022-03","2022-04","2022-05","2022-06","本月"],"firstData": ["0","0","0","0","0","0","0","0","0","0","0","0","0"],"secondData": ["0","0","0","0","0","0","0","0","0","0","0","0","0"]}
}
管理员配置的
{"selectBoxCount": "05,01,S0,T0","selectLine": "2",
}
  1. js
/*** 2022-5-27,获取接口参数*/
export function getConfigInfo(){return request({url: 'invoice/invoice/getConfigInfo',method: 'get',})
}
/*** 2022-5-27,首页展示面板图*/
export function getIndexSelectBoxCount01(){return request({url: 'invoice/invoice/getIndexSelectBoxCount01',method: 'get',})
}
export function getIndexSelectBoxCountS0(){return request({url: 'invoice/invoice/getIndexSelectBoxCountS0',method: 'get',})
}
export function getIndexSelectBoxCountT0(){return request({url: 'invoice/invoice/getIndexSelectBoxCountT0',method: 'get',})
}
export function getIndexSelectBoxCount05(){return request({url: 'invoice/invoice/getIndexSelectBoxCount05',method: 'get',})
}
export function getIndexSelectBoxCount10(){return request({url: 'invoice/invoice/getIndexSelectBoxCount10',method: 'get',})
}
export function getIndexSelectBoxCount15(){return request({url: 'invoice/invoice/getIndexSelectBoxCount15',method: 'get',})
}
export function getIndexSelectBoxCount20(){return request({url: 'invoice/invoice/getIndexSelectBoxCount20',method: 'get',})
}
export function getIndexSelectBoxCount25(){return request({url: 'invoice/invoice/getIndexSelectBoxCount25',method: 'get',})
}//查询首页折线图 当前周数据
export function getIndexLinechartData(){return request({url: '/invoice/invoice/getindexlinechart',method: 'get'})
}//查询首页折线图 当年数据
export function getIndexLinechartDataByMonth(query){return request({url: '/invoice/invoice/getIndexLineChartByMonth',method: 'get',params: {type: query}})
}

租户配置的页面

  1. template
        <!--首页参数--><el-col :span="24"><el-divider content-position="center">首页参数</el-divider></el-col><el-col :span="24"><label style="display: flex;margin-bottom: 20px">首页中展示的计数框</label><el-checkbox-group v-model="checkboxGroup" :min="1" :max="4" size="small" @change="handleUpdateCheck"><el-col :span="24"><el-checkbox label="入库" border></el-checkbox><el-checkbox label="提交" border></el-checkbox><el-checkbox label="核销" border></el-checkbox></el-col><el-col :span="24" style="display: flex; margin-top: 5px"><el-checkbox label="采集" border></el-checkbox><el-checkbox label="认证提交" border></el-checkbox><el-checkbox label="验收" border></el-checkbox><el-checkbox label="认证" border></el-checkbox><el-checkbox label="转出" border></el-checkbox></el-col></el-checkbox-group></el-col><el-col :span="24"><label style="display: flex;margin-bottom: 20px; margin-top: 20px">首页中展示的折线图</label><el-col :span="24"><el-radio-group v-model="form.selectLine" size="small" @change="handleUpdateLineCheck"><el-radio label="1" border>发票数/核销数</el-radio><el-radio label="2" border>发票数/转出数</el-radio></el-radio-group></el-col></el-col>
  1. data
data{checkboxGroup: [],
}
  1. methods
methods: {/** 2022-5-27,kxb,获得并计算当前选中的首页计数框的值 */setSelectCountBox(v){this.checkboxGroup = [];for (let node of v) {if (node === "01") this.checkboxGroup.push("入库");if (node === "S0") this.checkboxGroup.push("提交");if (node === "T0") this.checkboxGroup.push("核销");if (node === "05") this.checkboxGroup.push("采集");if (node === "10") this.checkboxGroup.push("认证提交");if (node === "15") this.checkboxGroup.push("验收");if (node === "20") this.checkboxGroup.push("认证");if (node === "25") this.checkboxGroup.push("转出");}},// 多选框改变调用handleUpdateCheck(checkeds){let str = "";for (let check of checkeds) {switch (check) {case "入库":str === "" ? str = "01" : str += ",01"break;case "提交":str === "" ? str = "S0" : str += ",S0"break;case "核销":str === "" ? str = "T0" : str += ",T0"break;case "采集":str === "" ? str = "05" : str += ",05"break;case "认证提交":str === "" ? str = "10" :  str += ",10"break;case "验收":str === "" ? str = "15" : str += ",15"break;case "认证":str === "" ? str = "20" : str += ",20"break;case "转出":str === "" ? str = "25" : str += ",25"break;}}this.form.selectBoxCount = str;},handleUpdateLineCheck(checked){this.form.selectLine = checked.toString();},
}

存到sql的数据长这个样子

后端,这里做个参考就好,每个项目都不一样,就是把数据返回前端,样子就是json上那个样子

  1. controller
/*** 2022-5-27,获取当前用户展示的显示框的信息。区别:根据后缀01、S0、T0来区分*/// 获取接口参数@GetMapping("getConfigInfo")public AjaxResult getConfigInfo(){YsIvInterfacelinemsg ysIvInterfacelinemsg = ysIvInterfacelinemsgService.selectCurIvInterfaceLinemsg();RemoteYsIvInterfacelinemsg remoteYsIvInterfacelinemsg = new RemoteYsIvInterfacelinemsg();BeanUtils.copyBeanProp(remoteYsIvInterfacelinemsg, ysIvInterfacelinemsg);return AjaxResult.success(ysIvInterfacelinemsg);}// 入库@GetMapping("getIndexSelectBoxCount01")public AjaxResult getIndexSelectBoxCount01(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_NOTYET));}// 提交@GetMapping("getIndexSelectBoxCountS0")public AjaxResult getIndexSelectBoxCountS0(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_SUBMIT));}// 核销@GetMapping("getIndexSelectBoxCountT0")public AjaxResult getIndexSelectBoxCountT0(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_DESTROY));}// 采集@GetMapping("getIndexSelectBoxCount05")public AjaxResult getIndexSelectBoxCount05(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_CONFIRMED));}// 认证提交@GetMapping("getIndexSelectBoxCount10")public AjaxResult getIndexSelectBoxCount10(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT));}// 验收@GetMapping("getIndexSelectBoxCount15")public AjaxResult getIndexSelectBoxCount15(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_AUTH_CHECK));}// 认证@GetMapping("getIndexSelectBoxCount20")public AjaxResult getIndexSelectBoxCount20(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_AUTH));}// 转出@GetMapping("getIndexSelectBoxCount25")public AjaxResult getIndexSelectBoxCount25(){return AjaxResult.success(ysInvoiceService.getIndexSelectBoxCount(InvoiceConstants.OPERATE_STATUS_TRANSFER));}/** 获取折线图数据 */@GetMapping("/getIndexLineChartByMonth")public AjaxResult getIndexLineChart(@RequestParam String type){Map<String,Object> map = ysInvoiceService.getOrSetLineCountByRedis(type);return AjaxResult.success("获取数据成功!", map);}
  1. service
    /*** 2022-5-27,获取最上方的采集、提交等等的数量* @return*/public Long getIndexSelectBoxCount(String status){ArrayList<String> condition = new ArrayList<>();switch (status){case InvoiceConstants.OPERATE_STATUS_NOTYET:// 入库过condition.add(InvoiceConstants.OPERATE_STATUS_NOTYET);condition.add(InvoiceConstants.OPERATE_STATUS_SUBMIT);condition.add(InvoiceConstants.OPERATE_STATUS_DESTROY);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_NOTYET, condition);case InvoiceConstants.OPERATE_STATUS_SUBMIT:// 提交过condition.add(InvoiceConstants.OPERATE_STATUS_NOTYET);condition.add(InvoiceConstants.OPERATE_STATUS_SUBMIT);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_SUBMIT, condition);case InvoiceConstants.OPERATE_STATUS_DESTROY:// 核销过condition.add(InvoiceConstants.OPERATE_STATUS_DESTROY);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_DESTROY,condition);case InvoiceConstants.OPERATE_STATUS_CONFIRMED:// 采集过condition.add(InvoiceConstants.OPERATE_STATUS_CONFIRMED);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_CHECK);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH);condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_CONFIRMED, condition);case InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT:// 认证提交过condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_CHECK);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH);condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT, condition);case InvoiceConstants.OPERATE_STATUS_AUTH_CHECK:// 验收过condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_CHECK);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH);condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);case InvoiceConstants.OPERATE_STATUS_AUTH:// 认证过condition.add(InvoiceConstants.OPERATE_STATUS_AUTH);condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_AUTH, condition);case InvoiceConstants.OPERATE_STATUS_TRANSFER:// 转出过condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);return getOrSetBoxCountByRedis(InvoiceConstants.OPERATE_STATUS_TRANSFER, condition);}return 0L;}/*** 通过redis获取,或存到redis* @param status* @return*/private Long getOrSetBoxCountByRedis(String status, ArrayList<String> condition){String key = "index_SelectBox:" + SecurityUtils.getEnterpriseId();// 1.如果缓存存在,则从缓存取if (RedisHashUtils.hExist(key,status)) {return (Long) RedisHashUtils.hGet(key, status);}// 2.如果缓存不存在,则从数据库取YsInvoice invoice = new YsInvoice();invoice.getParams().put("operateStatus",condition);Long value = ysInvoiceMapper.selectBoxCount(invoice);RedisHashUtils.hSetExpireOneDay(key, status, value);return value;}/*** 获取首页折线图数据 最近7天发票数据* invoiceData:[],* destroyedData:[],* dateData:[]** @return*/@Overridepublic Map<String, Object> getIndexLineChartByMonth(String type) {Map<String, Object> dataMap = new LinkedHashMap<>();List<String> dateData = new ArrayList<>();List<Long> fisstDataList = new ArrayList<>();List<Long> secondDataList = new ArrayList<>();Long enterpriseId = SecurityUtils.getEnterpriseId();for (int i = 12; i >= 0; i--) {String month = DateUtils.getNowBeforeMonthStr2(i);if (i == 0) {dateData.add("本月");} else {dateData.add(month);}// 1.查询当前发票数YsInvoice invoice = new YsInvoice();ArrayList<String> condition = new ArrayList<>();// 2.查询当前核销数/转出数Long first = 0L;Long second = 0L;if ("1".equals(type)) {condition.add(InvoiceConstants.OPERATE_STATUS_NOTYET);condition.add(InvoiceConstants.OPERATE_STATUS_SUBMIT);condition.add(InvoiceConstants.OPERATE_STATUS_DESTROY);invoice.getParams().put("operateStatus", condition);invoice.getParams().put("startDate", month + "-01");invoice.getParams().put("endDate",month + "-31");first = ysInvoiceMapper.selectLineCount(invoice);second = ysInvoiceLogMapper.selectByTypeBetween(InvoiceConstants.OPERATE_STATUS_DESTROY,month + "-01",month + "-31", enterpriseId);} else if ("2".equals(type)) {condition.add(InvoiceConstants.OPERATE_STATUS_NOTYET);condition.add(InvoiceConstants.OPERATE_STATUS_CONFIRMED);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_SUBMIT);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH_CHECK);condition.add(InvoiceConstants.OPERATE_STATUS_AUTH);condition.add(InvoiceConstants.OPERATE_STATUS_TRANSFER);invoice.getParams().put("operateStatus", condition);invoice.getParams().put("startDate", month + "-01");invoice.getParams().put("endDate",month + "-31");first = ysInvoiceMapper.selectLineCount(invoice);second = ysInvoiceLogMapper.selectByTypeBetween(InvoiceConstants.OPERATE_STATUS_TRANSFER,month + "-01",month + "-31", enterpriseId);}fisstDataList.add(first);secondDataList.add(second);}dataMap.put("dateData", dateData);dataMap.put("firstData", fisstDataList);dataMap.put("secondData", secondDataList);return dataMap;}/*** 获取当前折线图的数据或从redis获取* @param type 当前用户选择的类型* @return*/@Overridepublic Map<String, Object> getOrSetLineCountByRedis(String type){String key = "index_SelectLine:" + SecurityUtils.getEnterpriseId();// 1.如果缓存存在,则从缓存取if (RedisHashUtils.hExist(key,type)) {return (Map<String, Object>) RedisHashUtils.hGet(key, type);}// 2.如果缓存不存在,则从数据库取Map<String, Object> map = getIndexLineChartByMonth(type);// 当前日期到当月最后一天的秒数LocalDateTime midnight = LocalDateTime.now().plusMonths(1).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);long between = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);RedisHashUtils.hSetExpireOneMonth(key, type, map, between);return map;}
  1. 工具类
public class RedisHashUtils {private final static RedisService redisService = SpringUtils.getBean(RedisService.class);/*** 直接以map集合的方式添加key对应的值* @param key map中key已经存在,覆盖替换* @param map map中key不存在,新增* @return*/public static Boolean hmSet(final String key, Map map) {boolean result = false;try {redisService.redisTemplate.opsForHash().putAll(key, map);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 以map集合的方式添加key对应的值,并缓存一天时间*/public static Boolean hmSetExpireOneDay(final String key, Map map) {boolean result = false;try {redisService.redisTemplate.opsForHash().putAll(key, map);redisService.redisTemplate.expire(key, 1, TimeUnit.DAYS);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 新增hashMap值* @param key   为Redis的key* @param mapKey    为key对应的map值的key* @param value 为key对应的map值的值* @return*/public static Boolean hSet(String key, String mapKey, Object value){boolean result = false;try {redisService.redisTemplate.opsForHash().put(key, mapKey, value);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 新增hashMap值,并缓存一天时间*/public static Boolean hSetExpireOneDay(String key, String mapKey, Object value){boolean result = false;try {redisService.redisTemplate.opsForHash().put(key, mapKey, value);redisService.redisTemplate.expire(key, 86400, TimeUnit.SECONDS);result = true;} catch (Exception e) {e.printStackTrace();}return result;}public static Boolean hSetExpireOneMonth(String key, String mapKey, Object value, Long time){boolean result = false;try {redisService.redisTemplate.opsForHash().put(key, mapKey, value);redisService.redisTemplate.expire(key, time, TimeUnit.SECONDS);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 以hashMap集合的方式添加key对应的值,并缓存到指定的时间*/public static Boolean hSetExpireCustomize(final String key, String mapKey, Object value, Date date) {boolean result = false;try {redisService.redisTemplate.opsForHash().put(key, mapKey, value);redisService.redisTemplate.expireAt(key, date);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** 获取hash缓存* @param key   redis的key* @param filed hash的map的key* @return*/public static Object hGet(String key, Object filed) {return redisService.redisTemplate.opsForHash().get(key, filed);}/*** 当前key是否存在value*/public static Boolean hExist(String key, String mapName){return redisService.redisTemplate.opsForHash().hasKey(key, mapName);}/*** 以集合的方式获取这些键对应的map* @param key   redis的key* @param list  将hash中的key存到list当中查找* @return*/public static List HmultiGet(String key, List list) {return redisService.redisTemplate.opsForHash().multiGet(key, list);}/*** 删除整个对应key的redis数据*/public static Boolean DelAll(String key) {return redisService.redisTemplate.delete(key);}/*** 删除hash中某个对应key的数据* @param key  redis的key* @param filed key* @return*/public static Long HDelete(String key, Object filed){return redisService.redisTemplate.opsForHash().delete(key, filed);}/*** redis的hash自助工具:先判空,有数据就删除,重新写入;否则,直接写入* @param key redis的key* @param filed 数据的key* @param obj 数据的value*/public static void HelpMeSet(String key, Object filed, Object obj){if (RedisHashUtils.hExist(key, String.valueOf(filed))) {RedisHashUtils.HDelete(key, String.valueOf(filed));}RedisHashUtils.hSet(key, String.valueOf(filed), obj);}
}

Vue若依管理系统-实现管理员配置首页计数框/折线图相关推荐

  1. 【uniapp小程序】—— 配置首页搜索框

    面试专栏分享,感觉有用的小伙伴可以点个订阅,不定时更新相关面试题:面试专栏 . 文章目录

  2. 用 vue+elemnet ui实现仿有赞首页搜索框点击放大input并展开下拉盒子的动画效果

    静止时 点击时展开动画 html结构 <el-popover placement="bottom" title="最近搜过" width="28 ...

  3. Echarts 折线图完全配置指南 - 手把手教你设置 Echarts 折线图详细教程

    本文首发:<Echarts 折线图完全配置指南> Echarts 折线图是图表中最常用的显示形式之一.使用 Echarts 做出基本的折线图很简单,但要是想把多组数据放在一张图表中,展示的 ...

  4. 常用echart图表(柱状图、折线图、饼图、环形进度条、雷达图等等)基础配置和用法、resize()响应、轮播tooltip

    一.最简单的使用方式引入官方echart.js即可 <script src="js/echarts.js"></script> 二.页面准备一个DOM容器 ...

  5. 【Vue】后台管理系统

    O 项目说明 1.脚手架 vite vue-cli ==> webpack 2.vite脚手架使用 官网:https://vitejs.cn/ Vue3 vite官网:https://cn.vi ...

  6. 计算机毕业设计之java+springboot基于vue的人事管理系统-员工管理系统

    计算机毕业设计之java+springboot基于vue的人事管理系统-员工管理系统 项目介绍 系统权限按管理员和员工这两类涉及用户划分. (a)管理员:管理员使用本系统涉到的功能主要有:首页,个人中 ...

  7. 计算机毕业设计Node.js+Vue综合型体育场馆管理系统(程序+源码+LW+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue ...

  8. Java基于springboot+vue的电子相册管理系统 前后端分离node

    智能电子相册是一个可以永久保留记忆的东西,用户可以讲自己美好的一面展示在网络上,人更多的人了解到自己的生活,为此我们通过Java语言并结合springboot+vue开发了本次的电子相册管理系统,希望 ...

  9. 计算机毕业设计Node.js+Vue酒店住房管理系统(程序+源码+LW+部署)

    该项目含有源码.文档.程序.数据库.配套开发软件.软件安装教程.欢迎交流 项目运行 环境配置: Node.js+ Vscode + Mysql5.7 + HBuilderX+Navicat11+Vue ...

  10. Springboot+Vue成果统一管理系统

    文章目录 Springboot+Vue成果统一管理系统 一.项目简介 1.简介 2.项目结构 3.逻辑结构 4.开发环境 二.运行效果 1.用户界面 2,管理员界面 三.项目的结构 1.前端 2.后端 ...

最新文章

  1. 管理者如何打造一个有执行力的团队?
  2. 江苏省三级偏硬试题样卷
  3. SHELL脚本--简介
  4. 基于光线追踪的渲染中景深(Depth of field)效果的实现
  5. 关于Jquery EasyUI中的DataGrid服务器端分页随记
  6. Linux 下的几个游戏模拟器
  7. linux 定时任务,压缩 日志,并删除掉 指定日期之前的 日志
  8. 关于计算机硬盘属性对话框中,计算机文化基础练习题(2).docx
  9. Kubernetes 1.5安装
  10. android 如何实现连接蓝牙打印机来实现打印功能
  11. 遍历Java中的列表的方法
  12. Grails枚举一例
  13. 降压稳压器LM2596SX-ADJ技术参考
  14. matlab怎么做空间计量,六步学会用MATLAB做空间计量回归详细步骤
  15. 模型及贴图的细节及优化
  16. Spec2006使用说明
  17. 面试必问之JVM原理 1
  18. python数字水印嵌入与提取_基于LSB的图像数字水印实验
  19. mysql极客_极客mysql38
  20. mysql ud83cudf19__如何转义emoji表情,让它可以存入utf8的数据库?

热门文章

  1. CentOS下LVM的使用
  2. Android TV开发
  3. 基于蒙特卡洛方法的机器人工作空间MATLAB仿真
  4. 差点被一个截图忽悠了,分析一个QQ空间钓鱼网站
  5. SpringBoot 获取 Yml 配置 信息 Environment
  6. EDA 电子设计自动化VHDL系列课程8 – 脉冲信号发生器
  7. 风格迁移篇--StarGAN:用于多域图像到图像翻译的统一生成对抗网络
  8. Android系统预装Chrome并自定义主页
  9. Windows系统邮件中如何绑定QQ邮箱
  10. 程序员小助手 | Emacs,最强编辑器,没有之一