Authored by 王涛

Merge branch 'master-500-dev-lushangqing' into 'master-500-dev'

【无】操作记录日志页面搭建(50%) #1



See merge request !998
  1 +<title>操作日志</title>
  2 +<iframe class="layadmin-iframe" src="/vue3/index.html#/vue3/operationLog" style="height: 99.5%!important;"/>
@@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
11 @import "../css/cmdbdatasync.css"; 11 @import "../css/cmdbdatasync.css";
12 /*登录logo配置*/ 12 /*登录logo配置*/
13 @import "../css/logoConfig.css"; 13 @import "../css/logoConfig.css";
  14 +/*lsq 操作记录日志样式 2022-09-26*/
  15 +@import "../css/operationLog.css";
14 16
15 .d-flex { 17 .d-flex {
16 display: flex; 18 display: flex;
  1 +.operation-log-search{
  2 + display: flex;
  3 + align-items: center;
  4 + justify-content: center;
  5 + margin-top:6px;
  6 +}
  7 +.container-none{
  8 + width:100%;
  9 + height: 20px;
  10 + background:#fafafa;
  11 +}
  12 +.operation-log-container.container .cm-card .search-table{padding:15px;}
  13 +.echart-con{
  14 + padding:10px;
  15 +}
  16 +.echart-con .echart-title{
  17 + font-size: 16px;
  18 + color:#1e9fff;
  19 + text-align: left;
  20 + margin-bottom: 6px;
  21 + padding:10px;
  22 +}
  23 +.echart-left,.echart-right{
  24 + border:1px solid #eee;
  25 +}
  26 +.echart-chart{
  27 + height: 300px;
  28 +
  29 +}
@@ -178,6 +178,12 @@ const routes = [{ @@ -178,6 +178,12 @@ const routes = [{
178 name: 'thirdSet', 178 name: 'thirdSet',
179 component: () => myImport('views/thirdSet/index') 179 component: () => myImport('views/thirdSet/index')
180 }, 180 },
  181 + //操作日志
  182 + {
  183 + path: '/vue3/operationLog',
  184 + name: 'operationLog',
  185 + component: () => myImport('views/operationLog/index')
  186 + }
181 ]; 187 ];
182 188
183 // hash模式: createWebHashHistory 189 // hash模式: createWebHashHistory
  1 +<div :style="{'height':height+'px','max-height':height+'px'}" class="container operation-log-container">
  2 + <div :style="{'min-height':height+'px','max-height':height+'px','height':'100%'}" class="cm-card">
  3 + <el-row>
  4 + <el-col :span="14" class="search-item">
  5 + <div class="search">
  6 + <div class="operation-log-search">
  7 + <el-button-group class="ml-4">
  8 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 1 ? 'primary' : ''"
  9 + @click="getDataList(1)">用户名
  10 + </el-button>
  11 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 2 ? 'primary' : ''"
  12 + @click="getDataList(2)">巡检组
  13 + </el-button>
  14 + </el-button-group>
  15 + </div>
  16 + </div>
  17 + <div class="echart-con">
  18 + <div class="echart-left">
  19 + <div class="echart-title">巡检点击完成统计</div>
  20 + <div class="echart-chart">
  21 + <LineChart :optionData="optionData" v-if="optionData"></LineChart>
  22 + </div>
  23 + </div>
  24 + </div>
  25 +
  26 + </el-col>
  27 + <el-col :span="10">
  28 + <div class="search">
  29 + <div class="operation-log-search">
  30 + <el-button-group class="ml-4">
  31 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 'yesterday' ? 'primary' : ''"
  32 + @click="getDataList('yesterday')">昨天
  33 + </el-button>
  34 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 'today' ? 'primary' : ''"
  35 + @click="getDataList('today')">今天
  36 + </el-button>
  37 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 'lastWeek' ? 'primary' : ''"
  38 + @click="getDataList('lastWeek')">上周
  39 + </el-button>
  40 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 'thisWeek' ? 'primary' : ''"
  41 + @click="getDataList('thisWeek')">本周
  42 + </el-button>
  43 + <el-button :size="$global.elementConfig.size.button" :type="search.status == 'thisMonth' ? 'primary' : ''"
  44 + @click="getDataList('thisMonth')">本月
  45 + </el-button>
  46 + <el-button style="border-radius: 0;" :size="$global.elementConfig.size.button" :type="search.status == 'all' ? 'primary' : ''"
  47 + @click="getDataList('all')">全部
  48 + </el-button>
  49 + </el-button-group>
  50 + <el-date-picker
  51 + :size="$global.elementConfig.size.input"
  52 + style="width:150px;border-radius: 0 4px 4px 0;"
  53 + end-placeholder="结束日期"
  54 + format="YYYY-MM-DD"
  55 + range-separator="-"
  56 + start-placeholder="开始日期"
  57 + type="daterange"
  58 + v-model="search.dateTime"
  59 + value-format="YYYY-MM-DD"
  60 + :prefix-icon="'none'"
  61 + @focus="dateFocus"
  62 + @change="dateChange"
  63 + />
  64 + </div>
  65 + </div>
  66 + <div class="echart-con">
  67 + <div class="echart-right">
  68 + <div class="echart-title">人员功能点击量</div>
  69 + <div class="echart-chart">
  70 + <LineChart :optionData="optionDataR" v-if="optionDataR"></LineChart>
  71 + </div>
  72 + </div>
  73 + </div>
  74 +
  75 + </el-col>
  76 + </el-row>
  77 +
  78 + <div class="container-none"></div>
  79 + <div class="search-table">
  80 + <cm-table-page :columns="tableData.columns" :dataList="tableData.dataList"
  81 + :height="height - 110"
  82 + :loading="false"
  83 + :pageSize="pageSize"
  84 + :showBorder="true"
  85 + :showIndex="true"
  86 + :showPage="true"
  87 + :showSelection="false"
  88 + :showTools="false"
  89 + :total="tableData.count"
  90 + @loaddata="loaddata">
  91 + <template #default="{row,prop,column}">
  92 +
  93 + </template>
  94 + </cm-table-page>
  95 + </div>
  96 + </div>
  97 +</div>
  98 +
  99 +<!--新增编辑弹框-->
  100 +<cm-dialog :showDialogVisible="dialog.show" :showFooter="false" :title="dialog.title" @hidedialog="hideDialog">
  101 + <template v-slot>
  102 + </template>
  103 +</cm-dialog>
  104 +
  1 +export default {
  2 + name: 'operationLog',
  3 + template: '',
  4 + components: {
  5 + 'LineChart': Vue.defineAsyncComponent(
  6 + () => myImport('views/page/components/lineChart/index')
  7 + )
  8 + },
  9 + props: [],
  10 + setup(props, {attrs, slots, emit}) {
  11 + const {proxy} = Vue.getCurrentInstance();
  12 + let isView = Vue.ref(false);
  13 + let height = Vue.ref(window.innerHeight);
  14 + let optionData = Vue.ref('');
  15 + let optionDataR = Vue.ref('');
  16 + let series = Vue.ref([]);
  17 + let seriesR = Vue.ref([]);
  18 + let names = Vue.ref(['智能综合巡检系统', '数据中心虚拟化', '备份系统']);
  19 + let namesR = Vue.ref(['吴斌斌','袁晋鹏'])
  20 + let kpiName=Vue.ref('');
  21 + let kpiNameR = Vue.ref('');
  22 + let kpiUnit=Vue.ref('');
  23 + let kpiUnitR=Vue.ref('');
  24 + let colorsArr = Vue.ref([
  25 + {
  26 + start: '#468ced',
  27 + end: '#68a5fa'
  28 + },
  29 + {
  30 + start: '#79dda1',
  31 + end: '#9bddb5'
  32 + }
  33 + ])
  34 + const optionDataInit = () => {
  35 +
  36 + optionData.value = {
  37 + tooltip: {
  38 + trigger: 'axis',
  39 + formatter: function (param) {
  40 + var tips = kpiName.value + " " + param[0].name + "<br/>";
  41 + $.each(param, function (i, v) {
  42 + tips += v.marker + " " + v.seriesName + ":" + v.value + kpiUnit.value + "</br>"
  43 + });
  44 + return tips;
  45 + }
  46 + },
  47 + legend: {
  48 + show: true
  49 + },
  50 + grid: {
  51 + top: '10%',
  52 + left: '3%',
  53 + right: '4%',
  54 + bottom: '5%',
  55 + containLabel: true
  56 + },
  57 + toolbox: {
  58 + feature: {
  59 + saveAsImage: {
  60 + show: false
  61 + }
  62 + }
  63 + },
  64 + xAxis: {
  65 + type: 'category',
  66 + data: names.value,
  67 + axisLine: {
  68 + lineStyle: {
  69 + color: '#c9c9c9'
  70 + }
  71 + },
  72 + axisLabel: {
  73 + color: '#232425',
  74 + showMaxLabel: true,
  75 + lineHeight:18,
  76 + formatter: function (params) {
  77 + var newParamsName = '';
  78 + let paramsNameNumber = params.length;
  79 + let provideNumber = 4;
  80 + let rowNumber = Math.ceil(paramsNameNumber / provideNumber);
  81 + if (paramsNameNumber > provideNumber) {
  82 + for (let i = 0; i < rowNumber; i++) {
  83 + let tempStr = '';
  84 + let start = i * provideNumber;
  85 + let end = start + provideNumber;
  86 + if (i == rowNumber - 1) {
  87 + tempStr = params.substring(start, paramsNameNumber);
  88 + } else {
  89 + tempStr = params.substring(start, end) + "\n";
  90 + }
  91 + newParamsName += tempStr;
  92 + }
  93 + } else {
  94 + newParamsName = params;
  95 + }
  96 + return newParamsName;
  97 + }
  98 + },
  99 + splitArea: {
  100 + show: true,
  101 + areaStyle: {
  102 + color: ['rgba(200,200,200,0.1)', 'transparent'
  103 + ]
  104 + }
  105 + }
  106 + },
  107 + yAxis: {
  108 + type: 'value',
  109 + scale: true,
  110 + min:0,
  111 + boundaryGap: ['10%', '10%'],
  112 + axisLine: {
  113 + lineStyle: {
  114 + color: '#232425'
  115 + },
  116 + show: false
  117 + },
  118 + axisTick: {
  119 + show: false
  120 + },
  121 + splitLine: {
  122 + lineStyle: {
  123 + color: ['#ddd'],
  124 + type: 'dotted',
  125 +
  126 + }
  127 + }
  128 + },
  129 + series: series.value
  130 + };
  131 + optionDataR.value= {
  132 + tooltip: {
  133 + trigger: 'axis',
  134 + formatter: function (param) {
  135 + var tips = kpiName.value + " " + param[0].name + "<br/>";
  136 + $.each(param, function (i, v) {
  137 + tips += v.marker + " " + v.seriesName + ":" + v.value + kpiUnit.value + "</br>"
  138 + });
  139 + return tips;
  140 + }
  141 + },
  142 + legend: {
  143 + show: true
  144 + },
  145 + grid: {
  146 + top: '10%',
  147 + left: '3%',
  148 + right: '4%',
  149 + bottom: '5%',
  150 + containLabel: true
  151 + },
  152 + toolbox: {
  153 + feature: {
  154 + saveAsImage: {
  155 + show: false
  156 + }
  157 + }
  158 + },
  159 + xAxis: {
  160 + type: 'category',
  161 + data: namesR.value,
  162 + axisLine: {
  163 + lineStyle: {
  164 + color: '#c9c9c9'
  165 + }
  166 + },
  167 + axisLabel: {
  168 + color: '#232425',
  169 + showMaxLabel: true,
  170 + lineHeight:18,
  171 + formatter: function (params) {
  172 + var newParamsName = '';
  173 + let paramsNameNumber = params.length;
  174 + let provideNumber = 4;
  175 + let rowNumber = Math.ceil(paramsNameNumber / provideNumber);
  176 + if (paramsNameNumber > provideNumber) {
  177 + for (let i = 0; i < rowNumber; i++) {
  178 + let tempStr = '';
  179 + let start = i * provideNumber;
  180 + let end = start + provideNumber;
  181 + if (i == rowNumber - 1) {
  182 + tempStr = params.substring(start, paramsNameNumber);
  183 + } else {
  184 + tempStr = params.substring(start, end) + "\n";
  185 + }
  186 + newParamsName += tempStr;
  187 + }
  188 + } else {
  189 + newParamsName = params;
  190 + }
  191 + return newParamsName;
  192 + }
  193 + },
  194 + splitArea: {
  195 + show: true,
  196 + areaStyle: {
  197 + color: ['rgba(200,200,200,0.1)', 'transparent'
  198 + ]
  199 + }
  200 + }
  201 + },
  202 + yAxis: {
  203 + type: 'value',
  204 + scale: true,
  205 + boundaryGap: ['10%', '10%'],
  206 + axisLine: {
  207 + lineStyle: {
  208 + color: '#232425'
  209 + },
  210 + show: false
  211 + },
  212 + axisTick: {
  213 + show: false
  214 + },
  215 + splitLine: {
  216 + lineStyle: {
  217 + color: ['#ddd'],
  218 + type: 'dotted',
  219 +
  220 + }
  221 + }
  222 + },
  223 + series: seriesR.value
  224 + };
  225 + }
  226 + let rateData=Vue.ref([
  227 + {name:'应点击量',data:[1,34,12]},
  228 + {name:'实际点击量',data:[15,24,10]}
  229 + ])
  230 + let rateDataR=Vue.ref([
  231 + {name:'',data:[1,6,8,9,10]},
  232 + ])
  233 + const setSeries = () => {
  234 + series.value = [];
  235 + $.each(rateData.value, function (i, v) {
  236 + series.value.push({
  237 + name: v.name,
  238 + type: 'bar',
  239 + barWidth: 16,//设置柱状图大小
  240 + data: v.data,
  241 + stack:'total',
  242 + symbolSize: 12,
  243 + symbol: 'circle',
  244 + itemStyle: {
  245 + normal: {
  246 + // color: colorsArr.value[i].start //图标颜色
  247 + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ //关键在这里, 设置面积渐变
  248 + offset: 0,
  249 + color: colorsArr.value[i].start //这里是我设置的渐变的颜色从线条颜色变为透明
  250 + }, {
  251 + offset: 1,
  252 + color: colorsArr.value[i].end
  253 + }])
  254 + }
  255 + }
  256 + })
  257 + });
  258 +
  259 + seriesR.value = [];
  260 + $.each(rateDataR.value, function (i, v) {
  261 + seriesR.value.push({
  262 + name: v.name,
  263 + type: 'bar',
  264 + barWidth: 16,//设置柱状图大小
  265 + data: v.data,
  266 + stack:'noStack',
  267 + symbolSize: 12,
  268 + symbol: 'circle',
  269 + itemStyle: {
  270 + normal: {
  271 + // color: colorsArr.value[i].start //图标颜色
  272 + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ //关键在这里, 设置面积渐变
  273 + offset: 0,
  274 + color: colorsArr.value[i].start //这里是我设置的渐变的颜色从线条颜色变为透明
  275 + }, {
  276 + offset: 1,
  277 + color: colorsArr.value[i].end
  278 + }])
  279 + },
  280 + borderRadius:[3,3,0,0]
  281 + }
  282 + })
  283 + });
  284 +
  285 + optionDataInit();
  286 + }
  287 + let search = Vue.ref({
  288 + status: 'today',
  289 + dateTime:'',
  290 + keyword: '',
  291 + page: 1,
  292 + limit: 10,
  293 + });
  294 + let dialog = Vue.ref({
  295 + title: "处理审批",
  296 + show: false,
  297 + amId: '',
  298 + amStatus: 0,
  299 + alarmId: '',
  300 + });
  301 +
  302 + //表格字段
  303 + let tableData = Vue.ref({
  304 + count: 0,
  305 + dataList: [],
  306 + columns: [
  307 + {
  308 + prop: 'alarmNo',
  309 + label: '用户名',
  310 + sortable: true,
  311 + align: 'center',
  312 + width: '150'
  313 + },
  314 + {
  315 + prop: 'resName',
  316 + label: '时间',
  317 + sortable: true,
  318 + align: 'center',
  319 + width: '250',
  320 + },
  321 + {
  322 + prop: 'resTypeName',
  323 + label: 'IP地址',
  324 + sortable: true,
  325 + align: 'center',
  326 + width: '150'
  327 + }, {
  328 + prop: 'managenameName',
  329 + label: '访问位置',
  330 + sortable: true,
  331 + align: 'center',
  332 + }, {
  333 + prop: 'reason',
  334 + label: '停留总时长',
  335 + sortable: true,
  336 + align: 'center',
  337 + width: '120'
  338 + }
  339 + ]
  340 + })
  341 + //点击时间选择时,其他按钮不高亮
  342 + let dateFocus=()=>{
  343 + search.value.status = 'dateRange';
  344 + }
  345 + //时间更改事件
  346 + let dateChange=(val)=>{
  347 + console.log(val,search.value.dateTime)
  348 + getDataList('dateRange')
  349 + }
  350 +
  351 + //获取aj配置信息
  352 + let statusVal = Vue.ref('today');
  353 + let getDataList = (status) => {
  354 + if (status == undefined) {
  355 + status = 'today'
  356 + }
  357 + if(status != 'dateRange'){
  358 + search.value.dateTime=[];
  359 + }
  360 + statusVal.value = status;
  361 + search.value.status = status;
  362 + let startTime='';
  363 + let endTime=''
  364 + if(search.value.dateTime && search.value.dateTime.length>0){
  365 + startTime=search.value.dateTime[0];
  366 + endTime=search.value.dateTime[1];
  367 + }
  368 + let params={
  369 + page: search.value.page,
  370 + limit: search.value.limit,
  371 + keyword: search.value.keyword,
  372 + status: search.value.status,
  373 + startTime:startTime,
  374 + endTime:endTime
  375 + }
  376 + proxy.$http.get(`/api-web/bAlarmManage/page`, params, function (res) {
  377 + if (res && res.data) {
  378 + tableData.value.dataList = res.data;
  379 + tableData.value.count = res.count;
  380 + } else {
  381 + tableData.value.dataList = [];
  382 + tableData.value.count = 0;
  383 + }
  384 + });
  385 + }
  386 +
  387 + let loaddata = ({page, limit}) => {
  388 + search.value.page = page;
  389 + search.value.limit = limit;
  390 + }
  391 +
  392 +
  393 + let hideDialog = (flg) => {
  394 + dialog.value.show = flg;
  395 + if (!flg) {
  396 + getDataList(dialog.value.amStatus)
  397 + }
  398 + }
  399 +
  400 + // 处理弹框
  401 + let handle = (row, flag) => {
  402 + isView.value = flag;
  403 + hideDialog(true);
  404 + dialog.value.amId = row.id;
  405 + dialog.value.amStatus = row.status;
  406 + dialog.value.alarmId = row.alarmId;
  407 + }
  408 + //审核保存后关闭弹框
  409 + let saveback = (val) => {
  410 + hideDialog(val)
  411 + }
  412 + let loginName = Vue.ref(localStorage.getItem('lgn'));
  413 +
  414 + // 挂载完
  415 + Vue.onMounted(() => {
  416 + getDataList();
  417 + setSeries();
  418 + })
  419 +
  420 + return {
  421 + loginName,
  422 + height,
  423 + optionData,
  424 + optionDataInit,
  425 + series,
  426 + names,
  427 + rateData,
  428 + optionDataR,
  429 + seriesR,
  430 + namesR,
  431 + rateDataR,
  432 + setSeries,
  433 + dateFocus,
  434 + dateChange,
  435 + dialog,
  436 + hideDialog,
  437 + search,
  438 + tableData,
  439 + loaddata,
  440 + getDataList,
  441 + handle,
  442 + saveback,
  443 + statusVal,
  444 + isView
  445 + }
  446 + }
  447 +
  448 +}
@@ -279,6 +279,12 @@ const routes = [{ @@ -279,6 +279,12 @@ const routes = [{
279 name: 'thirdSet', 279 name: 'thirdSet',
280 component: () => myImport('views/thirdSet/index') 280 component: () => myImport('views/thirdSet/index')
281 }, 281 },
  282 + //操作日志
  283 + {
  284 + path: '/vue3/operationLog',
  285 + name: 'operationLog',
  286 + component: () => myImport('views/operationLog/index')
  287 + }
282 ]; 288 ];
283 289
284 // hash模式: createWebHashHistory 290 // hash模式: createWebHashHistory