wenhongquan 1 год назад
Родитель
Сommit
1d1a3005a5

+ 50 - 3
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java

@@ -1,20 +1,30 @@
 package com.ruoyi.web.controller.monitor;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
+import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.constant.CacheNames;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
+import com.ruoyi.common.core.domain.entity.SysUser;
+import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.JsonUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.common.utils.redis.CacheUtils;
 import com.ruoyi.common.utils.redis.RedisUtils;
 import com.ruoyi.system.domain.SysCache;
+import com.ruoyi.system.domain.SysUserOnline;
+import com.ruoyi.system.domain.vo.CacheDataVo;
 import lombok.RequiredArgsConstructor;
 import org.redisson.spring.data.connection.RedissonConnectionFactory;
 import org.springframework.data.redis.connection.RedisConnection;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -72,6 +82,34 @@ public class CacheController {
         return R.ok(result);
     }
 
+    @Log(title = "缓存导出", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response) {
+
+        RedisConnection connection = connectionFactory.getConnection();
+        Properties info = connection.info();
+        Properties commandStats = connection.info("commandstats");
+        Long dbSize = connection.dbSize();
+
+        Map<String, Object> result = new HashMap<>(3);
+        result.put("info", info);
+        result.put("dbSize", dbSize);
+        List<CacheDataVo> cacheDataVoList = new ArrayList<>();
+
+//        List<Map<String, String>> pieList = new ArrayList<>();
+        if (commandStats != null) {
+            commandStats.stringPropertyNames().forEach(key -> {
+                Map<String, String> data = new HashMap<>(2);
+                String property = commandStats.getProperty(key);
+                CacheDataVo vo = new CacheDataVo();
+                vo.setName(StringUtils.removeStart(key, "cmdstat_"));
+                vo.setValue(StringUtils.substringBetween(property, "calls=", ",usec"));
+                cacheDataVoList.add(vo);
+            });
+        }
+        ExcelUtil.exportExcel(cacheDataVoList, "用户数据", CacheDataVo.class, response);
+    }
+
     /**
      * 获取缓存监控缓存名列表
      */
@@ -81,6 +119,12 @@ public class CacheController {
         return R.ok(CACHES);
     }
 
