xiejun
2023-11-26 c4d687aacfb4e7b6ee5ce67df93cf2f8d8df80c1
Merge remote-tracking branch 'origin/master'
已修改28个文件
已删除3个文件
已重命名1个文件
已添加14个文件
2038 ■■■■ 文件已修改
Source/UBCS-WEB/src/api/logs.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/FormTemplate/FormTemplate.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/MasterCrud/VciMasterCrud.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/StatisticsComponent/ColumnarChart.vue 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/StatisticsComponent/lineChart.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/StatisticsComponent/mixCart.vue 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/components/StatisticsComponent/pieChart.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/monitor/log/authLog.vue 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/monitor/log/localLog.vue 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/monitor/log/loginLog.vue 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/monitor/log/operateLog.vue 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/views/statistic/statisticPage.vue 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/vue.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-codeApply/src/main/java/com/vci/rmip/code/client/codeapply/Apply410/utils/HttpUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/entity/LocalLog.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/entity/LogOperate.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/vo/LocalLogVO.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/entity/Attach.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileDownloadUtil.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/LogApplication.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogErrorController.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogLocalController.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogOperateController.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogSystemController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/feign/LogClient.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/mapper/LogOperateMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogLocalService.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogOperateService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogSystemService.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogLocalServiceImpl.java 310 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogOperateServiceImpl.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogSystemServiceImpl.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/application-prod.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/mapper/AttachMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/mapper/SmsMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-applyjtcodeservice/src/main/java/com/vci/ubcs/code/applyjtcodeservice/service/impl/DockingPreAttrMappingServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-applyjtcodeservice/src/main/java/com/vci/ubcs/code/applyjtcodeservice/service/impl/GroupMdmInterServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/CodeApplication.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeSyncUniversalController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeApplyWebManagementServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/UniversalInterfaceImpl.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/wrapper/CodeButtonWrapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/MdmCountConfigController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Source/UBCS-WEB/src/api/logs.js
@@ -62,3 +62,25 @@
  })
}
export const getLazyList = (data) => {
  return request({
    url: '/api/ubcs-log/localLog/lazy-list',
    method: 'post',
    data: data,
  })
}
export const downLoadLog = (data) => {
  return request({
    url: '/api/ubcs-log/localLog/downLoadLog',
    method: 'post',
    data:data,
  })
}
export const deleteLocalLog = (data) => {
  return request({
    url: '/api/ubcs-log/localLog/deleteLogFile',
    method: 'delete',
    data: data
  })
}
Source/UBCS-WEB/src/components/FormTemplate/FormTemplate.vue
@@ -201,7 +201,7 @@
      let dictKeys = [];
      let slotColumnList = [];
      formItemList.forEach((formItem) => {
        // console.log('formItem',formItem)
        console.log('formItem',formItem)
        formItem = this.resetFormConfig(formItem);
        if (formItem.secType === "codeattrsec") {
          this.attrList.push(formItem);
@@ -341,7 +341,6 @@
      let that = this;
      items.forEach((item) => {
        let formItem = this.resetFormConfig(item);
        if (formItem.field == "lcstatus") {
          formItem.field = formItem.field + "_text";
          formItem.readOnly = true;
Source/UBCS-WEB/src/components/MasterCrud/VciMasterCrud.vue
@@ -36,8 +36,8 @@
              </el-select></span>
            </div>
            <div class="custom-table">
              <el-table class="cus-table" ref="dataTable" v-loading="isLoading" :data="tableData"
                        :height="tableHeight"  border
              <el-table ref="dataTable" v-loading="isLoading" :data="tableData" :height="tableHeight"
                        border class="cus-table"
                        @select="handleSelection" @cell-click="handleCellClick" @row-click="handleRowClick"
                        @select-all="handleSelectionAll" @selection-change="handleSelectionChange"
                        @sort-change="sortChange">
@@ -45,15 +45,17 @@
                <el-table-column v-if="tableData.length != 0" fixed label="序号" type="index" width="55">
                </el-table-column>
                <!--              ç”Ÿå‘½å‘¨æœŸ-->
                <el-table-column v-for="(item,index) in lcstatusArray" key="index" v-if=" lcstatusArray.length !== 0 && !item.hidden" label="生命周期值" prop="lcstatus"
                                 :show-overflow-tooltip="true" :sortable="item.sortable" :width="item.width"
                                 align="center">
                <el-table-column v-for="(item,index) in lcstatusArray" v-if=" lcstatusArray.length !== 0 && !item.hidden"
                                 key="index" :show-overflow-tooltip="true" :sortable="item.sortable"
                                 :width="item.width" align="center" label="生命周期值"
                                 prop="lcstatus">
                  <template slot-scope="scope">
                    <span>{{ scope.row.lcstatus_text }}</span>
                  </template>
                </el-table-column>
                <!--              ç¼–号-->
                <el-table-column  v-for="(item, index) in CodeArray" key="index" v-if="CodeArray.length !== 0 && !item.hidden" :label="item.label" :prop="item.prop"
                <el-table-column v-for="(item, index) in CodeArray" v-if="CodeArray.length !== 0 && !item.hidden"
                                 key="index" :label="item.label" :prop="item.prop"
                                  :show-overflow-tooltip="true" :sortable="item.sortable" :width="item.width"
                                  align="center">
                  <template slot-scope="scope">
@@ -62,7 +64,8 @@
                    </el-link>
                  </template>
                </el-table-column>
                <el-table-column v-for="item in this.tableHeadFindData" v-if="!item.hidden && item.prop !== 'id' && item.prop !== 'lcstatus' && Object.keys(item.referConfig).length <= 0"
                <el-table-column v-for="item in this.tableHeadFindData"
                                 v-if="!item.hidden && item.prop !== 'id' && item.prop !== 'lcstatus' && Object.keys(item.referConfig).length <= 0"
                                 :key="item.id"
                                 :formatter="item.formatter"
                                 :label="item.label" :prop="item.prop"
@@ -72,9 +75,11 @@
                                 align="center">
                </el-table-column>
                <!--               å‚照数据-->
                <el-table-column v-for="(item,index) in referArray" :key="index" v-if="item.referConfig && Object.keys(item.referConfig).length > 0 && !item.hidden" :label="item.title" prop="jiliangdw"
                                 :show-overflow-tooltip="true" :sortable="item.sortable" :width="item.width"
                                 align="center">
                <el-table-column v-for="(item,index) in referArray" v-if="item.referConfig && Object.keys(item.referConfig).length > 0 && !item.hidden"
                                 :key="index"
                                 :label="item.title" :show-overflow-tooltip="true"
                                 :sortable="item.sortable" :width="item.width" align="center"
                                 prop="jiliangdw">
                  <template slot-scope="scope">
                    <span>{{ scope.row.jiliangdwname }}</span>
                  </template>
@@ -142,7 +147,8 @@
                          :visible.sync="dialogPush"></MasterTransfer>
          <!--        å¯¼å…¥-->
          <BatchImport v-if="batchImportData.visible" v-bind="batchImportData" :resetTable="CrudRend"
                       :visible.sync="batchImportData.visible" :tableHeadData="tableHeadFindData" :selectRow="selectRow">
                       :selectRow="selectRow" :tableHeadData="tableHeadFindData"
                       :visible.sync="batchImportData.visible">
          </BatchImport>
          <!--          ç›¸ä¼¼é¡¹-->
          <ResembleQueryDialog :codeClassifyOid="codeClassifyOid" :codeRuleOid="this.codeRuleOid" :rowOid="rowOid"
@@ -582,8 +588,6 @@
    codeAMENDHandler(){
      if (this.selectRow.length !== 1) {
        this.$message.warning("请选择一条数据");
      } else if (this.selectRow[0].lcstatus !== "Editing") {
        this.$message.warning("编码状态不是“编辑中”,不可编辑");
      } else {
        this.amendvisible = true;
        this.rowOid = this.selectRow[0].oid;
@@ -1041,6 +1045,7 @@
/deep/ .el-table__fixed {
  height: calc(100vh - 370px)!important;
}
// æ»šåŠ¨æ¡æ ·å¼ä¿®æ”¹
// æ»šåŠ¨æ¡çš„å®½åº¦
/deep/ .el-table__body-wrapper::-webkit-scrollbar {
@@ -1050,6 +1055,7 @@
  width: 10px;
}
// æ»šåŠ¨æ¡çš„æ»‘å—
/deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
  background-color: #ececec;
Source/UBCS-WEB/src/components/StatisticsComponent/ColumnarChart.vue
@@ -2,120 +2,149 @@
  <basic-container>
    <v-chart id="chart" :auto-resize="true" :options="chartOptions"></v-chart>
  </basic-container>
</template>
<script>
import 'echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/pie'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/title'
import 'echarts/lib/component/legend'
var data = [
  [120, 132, 101, 134, 90, 230, 210, 130, 0, 122, 100, 80],
  [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
];
// æ‰¾åˆ°æ¯ä¸€é¡¹æ•°æ®ä¸­çš„æœ€å¤§å€¼å¹¶ä¿å­˜åˆ°æ•°ç»„
var maxValues = data[0].map(function (_, i) {
  return Math.max.apply(null, data.map(function (item) {
export default {
  name: "ColumnarChart",
  props:{
    columnarData:{
      type:Array,
      default:[]
    },
    chartName:{
      type:String,
      default: ""
    }
  },
  watch:{
    columnarData:{
      immediate:true,
      handler(newval,oldval){
        if(newval && newval.length > 0){
          const minValues = newval[0].map(function (_, i) {
            return Math.min.apply(
              null,
              newval.map(function (item) {
    return item[i];
  }));
              })
            );
});
var colors = ['#91CC75', '#5470C6'];
// ç”ŸæˆæŸ±çŠ¶å›¾çš„ series æ•°æ®
var seriesData = [];
for (var i = 0; i < data.length; i++) {
  var curSeriesData = [];
  // è®¡ç®—数据中的每组数据的最大值
  for (var j = 0; j < data[i].length; j++) {
    var borderRadius = [0, 0, 0, 0];  // é»˜è®¤ä¸è®¾ç½®åœ†è§’
    if (data[i][j] === maxValues[j]) {  // å¦‚果当前柱子的值等于对应列的最大值,设置圆角
      borderRadius = [50, 50, 0, 0];  // è®¾ç½®å››ä¸ªè§’都为圆角
          let colors = ["#91CC75", "#5470C6"];
          const seriesData = [];
          for (let i = 0; i < newval.length; i++) {
            let curSeriesData = [];
            for (let j = 0; j < newval[i].length; j++) {
              let borderRadius = [0, 0, 0, 0];
              if (newval[i][j] === minValues[j]) {
                borderRadius = [50, 50, 0, 0];
    }
    curSeriesData.push({
      value: data[i][j],
                value: newval[i][j],
      itemStyle: {
        normal: {
          barBorderRadius: borderRadius,  // è®¾ç½®åœ†è§’
          color: colors[i],
          show: function (params) {
            // æ ¹æ®æ•°æ®å€¼çš„大小来判断是否显示 label
            return params.value > 30;
          }
        }
      }
                },
    });
  }
  var seriesName = '';
  if (i === 0) {
    seriesName = '总量';
  } else if (i === 1) {
    seriesName = '新增';
  }
            let seriesName = (i === 0 ? "总量" : "新增")
  seriesData.push({
    name: seriesName,
    type: 'bar',
    stack: '总量',
              type: "bar",
              stack: "总量",
              barWidth: 60,
    data: curSeriesData,
    label: {
      show: true,
      position: 'top'
    },
    itemStyle: {
      color: colors[i]  // è®¾ç½®æŸ±å­çš„颜色
    },
    emphasis: {
      focus: 'series'
    }
                focus: "series",
              },
  });
            this.chartOptions.series=seriesData
}
export default {
  name: "ColumnarChart",
        }
      }
    },
    chartName:{
      handler(newval,oldval){
        if(newval){
          console.log(newval)
          this.chartOptions.title.text = newval + "数据统计"
        }
      },
      immediate:true,
      deep:true
    }
  },
  data() {
    return {
      chartOptions: {
        color:["#91CC75", "#5470C6"],
        title: {
          text: '人员主数据统计'
          text: "",
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        tooltip: {
          trigger: 'axis',
          trigger: "axis",
          axisPointer: {
            type: 'shadow'
          }
            type: "shadow",
          },
        },
        legend: {
          data: ['总量', '新增'],
          left: 'center'
          data: ["总量", "新增"],
          left: "center",
          textStyle: {
            fontSize: 14 // è°ƒæ•´å­—体大小
          }
        },
        xAxis: {
          type: 'category',
          data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
          type: "category",
          data: [
            "一月",
            "二月",
            "三月",
            "四月",
            "五月",
            "六月",
            "七月",
            "八月",
            "九月",
            "十月",
            "十一月",
            "十二月",
          ],
        },
        yAxis: {
          type: 'value'
          type: "value",
        },
        series: seriesData,
      }
    }
  }
}
        series: [],
      },
    };
  },
  created() {
  },
};
</script>
<style scoped lang="scss">
#chart {
  width: 1280px;
  height: 800px;
  width: 100%;
  height: 560px;
}
</style>
Source/UBCS-WEB/src/components/StatisticsComponent/lineChart.vue
@@ -9,70 +9,92 @@
<script>
import 'echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/pie'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/title'
import 'echarts/lib/component/legend'
export default {
  name: "lineChart",
  props: {
    lineData: {
      type: Array,
      default: []
    },
    chartName: {
      type: String,
      default: ""
    }
  },
  watch: {
    lineData: {
      immediate: true,
      handler(newval, oldval) {
        if (newval) {
          const series = newval.map((data, index) => ({
            name: index === 0 ? "总量" : "新增",
            type: "line",
            smooth: true,
            stack: "Total",
            label: {
              show: true,
              position: "top",
              textStyle: {
                fontSize: 14 // è°ƒæ•´å­—体大小
              }
            },
            data: data.map(value => ({value}))
          }));
          this.chartOptions.series = series;
        }
      }
    },
    chartName:{
      handler(newval,oldval){
        if(newval){
          this.chartOptions.title.text = newval + "数据统计"
        }
      },
      immediate:true,
      deep:true
    }
  },
  data() {
    return {
      chartOptions: {
        color:['#2eadd6  ','#FFA500 '],
        title: {
          text: '物品主数据统计'
          text: ''
        },
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          data: ['总量', '新增']
          data: ['总量', '新增'],
          textStyle: {
            fontSize: 14 // è°ƒæ•´å­—体大小
          }
        },
        xAxis: {
          boundaryGap: true, // æŽ§åˆ¶åæ ‡è½´ä¸¤ä¾§ç•™ç™½
          boundaryGap: true,
          type: 'category',
          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
          data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        },
        yAxis: {
          type: 'value'
          type: 'value',
        },
        series: [
          {
            name: '总量',
            type: 'line',
            smooth: true,
            stack: 'Total',
            label: {
              show: true,
              position: 'top'
            },
            data: [5000, 2000, 3600, 1000, 1000, 2000, 500, 2000, 500, 2000, 500, 2000]
          },
          {
            name: '新增',
            type: 'line',
            smooth: true,
            stack: 'Total',
            label: {
              show: true,
              position: 'top'
            },
            data: [1510, 1010, 2610, 2010, 3010, 1010, 1510, 3010, 1010, 1510, 3010, 2000]
        series: []
          }
        ]
      },
    };
  },
  mounted() {
  },
  created() {
}
};
</script>
<style lang="scss" scoped>
#chart {
  width: 1280px;
  width: 100%;
  height: 400px;
}
</style>
Source/UBCS-WEB/src/components/StatisticsComponent/mixCart.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,124 @@
<template>
  <basic-container>
    <v-chart id="chart" :auto-resize="true" :options="chartOptions"></v-chart>
  </basic-container>
</template>
<script>
import 'echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/chart/pie'
import 'echarts/lib/chart/bar'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/title'
import 'echarts/lib/component/legend'
export default {
  name: "mixCart",
  props: {
    mixData: {
      type: Array,
      default: []
    },
    chartName: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      chartOptions: {
        title: {
          text: "",
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow",
          },
        },
        legend: {
          data: ["总量", "新增"],
          left: "center",
          textStyle: {
            fontSize: 14 // è°ƒæ•´å­—体大小
          }
        },
        xAxis: {
          type: "category",
          data: [
            "一月",
            "二月",
            "三月",
            "四月",
            "五月",
            "六月",
            "七月",
            "八月",
            "九月",
            "十月",
            "十一月",
            "十二月",
          ],
        },
        yAxis: {
          type: "value",
        },
        series: [],
      },
    };
  },
  watch: {
    mixData: {
      immediate: true,
      handler(newval, oldval) {
        if (newval) {
          const colors = ["#8fef5b", "#db3c3c"];
          const seriesData = newval.map((data, index) => ({
            name: index === 0 ? "总量" : "新增",
            type: index === 0 ? "bar" : "line",
            stack: index === 0 ? "总量" : null,
            data: data.map(value => ({value})),
            barWidth: 68,
            label: {
              show: true,
              position: "top"
            },
            itemStyle: {
              color: colors[index]
            },
            emphasis: {
              focus: "series"
            }
          }));
          this.chartOptions.series = seriesData;
        }
      },
    },
    chartName:{
      handler(newval,oldval){
        if(newval){
          this.chartOptions.title.text = newval + "数据统计"
        }
      },
      immediate:true,
      deep:true
    }
  },
};
</script>
<style scoped lang="scss">
#chart {
  width: 100%;
  height: 560px;
}
</style>
Source/UBCS-WEB/src/components/StatisticsComponent/pieChart.vue
@@ -1,5 +1,5 @@
<template>
  <basic-container>
  <basic-container style="width: 100%">
    <v-chart :options="chartOptions" :auto-resize="true" id="chart"></v-chart>
  </basic-container>
</template>
@@ -11,6 +11,16 @@
import 'echarts/lib/component/legend'
export default {
  name: "pieChart",
  props:{
    pieData:{
      type:Array,
      default:[]
    },
    chartName:{
      type:String,
      default: ""
    }
  },
  data() {
    return {
      chartOptions: {
@@ -21,7 +31,7 @@
        tooltip: {
          trigger: 'item',
          formatter: function (params) {
            var result = '';
            let result = '';
            if (params.componentType === 'series') {
              result += params.name + '<br/>';
              result += '新增:' + params.data.newValue + '<br/>';
@@ -50,7 +60,7 @@
            itemStyle: {
              color: function(params) {
                // æ ¹æ®å…·ä½“需求设置颜色
                var colorList = ['#5470C6', '#91CC75', '#fac858', '#EE6666', '#3BA272', '#FC8452', '#9A60B4', '#e34d4d', '#b3e9b9', '#eaaaed', '#1bc6e4', '#c6b3e9'];
                const colorList = ['#5470C6', '#91CC75', '#fac858', '#EE6666', '#3BA272', '#FC8452', '#9A60B4', '#e34d4d', '#b3e9b9', '#eaaaed', '#1bc6e4', '#c6b3e9'];
                return colorList[params.dataIndex % colorList.length];
              }
            },
@@ -78,7 +88,8 @@
<style scoped lang="scss">
#chart {
  width: 800px;
  height: 600px;
  width: 90%;
  height: 530px;
}
</style>
Source/UBCS-WEB/src/views/monitor/log/authLog.vue
Source/UBCS-WEB/src/views/monitor/log/localLog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,207 @@
<template>
  <basic-container>
    <avue-crud ref="crud"
              v-model="form"
              :before-close="beforeClose"
              :before-open="beforeOpen"
              :data="data"
              :option="option"
              :permission="permissionList"
              :table-loading="loading"
              @row-del="rowDel"
              @search-change="searchChange"
              @search-reset="searchReset"
              @selection-change="selectionChange"
              @row-click="clickRowChange"
              @current-change="currentChange"
              @size-change="sizeChange"
              @refresh-change="refreshChange"
              @on-load="onLoad"
              @tree-load="treeLoad">
          <template slot="menu" slot-scope="scope">
              <el-button
                  icon="el-icon-download el-icon--right"
                  size="small"
                  type="text"
                  :loading="downloadLoading"
                  @click="downLoadLogFile(scope.row)"
                  v-if="permissionList.downLoadBtn"
              >下载
              </el-button>
          </template>
    </avue-crud>
  </basic-container>
</template>
<script>
  import {getLazyList, deleteLocalLog,downLoadLog} from "@/api/logs";
  import func from "@/util/func";
  import {mapGetters} from "vuex";
  export default {
    data() {
      return {
        form: {},
        selectionList: [],
        query: {},
        logPath: "",
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        option: {
          height: "auto",
          lazy: true,
          columnBtn: false,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          tree: true,
          border: true,
          index: true,
          selection: true,
          editBtn: false,
          delBtn: true,
          addBtn: false,
          viewBtn: false,
          // menuWidth: 300,
          dialogClickModal: false,
          highlightCurrentRow: true, //行选中时高亮
          rowKey: "logName", //行数据的 Key,用来优化 Table çš„æ¸²æŸ“
          column: [
            {
              label: "服务名称",
              prop: "serviceName",
              width:'120',
              search: true
            },
            {
              label: "服务ID",
              prop: "serviceId",
              search: true
            },
            {
              label: "日志路径",
              prop: "logPath",
              width:'160'
            },
            {
              label: "日志名称",
              prop: "logName",
              width:'80',
            },
            {
              label: "日志类型",
              prop: "logType"
            },
            {
              label: "创建时间",
              prop: "createTime",
              width:'180'
            },
            {
              label: "最后修改时间",
              prop: "lastModifier",
              width:'180'
            }
          ]
        },
        data: [],
        downloadLoading: false,
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          delBtn: this.vaildData(this.permission.localLog.localLog_delete, false),
          downLoadBtn: this.vaildData(this.permission.localLog.localLog_dwonload, false)
        };
      }
    },
    methods: {
      downLoadLogFile(row){
          this.downloadLoading = true;
          let logPath = row.hasChildren ?  row.logPath:row.logPath+"\\"+row.logName;
          downLoadLog(Object.assign({},row,{logFullPaths:logPath})).then(res=>{
              func.downloadFileByBlobHandler(res);
              this.downloadLoading = false;
          }).catch((res)=>{
              //this.$message.warning(res)
              this.downloadLoading = false;
          })
      },
      // è¡Œåˆ é™¤
      rowDel(row, index, done) {
          this.$confirm("确定将选择的日志文件删除?", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning"
          })
          .then(() => {
              let logPath = row.hasChildren ?  row.logPath:row.logPath+"\\"+row.logName;
              return deleteLocalLog(Object.assign({},row,{logFullPaths:logPath}));
          })
          .then(() => {
              this.$message({
                  type: "success",
                  message: "操作成功!"
              });
              // æ•°æ®å›žè°ƒè¿›è¡Œåˆ·æ–°
              done(row);
              //this.onLoad();
          });
      },
      searchReset() {
          this.query = {};
          this.parentId = 0;
          this.onLoad(this.page);
      },
      searchChange(params, done) {
          this.query = params;
          this.parentId = '';
          this.page.currentPage = 1;
          this.onLoad(this.page, params);
          done();
      },
      clickRowChange(row) {
          this.$refs.crud.toggleSelection();
          this.selectionList = row;
          this.$refs.crud.setCurrentRow(row);
          this.$refs.crud.toggleRowSelection(row); //选中当前行
      },
      selectionChange(list) {
          this.selectionList = list;
          this.$refs.crud.setCurrentRow(this.selectionList[list.length - 1]);
      },
      selectionClear() {
          this.selectionList = [];
          this.$refs.crud.toggleSelection();
      },
      refreshChange() {
          this.onLoad(this.page, this.query);
      },
      onLoad(page, params = {}) {
          this.loading = true;
          //Object.assign(params, this.query)
          getLazyList({"logPath": this.logPath}).then(res => {
              this.data = res.data.data;
              this.loading = false;
              this.selectionClear();
          });
      },
      treeLoad(tree, treeNode, resolve) {
          const logPath = tree.logPath;
          getLazyList({"logPath": logPath}).then(res => {
              resolve(res.data.data);
          });
      }
    }
  };
</script>
<style>
</style>
Source/UBCS-WEB/src/views/monitor/log/loginLog.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,139 @@
<template>
  <basic-container>
    <avue-crud :option="option"
               :table-loading="loading"
               :data="data"
               ref="crud"
               v-model="form"
               :permission="permissionList"
               :page.sync="page"
               :before-open="beforeOpen"
               @search-change="searchChange"
               @search-reset="searchReset"
               @current-change="currentChange"
               @size-change="sizeChange"
               @refresh-change="refreshChange"
               @on-load="onLoad">
    </avue-crud>
  </basic-container>
</template>
<script>
  import {getUsualList, getUsualLogs} from "@/api/logs";
  import {mapGetters} from "vuex";
  export default {
    data() {
      return {
        form: {},
        selectionList: [],
        query: {},
        loading: true,
        page: {
          pageSize: 10,
          currentPage: 1,
          total: 0
        },
        option: {
          height: 'auto',
          calcHeight: 30,
          columnBtn:false,
          tip: false,
          searchShow: true,
          searchMenuSpan: 6,
          border: true,
          index: true,
          viewBtn: true,
          editBtn: false,
          addBtn: false,
          delBtn: false,
          menuWidth: 120,
          dialogType: 'drawer',
          column: [
            {
              label: "用户名",
              prop: "serviceId",
              search: true
            },
            {
              label: "姓名",
              prop: "serverHost",
              search: true
            },
            {
              label: "用户id",
              prop: "serverIp"
            },
            {
              label: "模块",
              prop: "env",
              width:'80'
            },
            {
              label: "时间",
              prop: "logLevel"
            },
            {
              label: "操作结果",
              prop: "logId"
            },
            {
              label: "描述",
              prop: "requestUri"
            },
          ]
        },
        data: []
      };
    },
    computed: {
      ...mapGetters(["permission"]),
      permissionList() {
        return {
          viewBtn: this.vaildData(this.permission.log_usual.log_usual_view, false)
        };
      }
    },
    methods: {
      searchReset() {
        this.query = {};
        this.onLoad(this.page);
      },
      searchChange(params, done) {
        this.query = params;
        this.page.currentPage = 1;
        this.onLoad(this.page, params);
        done();
      },
      beforeOpen(done, type) {
        if (["edit", "view"].includes(type)) {
          getUsualLogs(this.form.id).then(res => {
            this.form = res.data.data;
          });
        }
        done();
      },
      currentChange(currentPage){
        this.page.currentPage = currentPage;
      },
      sizeChange(pageSize){
        this.page.pageSize = pageSize;
      },
      refreshChange() {
        this.onLoad(this.page, this.query);
      },
      onLoad(page, params = {}) {
        this.loading = true;
        getUsualList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
          const data = res.data.data;
          this.page.total = data.total;
          this.data = data.records;
          this.loading = false;
        });
      }
    }
  };
</script>
<style>
</style>
Source/UBCS-WEB/src/views/monitor/log/operateLog.vue
Source/UBCS-WEB/src/views/statistic/statisticPage.vue
@@ -8,14 +8,53 @@
    <el-dialog
      :visible.sync="addVisible"
      append-to-body
      class="avue-dialog avue-dialog--top"
      title="新增数据统计分析"
      top="-50px"
    >
      <el-table
        :data="tableData"
        border
        style="width: 100%"
        @selection-change="selectChange"
       >
        <el-table-column
          type="selection"
          width="55">
        </el-table-column>
        <el-table-column
          align="center"
          label="主数据库名"
          prop="menuName">
        </el-table-column>
        <el-table-column
          align="center"
          label="类型"
          prop="codeType">
          <template slot-scope="{ row }">
            <el-select v-model="row.codeType" placeholder="请选择图表类型">
              <el-option label="折线图" value="0"></el-option>
              <el-option label="饼状图" value="1"></el-option>
              <el-option label="柱状图" value="2"></el-option>
              <el-option label="柱状折线图" value="3"></el-option>
            </el-select>
          </template>
        </el-table-column>
      </el-table>
      <span slot="footer" class="dialog-footer">
    <el-button @click="escHandler">取 æ¶ˆ</el-button>
    <el-button type="primary" @click="addSaveHandler">保存</el-button>
  </span>
    </el-dialog>
    <!--    echarts组件-->
    <div>
            <lineChart></lineChart>
            <pieChart></pieChart>
            <ColumnarChart></ColumnarChart>
      <lineChart v-for="(item,index) in lineList" :key="index" :chartName="item.menuName"
                 :lineData="item.menuData"></lineChart>
      <!--      <pieChart :pieData="pieData" :chartName="chartName"></pieChart>-->
      <ColumnarChart v-for="(item,index) in columnarList" :key="index" :chartName="item.menuName"
                     :columnarData="item.menuData"></ColumnarChart>
      <mixCart v-for="(item,index) in mixList" :key="index" :chartName="item.menuName"
               :mixData="item.menuData"></mixCart>
    </div>
  </div>
</template>
@@ -24,23 +63,164 @@
import lineChart from "../../components/StatisticsComponent/lineChart"
import pieChart from "../../components/StatisticsComponent/pieChart"
import ColumnarChart from "../../components/StatisticsComponent/ColumnarChart"
import mixCart from "../../components/StatisticsComponent/mixCart"
export default {
  components: {
    lineChart,
    pieChart,
    ColumnarChart
    ColumnarChart,
    mixCart
  },
  name: "statisticPage",
  data() {
    return {
      addVisible: false,
      chartName: "",
      lineList: [],
      pieList: [],
      columnarList: [],
      mixList: [],
      selectData: [],
      tableData: [
        {
          menuName: "工艺文件",
          codeType: "1",
          menuData: [
            [222, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "测试sc",
          codeType: "2",
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "产品型号",
          codeType: "0",
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "固定资产",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "李航主数据",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "Part",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "人员主数据",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "人员",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "标准",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "物品主数据",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        },
        {
          menuName: "型号",
          codeType: null,
          menuData: [
            [220, 232, 301, 334, 290, 330, 410, 330, 212, 322, 200, 234],
            [120, 132, 101, 134, 90, 230, 210, 130, 10, 122, 100, 80],
          ]
        }
      ]
    }
  },
  methods: {
    //新增
    addHandler() {
      this.addVisible = true;
    },
    //取消
    escHandler() {
      this.addVisible = false;
    },
    //保存
    addSaveHandler() {
      debugger
      if (this.selectData.length <= 0) {
        this.$message.warning('请至少选择一条数据!');
        return;
    }
      const typeList = {
        "0": "lineList",
        "1": "pieList",
        "2": "columnarList",
        "3": "mixList"
      };
      let hasValidData = false; // æ·»åŠ ä¸€ä¸ªæ ‡å¿—æ¥è®°å½•æ˜¯å¦æœ‰æœ‰æ•ˆçš„é€‰æ‹©æ•°æ®
      let codeStatus = this.selectData.every(key => key.codeType)
      if (!codeStatus) {
        this.$message.warning("请检查已勾选数据类型是否为空!");
        return;
      }
      this.selectData.forEach(item => {
        const dataKey = typeList[item.codeType];
        if (dataKey) {
          this[dataKey].push(item);
          hasValidData = true; // æ ‡è®°æœ‰æœ‰æ•ˆæ•°æ®è¢«æ·»åŠ 
        }
      });
      if (hasValidData) {
        this.addVisible = false;
      }
    },
    //表格多选
    selectChange(selection, row) {
      // console.log(selection, row)
      this.selectData = selection;
    },
  }
}
</script>
Source/UBCS-WEB/vue.config.js
@@ -26,9 +26,9 @@
    proxy: {
      '/api': {
        //本地服务接口地址
        // target: 'http://127.0.0.1:37000',
        target: 'http://127.0.0.1:37000',
        // target: 'http://192.168.1.51:37000',
        target: 'http://dev.vci-tech.com:37000',
        // target: 'http://dev.vci-tech.com:37000',
        //yxc
        // target: 'http:// 192.168.0.104:37000',
        // target: 'http://192.168.0.105:37000',
Source/UBCS/ubcs-codeApply/src/main/java/com/vci/rmip/code/client/codeapply/Apply410/utils/HttpUtil.java
@@ -346,7 +346,7 @@
                return result;
            }
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
        }
        return result;
    }
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/entity/LocalLog.java
ÎļþÃû´Ó Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/entity/SystemLog.java ÐÞ¸Ä
@@ -4,7 +4,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
import java.io.Serializable;
/**
 * @author ludc
@@ -13,7 +13,12 @@
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SystemLog {
public class LocalLog implements Serializable {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 2217599544701726181L;
    /**
     * æ—¥å¿—所属服务名称
@@ -48,6 +53,11 @@
    /**
     * æ—¥å¿—的最后修改时间
     */
    private String lastmodifier;
    private String lastModifier;
    /**
     * æ˜¯å¦åŒ…含存在子文件
     */
    private Boolean hasChildren;
}
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/entity/LogOperate.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package com.vci.ubcs.log.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
 * æ“ä½œæ—¥å¿—管理:(包括登录日志、操作日志、授权日志,以及管理员的以上三种日志)
 * @author ludc
 * @date 2023/11/24 10:58
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("PL_LOG_OPERATE")
public class LogOperate implements Serializable {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 2217599544701724211L;
    /**
     * ä¸»é”®
     */
    @TableId("OID")
    private String oid;
    /**
     * ç”¨æˆ·å
     */
    private String userName;
    /**
     * å§“名
     */
    private String realName;
    /**
     * ip地址
     */
    private String ip;
    /**
     * æ¨¡å—
     */
    private String model;
    /**
     * æ“ä½œ
     */
    private String operate;
    /**
     * æ—¶é—´
     */
    private Date time;
    /**
     * æ“ä½œç»“æžœ
     */
    private String operateResult;
    /**
     * æè¿°
     */
    private String description;
    /**
     * æ—¥å¿—类型
     */
    private String logType;
}
Source/UBCS/ubcs-ops-api/ubcs-log-api/src/main/java/com/vci/ubcs/log/vo/LocalLogVO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.vci.ubcs.log.vo;
import com.vci.ubcs.log.entity.LocalLog;
import javafx.scene.Parent;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
 * @author ludc
 * @date 2023/11/23 11:17
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class LocalLogVO extends LocalLog implements Serializable {
    /**
     * åºåˆ—化
     */
    private static final long serialVersionUID = 2217599544701726981L;
    /**
     * æ—¥å¿—全路径集合
     */
    private String logFullPaths;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/entity/Attach.java
@@ -16,11 +16,13 @@
 */
package com.vci.ubcs.resource.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.tenant.mp.TenantEntity;
/**
@@ -32,7 +34,7 @@
@TableName("pl_attach")
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "Attach对象", description = "附件表")
public class Attach extends TenantEntity {
public class Attach extends BaseEntity {
    private static final long serialVersionUID = 1L;
@@ -66,6 +68,11 @@
     */
    @ApiModelProperty(value = "附件大小")
    private Long attachSize;
    /**
     * ç§Ÿæˆ·ID
     */
    @ApiModelProperty(value = "租户ID")
    @TableField("TENANT_ID")
    private String tenantId;
}
Source/UBCS/ubcs-ops-api/ubcs-resource-api/src/main/java/com/vci/ubcs/resource/utils/FileDownloadUtil.java
@@ -77,4 +77,52 @@
            }
        }
    }
    /**
     * ä¸‹è½½æ–‡ä»¶
     * @param response å“åº”对象
     * @param fileObjectBO æ–‡ä»¶çš„信息,包含文件的输入流
     * @param closeInputStream æ˜¯å¦å…³é—­æµ
     * @throws IOException ä¸‹è½½å‡ºé”™çš„æ—¶å€™æŠ›å‡ºå¼‚常
     */
    public static void downloadFileLocal(HttpServletResponse response, FileObjectBO fileObjectBO,boolean closeInputStream) throws IOException {
        MediaType mediaType = MediaTypeFactory.getMediaType(fileObjectBO.getFileExtension()).orElse(MediaType.APPLICATION_OCTET_STREAM);
        // è®¾ç½®å¼ºåˆ¶ä¸‹è½½ä¸æ‰“å¼€
        response.setContentType(mediaType.toString()+";application/force-download;charset=UTF-8");
        try{
            String fileName = URLEncoder.encode(fileObjectBO.getName(), "UTF8");
            response.addHeader("Content-Disposition", "attachment;filename="+ fileName+ ";filename*=utf-8''");
        }catch(Exception e){
            if(log.isErrorEnabled()){
                log.error("设置文件的名称到响应流的时候出错",e);
            }
        }
        response.setCharacterEncoding("UTF-8");
        Cookie cookie = new Cookie("fileDownload", "true");
        cookie.setPath("/");
        response.addCookie(cookie);
        if(closeInputStream) {
            try (InputStream ins = (fileObjectBO.getInputStream() != null ? fileObjectBO.getInputStream() : new FileInputStream(fileObjectBO.getFileLocalPath()))) {
                IOUtils.copy(ins, response.getOutputStream());
            } catch (IOException e) {
                //有可能客户端的链接
                if (log.isErrorEnabled()) {
                    log.error("写入文件到响应流出错", e);
                }
                throw e;
            }
        }else{
            try {
                InputStream ins = (fileObjectBO.getInputStream() != null ? fileObjectBO.getInputStream() : new FileInputStream(fileObjectBO.getFileLocalPath()));
                IOUtils.copy(ins, response.getOutputStream());
            } catch (IOException e) {
                //有可能客户端的链接
                if (log.isErrorEnabled()) {
                    log.error("写入文件到响应流出错", e);
                }
                throw e;
            }
        }
    }
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/LogApplication.java
@@ -29,7 +29,7 @@
 * @author Chill
 */
@EnableDiscoveryClient
@EnableFeignClients("org.springblade")
@EnableFeignClients(basePackages = {"com.vci.ubcs", "org.springblade"})
@SpringBootApplication
public class LogApplication {
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogErrorController.java
@@ -25,10 +25,7 @@
import org.springblade.core.mp.support.Query;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.util.Map;
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogLocalController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,78 @@
package com.vci.ubcs.log.controller;
import com.alibaba.nacos.common.utils.StringUtils;
import com.vci.ubcs.log.vo.LocalLogVO;
import com.vci.ubcs.log.service.ILogLocalService;
import com.vci.ubcs.log.entity.LocalLog;
import com.vci.ubcs.resource.utils.FileDownloadUtil;
import com.vci.ubcs.starter.web.util.ControllerUtil;
import com.vci.ubcs.starter.web.util.LangBaseUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.rmi.ServerException;
import java.util.List;
/**
 * æœ¬åœ°ç³»ç»Ÿæ—¥å¿—
 * @author ludc
 * @date 2023/10/31 15:37
 */
@NonDS
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/localLog")
public class LogLocalController {
    private final ILogLocalService logLocalService;
    /**
     * èŽ·å–æ—¥å¿—æ–‡ä»¶åˆ—è¡¨
     * @param localLog
     * @return
     */
    @PostMapping("/lazy-list")
    public R<List<LocalLog>> getSystemLogList(@RequestBody LocalLog localLog){
         return R.data(logLocalService.getSystemLogList(localLog.getLogPath()));
    }
    /**
     * ä¸‹è½½æ—¥å¿—文件
     * @param localLogVO ä¸‹è½½æ—¥å¿—的全路径集合
     * @param response
     * @return
     */
    @RequestMapping(value = "/downLoadLog",method = {RequestMethod.GET,RequestMethod.POST})
    public void downloadLogByServiceName(@RequestBody LocalLogVO localLogVO, HttpServletResponse response) throws IOException {
        try {
            //ControllerUtil.writeFileToResponse(response,excelName);
            FileDownloadUtil.downloadFileLocal(response, logLocalService.downloadLogByServiceNameAndFileName(localLogVO),true);
        } catch (Throwable e) {
            //如果出错,把错误信息写到text
            String msg = LangBaseUtil.getErrorMsg(e);
            if(StringUtils.isBlank(msg)){
                msg = "未知错误";
            }
            ControllerUtil.writeDataToResponse(response,msg.getBytes(StandardCharsets.UTF_8),null);
        }
    }
    /**
     * åˆ é™¤æ—¥å¿—文件
     * @param localLogVO
     * @return
     * @throws ServerException
     */
    @DeleteMapping("/deleteLogFile")
    public R deleteLogFile(@RequestBody LocalLogVO localLogVO) throws ServerException {
        return logLocalService.deleteLogFile(localLogVO);
    }
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogOperateController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.vci.ubcs.log.controller;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tenant.annotation.NonDS;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * æ“ä½œæ—¥å¿—管理:(包括登录日志、操作日志、授权日志,以及管理员的以上三种日志)
 * @author ludc
 * @date 2023/11/24 10:43
 */
@NonDS
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/operateLog")
public class LogOperateController {
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/controller/LogSystemController.java
ÎļþÒÑɾ³ý
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/feign/LogClient.java
@@ -67,4 +67,7 @@
        log.setParams(log.getParams().replace("&amp;", "&"));
        return R.data(errorLogService.save(log));
    }
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/mapper/LogOperateMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,16 @@
package com.vci.ubcs.log.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.vci.ubcs.log.entity.LogOperate;
import org.apache.ibatis.annotations.Mapper;
/**
 * æ“ä½œæ—¥å¿—管理:(包括登录日志、操作日志、授权日志,以及管理员的以上三种日志)
 * @author ludc
 * @date 2023/11/24 10:50
 */
@Mapper
public interface LogOperateMapper extends BaseMapper<LogOperate> {
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogLocalService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.vci.ubcs.log.service;
import com.vci.ubcs.log.vo.LocalLogVO;
import com.vci.ubcs.log.entity.LocalLog;
import com.vci.ubcs.resource.bo.FileObjectBO;
import org.springblade.core.tool.api.R;
import java.rmi.ServerException;
import java.util.List;
/**
 * æœ¬åœ°ç³»ç»Ÿæ—¥å¿—
 * @author ludc
 * @date 2023/10/31 15:38
 */
public interface ILogLocalService {
    /**
     * æŸ¥çœ‹ï¼Œæœ¬åœ°ç³»ç»Ÿæ—¥å¿—列表
     * @param logParentPath
     * @return
     */
    List<LocalLog> getSystemLogList(String logParentPath);
    /**
     * ä¸‹è½½ï¼Œæ ¹æ®æœåŠ¡åæ‰€åœ¨æ–‡ä»¶åå’Œæ–‡ä»¶åä¸‹è½½æ–‡ä»¶
     * @param localLogVO ä¸‹è½½æ—¥å¿—的对象
     * @return æ–‡ä»¶çš„信息
     */
    FileObjectBO downloadLogByServiceNameAndFileName(LocalLogVO localLogVO) throws ServerException;
    /**
     * åˆ é™¤ï¼Œæ ¹æ®æœåŠ¡æ‰€åœ¨æ–‡ä»¶åï¼Œå’Œæ—¥å¿—æ–‡ä»¶åç§°åˆ é™¤
     * @param localLogVO
     * @return æ‰§è¡Œç»“æžœ
     */
    R deleteLogFile(LocalLogVO localLogVO) throws ServerException;
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogOperateService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.vci.ubcs.log.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.vci.ubcs.log.entity.LogOperate;
import com.vci.ubcs.starter.web.pagemodel.BladeQueryObject;
import org.springblade.core.log.exception.ServiceException;
import java.util.List;
/**
 * æ“ä½œæ—¥å¿—管理:(包括登录日志、操作日志、授权日志,以及管理员的以上三种日志)
 * @author ludc
 * @date 2023/11/24 10:50
 */
public interface ILogOperateService extends IService<LogOperate> {
    /**
     * ä¿å­˜æ“ä½œæ—¥å¿—
     * @param logOperate
     * @return
     */
    boolean saveLogOperate(LogOperate logOperate) throws ServiceException;
    /**
     * æ¡ä»¶æŸ¥è¯¢èŽ·å–æ—¥å¿—åˆ—è¡¨
     * @param bladeQueryObject
     * @return
     */
    List<LogOperate> listByCondition(BladeQueryObject bladeQueryObject) throws ServiceException;
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/ILogSystemService.java
ÎļþÒÑɾ³ý
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogLocalServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,310 @@
package com.vci.ubcs.log.service.impl;
import com.vci.ubcs.log.vo.LocalLogVO;
import com.vci.ubcs.log.service.ILogLocalService;
import com.vci.ubcs.log.entity.LocalLog;
import com.vci.ubcs.resource.utils.FileUtil;
import com.vci.ubcs.resource.utils.ZipUtil;
import com.vci.ubcs.starter.exception.VciBaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springblade.core.log.exception.ServiceException;
import com.vci.ubcs.omd.cache.EnumCache;
import com.vci.ubcs.omd.enums.EnumEnum;
import com.vci.ubcs.resource.bo.FileObjectBO;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.rmi.ServerException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * æœ¬åœ°ç³»ç»Ÿæ—¥å¿—
 * @author ludc
 * @date 2023/10/31 15:39
 */
@Service
@Slf4j
public class LogLocalServiceImpl implements ILogLocalService{
    /**
     * å„个服务存放的的父路径
     */
    @Value("${local-log.parent-path:/data1/ubcs/ubcs-server}")
    private String PARENTPATH;
    /**
     * æ—¥å¿—文件的具体位置
     */
    @Value("${local-log.log-path:/target/log}")
    private String LOGPATH;
    /**
     * å½“前操作系统,是否为windows系统
     */
    private Boolean isWindows = true;
    {
        String os = System.getProperty("os.name").toLowerCase();
        //默认就配置为windows的,如果不是当前系统不是windows就需要对其转换为linux的文件路径格式
        if (!os.contains("win")) {
            this.PARENTPATH = this.PARENTPATH.substring(this.PARENTPATH.lastIndexOf(":") + 1).replace("\\", "/");
            this.LOGPATH = this.LOGPATH.replace("\\", "/");
            this.isWindows = false;
        }
    }
    /**
     * åŽ‹ç¼©æ–‡ä»¶çš„å·¥å…·ç±»
     */
    @Resource
    private ZipUtil zipUtil;
    /**
     * èŽ·å–æœ¬åœ°æ—¥å¿—åˆ—è¡¨
     * @param logParentPath
     * @return
     */
    //@Override
    public List<LocalLog> getSystemLogList(String logParentPath) {
        List<LocalLog> localLogs = new ArrayList<>();
        // ä¸ä¸ºç©ºè¯´æ˜Žæ˜¯åŠ è½½å½“å‰è¿™ä¸ªæœåŠ¡è·¯å¾„ä¸‹çš„æ—¥å¿—æ–‡ä»¶
        if(Func.isNotEmpty(logParentPath)){
            File file = new File(logParentPath);
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                Arrays.stream(files).forEach(item->{
                    // ç»„建日志文件对象
                    LocalLog localLog = new LocalLog();
                    localLog.setLogName(item.getName());
                    localLog.setLogType(getLogType(item.getName()));
                    localLog.setCreateTime(getLastModifiedOrCreatTime(false,logParentPath));
                    localLog.setLastModifier(getLastModifiedOrCreatTime(true,logParentPath));
                    localLog.setLogPath(logParentPath);
                    String serviceId = getServiceId(logParentPath);
                    localLog.setServiceId(serviceId);
                    localLog.setServiceName(getServiceName(serviceId));
                    localLog.setHasChildren(false);
                    localLogs.add(localLog);
                });
            }
        }else {
            File fileDir = new File(PARENTPATH);
            File[] childDir = fileDir.listFiles();
            Arrays.stream(childDir).forEach(dir->{
                if(dir.getName().contains("ubcs_")){
                    String fullPath = dir.getPath() + LOGPATH;
                    File file = new File(fullPath);
                    LocalLog localLog = new LocalLog();
                    localLog.setLastModifier(getLastModifiedOrCreatTime(true,fullPath));
                    localLog.setCreateTime(getLastModifiedOrCreatTime(false,fullPath));
                    localLog.setLogPath(fullPath);
                    String serviceId = getServiceId(file.getPath());
                    localLog.setServiceId(serviceId);
                    String serviceName = getServiceName(serviceId);
                    localLog.setServiceName(serviceName);
                    localLog.setLogType(serviceName+"日志父目录");
                    localLog.setLogName(serviceName+"日志父目录");
                    localLog.setHasChildren(true);
                    localLogs.add(localLog);
                }
            });
        }
        return localLogs;
    }
    /**
     * èŽ·å–æ–‡ä»¶æœ€åŽä¿®æ”¹æˆ–è€…åˆ›å»ºæ—¶é—´
     * @param isModifier
     * @return
     */
    private String getLastModifiedOrCreatTime(boolean isModifier,String pathStr) {
        Path path = FileSystems.getDefault().getPath(pathStr);
        String date = "";
        try {
            BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // æ˜¯èŽ·å–æœ€åŽä¿®æ”¹æ—¶é—´
            if(isModifier){
                date = dateFormat.format(new Date(attr.lastModifiedTime().toMillis()));
            }else {
                date = dateFormat.format(new Date(attr.creationTime().toMillis()));
            }
        } catch (IOException e) {
            throw new ServiceException("Error reading file date attributes: " + e.getMessage());
        }
        return date;
    }
    /**
     * èŽ·å–æ—¥å¿—ç±»åž‹
     * @param fileName
     * @return
     */
    private String getLogType(String fileName){
        //判断日志的的类型
        if (fileName.contains("error")) {
            return "Error";
        } else if (fileName.contains("info")) {
            return "Info";
        } else if (fileName.contains("warning")) {
            return "Warning";
        } else {
            return "Unknown";
        }
    }
    /**
     * èŽ·å–æœåŠ¡ID
     * @param servciePath
     * @return
     */
    private String getServiceId(String servciePath){
        // æ ¹æ®å½“前操作系统来决定是通过什么字符来截取
        String[] parts = servciePath.split(this.isWindows ? "\\\\":"/");
        String extractedString = "";
        if(parts.length > 3){
            extractedString = parts[parts.length - 3];
        }
        return extractedString;
    }
    /**
     * èŽ·å–æœåŠ¡åç§°
     * @param serViceId
     * @return
     */
    private String getServiceName(String serViceId){
        return EnumCache.getValue(EnumEnum.SERCIVE_NAME_ROLE, serViceId);
    }
    /**
     * æˆªå–路径中的日志文件名称
     * @param logFullPath
     * @return
     */
    private String getLogFileName(String logFullPath){
        // æ ¹æ®å½“前操作系统来决定是通过什么字符来截取
        String[] parts = logFullPath.split(this.isWindows ? "\\\\":"/");
        String logFileName = "";
        if(parts.length > 3){
            logFileName = parts[parts.length - 1];
        }
        return logFileName;
    }
    /**
     * ä¸‹è½½æ—¥å¿—文件
     * @param localLogVO ä¸‹è½½æ—¥å¿—对象
     * @return
     * @throws ServerException
     */
    @Override
    public FileObjectBO downloadLogByServiceNameAndFileName(LocalLogVO localLogVO) throws ServerException {
        if(Func.isEmpty(localLogVO) || Func.isEmpty(localLogVO.getLogPath())){
            throw new ServerException("未获取到该日志路径!");
        }
        FileObjectBO fileObjectBO = new FileObjectBO();
        String logFullPaths = localLogVO.getLogFullPaths();
        // åˆ¤æ–­æ˜¯å¦æ˜¯çˆ¶ç›®å½•
        if(!localLogVO.getHasChildren()){
            //只下载一个日志文件
            File file = new File(logFullPaths);
            if(!file.isFile() || !file.exists()){
                throw new ServerException("本地日志文件路径"+ logFullPaths +"中未找到日志");
            }
            try {
                fileObjectBO.setName(file.getName());
                fileObjectBO.setInputStream(new FileInputStream(file));
                fileObjectBO.setFileLocalPath(logFullPaths);
                fileObjectBO.setFileExtension(".log");
            }catch (Throwable e){
                throw new VciBaseException("获取文件的流有问题",new String[]{logFullPaths},e);
            }
        }else{
            // æ˜¯çˆ¶ç›®å½•,所以需要获取到下面的所有子目录
            // æœ‰å¤šä¸ªï¼Œéœ€è¦ä½¿ç”¨zip进行压缩
            String tempFolder = FileUtil.getDefaultTempFolder();
            File[] file1 = new File(logFullPaths).listFiles();
            if(file1.length > 0){
                Arrays.stream(file1).forEach(item->{
                    String fileName = tempFolder + File.separator + System.currentTimeMillis() + ".log";
                    File file = new File(fileName);
                    try {
                        if(!file.exists()) {
                            file.createNewFile();
                        }
                    }catch (Throwable e){
                        throw new VciBaseException("创建文件出错,{0}",new String[]{fileName});
                    }
                    File logFile = new File(item.getPath());
                    if(!logFile.exists() || !logFile.isFile()){
                        throw new VciBaseException("本地日志文件路径"+item.getPath()+"中未找到日志");
                    }
                    try(OutputStream os = new FileOutputStream(file);
                        InputStream ins = new FileInputStream(logFile);
                    ){
                        IOUtils.copy(ins,os);
                    }catch (Throwable e){
                        throw new VciBaseException("下载文件到临时文件夹里出错,{0}",new String[]{fileName});
                    }
                });
                String zipName = new File(tempFolder).getPath() + File.separator + getLogFileName(logFullPaths) + "等"+file1.length + "个文件.zip";
                zipUtil.folderToZipFile(tempFolder,zipName);
                fileObjectBO.setFileLocalPath(zipName);
                fileObjectBO.setFileExtension(".log");
                if(log.isDebugEnabled()){
                    log.debug("下载文件的信息,",zipName);
                }
            }
        }
        return fileObjectBO;
    }
    /**
     * åˆ é™¤æ—¥å¿—文件
     * @param localLogVO æ–‡ä»¶å…¨è·¯å¾„集合
     * @throws ServerException
     */
    @Override
    public R deleteLogFile(LocalLogVO localLogVO) throws ServerException {
        List<String> resMsgs = new ArrayList<>();
        // åˆ¤æ–­æ˜¯å¦æ˜¯æ—¥å¿—顶层目录
        if(localLogVO.getHasChildren()){
            // æ˜¯é¡¶å±‚目录,需要循环去删除包含的所有日志文件
            File parentFile = new File(localLogVO.getLogFullPaths());
            if(parentFile.isDirectory()){
                Arrays.stream(parentFile.listFiles()).forEach(logFile->{
                    if (logFile.exists()) {
                        //删除失败的直接记录下文件名
                        if (!logFile.delete()) {
                            resMsgs.add(getLogFileName(logFile.getPath()));
                        }
                    }
                });
            }
        }else {
            // å•个删除
            File file = new File(localLogVO.getLogFullPaths());
            if (file.exists()) {
                //删除失败的直接记录下文件名
                if (!file.delete()) {
                    resMsgs.add(getLogFileName(localLogVO.getLogFullPaths()));
                }
            }
        }
        return resMsgs.size()==0 ? R.success("删除成功!"):R.fail("以下日志文件:"+resMsgs.stream().collect(Collectors.joining(","))+"删除失败!");
    }
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogOperateServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.vci.ubcs.log.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.vci.ubcs.log.entity.LogOperate;
import com.vci.ubcs.log.mapper.LogOperateMapper;
import com.vci.ubcs.log.service.ILogOperateService;
import com.vci.ubcs.starter.web.pagemodel.BladeQueryObject;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * æ“ä½œæ—¥å¿—管理:(包括登录日志、操作日志、授权日志,以及管理员的以上三种日志)
 * @author ludc
 * @date 2023/11/24 10:51
 */
@Service
public class LogOperateServiceImpl extends ServiceImpl<LogOperateMapper,LogOperate> implements ILogOperateService {
    @Autowired
    private LogOperateMapper logOperateMapper;
    /**
     * ä¿å­˜æ“ä½œæ—¥å¿—
     * @param logOperate
     * @return
     */
    @Override
    public boolean saveLogOperate(LogOperate logOperate)throws ServiceException {
        if(Func.isEmpty(logOperate)){
            return false;
        }
        return SqlHelper.retBool(logOperateMapper.insert(logOperate));
    }
    /**
     * æ¡ä»¶æŸ¥è¯¢èŽ·å–æ—¥å¿—åˆ—è¡¨
     * @param bladeQueryObject
     * @return
     */
    @Override
    public List<LogOperate> listByCondition(BladeQueryObject bladeQueryObject) throws ServiceException{
        Map<String, Object> conditionMap = bladeQueryObject.getConditionMap();
        if(conditionMap.isEmpty() || Func.isBlank(conditionMap.get("logType").toString())){
            throw new ServiceException("日志查询必传参数【日志类型】不能为空!");
        }
        // map对象转换为查询对象
        QueryWrapper<LogOperate> queryWrapper = Condition.getQueryWrapper(bladeQueryObject.getConditionMap(),LogOperate.class);
        return this.list(queryWrapper);
    }
}
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogSystemServiceImpl.java
ÎļþÒÑɾ³ý
Source/UBCS/ubcs-ops/ubcs-resource/src/main/java/com/vci/ubcs/resource/controller/FileController.java
@@ -1,6 +1,7 @@
package com.vci.ubcs.resource.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.vci.ubcs.resource.dto.FileObjectDTO;
import com.vci.ubcs.resource.dto.FileReleaseDTO;
@@ -24,6 +25,7 @@
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;
@@ -51,14 +53,18 @@
     * @return æ‰§è¡Œç»“果,只有下载失败的时候才会这样
     */
    @RequestMapping(value = "/downloadFilesByOids",method = {RequestMethod.GET,RequestMethod.POST})
    public String downloadFilesByOids(@RequestParam String fileOids, HttpServletResponse response){
    public void downloadFilesByOids(@RequestParam String fileOids, HttpServletResponse response) throws IOException {
        try{
            //ControllerUtil.writeFileToResponse(response,excelName);
            FileDownloadUtil.downloadFile(response, fileService.downloadFileByOids(VciBaseUtil.str2List(fileOids)));
        }catch (Throwable e){
            return JSON.toJSONString(R.fail(LangBaseUtil.getErrorMsg(e)));
            //如果出错,把错误信息写到text
            String msg = LangBaseUtil.getErrorMsg(e);
            if(StringUtils.isBlank(msg)){
                msg = "未知错误";
        }
        //因为设置了响应contentType,所以这儿不能再直接返回R了,可能会导致报错
        return JSON.toJSONString(R.success("下载完成")) ;
            ControllerUtil.writeDataToResponse(response,msg.getBytes(StandardCharsets.UTF_8),null);
        }
    }
    /**
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/application-prod.yml
@@ -23,7 +23,3 @@
  secret-key: Reo4wW8EWF4gSizUmVsNjWfbDZzR3rBYFn5Jehd9
  bucket-name: vci-ubcs
#关闭驼峰命名映射
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: false
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/mapper/AttachMapper.xml
@@ -22,7 +22,7 @@
    <select id="selectAttachPage" resultMap="attachResultMap">
        select * from blade_attach where is_deleted = 0
        select * from blade_attach where isdeleted = 0
    </select>
</mapper>
Source/UBCS/ubcs-ops/ubcs-resource/src/main/resources/mapper/SmsMapper.xml
@@ -24,7 +24,7 @@
    <select id="selectSmsPage" resultMap="smsResultMap">
        select * from pl_sys_sms where is_deleted = 0
        select * from pl_sys_sms where isdeleted = 0
    </select>
</mapper>
Source/UBCS/ubcs-service/ubcs-applyjtcodeservice/src/main/java/com/vci/ubcs/code/applyjtcodeservice/service/impl/DockingPreAttrMappingServiceImpl.java
@@ -225,7 +225,7 @@
        try {
            count = dockingPreAttrMappingMapper.selectCount(Wrappers.<DockingPreAttrMapping>query().lambda().eq(DockingPreAttrMapping::getTargetClassifyId, targetClassifyId).eq(DockingPreAttrMapping::getSourceClassifyId,sourceClassifyId));
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
        } finally {
            return  count>0?true:false;
        }
Source/UBCS/ubcs-service/ubcs-applyjtcodeservice/src/main/java/com/vci/ubcs/code/applyjtcodeservice/service/impl/GroupMdmInterServiceImpl.java
@@ -471,7 +471,7 @@
            }
            return R.success(message);
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            log.error("获取数据模型失败"+e);
            R.fail(message);
        }
@@ -537,7 +537,7 @@
            }
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            log.error("获取申请单状态失败"+e);
            throw  new VciBaseException(message);
        }
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/CodeApplication.java
@@ -16,12 +16,10 @@
 */
package com.vci.ubcs.code;
import com.vci.ubcs.starter.util.VciSpringUtil;
import org.springblade.core.cloud.client.UbcsCloudApplication;
import org.springblade.core.launch.UbcsApplication;
import org.springblade.core.launch.constant.AppConstant;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
/**
 * Code启动器
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/controller/CodeSyncUniversalController.java
@@ -71,7 +71,7 @@
            this.setHttpToThreadLocal(request);
            result= universalInterfaceI.syncEditData(dataString,dataType);
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            logger.error("syncData->"+e.getMessage());
        }
        return result;
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/CodeApplyWebManagementServiceImpl.java
@@ -48,7 +48,7 @@
        QueryWrapper<SystemClassifyRole> wrapper = new QueryWrapper<>();
        wrapper.eq("systemOid",systemOid);
        wrapper.eq("systemId",systemId);
        List<SystemClassifyRole> systemClassifyRoles = this.listByIds(roleList.stream().map(SystemClassifyRole ::getOid).collect(Collectors.toList()));;
        List<SystemClassifyRole> systemClassifyRoles = this.listByIds(roleList.stream().map(SystemClassifyRole ::getOid).collect(Collectors.toList()));
        this.remove(wrapper);
        List<SystemClassifyRole> newSCRoles = new ArrayList<>();
        //数据处理
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmEngineServiceImpl.java
@@ -873,13 +873,13 @@
                    //不忽略大小写、不去空、不忽略全半角
                    temp = "%s";
                }
                queryKey = String.format(temp, "t." + attrId);
                queryKey = String.format(temp, "nvl("+ "t." + attrId +",'/')");
                queryValue = String.format(temp, "'" + (trim ? value.trim() : value) + "'");
                conditionMap.put(queryKey, queryValue);
            } else {
                if(StringUtils.isNotBlank(value)) {
                    //为空的时候不代表不校验,只是不去除相关的信息
                    conditionMap.put("t." + attrId, "'" + value + "'");
                    conditionMap.put("nvl("+ "t." + attrId+",'/')", "'" + value + "'");
                }else{
                    conditionMap.put("t." + attrId, QueryOptionConstant.ISNULL);
                }
@@ -1961,7 +1961,7 @@
        String sqlHasPage = pageHelper.getLimit() > 0 ? ("select * from (select A.*,rownum RN from (" + sql + whereSubfixForPage) : sql;
        String sqlCount = "select count(1) from " + tableName + SPACE + "t" + SPACE + joinTableList.values().stream().collect(Collectors.joining(SPACE))
                + (StringUtils.isBlank(whereSql) ? "" : " where ") + whereSql;
        String sqlId = "select ID from " + tableName + SPACE + "t" + SPACE + joinTableList.values().stream().collect(Collectors.joining(SPACE))
        String sqlId = "select t.ID from " + tableName + SPACE + "t" + SPACE + joinTableList.values().stream().collect(Collectors.joining(SPACE))
            + (StringUtils.isBlank(whereSql) ? "" : " where ") + whereSql;
        CodeTemplateAttrSqlBO sqlBO = new CodeTemplateAttrSqlBO();
        sqlBO.setTableName(tableName);
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmIOServiceImpl.java
@@ -885,7 +885,7 @@
            String idFieldName = attrVOS.stream().filter(s -> VciQueryWrapperForDO.ID_FIELD.equalsIgnoreCase(s.getId())).findFirst().orElseGet(() -> new CodeClassifyTemplateAttrVO()).getName();
            getFieldIndexMap(titleRowData, attrNameIdMap, fieldIndexMap);
            //先不用管属性是否都存在,先转换一下数据
            List<ClientBusinessObject> cboList = new CopyOnWriteArrayList<>();
            List<ClientBusinessObject> cboList = new ArrayList<>();
            String fullPath = getFullPath(classifyFullInfo);
            //我们需要获取到所有的下级分类的oid的路径,因为后面需要
            Map<String/**主键**/, String/**路径**/> childOidPathMap = getChildClassifyPathMap(classifyFullInfo, fullPath);
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/UniversalInterfaceImpl.java
@@ -1070,7 +1070,7 @@
                }
            });
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            msg="编码更改/状态更改/删除:"+e.getMessage();
          /*  XMLResultSystemVO XMLResultSystemVO=new XMLResultSystemVO();
            XMLResultSystemVO.setErrorid(errorid);
@@ -1254,7 +1254,7 @@
            issucess=true;
            resultData.setLibrary(libraryVo);
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            msg="查询分类失败:"+e.getMessage();
        }finally {
            resultData.setErrorid(errorid);
@@ -1473,7 +1473,7 @@
                msg = "接口参数:library æœªæŸ¥è¯¢åˆ°å¯¹åº”的库节点信息";
            }
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            msg="查询数据失败:"+e.getMessage();
        }finally {
            resultDataVO.setErrorid(errorid);
@@ -1925,7 +1925,7 @@
            issucess=true;
            resultClassifyRuleData.setLibrary(resultLibraryVO);
        }catch (Throwable e){
            e.printStackTrace();;
            e.printStackTrace();
            msg="查询分类失败:"+e.getMessage();
        }finally {
            resultClassifyRuleData.setErrorid(errorid);
Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/wrapper/CodeButtonWrapper.java
@@ -38,7 +38,7 @@
    @Override
    public CodeButtonVO entityVO(CodeButton codebutton) {
        CodeButtonVO codebuttonVO = new CodeButtonVO();;
        CodeButtonVO codebuttonVO = new CodeButtonVO();
        BeanUtilForVCI.copyPropertiesIgnoreCase(codebutton,codebuttonVO);
        Objects.requireNonNull(codebuttonVO);
        codebuttonVO.setUsedpositiontypeText(DictCache.getValue("codeButtonPosition", codebutton.getUsedPositionType()));
Source/UBCS/ubcs-service/ubcs-system/src/main/java/com/vci/ubcs/system/controller/MdmCountConfigController.java
@@ -30,5 +30,4 @@
        return countConfigService.saveMdmCountConfig(mdmCountConfigVO);
    }
}