自定义若依首页展示的数据内容,并且每个租户能够自行配置
没实现之前的页面:
管理员配置展示信息(计数框选择入库、提交、核销、采集。折线图选发票数/转出数。):
首页+首页中的组件 代码:https://cloud.189.cn/web/share?code=MZfaQnqi6Nbm(访问码:0w36)
前端首页主页
<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">--> <!-- <!–雷达图–>--> <!-- <el-col :xs="24" :sm="24" :lg="8">--> <!-- <div class="chart-wrapper">--> <!-- <raddar-chart />--> <!-- </div>--> <!-- </el-col>--> <!-- <!–饼状图–>--> <!-- <el-col :xs="24" :sm="24" :lg="8">--> <!-- <div class="chart-wrapper">--> <!-- <pie-chart />--> <!-- </div>--> <!-- </el-col>--> <!-- <!–条形图–>--> <!-- <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>在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控制其是否渲染
比如折线图,原来的数据如下,这些是写死的,所以通过后端传入的数据改一下就行。折线图不是有两个标题吗,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"] },把上面固定的数据通过后端传过来,就能实现租户自定义了
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} }) } 租户配置的页面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>data
data{ checkboxGroup: [], }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的数据长这个样子
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); }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 */ @Override public 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 */ @Override public 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; }工具类
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); } }