+
+    @Log(title = "缓存列表导出", businessType = BusinessType.EXPORT)
+    @PostMapping("/listexport")
+    public void exportlist(HttpServletResponse response) {
+        ExcelUtil.exportExcel(CACHES, "用户数据", SysCache.class, response);
+    }
     /**
      * 获取缓存监控Key列表
      *
@@ -92,9 +136,12 @@ public class CacheController {
         Collection<String> cacheKeys = new HashSet<>(0);
         if (isCacheNames(cacheName)) {
             Set<Object> keys = CacheUtils.keys(cacheName);
-            if (CollUtil.isNotEmpty(keys)) {
-                cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList());
-            }
+            try{
+                if (CollUtil.isNotEmpty(keys)) {
+                    cacheKeys = keys.stream().map(Object::toString).collect(Collectors.toList());
+                }
+            }catch (Exception e){}
+
         } else {
             cacheKeys = RedisUtils.keys(cacheName + "*");
         }

+ 30 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysUserOnlineController.java

@@ -4,20 +4,26 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.dev33.satoken.exception.NotLoginException;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.constant.CacheConstants;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.utils.StreamUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.common.utils.redis.RedisUtils;
 import com.ruoyi.system.domain.SysUserOnline;
+import com.ruoyi.system.domain.vo.SysUserExportVo;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -87,4 +93,28 @@ public class SysUserOnlineController extends BaseController {
         }
         return R.ok();
     }
+
+    @Log(title = "在线用户", businessType = BusinessType.EXPORT)
+    @SaCheckPermission("system:user:export")
+    @PostMapping("/export")
+    public void export(SysUser user, HttpServletResponse response) {
+
+
+        // 获取所有未过期的 token
+        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
+        List<UserOnlineDTO> userOnlineDTOList = new ArrayList<>();
+        for (String key : keys) {
+            String token = StringUtils.substringAfterLast(key, ":");
+            // 如果已经过期则跳过
+            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
+                continue;
+            }
+            userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
+        }
+        Collections.reverse(userOnlineDTOList);
+        userOnlineDTOList.removeAll(Collections.singleton(null));
+        List<SysUserOnline> userOnlineList = BeanUtil.copyToList(userOnlineDTOList, SysUserOnline.class);
+
+        ExcelUtil.exportExcel(userOnlineList, "用户数据", SysUserOnline.class, response);
+    }
 }

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -277,4 +277,4 @@ mqtt:
   user: ${MQTT_USER:iotc}
   password: ${MQTT_PWD:iotc}
   topic: ${MQTT_TOPIC:/sensor/#}
-  saveAndForward: ${DATASAVE:true}
+  saveAndForward: ${DATASAVE:false}

+ 2 - 0
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysUser.java

@@ -158,6 +158,8 @@ public class SysUser extends BaseEntity {
     @TableField(exist = false)
     private Long roleId;
 
+    private String ext1;
+
     public SysUser(Long userId) {
         this.userId = userId;
     }

+ 8 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblDatapointVo.java

@@ -85,6 +85,14 @@ public class TblDatapointVo implements Serializable {
 
     private String unitType;
 
+    private Date createTime;
+
+    private Date updateTime;
+
+    private Long createBy;
+
+    private Long updateBy;
+
     private int toOffset;
 
 }

+ 5 - 3
ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml

@@ -24,6 +24,7 @@
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
         <result property="remark" column="remark"/>
+        <result property="ext1" column="ext1"/>
         <association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult"/>
         <collection property="roles" javaType="java.util.List" resultMap="RoleResult"/>
     </resultMap>
@@ -77,7 +78,8 @@
                r.role_key,
                r.role_sort,
                r.data_scope,
-               r.status as role_status
+               r.status as role_status,
+               u.ext1
         from sys_user u
             left join sys_dept d on u.dept_id = d.dept_id
             left join sys_user_role sur on u.user_id = sur.user_id
@@ -86,7 +88,7 @@
 
     <select id="selectPageUserList" resultMap="SysUserResult">
         select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
-            u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
+            u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader,u.ext1
         from sys_user u
             left join sys_dept d on u.dept_id = d.dept_id
         ${ew.getCustomSqlSegment}
@@ -94,7 +96,7 @@
 
     <select id="selectUserList" resultMap="SysUserResult">
         select u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex,
-            u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader
+            u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader,u.ext1
         from sys_user u
             left join sys_dept d on u.dept_id = d.dept_id
         ${ew.getCustomSqlSegment}

+ 7 - 0
ruoyi-ui-vue3/src/api/monitor/online.js

@@ -16,3 +16,10 @@ export function forceLogout(tokenId) {
     method: 'delete'
   })
 }
+
+export function exportexcel() {
+  return request({
+    url: '/monitor/online/export',
+    method: 'post'
+  })
+}

+ 5 - 78
ruoyi-ui-vue3/src/views/data/datapoint/index.vue

@@ -49,38 +49,6 @@
           @keyup.enter.native="handleQuery"
         />
       </el-form-item>
-      <el-form-item label="创建人" prop="creator">
-        <el-input
-          v-model="queryParams.creator"
-          placeholder="请输入创建人"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="创建时间" prop="ctime">
-        <el-date-picker clearable
-          v-model="queryParams.ctime"
-          type="date"
-          value-format="yyyy-MM-dd"
-          placeholder="请选择创建时间">
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item label="更新人" prop="modifier">
-        <el-input
-          v-model="queryParams.modifier"
-          placeholder="请输入更新人"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
-      <el-form-item label="更新时间" prop="utime">
-        <el-input
-          v-model="queryParams.utime"
-          placeholder="请输入更新时间"
-          clearable
-          @keyup.enter.native="handleQuery"
-        />
-      </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
@@ -145,16 +113,8 @@
       <el-table-column label="待读寄存器的个数" align="center" prop="len" />
       <el-table-column label="变量类型" align="center" prop="valueType" />
       <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="创建人" align="center" prop="creator" />
-      <el-table-column label="创建时间" align="center" prop="ctime" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.ctime, '{y}-{m}-{d}') }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="更新人" align="center" prop="modifier" />
-      <el-table-column label="更新时间" align="center" prop="utime" />
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template slot-scope="scope">
+        <template #default="scope">
           <el-button
             size="mini"
             type="text"
@@ -205,23 +165,6 @@
         <el-form-item label="备注" prop="remark">
           <el-input v-model="form.remark" placeholder="请输入备注" />
         </el-form-item>
-        <el-form-item label="创建人" prop="creator">
-          <el-input v-model="form.creator" placeholder="请输入创建人" />
-        </el-form-item>
-        <el-form-item label="创建时间" prop="ctime">
-          <el-date-picker clearable
-            v-model="form.ctime"
-            type="datetime"
-            value-format="yyyy-MM-dd HH:mm:ss"
-            placeholder="请选择创建时间">
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label="更新人" prop="modifier">
-          <el-input v-model="form.modifier" placeholder="请输入更新人" />
-        </el-form-item>
-        <el-form-item label="更新时间" prop="utime">
-          <el-input v-model="form.utime" placeholder="请输入更新时间" />
-        </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
         <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
@@ -270,10 +213,6 @@ export default {
         addrOffset: undefined,
         len: undefined,
         valueType: undefined,
-        creator: undefined,
-        ctime: undefined,
-        modifier: undefined,
-        utime: undefined
       },
       // 表单参数
       form: {},
@@ -309,18 +248,6 @@ export default {
         remark: [
           { required: true, message: "备注不能为空", trigger: "blur" }
         ],
-        creator: [
-          { required: true, message: "创建人不能为空", trigger: "blur" }
-        ],
-        ctime: [
-          { required: true, message: "创建时间不能为空", trigger: "blur" }
-        ],
-        modifier: [
-          { required: true, message: "更新人不能为空", trigger: "blur" }
-        ],
-        utime: [
-          { required: true, message: "更新时间不能为空", trigger: "blur" }
-        ]
       }
     };
   },
@@ -355,10 +282,10 @@ export default {
         len: undefined,
         valueType: undefined,
         remark: undefined,
-        creator: undefined,
-        ctime: undefined,
-        modifier: undefined,
-        utime: undefined
+        createBy: undefined,
+        createTime: undefined,
+        updateBy: undefined,
+        updateTime: undefined
       };
       this.resetForm("form");
     },

+ 11 - 1
ruoyi-ui-vue3/src/views/monitor/cache/index.vue

@@ -45,7 +45,9 @@
 
       <el-col :span="12" class="card-box">
         <el-card>
-          <template #header><PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">命令统计</span></template>
+          <template #header> <PieChart style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">命令统计</span>
+            <el-button style="float: right;" type="primary" link @click="exportfile">导出</el-button>
+          </template>
           <div class="el-table el-table--enable-row-hover el-table--medium">
             <div ref="commandstats" style="height: 420px" />
           </div>
@@ -73,6 +75,14 @@ const commandstats = ref(null);
 const usedmemory = ref(null);
 const { proxy } = getCurrentInstance();
 
+
+const  exportfile = () => {
+  proxy.download('/monitor/cache/export', {
+    // ...queryParams.value
+  }, `缓存_${new Date().getTime()}.xlsx`)
+
+};
+
 function getList() {
   proxy.$modal.loading("正在加载缓存监控数据,请稍候!");
   getCache().then(response => {

+ 17 - 0
ruoyi-ui-vue3/src/views/monitor/cache/list.vue

@@ -5,6 +5,14 @@
         <el-card style="height: calc(100vh - 125px)">
           <template #header>
             <Collection style="width: 1em; height: 1em; vertical-align: middle;" /> <span style="vertical-align: middle;">缓存列表</span>
+
+
+            <el-button
+              style="float: right; padding: 3px 0"
+              link
+              type="primary"
+              @click="exportfile()"
+            >导出</el-button>
             <el-button
               style="float: right; padding: 3px 0"
               link
@@ -167,6 +175,15 @@ const subLoading = ref(false);
 const nowCacheName = ref("");
 const tableHeight = ref(window.innerHeight - 200);
 
+
+const  exportfile = () => {
+  proxy.download('/monitor/cache/listexport', {
+    // ...queryParams.value
+  }, `缓存_${new Date().getTime()}.xlsx`)
+
+};
+
+
 /** 查询缓存名称列表 */
 function getCacheNames() {
   loading.value = true;

+ 9 - 1
ruoyi-ui-vue3/src/views/monitor/online/index.vue

@@ -22,6 +22,7 @@
          <el-form-item>
             <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
             <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+           <el-button icon="Download" @click="exportfile">导出excel</el-button>
          </el-form-item>
       </el-form>
       <el-table
@@ -58,7 +59,7 @@
 </template>
 
 <script setup name="Online">
-import { forceLogout, list as initData } from "@/api/monitor/online";
+import { forceLogout, list as initData,exportexcel } from "@/api/monitor/online";
 
 const { proxy } = getCurrentInstance();
 
@@ -73,6 +74,13 @@ const queryParams = ref({
   userName: undefined
 });
 
+
+const  exportfile = () => {
+  proxy.download('/monitor/online/export', {
+    ...queryParams.value
+  }, `用户_${new Date().getTime()}.xlsx`)
+
+};
 /** 查询登录日志列表 */
 function getList() {
   loading.value = true;

+ 51 - 1
ruoyi-ui-vue3/src/views/system/user/index.vue

@@ -225,6 +225,29 @@
                   </el-form-item>
                </el-col>
             </el-row>
+
+           <el-row>
+             <el-col :span="12">
+               <el-form-item  label="工号" prop="ext1.gh">
+                 <el-input v-model="form.ext1.gh" placeholder="请输入工号" maxlength="30" />
+               </el-form-item>
+             </el-col>
+             <el-col :span="12">
+               <el-form-item  label="生日" prop="ext1.sr">
+                 <el-date-picker
+                   v-model="form.ext1.sr"
+                   type="date"
+                   placeholder="选择日期"
+                   style="width: 100%;"
+                 />
+               </el-form-item>
+             </el-col>
+             <el-col :span="24">
+               <el-form-item label="身份证号" prop="ext1.sfz">
+                 <el-input v-model="form.ext1.sfz" placeholder="身份证号"  maxlength="20" />
+               </el-form-item>
+             </el-col>
+           </el-row>
             <el-row>
                <el-col :span="12">
                   <el-form-item label="用户性别">
@@ -252,7 +275,7 @@
             </el-row>
             <el-row>
                <el-col :span="12">
-                  <el-form-item label="位">
+                  <el-form-item label="位">
                      <el-select v-model="form.postIds" multiple placeholder="请选择">
                         <el-option
                            v-for="item in postOptions"
@@ -546,6 +569,11 @@ function reset() {
     sex: undefined,
     status: "0",
     remark: undefined,
+    ext1:{
+      gh:"",
+      sfz:"",
+      sr:""
+    },
     postIds: [],
     roleIds: []
   };
@@ -565,6 +593,15 @@ function handleAdd() {
     open.value = true;
     title.value = "添加用户";
     form.value.password = initPassword.value;
+    if(form.value["ext1"]==null){
+      form.value["ext1"]={
+        gh:"",
+        sfz:"",
+        sr:""
+      }
+    }else {
+      form.value["ext1"]=JSON.parse(form.value["ext1"]);
+    }
   });
 };
 /** 修改按钮操作 */
