wenhongquan il y a 1 an
Parent
commit
e5b181513e
33 fichiers modifiés avec 1681 ajouts et 111 suppressions
  1. 0 1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java
  2. 9 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheDataVo.java
  3. 107 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TblPointsController.java
  4. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/TblEquipment.java
  5. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/TblEquipmentSbook.java
  6. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/TblSensor.java
  7. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/TblVideo.java
  8. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblEquipmentBo.java
  9. 1 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblEquipmentSbookBo.java
  10. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblSensorBo.java
  11. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblVideoBo.java
  12. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblEquipmentSbookVo.java
  13. 3 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblEquipmentVo.java
  14. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblSensorSbookVo.java
  15. 2 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblSensorVo.java
  16. 1 0
      ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblVideoVo.java
  17. 82 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/TblPoints.java
  18. 78 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/TblPointsBo.java
  19. 99 0
      ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TblPointsVo.java
  20. 16 0
      ruoyi-system/src/main/java/com/ruoyi/system/mapper/TblPointsMapper.java
  21. 70 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/ITblPointsService.java
  22. 140 0
      ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TblPointsServiceImpl.java
  23. 1 0
      ruoyi-system/src/main/resources/mapper/data/TblEquipmentMapper.xml
  24. 3 1
      ruoyi-system/src/main/resources/mapper/data/TblEquipmentSbookMapper.xml
  25. 7 0
      ruoyi-system/src/main/resources/mapper/system/TblPointsMapper.xml
  26. 63 0
      ruoyi-ui-vue3/src/api/system/points/index.ts
  27. 191 0
      ruoyi-ui-vue3/src/api/system/points/types.ts
  28. 24 2
      ruoyi-ui-vue3/src/views/data/video/index.vue
  29. 100 32
      ruoyi-ui-vue3/src/views/device/camera/add.vue
  30. 64 8
      ruoyi-ui-vue3/src/views/device/device/index.vue
  31. 232 62
      ruoyi-ui-vue3/src/views/device/equipmentdash/add.vue
  32. 51 5
      ruoyi-ui-vue3/src/views/device/sensordash/add.vue
  33. 319 0
      ruoyi-ui-vue3/src/views/points/index.vue

+ 0 - 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheController.java

@@ -18,7 +18,6 @@ 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;

+ 9 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/CacheDataVo.java

@@ -0,0 +1,9 @@
+package com.ruoyi.web.controller.monitor;
+
+import lombok.Data;
+
+@Data
+public class CacheDataVo {
+    private String name;
+    private String value;
+}

+ 107 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/TblPointsController.java

