目录
- 需求
- 实现效果
- 主要代码
-
- 前端首页
- 面板组组件:
- 折线图组件:
- 详细解释
-
-
-
- 面板组
- 折线图
- 关于他们底下的数据
-
-
- 后端传来的json参考
- 租户配置的页面
-
- 后端,这里做个参考就好,每个项目都不一样,就是把数据返回前端,样子就是json上那个样子
关键词:Vue;若依管理系统;实现管理员配置 首页计数框/折线图 数据
需求
自定义若依首页展示的数据内容,并且每个租户能够自行配置
没实现之前的页面:
实现效果
管理员配置展示信息(计数框选择入库、提交、核销、采集。折线图选发票数/转出数。):
效果(页面展示与用户设置的选择相同):
主要代码
首页+首页中的组件 代码: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控制其是否渲染
可以看到这里面都用了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",
}
- 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的数据长这个样子
后端,这里做个参考就好,每个项目都不一样,就是把数据返回前端,样子就是json上那个样子
- 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);
}
}