@@ -573,6 +610,16 @@ function handleUpdate(row) {
   const userId = row.userId || ids.value;
   getUser(userId).then(response => {
     form.value = response.data.user;
+    if(form.value["ext1"]==null){
+      form.value["ext1"]={
+        gh:"",
+          sfz:"",
+          sr:""
+      }
+    }else {
+      form.value["ext1"]=JSON.parse(form.value["ext1"]);
+    }
+
     postOptions.value = response.data.posts;
     roleOptions.value = response.data.roles;
     form.value.postIds = response.data.postIds;
@@ -586,6 +633,9 @@ function handleUpdate(row) {
 function submitForm() {
   proxy.$refs["userRef"].validate(valid => {
     if (valid) {
+      if(form.value.ext1){
+        form.value.ext1=JSON.stringify(form.value.ext1);
+      }
       if (form.value.userId != undefined) {
         updateUser(form.value).then(response => {
           proxy.$modal.msgSuccess("修改成功");

+ 2 - 2
ruoyi-ui-vue3/vite.config.js

@@ -30,8 +30,8 @@ export default defineConfig(({ mode, command }) => {
       proxy: {
         // https://cn.vitejs.dev/config/#server-proxy
         "/dev-api": {
-          target: "http://58.252.235.18:8084/iot/prod-api",
-          // target: "http://localhost:8989",
+          // target: "http://58.252.235.18:8084/iot/prod-api",
+          target: "http://localhost:8989",
           changeOrigin: true,
           rewrite: (p) => p.replace(/^\/dev-api/, ""),
         },

+ 9 - 1
ruoyi-ui/src/views/monitor/cache/index.vue

@@ -45,7 +45,9 @@
 
       <el-col :span="12" class="card-box">
         <el-card>
-          <div slot="header"><span><i class="el-icon-pie-chart"></i> 命令统计</span></div>
+          <div slot="header"><span><i class="el-icon-pie-chart"></i> 命令统计</span>
+            <el-button style="float: right; padding: 3px 0" type="primary" size="mini" @click="exportfile">导出</el-button>
+          </div>
           <div class="el-table el-table--enable-row-hover el-table--medium">
             <div ref="commandstats" style="height: 420px" />
           </div>
@@ -85,6 +87,12 @@ export default {
     this.openLoading();
   },
   methods: {
+    exportfile(){
+      proxy.download('/monitor/cache/export', {
+        ...queryParams.value
+      }, `缓存_${new Date().getTime()}.xlsx`)
+
+    },
     /** 查缓存询信息 */
     getList() {
       getCache().then((response) => {