@@ -0,0 +1,107 @@
+package com.ruoyi.web.controller.system;
+
+import java.util.List;
+
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.annotation.RepeatSubmit;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.common.core.page.TableDataInfo;
+import javax.servlet.http.HttpServletResponse;
+import com.ruoyi.common.core.validate.AddGroup;
+import com.ruoyi.common.core.validate.EditGroup;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.system.domain.TblPoints;
+import com.ruoyi.system.domain.vo.TblPointsVo;
+import com.ruoyi.system.service.ITblPointsService;
+import lombok.RequiredArgsConstructor;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 点表
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@Slf4j
+@RequestMapping("/system/points")
+public class TblPointsController extends BaseController {
+
+    private final ITblPointsService tblPointsService;
+
+    /**
+     * 查询点表列表
+     */
+    @SaCheckPermission("system:points:list")
+    @GetMapping("/list")
+    public TableDataInfo<TblPointsVo> list(TblPoints bo, PageQuery pageQuery) {
+        return tblPointsService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出点表列表
+     */
+    @SaCheckPermission("system:points:export")
+    @PostMapping("/export")
+    public void export(TblPoints bo, HttpServletResponse response) {
+        List<TblPointsVo> list = tblPointsService.queryList(bo);
+        ExcelUtil.exportExcel(list, "点表", TblPointsVo.class, response);
+    }
+
+    /**
+     * 获取点表详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:points:query")
+    @GetMapping("/{id}")
+    public R<TblPointsVo> getInfo(@NotEmpty(message = "主键不能为空") @PathVariable String id) {
+        return R.ok(tblPointsService.queryById(Long.parseLong(id)));
+    }
+
+    /**
+     * 新增点表
+     */
+    @SaCheckPermission("system:points:add")
+    @Log(title = "参数管理", businessType = BusinessType.EXPORT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody TblPoints bo) {
+        return toAjax(tblPointsService.insertByBo(bo));
+    }
+
+    /**
+     * 修改点表
+     */
+    @SaCheckPermission("system:points:edit")
+    @Log(title = "点表", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody TblPoints bo) {
+        return toAjax(tblPointsService.updateByBo(bo));
+    }
+
+    /**
+     * 删除点表
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:points:remove")
+    @Log(title = "点表", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable Long[] ids) {
+        return toAjax(tblPointsService.deleteWithValidByIds(ids, true));
+    }
+}

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/TblEquipment.java

@@ -77,4 +77,6 @@ public class TblEquipment extends BaseEntity {
      */
     private Integer protocalType;
 
+    private String ext1;
+
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/TblEquipmentSbook.java

@@ -136,5 +136,7 @@ public class TblEquipmentSbook extends BaseEntity {
 
     private String isDelete;
 
+    private String ext1;
+
 
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/TblSensor.java

@@ -70,4 +70,6 @@ public class TblSensor extends BaseEntity {
 
     private Long configUuid;
 
+    private String ext1;
+
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/TblVideo.java

@@ -78,4 +78,6 @@ public class TblVideo extends BaseEntity {
 
     private Integer isDelete;
 
+    private String ext1;
+
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblEquipmentBo.java

@@ -125,5 +125,7 @@ public class TblEquipmentBo extends BaseEntity {
 //    @NotBlank(message = "拓展字段2不能为空", groups = { AddGroup.class, EditGroup.class })
     private Integer protocalType;
 
+    private String ext1;
+
 
 }

+ 1 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblEquipmentSbookBo.java

@@ -210,4 +210,5 @@ public class TblEquipmentSbookBo extends BaseEntity {
     private String expr2;
 
     private Integer isDelete;
+    private String ext1;
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblSensorBo.java

@@ -85,4 +85,6 @@ public class TblSensorBo extends BaseEntity {
     private String equipmentName;
 
     private Long configUuid;
+
+    private String ext1;
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/bo/TblVideoBo.java

@@ -127,5 +127,7 @@ public class TblVideoBo extends BaseEntity {
 
     private Integer isDelete;
 
+    private String ext1;
+
 
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblEquipmentSbookVo.java

@@ -199,4 +199,6 @@ public class TblEquipmentSbookVo implements Serializable {
     private Date updateTime;
 
     private Integer isDelete;
+
+    private String ext1;
 }

+ 3 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblEquipmentVo.java

@@ -102,4 +102,7 @@ public class TblEquipmentVo implements Serializable {
 
     private TblEquipment equipment;
 
+    private String ext1;
+
+
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblSensorSbookVo.java

@@ -125,4 +125,6 @@ public class TblSensorSbookVo implements Serializable {
     private String expr2;
 
     private TblEquipment equipment;
+
+    private String ext1;
 }

+ 2 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblSensorVo.java

@@ -93,5 +93,7 @@ public class TblSensorVo implements Serializable {
 
     private Long configUuid;
 
+    private String ext1;
+
 
 }

+ 1 - 0
ruoyi-system/src/main/java/com/ruoyi/data/domain/vo/TblVideoVo.java

@@ -102,4 +102,5 @@ public class TblVideoVo implements Serializable {
     private Integer isDelete;
 
 
+    private String ext1;
 }

+ 82 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/TblPoints.java

@@ -0,0 +1,82 @@
+package com.ruoyi.system.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/**
+ * 【请填写功能名称】对象 tbl_points
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+@Data
+@TableName("tbl_points")
+public class TblPoints {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 编号
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 设备编号
+     */
+    private Long deviceId;
+
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+
+    /**
+     * 备用编码
+     */
+    private String bmB;
+
+    /**
+     * 点表数
+     */
+    private Long pointNum;
+
+    /**
+     * 上层位置
+     */
+    private String topAddr;
+
+    /**
+     * 设备型号
+     */
+    private String deviceType;
+
+    /**
+     * 设备模版
+     */
+    private String deviceTpl;
+
+    /**
+     * 所属组织机构
+     */
+    private String deptName;
+
+    /**
+     * 变量
+     */
+    private String bl;
+
+    /**
+     * 变量类型
+     */
+    private String blType;
+
+    /**
+     * 扩展
+     */
+    private String ext1;
+
+
+}

+ 78 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/bo/TblPointsBo.java

@@ -0,0 +1,78 @@
+package com.ruoyi.system.domain.bo;
+
+import com.ruoyi.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 【请填写功能名称】业务对象 tbl_points
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class TblPointsBo extends BaseEntity {
+
+    /**
+     * 编号
+     */
+    private Long id;
+
+    /**
+     * 设备编号
+     */
+    private Long deviceId;
+
+    /**
+     * 设备名称
+     */
+    private String deviceName;
+
+    /**
+     * 备用编码
+     */
+    private String bmB;
+
+    /**
+     * 点表数
+     */
+    private Long pointNum;
+
+    /**
+     * 上层位置
+     */
+    private String topAddr;
+
+    /**
+     * 设备型号
+     */
+    private String deviceType;
+
+    /**
+     * 设备模版
+     */
+    private String deviceTpl;
+
+    /**
+     * 所属组织机构
+     */
+    private String deptName;
+
+    /**
+     * 变量
+     */
+    private String bl;
+
+    /**
+     * 变量类型
+     */
+    private String blType;
+
+    /**
+     * 扩展
+     */
+    private String ext1;
+
+
+}

+ 99 - 0
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/TblPointsVo.java

@@ -0,0 +1,99 @@
+package com.ruoyi.system.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+
+import com.ruoyi.system.domain.TblPoints;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 【请填写功能名称】视图对象 tbl_points
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+@Data
+@ExcelIgnoreUnannotated
+public class TblPointsVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 编号
+     */
+    @ExcelProperty(value = "编号")
+    private Long id;
+
+    /**
+     * 设备编号
+     */
+    @ExcelProperty(value = "设备编号")
+    private Long deviceId;
+
+    /**
+     * 设备名称
+     */
+    @ExcelProperty(value = "设备名称")
+    private String deviceName;
+
+    /**
+     * 备用编码
+     */
+    @ExcelProperty(value = "备用编码")
+    private String bmB;
+
+    /**
+     * 点表数
+     */
+    @ExcelProperty(value = "点表数")
+    private Long pointNum;
+
+    /**
+     * 上层位置
+     */
+    @ExcelProperty(value = "上层位置")
+    private String topAddr;
+
+    /**
+     * 设备型号
+     */
+    @ExcelProperty(value = "设备型号")
+    private String deviceType;
+
+    /**
+     * 设备模版
+     */
+    @ExcelProperty(value = "设备模版")
+    private String deviceTpl;
+
+    /**
+     * 所属组织机构
+     */
+    @ExcelProperty(value = "所属组织机构")
+    private String deptName;
+
+    /**
+     * 变量
+     */
+    @ExcelProperty(value = "变量")
+    private String bl;
+
+    /**
+     * 变量类型
+     */
+    @ExcelProperty(value = "变量类型")
+    private String blType;
+
+    /**
+     * 扩展
+     */
+    @ExcelProperty(value = "扩展")
+    private String ext1;
+
+
+}

+ 16 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/TblPointsMapper.java

@@ -0,0 +1,16 @@
+package com.ruoyi.system.mapper;
+
+
+import com.ruoyi.common.core.mapper.BaseMapperPlus;
+import com.ruoyi.system.domain.TblPoints;
+import com.ruoyi.system.domain.vo.TblPointsVo;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+public interface TblPointsMapper extends BaseMapperPlus<TblPointsMapper,TblPoints, TblPointsVo> {
+
+}

+ 70 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/ITblPointsService.java

@@ -0,0 +1,70 @@
+package com.ruoyi.system.service;
+
+
+import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.system.domain.TblPoints;
+import com.ruoyi.system.domain.bo.TblPointsBo;
+import com.ruoyi.system.domain.vo.TblPointsVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 【请填写功能名称】Service接口
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+public interface ITblPointsService {
+
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 主键
+     * @return 【请填写功能名称】
+     */
+    TblPointsVo queryById(Long id);
+
+    /**
+     * 分页查询【请填写功能名称】列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 【请填写功能名称】分页列表
+     */
+    TableDataInfo<TblPointsVo> queryPageList(TblPoints bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的【请填写功能名称】列表
+     *
+     * @param bo 查询条件
+     * @return 【请填写功能名称】列表
+     */
+    List<TblPointsVo> queryList(TblPoints bo);
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param bo 【请填写功能名称】
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(TblPoints bo);
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param bo 【请填写功能名称】
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(TblPoints bo);
+
+    /**
+     * 校验并批量删除【请填写功能名称】信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Long[] ids, Boolean isValid);
+}

+ 140 - 0
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/TblPointsServiceImpl.java

@@ -0,0 +1,140 @@
+package com.ruoyi.system.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.common.core.domain.PageQuery;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.domain.TblPoints;
+import com.ruoyi.system.domain.bo.TblPointsBo;
+import com.ruoyi.system.domain.vo.TblPointsVo;
+import com.ruoyi.system.mapper.TblPointsMapper;
+import com.ruoyi.system.service.ITblPointsService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ *
+ * @author Lion Li
+ * @date 2024-09-01
+ */
+@RequiredArgsConstructor
+@Service
+public class TblPointsServiceImpl implements ITblPointsService {
+
+    private final TblPointsMapper baseMapper;
+
+    /**
+     * 查询【请填写功能名称】
+     *
+     * @param id 主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public TblPointsVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询【请填写功能名称】列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 【请填写功能名称】分页列表
+     */
+    @Override
+    public TableDataInfo<TblPointsVo> queryPageList(TblPoints bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<TblPoints> lqw = buildQueryWrapper(bo);
+        Page<TblPointsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的【请填写功能名称】列表
+     *
+     * @param bo 查询条件
+     * @return 【请填写功能名称】列表
+     */
+    @Override
+    public List<TblPointsVo> queryList(TblPoints bo) {
+        LambdaQueryWrapper<TblPoints> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<TblPoints> buildQueryWrapper(TblPoints bo) {
+        LambdaQueryWrapper<TblPoints> lqw = Wrappers.lambdaQuery();
+        lqw.eq(bo.getDeviceId() != null, TblPoints::getDeviceId, bo.getDeviceId());
+        lqw.like(StringUtils.isNotBlank(bo.getDeviceName()), TblPoints::getDeviceName, bo.getDeviceName());
+        lqw.eq(StringUtils.isNotBlank(bo.getBmB()), TblPoints::getBmB, bo.getBmB());
+        lqw.eq(bo.getPointNum() != null, TblPoints::getPointNum, bo.getPointNum());
+        lqw.eq(StringUtils.isNotBlank(bo.getTopAddr()), TblPoints::getTopAddr, bo.getTopAddr());
+        lqw.eq(StringUtils.isNotBlank(bo.getDeviceType()), TblPoints::getDeviceType, bo.getDeviceType());
+        lqw.eq(StringUtils.isNotBlank(bo.getDeviceTpl()), TblPoints::getDeviceTpl, bo.getDeviceTpl());
+        lqw.like(StringUtils.isNotBlank(bo.getDeptName()), TblPoints::getDeptName, bo.getDeptName());
+        lqw.eq(StringUtils.isNotBlank(bo.getBl()), TblPoints::getBl, bo.getBl());
+        lqw.eq(StringUtils.isNotBlank(bo.getBlType()), TblPoints::getBlType, bo.getBlType());
+        lqw.eq(StringUtils.isNotBlank(bo.getExt1()), TblPoints::getExt1, bo.getExt1());
+        return lqw;
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     *
+     * @param bo 【请填写功能名称】
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(TblPoints bo) {
+        TblPoints add = bo;
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     *
+     * @param bo 【请填写功能名称】
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(TblPoints bo) {
+        TblPoints update = bo;
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(TblPoints entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除【请填写功能名称】信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Long[] ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        List<Long> ids1 = Arrays.asList(ids);
+        return baseMapper.deleteBatchIds(ids1) > 0;
+    }
+}

+ 1 - 0
ruoyi-system/src/main/resources/mapper/data/TblEquipmentMapper.xml

@@ -22,6 +22,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
+        <result property="ext1" column="ext1"/>
     </resultMap>
 
 

+ 3 - 1
ruoyi-system/src/main/resources/mapper/data/TblEquipmentSbookMapper.xml

@@ -37,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
         <result property="isDelete" column="is_delete"/>
+        <result property="ext1" column="ext1"/>
 <!--        <association property="equipment" column="id" javaType="TblEquipment" resultMap="TblEquipmentResult"/>-->
     </resultMap>
 
@@ -93,12 +94,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="createTime" column="create_time"/>
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
+        <result property="ext1" column="ext1"/>
     </resultMap>
 
     <select id="selectPageList" resultMap="TblEquipmentSbookVoResult">
         select u.id, u.equipment_tree_id, u.sn, u.spare_sn, u.name, u.equipment_info_id, u.dept_id, u.dept_name,
                u.equipment_type_id, u.person_in_charge, u.installation_date, u.asset_no, u.serial_number,u.use_certificate_no,
-               u.security_level,u.useful_life,u.change_date,u.supplier,
+               u.security_level,u.useful_life,u.change_date,u.supplier,u.ext1,
                u.create_by, u.create_time, u.update_by, u.update_time, u.remark,d.id
         from tbl_equipment_sbook u
                  left join tbl_equipment d on u.equipment_info_id = d.id

+ 7 - 0
ruoyi-system/src/main/resources/mapper/system/TblPointsMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.system.mapper.TblPointsMapper">
+
+</mapper>

+ 63 - 0
ruoyi-ui-vue3/src/api/system/points/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request'
+import { AxiosPromise } from 'axios';
+import { PointsVO, PointsForm, PointsQuery } from '@/api/system/points/types';
+
+/**
+ * 查询【请填写功能名称】列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listPoints = (query?: PointsQuery): AxiosPromise<PointsVO[]> => {
+  return request({
+    url: '/system/points/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询【请填写功能名称】详细
+ * @param id
+ */
+export const getPoints = (id: string | number): AxiosPromise<PointsVO> => {
+  return request({
+    url: '/system/points/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增【请填写功能名称】
+ * @param data
+ */
+export const addPoints = (data: PointsForm) => {
+  return request({
+    url: '/system/points',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改【请填写功能名称】
+ * @param data
+ */
+export const updatePoints = (data: PointsForm) => {
+  return request({
+    url: '/system/points',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除【请填写功能名称】
+ * @param id
+ */
+export const delPoints = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/system/points/' + id,
+    method: 'delete'
+  });
+};

+ 191 - 0
ruoyi-ui-vue3/src/api/system/points/types.ts

@@ -0,0 +1,191 @@
+export interface PointsVO {
+  /**
+   * 编号
+   */
+  id: string | number;
+
+  /**
+   * 设备编号
+   */
+  deviceId: string | number;
+
+  /**
+   * 设备名称
+   */
+  deviceName: string;
+
+  /**
+   * 备用编码
+   */
+  bmB: string;
+
+  /**
+   * 点表数
+   */
+  pointNum: number;
+
+  /**
+   * 上层位置
+   */
+  topAddr: string;
+
+  /**
+   * 设备型号
+   */
+  deviceType: string;
+
+  /**
+   * 设备模版
+   */
+  deviceTpl: string;
+
+  /**
+   * 所属组织机构
+   */
+  deptName: string;
+
+  /**
+   * 变量
+   */
+  bl: string;
+
+  /**
+   * 变量类型
+   */
+  blType: string;
+
+  /**
+   * 扩展
+   */
+  ext1: string;
+
+}
+
+export interface PointsForm extends BaseEntity {
+  /**
+   * 编号
+   */
+  id?: string | number;
+
+  /**
+   * 设备编号
+   */
+  deviceId?: string | number;
+
+  /**
+   * 设备名称
+   */
+  deviceName?: string;
+
+  /**
+   * 备用编码
+   */
+  bmB?: string;
+
+  /**
+   * 点表数
+   */
+  pointNum?: number;
+
+  /**
+   * 上层位置
+   */
+  topAddr?: string;
+
+  /**
+   * 设备型号
+   */
+  deviceType?: string;
+
+  /**
+   * 设备模版
+   */
+  deviceTpl?: string;
+
+  /**
+   * 所属组织机构
+   */
+  deptName?: string;
+
+  /**
+   * 变量
+   */
+  bl?: string;
+
+  /**
+   * 变量类型
+   */
+  blType?: string;
+
+  /**
+   * 扩展
+   */
+  ext1?: string;
+
+}
+
+export interface PointsQuery extends PageQuery {
+
+  /**
+   * 设备编号
+   */
+  deviceId?: string | number;
+
+  /**
+   * 设备名称
+   */
+  deviceName?: string;
+
+  /**
+   * 备用编码
+   */
+  bmB?: string;
+
+  /**
+   * 点表数
+   */
+  pointNum?: number;
+
+  /**
+   * 上层位置
+   */
+  topAddr?: string;
+
+  /**
+   * 设备型号
+   */
+  deviceType?: string;
+
+  /**
+   * 设备模版
+   */
+  deviceTpl?: string;
+
+  /**
+   * 所属组织机构
+   */
+  deptName?: string;
+
+  /**
+   * 变量
+   */
+  bl?: string;
+
+  /**
+   * 变量类型
+   */
+  blType?: string;
+
+  /**
+   * 扩展
+   */
+  ext1?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 24 - 2
ruoyi-ui-vue3/src/views/data/video/index.vue

@@ -219,6 +219,9 @@
         <el-form-item label="设备型号" prop="model">
           <el-input v-model="form.model" placeholder="请输入设备型号" />
         </el-form-item>
+        <el-form-item label="NVR" prop="model">
+          <el-input v-model="form.ext1.nvr" placeholder="请输入NVR" />
+        </el-form-item>
         <el-form-item label="视频制式" prop="videoFormat">
           <el-input v-model="form.videoFormat" placeholder="请输入视频制式" />
         </el-form-item>
@@ -267,6 +270,7 @@
 
 <script>
 import { listVideo, getVideo, delVideo, addVideo, updateVideo } from "@/api/data/video";
+import {cloneDeep} from "lodash";
 
 export default {
   name: "Video",
@@ -378,7 +382,8 @@ export default {
     getList() {
       this.loading = true;
       listVideo(this.queryParams).then(response => {
-        this.videoList = response.rows;
+        let rr = response.rows.map(i=>{i["ext1"]=JSON.parse(i["ext1"]??"{}");  return i;})
+        this.videoList = rr;
         this.total = response.total;
         this.loading = false;
       });
@@ -407,7 +412,15 @@ export default {
         utime: undefined,
         remark: undefined,
         expr1: undefined,
-        expr2: undefined
+        expr2: undefined,
+        ext1:{
+          nvr:"",
+          wd:"",
+          scs:"",
+          zzs:"",
+          gg:"",
+          xh:"",
+        }
       };
       this.resetForm("form");
     },
@@ -440,7 +453,11 @@ export default {
       const id = row.id || this.ids
       getVideo(id).then(response => {
         this.loading = false;
+        if(response.data["ext1"]){
+          response.data["ext1"] = JSON.stringify(response.data["ext1"])
+        }
         this.form = response.data;
+
         this.open = true;
         this.title = "修改视频";
       });
@@ -448,7 +465,12 @@ export default {
     /** 提交按钮 */
     submitForm() {
       this.$refs["form"].validate(valid => {
+
         if (valid) {
+
+          if(this.form["ext1"]){
+            this.form["ext1"] = JSON.stringify(this.form["ext1"])
+          }
           this.buttonLoading = true;
           if (this.form.id != null) {
             updateVideo(this.form).then(response => {

+ 100 - 32
ruoyi-ui-vue3/src/views/device/camera/add.vue

@@ -12,12 +12,11 @@
             </template>
             <el-row>
                 <el-col :span="24">
-                    <el-descriptions :column="4">
-                        <el-descriptions-item>
+                    <el-descriptions :column="4" >
+                        <el-descriptions-item >
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
+
                                      设备名称
-                                </div>
 
                             </template>
                             <div class="content-w">
@@ -26,9 +25,8 @@
                         </el-descriptions-item>
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
-                                    平台编码
-                                </div>
+                                     平台编码
+
 
                             </template>
                             <div class="content-w">
@@ -38,9 +36,9 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
+
                                      主设备类型
-                                </div>
+
 
                             </template>
                             <div class="content-w">
@@ -50,9 +48,8 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
-                                     主设备协议类型
-                                </div>
+                                      主设备协议类型
+
 
                             </template>
                             <div class="content-w">
@@ -62,9 +59,8 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
                                     设备互联网编码
-                                </div>
+
 
                             </template>
                             <div class="content-w">
@@ -74,9 +70,8 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
-                                    设备型号
-                                </div>
+                                   设备型号
+
 
                             </template>
                             <div class="content-w">
@@ -84,11 +79,61 @@
                             </div>
                         </el-descriptions-item>
 
+                      <el-descriptions-item>
+                        <template #label>
+                           NVR
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.nvr"  placeholder="请输入NVR" />
+                        </div>
+                      </el-descriptions-item>
+                      <el-descriptions-item>
+                        <template #label>
+                          所属网段
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.wd"  placeholder="请输入所属网段" />
+                        </div>
+                      </el-descriptions-item>
+                      <el-descriptions-item>
+                        <template #label>
+                          生产商
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.scs"  placeholder="请输入生产商" />
+                        </div>
+                      </el-descriptions-item>
+                      <el-descriptions-item>
+                        <template #label>
+                          制造商
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.zzs"  placeholder="请输入制造商" />
+                        </div>
+                      </el-descriptions-item>
+
+                      <el-descriptions-item>
+                        <template #label>
+                          规格
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.gg"  placeholder="请输入规格" />
+                        </div>
+                      </el-descriptions-item>
+
+                      <el-descriptions-item>
+                        <template #label>
+                          型号
+                        </template>
+                        <div class="content-w">
+                          <el-input v-model="vidoeParams.ext1.xh"  placeholder="请输入型号" />
+                        </div>
+                      </el-descriptions-item>
+
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
                                     设备制式
-                                </div>
+
 
                             </template>
                             <div class="content-w">
@@ -98,9 +143,8 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
                                     设备提供商类型
-                                </div>
+
 
                             </template>
                             <div class="content-w">
@@ -110,9 +154,8 @@
 
                         <el-descriptions-item>
                             <template #label>
-                                <div style="display: inline-block;min-width: 100px;text-align: right">
-                                    序列号
-                                </div>
+                                     序列号
+
 
                             </template>
                             <div class="content-w">
@@ -218,12 +261,13 @@
         </el-dialog>
     </div>
 </template>
-  
+
 <script setup lang="ts" name="Units">
-import { ref } from "vue";
+import {getCurrentInstance, ref} from "vue";
 import { useRoute, useRouter } from "vue-router";
 import { listVideo, getVideo, delVideo, addVideo, updateVideo } from "@/api/data/video";
 import { listVideoDetail, getVideoDetail, delVideoDetail, addVideoDetail, updateVideoDetail } from "@/api/data/videoDetail";
+import {cloneDeep} from "lodash";
 
 const route = useRoute();
 const router = useRouter();
@@ -251,7 +295,15 @@ const vidoeParams = ref({
     model: "",
     videoFormat: "",
     vendorType: '',
-    serialNumber: ''
+    serialNumber: '',
+  ext1:{
+    nvr:"",
+    wd:"",
+    scs:"",
+    zzs:"",
+    gg:"",
+    xh:""
+  }
 })
 
 const videoDeTailParams = ref({
@@ -278,6 +330,18 @@ const getVideoData = () => {
     getVideo(objId).then(res => {
         if (res.code == 200) {
             vidoeParams.value = res.data
+            if(vidoeParams.value["ext1"]!=null){
+              vidoeParams.value["ext1"] = JSON.parse(vidoeParams.value["ext1"])
+            }else{
+              vidoeParams.value["ext1"] = {
+                nvr:"",
+                wd:"",
+                scs:"",
+                zzs:"",
+                gg:"",
+                xh:""
+              }
+            }
         }
     })
 }
@@ -353,14 +417,19 @@ const godelVideoDetail = (item) => {
 }
 
 const saveVideo = () => {
+  let data = cloneDeep(vidoeParams.value);
+  if(data["ext1"]!=null){
+    data["ext1"] = JSON.stringify(data["ext1"])
+  }
     if (objId != null) {
-        updateVideo(vidoeParams.value).then(res => {
+
+        updateVideo(data).then(res => {
             if (res.code == 200) {
                 router.back()
             }
         })
     } else {
-        addVideo(vidoeParams.value).then(res => {
+        addVideo(data).then(res => {
             if (res.code == 200) {
                 router.back()
             }
@@ -377,7 +446,7 @@ if (objId != null) {
 }
 
 </script>
-  
+
 <style lang="scss" scoped>
 .card-header {
     display: flex;
@@ -392,8 +461,7 @@ if (objId != null) {
 }
 
 .content-w {
-    display: inline-flex;
+    display: inline-block;
     max-width: 160px;
 }
 </style>
-  

+ 64 - 8
ruoyi-ui-vue3/src/views/device/device/index.vue

@@ -9,7 +9,7 @@
               flex-wrap: nowrap;
               align-items: center;
             ">
-            <div style="font-size: 12px; width: 80px">模板名称:</div>
+            <div style="font-size: 12px; width: 80px">名称:</div>
             <el-input v-model="searchform.name" placeholder="设备名称"></el-input>
           </div>
         </div>
@@ -22,7 +22,7 @@
     <el-card class="box-card" style="margin-top: 10px">
       <template #header>
         <div class="card-header">
-          <span>设备模板管理</span>
+          <span>设备管理</span>
 
           <div>
             <el-button type="primary" @click="adddevice">添加</el-button>
@@ -90,6 +90,26 @@
               <el-input v-model="currentdata.name" placeholder="设备名称" />
             </div>
           </el-descriptions-item>
+          <el-descriptions-item label="设备编码">
+            <template #label>
+              <div style="display: inline-block;min-width: 100px;text-align: right">
+                设备编码
+              </div>
+            </template>
+            <div class="content-w">
+              <el-input v-model="currentdata.ext1.bm" placeholder="设备编码" />
+            </div>
+          </el-descriptions-item>
+          <el-descriptions-item label="设备规格">
+            <template #label>
+              <div style="display: inline-block;min-width: 100px;text-align: right">
+                设备规格
+              </div>
+            </template>
+            <div class="content-w">
+              <el-input v-model="currentdata.ext1.gg" placeholder="设备规格" />
+            </div>
+          </el-descriptions-item>
           <el-descriptions-item label="设备型号">
             <template #label>
               <div style="display: inline-block;min-width: 100px;text-align: right">
@@ -154,6 +174,26 @@
               {{ detailObj.name }}
             </div>
           </el-descriptions-item>
+          <el-descriptions-item label="设备编码">
+            <template #label>
+              <div style="display: inline-block;min-width: 100px;text-align: right">
+                设备编码
+              </div>
+            </template>
+            <div class="content-w">
+              {{detailObj.ext1.bm}}
+            </div>
+          </el-descriptions-item>
+          <el-descriptions-item label="设备规格">
+            <template #label>
+              <div style="display: inline-block;min-width: 100px;text-align: right">
+                设备规格
+              </div>
+            </template>
+            <div class="content-w">
+              {{detailObj.ext1.gg}}
+            </div>
+          </el-descriptions-item>
           <el-descriptions-item label="设备型号">
             <template #label>
               <div style="display: inline-block;min-width: 100px;text-align: right">
@@ -223,6 +263,7 @@ import { ref, watch } from "vue";
 import { listEquipment, addEquipment, delEquipment, updateEquipment } from "@/api/data/equipment"
 import moment from "moment/moment";
 import { ElMessage, ElMessageBox } from "element-plus";
+import {cloneDeep} from "lodash";
 
 const route = useRoute();
 const router = useRouter();
@@ -249,6 +290,8 @@ const ziduanshow = ref(false);
 const cloumdata = ref([
   { label: '设备名称', prop: 'name', visible: true },
   { label: '型号', prop: 'model', visible: true },
+  { label: '编码', prop: 'ext1.bm', visible: true },
+  { label: '规格', prop: 'ext1.gg', visible: true },
   { label: '设备类型', prop: 'type', visible: true },
   { label: '生产厂商', prop: 'manufacturer', visible: true },
   { label: '制造商', prop: 'producer', visible: true },
@@ -267,7 +310,11 @@ const currentdata = ref({
   "pictures": "",
   "remark": "",
   "gatewayId": null,
-  "protocalType": null
+  "protocalType": null,
+  "ext1":{
+    bm:"",
+    gg:''
+  }
 })
 
 const searchform = ref({
@@ -298,7 +345,11 @@ const refresh = () => {
     "pictures": "",
     "remark": "",
     "gatewayId": null,
-    "protocalType": null
+    "protocalType": null,
+    "ext1":{
+      bm:"",
+      gg:''
+    }
   }
 }
 
@@ -363,14 +414,18 @@ const adddevice = () => {
 }
 
 const dosave = () => {
-  if (currentdata.value["id"] != undefined) {
-    updateEquipment(currentdata.value).then((res) => {
+  let ddd=cloneDeep(currentdata.value);
+  if(ddd["ext1"]){
+    ddd["ext1"] = JSON.stringify(ddd["ext1"])
+  }
+  if (ddd["id"] != undefined) {
+    updateEquipment(ddd).then((res) => {
       addshow.value = false;
       ElMessage.success("修改成功!")
       getalldata();
     });
   } else {
-    addEquipment(currentdata.value).then((res) => {
+    addEquipment(ddd).then((res) => {
       addshow.value = false;
       ElMessage.success("添加成功!")
       getalldata();
@@ -396,7 +451,8 @@ const devicetabledata = ref([]);
 const getalldata = () => {
   listEquipment({ ...searchform.value, pageSize: pagedata.value.size, pageNum: pagedata.value.current }).then((res) => {
     const { rows } = res;
-    devicetabledata.value = rows;
+    let rr =rows.map(i=>{i["ext1"]=JSON.parse(i["ext1"]??"{}");  return i;})
+    devicetabledata.value = rr;
   });
 
 }

+ 232 - 62
ruoyi-ui-vue3/src/views/device/equipmentdash/add.vue

@@ -18,10 +18,7 @@
           <el-descriptions :column="4">
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   <span style="color: red">*</span> 设备编码
-                </div>
-
               </template>
               <div class="content-w">
                 <el-input :disabled="isDisabled"  v-model="queryParams.sn" placeholder="请输入设备编码" />
@@ -29,9 +26,7 @@
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   <span style="color: red">*</span> 设备名称
-                </div>
               </template>
               <div class="content-w">
                 <el-input :disabled="isDisabled"  v-model="queryParams.name" placeholder="请输入设备名称" />
@@ -39,9 +34,7 @@
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   <span style="color: red">*</span> 上层位置
-                </div>
               </template>
               <div class="content-w">
                 <el-tree-select :disabled="isDisabled"  v-model="queryParams.equipmentTreeId" :data="treeList"
@@ -51,9 +44,7 @@
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   状态
-                </div>
               </template>
               <div class="content-w">
                 <el-select :disabled="isDisabled"  v-model="queryParams.status" filterable placeholder="Select">
@@ -64,7 +55,7 @@
             </el-descriptions-item>
             <!-- <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
+
                   状态
                 </div>
               </template>
@@ -77,9 +68,7 @@
             </el-descriptions-item> -->
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   设备模板
-                </div>
               </template>
               <div class="content-w">
                 <el-select :disabled="isDisabled"  v-model="equipmentObj" value-key="id" filterable placeholder="Select"
@@ -90,17 +79,13 @@
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   设备型号
-                </div>
               </template>
               <div class="content-w"> {{ equipmentObj.model }}</div>
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   所属类型
-                </div>
               </template>
               <div class="content-w">{{ equipmentObj.type }}</div>
             </el-descriptions-item>
@@ -108,27 +93,46 @@
             </el-descriptions-item>
             <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   负责人
-                </div>
               </template>
               <div class="content-w"> <el-input :disabled="isDisabled" v-model="queryParams.personInCharge" placeholder="" /> </div>
             </el-descriptions-item>
-            <!-- <el-descriptions-item>
+            <el-descriptions-item>
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
-                  所属组织机构
-                </div>
+                  设备型号
               </template>
               <div class="content-w">
-                <el-select-v2 v-model="value" :options="options" placeholder="请选择" />
+                <el-input  v-model="queryParams.ext1.sbxh"  :line-count="5" placeholder="请输入设备型号" />
               </div>
-            </el-descriptions-item> -->
+            </el-descriptions-item>
+            <el-descriptions-item>
+              <template #label>
+                所属组织机构
+              </template>
+              <div class="content-w">
+                <el-input  v-model="queryParams.ext1.ssjg"  :line-count="5" placeholder="请输入所属组织机构" />
+              </div>
+            </el-descriptions-item>
+            <el-descriptions-item>
+              <template #label>
+                设备用途
+              </template>
+              <div class="content-w">
+                <el-input  v-model="queryParams.ext1.sbyt"  :line-count="5" placeholder="请输入设备用途" />
+              </div>
+            </el-descriptions-item>
+
+            <el-descriptions-item>
+              <template #label>
+                所属项目
+              </template>
+              <div class="content-w">
+                <el-input  v-model="queryParams.ext1.ssxm"  :line-count="5" placeholder="请输入所属项目" />
+              </div>
+            </el-descriptions-item>
             <el-descriptions-item :span="2">
               <template #label>
-                <div style="display: inline-block;min-width: 100px;text-align: right">
                   标签
-                </div>
               </template>
               <div class="content-w" style="min-width: 500px">
                 <el-select :disabled="isDisabled"   v-model="tagidArry" filterable placeholder="Select" multiple>
@@ -156,9 +160,7 @@
               <el-descriptions :column="4">
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       供货厂家
-                    </div>
 
                   </template>
                   <div class="content-w">
@@ -167,10 +169,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       制造日期
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-date-picker :disabled="isDisabled"  value-format="YYYY-MM-DD HH:mm:ss" v-model="queryParams.manufacturingDate" type="date"
@@ -180,22 +179,72 @@
 
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       使用年限
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.usefulLife" placeholder="" />
                   </div>
                 </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    纬度
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.wd"  :line-count="5" placeholder="请输入纬度" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    经度
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.jd"  :line-count="5" placeholder="请输入经度" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    关联设备
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.glsb"  :line-count="5" placeholder="请输入关联设备" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    设备绑定状态
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.sbbdzt"  :line-count="5" placeholder="请输入设备绑定状态" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    区域分类
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.qyfl"  :line-count="5" placeholder="请输入区域分类" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    层级
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.cj"  :line-count="5" placeholder="请输入层级" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    图纸编号
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.tzbh"  :line-count="5" placeholder="请输入图纸编号" />
+                  </div>
+                </el-descriptions-item>
 
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       保修期结束日期
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-date-picker :disabled="isDisabled"  value-format="YYYY-MM-DD HH:mm:ss" v-model="queryParams.endOfWarrantyPeriod"
@@ -204,10 +253,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       安装日期
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-date-picker :disabled="isDisabled"  value-format="YYYY-MM-DD HH:mm:ss" v-model="queryParams.installationDate" type="date"
@@ -216,10 +262,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       安装地点地址
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.address" placeholder="" />
@@ -227,19 +270,49 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       变动日期
-                    </div>
-
                   </template>
                   <div class="content-w">
                     <el-date-picker :disabled="isDisabled"  value-format="YYYY-MM-DD HH:mm:ss" v-model="queryParams.changeDate" type="date"
                       placeholder="请选择" />
                   </div>
                 </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    设备寿命
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.sbsm"  :line-count="5" placeholder="请输入设备寿命" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    附件地址
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.fjdz"  :line-count="5" placeholder="请输入附件地址" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    警报规划
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.jbgh"  :line-count="5" placeholder="请输入警报规划" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    停产日期
+                  </template>
+                  <div class="content-w">
+                    <el-date-picker :disabled="isDisabled"  value-format="YYYY-MM-DD HH:mm:ss" v-model="queryParams.ext1.tcrq" type="date"
+                                    placeholder="请选择" />
+                  </div>
+                </el-descriptions-item>
                 <!-- <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
+
                       关联设备
                     </div>
 
@@ -259,7 +332,7 @@
               <el-descriptions column="4">
                 <!-- <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
+
                       供货厂家
                     </div>
                   </template>
@@ -269,9 +342,7 @@
                 </el-descriptions-item> -->
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       资产编码
-                    </div>
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.assetNo" placeholder="" />
@@ -279,9 +350,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       资产编号
-                    </div>
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.serialNumber" placeholder="" />
@@ -289,9 +358,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       使用证编号
-                    </div>
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.useCertificateNo" placeholder="" />
@@ -299,17 +366,48 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
                       安全级别
-                    </div>
                   </template>
                   <div class="content-w">
                     <el-input :disabled="isDisabled"  v-model="queryParams.securityLevel" placeholder="" />
                   </div>
                 </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    电气复杂系数
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.dqfzxs"  :line-count="5" placeholder="请输入电气复杂系数" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    延迟告警
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.ycgj"  :line-count="5" placeholder="请输入延迟告警" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    数据上报周期
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.sjsbzq"  :line-count="5" placeholder="请输入数据上报周期" />
+                  </div>
+                </el-descriptions-item>
+                <el-descriptions-item>
+                  <template #label>
+                    月票准使用时间(小时)
+                  </template>
+                  <div class="content-w">
+                    <el-input  v-model="queryParams.ext1.ypzsysj"  :line-count="5" placeholder="请输入月票准使用时间(小时)" />
+                  </div>
+                </el-descriptions-item>
+
                 <!-- <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
+
                       使用年限
                     </div>
                   </template>
@@ -319,7 +417,7 @@
                 </el-descriptions-item>
                 <el-descriptions-item>
                   <template #label>
-                    <div style="display: inline-block;min-width: 100px;text-align: right">
+
                       变动日期
                     </div>
                   </template>
@@ -422,6 +520,7 @@ import { listEquipmentOrganizational } from "@/api/data/equipmentOrganizational"
 import { listEquipment } from "@/api/data/equipment"
 import { addEquipmentSbook, getEquipmentSbook, updateEquipmentSbook } from "@/api/data/equipmentSbook"
 import { listEquipmentMqttByDeviceId, noListByDeviceId, addEquipmentMqtt, delEquipmentMqtt } from "@/api/data/equipmentMqtt"
+import {cloneDeep} from "lodash";
 
 
 
@@ -461,6 +560,27 @@ const inintdata = () => {
   changeDate: "",
   supplier: "",
   dialogFormVisible: true,
+    ext1:{
+      ssxm:"",
+      sbxh:"",
+      ssjg:"",
+      sbyt:"",
+      wd:"",
+      jd:"",
+      glsb:"",
+      sbbdzt:"",
+      qyfl:"",
+      cj:"",
+      tzbh:"",
+      dqfzxs:"",
+      ycgj:"",
+      sjsbzq:"",
+      ypzsysj:"",
+      sbsm:"",
+      fjdz:"",
+      jbgh:"",
+      tcrq:"",
+    }
 })
 
 }
@@ -490,6 +610,27 @@ const queryParams = ref({
   changeDate: "",
   supplier: "",
   dialogFormVisible: true,
+  ext1:{
+    ssxm:"",
+    sbxh:"",
+    ssjg:"",
+    sbyt:"",
+    wd:"",
+    jd:"",
+    glsb:"",
+    sbbdzt:"",
+    qyfl:"",
+    cj:"",
+    tzbh:"",
+    dqfzxs:"",
+    ycgj:"",
+    sjsbzq:"",
+    ypzsysj:"",
+    sbsm:"",
+    fjdz:"",
+    jbgh:"",
+    tcrq:"",
+  }
 })
 
 const tagidArry = ref([])
@@ -582,16 +723,22 @@ const selectMqtt = (selection, row) => {
 }
 
 const submit = () => {
+
+
   queryParams.value.equipmentInfoId = equipmentObj.value.id;
   queryParams.value.equipmentTypeId = equipmentObj.value.equipmentTypeId;
   queryParams.value.tagids = tagidArry.value.join(',');
-  if (queryParams.value.id == null) {
-    addEquipmentSbook(queryParams.value).then(res => {
+  let dd=cloneDeep(queryParams.value);
+  if(dd["ext1"]){
+    dd["ext1"] = JSON.stringify(dd["ext1"])
+  }
+  if (dd.id == null) {
+    addEquipmentSbook(dd).then(res => {
       console.log(res);
       router.back()
     })
   } else {
-    updateEquipmentSbook(queryParams.value).then(res => {
+    updateEquipmentSbook(dd).then(res => {
       console.log(res);
       router.back()
     })
@@ -605,8 +752,31 @@ const selectEquipment = (value) => {
 }
 
 const getDetail = () => {
-  console.log(2);
   getEquipmentSbook(objId).then(res => {
+    if(res.data["ext1"]){
+      res.data["ext1"]=JSON.parse(res.data["ext1"]);
+    }else{
+      res.data["ext1"]={
+        ssxm:"",
+          sbxh:"",
+          ssjg:"",
+          sbyt:"",
+          wd:"",
+          jd:"",
+          glsb:"",
+          sbbdzt:"",
+          qyfl:"",
+          cj:"",
+          tzbh:"",
+          dqfzxs:"",
+          ycgj:"",
+          sjsbzq:"",
+          ypzsysj:"",
+          sbsm:"",
+          fjdz:"",
+          jbgh:"",tcrq:"",
+      }
+    }
     queryParams.value = res.data
     tagidArry.value = res.data.tagids.split(',');
     for (var index in equipmentList.value) {

+ 51 - 5
ruoyi-ui-vue3/src/views/device/sensordash/add.vue

@@ -179,6 +179,27 @@
             <el-descriptions-item :span="2">
               <template #label>
                 <div style="display: inline-block;min-width: 100px;text-align: right;    vertical-align: top;">
+                  单位
+                </div>
+              </template>
+              <div class="content-w" style="min-width: 400px">
+                <el-input v-model="currentsensor.ext1.dw" placeholder="请输入单位"/>
+              </div>
+            </el-descriptions-item>
+            <el-descriptions-item :span="2">
+              <template #label>
+                <div style="display: inline-block;min-width: 100px;text-align: right;    vertical-align: top;">
+                  标签
+                </div>
+              </template>
+              <div class="content-w" style="min-width: 400px">
+                <el-input v-model="currentsensor.ext1.bq"  placeholder="请输入标签"/>
+              </div>
+            </el-descriptions-item>
+
+            <el-descriptions-item :span="2">
+              <template #label>
+                <div style="display: inline-block;min-width: 100px;text-align: right;    vertical-align: top;">
                   描述
                 </div>
               </template>
@@ -216,6 +237,7 @@ import {ElMessage} from "element-plus";
 import {listModbusTcp} from "@/api/data/modbusTcp";
 import {listModbusRtu} from "@/api/data/modbusRtu";
 import {listEquipmentSbook} from "@/api/data/equipmentSbook";
+import {deepClone} from "@/utils";
 const {proxy} = getCurrentInstance();
 const {protocal_type, sensor_type, sensor_status} = proxy.useDict("protocal_type", "sensor_type", "sensor_status");
 
@@ -244,7 +266,12 @@ const currentsensor = ref({
   "protocalId": null,
   "equipmentTreeId": null,
   "equipmentName": null,
-  "configUuid": null});
+  "configUuid": null,
+  "ext1":{
+    dw:"",
+    bq:"",
+  }
+});
 const initdata = ()=>{
   currentsensor.value = {
     "name": "",
@@ -258,16 +285,25 @@ const initdata = ()=>{
     "protocalId": null,
     "equipmentTreeId": null,
     "equipmentName": null,
-    "configUuid": null};
+    "configUuid": null,
+    "ext1":{
+      dw:"",
+      bq:"",
+    }
+  };
 }
 const savedata = ()=>{
+  let dd =deepClone(currentsensor.value);
+  if(dd["ext1"]){
+     dd["ext1"]=JSON.stringify(dd["ext1"])
+  }
   if (route.query["type"] == 1) {
-    updateSensor(currentsensor.value).then(res => {
+    updateSensor(dd).then(res => {
       ElMessage.success("保存成功")
        router.back();
     })
   } else {
-    addSensor(currentsensor.value).then(res => {
+    addSensor(dd).then(res => {
       ElMessage.success("保存成功")
       router.back();
     });
@@ -281,7 +317,17 @@ const searchform = ref({
 onMounted(()=>{
   if (route.query["type"] == 1) {
     if (localStorage.getItem("currentsensor")) {
-      currentsensor.value = JSON.parse(localStorage.getItem("currentsensor"))
+
+       let dd= JSON.parse(localStorage.getItem("currentsensor"))
+      if(dd["ext1"]){
+        dd["ext1"]=JSON.parse(dd["ext1"])
+      }else {
+        dd["ext1"]={
+          dw:"",
+            bq:"",
+        }
+      }
+      currentsensor.value = dd;
     } else {
       route.query["type"] = 0;
     }

+ 319 - 0
ruoyi-ui-vue3/src/views/points/index.vue

@@ -0,0 +1,319 @@
+<template>
+  <div class="p-2">
+
+      <div v-show="showSearch" class="mb-[10px]">
+        <el-card shadow="hover">
+          <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+            <el-form-item label="设备编号" prop="deviceId">
+              <el-input v-model="queryParams.deviceId" placeholder="请输入设备编号" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="设备名称" prop="deviceName">
+              <el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="备用编码" prop="bmB">
+              <el-input v-model="queryParams.bmB" placeholder="请输入备用编码" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="点表数" prop="pointNum">
+              <el-input v-model="queryParams.pointNum" placeholder="请输入点表数" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="上层位置" prop="topAddr">
+              <el-input v-model="queryParams.topAddr" placeholder="请输入上层位置" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="设备模版" prop="deviceTpl">
+              <el-input v-model="queryParams.deviceTpl" placeholder="请输入设备模版" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="所属组织机构" prop="deptName">
+              <el-input v-model="queryParams.deptName" placeholder="请输入所属组织机构" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item label="变量" prop="bl">
+              <el-input v-model="queryParams.bl" placeholder="请输入变量" clearable @keyup.enter="handleQuery" />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+              <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+            </el-form-item>
+          </el-form>
+        </el-card>
+      </div>
+
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="10" class="mb8">
+          <el-col :span="1.5">
+            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:points:add']">新增</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:points:edit']">修改</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:points:remove']">删除</el-button>
+          </el-col>
+          <el-col :span="1.5">
+            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:points:export']">导出</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+
+      <el-table v-loading="loading" :data="pointsList" @selection-change="handleSelectionChange">
+        <el-table-column type="selection" width="55" align="center" />
+        <el-table-column label="编号" align="center" prop="id" v-if="true" />
+        <el-table-column label="设备编号" align="center" prop="deviceId" />
+        <el-table-column label="设备名称" align="center" prop="deviceName" />
+        <el-table-column label="备用编码" align="center" prop="bmB" />
+        <el-table-column label="点表数" align="center" prop="pointNum" />
+        <el-table-column label="上层位置" align="center" prop="topAddr" />
+        <el-table-column label="设备型号" align="center" prop="deviceType" />
+        <el-table-column label="设备模版" align="center" prop="deviceTpl" />
+        <el-table-column label="所属组织机构" align="center" prop="deptName" />
+        <el-table-column label="变量" align="center" prop="bl" />
+        <el-table-column label="变量类型" align="center" prop="blType" />\
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-tooltip content="修改" placement="top">
+              <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:points:edit']"></el-button>
+            </el-tooltip>
+            <el-tooltip content="删除" placement="top">
+              <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:points:remove']"></el-button>
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+    <!-- 添加或修改点表对话框 -->
+    <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
+      <el-form ref="pointsFormRef" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="设备编号" prop="deviceId">
+          <el-input v-model="form.deviceId" placeholder="请输入设备编号" />
+        </el-form-item>
+        <el-form-item label="设备名称" prop="deviceName">
+          <el-input v-model="form.deviceName" placeholder="请输入设备名称" />
+        </el-form-item>
+        <el-form-item label="备用编码" prop="bmB">
+          <el-input v-model="form.bmB" placeholder="请输入备用编码" />
+        </el-form-item>
+        <el-form-item label="点表数" prop="pointNum">
+          <el-input v-model="form.pointNum" placeholder="请输入点表数" />
+        </el-form-item>
+        <el-form-item label="上层位置" prop="topAddr">
+          <el-input v-model="form.topAddr" placeholder="请输入上层位置" />
+        </el-form-item>
+        <el-form-item label="设备模版" prop="deviceTpl">
+          <el-input v-model="form.deviceTpl" placeholder="请输入设备模版" />
+        </el-form-item>
+        <el-form-item label="所属组织机构" prop="deptName">
+          <el-input v-model="form.deptName" placeholder="请输入所属组织机构" />
+        </el-form-item>
+        <el-form-item label="变量" prop="bl">
+          <el-input v-model="form.bl" placeholder="请输入变量" />
+        </el-form-item>
+        <el-form-item label="变量类型" prop="bl">
+          <el-input v-model="form.blType" placeholder="请输入变量" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
+          <el-button @click="cancel">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup name="Points" lang="ts">
+import { listPoints, getPoints, delPoints, addPoints, updatePoints } from '@/api/system/points';
+import { PointsVO, PointsQuery, PointsForm } from '@/api/system/points/types';
+import {ComponentInternalInstance, getCurrentInstance, reactive, ref, toRefs} from "vue";
+
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const pointsList = ref<PointsVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+
+const queryFormRef = ref();
+const pointsFormRef = ref();
+
+const dialog = reactive({
+  visible: false,
+  title: ''
+});
+
+const initFormData: PointsForm = {
+  id: undefined,
+  deviceId: undefined,
+  deviceName: undefined,
+  bmB: undefined,
+  pointNum: undefined,
+  topAddr: undefined,
+  deviceType: undefined,
+  deviceTpl: undefined,
+  deptName: undefined,
+  bl: undefined,
+  blType: undefined,
+  ext1: undefined,
+}
+const data = reactive({
+  form: {...initFormData},
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    deviceId: undefined,
+    deviceName: undefined,
+    bmB: undefined,
+    pointNum: undefined,
+    topAddr: undefined,
+    deviceType: undefined,
+    deviceTpl: undefined,
+    deptName: undefined,
+    bl: undefined,
+    blType: undefined,
+    ext1: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "编号不能为空", trigger: "blur" }
+    ],
+    deviceId: [
+      { required: true, message: "设备编号不能为空", trigger: "blur" }
+    ],
+    deviceName: [
+      { required: true, message: "设备名称不能为空", trigger: "blur" }
+    ],
+    bmB: [
+      { required: true, message: "备用编码不能为空", trigger: "blur" }
+    ],
+    pointNum: [
+      { required: true, message: "点表数不能为空", trigger: "blur" }
+    ],
+    topAddr: [
+      { required: true, message: "上层位置不能为空", trigger: "blur" }
+    ],
+    deviceType: [
+      { required: true, message: "设备型号不能为空", trigger: "change" }
+    ],
+    deviceTpl: [
+      { required: true, message: "设备模版不能为空", trigger: "blur" }
+    ],
+    deptName: [
+      { required: true, message: "所属组织机构不能为空", trigger: "blur" }
+    ],
+    bl: [
+      { required: true, message: "变量不能为空", trigger: "blur" }
+    ],
+    blType: [
+      { required: true, message: "变量类型不能为空", trigger: "change" }
+    ],
+    ext1: [
+      { required: true, message: "扩展不能为空", trigger: "blur" }
+    ],
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+
+/** 查询点表列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listPoints(queryParams.value);
+  pointsList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = {...initFormData};
+  pointsFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = () => {
+  queryParams.value.pageNum = 1;
+  getList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: PointsVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加点表";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: PointsVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getPoints(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改点表";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  pointsFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updatePoints(form.value).finally(() =>  buttonLoading.value = false);
+      } else {
+        await addPoints(form.value).finally(() =>  buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("操作成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: PointsVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除点表编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delPoints(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('system/points/export', {
+    ...queryParams.value
+  }, `points_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+});
+</script>