Commit 0e8fad88 by yuwei

项目初始化

parent db97a2bf
...@@ -25,6 +25,8 @@ import cn.datax.service.data.metadata.api.entity.MetadataColumnEntity; ...@@ -25,6 +25,8 @@ import cn.datax.service.data.metadata.api.entity.MetadataColumnEntity;
import cn.datax.service.data.metadata.api.entity.MetadataSourceEntity; import cn.datax.service.data.metadata.api.entity.MetadataSourceEntity;
import cn.datax.service.data.metadata.api.entity.MetadataTableEntity; import cn.datax.service.data.metadata.api.entity.MetadataTableEntity;
import cn.datax.service.data.metadata.api.enums.DataLevel; import cn.datax.service.data.metadata.api.enums.DataLevel;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.aspose.words.Document; import com.aspose.words.Document;
import com.aspose.words.MailMerge; import com.aspose.words.MailMerge;
...@@ -370,13 +372,20 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit ...@@ -370,13 +372,20 @@ public class DataApiServiceImpl extends BaseServiceImpl<DataApiDao, DataApiEntit
@Override @Override
public void copyDataApi(String id) { public void copyDataApi(String id) {
DataApiEntity dataApiEntity = super.getById(id); DataApiEntity dataApiEntity = Optional.ofNullable(super.getById(id)).orElseThrow(() -> new DataException("获取失败"));
dataApiEntity.setApiName(dataApiEntity.getApiName() + "_副本"); DataApiEntity copy = new DataApiEntity();
dataApiEntity.setId(null); copy.setApiName(dataApiEntity.getApiName() + "_副本" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
dataApiEntity.setCreateTime(LocalDateTime.now()); copy.setApiVersion(dataApiEntity.getApiVersion());
dataApiEntity.setUpdateTime(LocalDateTime.now()); copy.setApiUrl(dataApiEntity.getApiUrl() + "/copy" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
dataApiEntity.setStatus(DataConstant.ApiState.WAIT.getKey()); copy.setReqMethod(dataApiEntity.getReqMethod());
dataApiDao.insert(dataApiEntity); copy.setResType(dataApiEntity.getResType());
copy.setDeny(dataApiEntity.getDeny());
copy.setRateLimit(dataApiEntity.getRateLimit());
copy.setExecuteConfig(dataApiEntity.getExecuteConfig());
copy.setReqParams(dataApiEntity.getReqParams());
copy.setResParams(dataApiEntity.getResParams());
copy.setStatus(DataConstant.ApiState.WAIT.getKey());
dataApiDao.insert(copy);
} }
@Override @Override
......
package cn.datax.service.data.visual.api.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class BoardConfig implements Serializable {
private static final long serialVersionUID=1L;
}
package cn.datax.service.data.visual.api.dto;
import cn.datax.common.validate.ValidationGroups;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* <p>
* 可视化看板配置信息表 实体DTO
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@ApiModel(value = "可视化看板配置信息表Model")
@Data
public class BoardDto implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键ID")
@NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class})
private String id;
@ApiModelProperty(value = "看板名称")
@NotBlank(message = "看板名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String boardName;
@ApiModelProperty(value = "看板缩略图(图片base64)")
private String boardThumbnail;
@ApiModelProperty(value = "看板配置")
@Valid
private BoardConfig boardConfig;
}
package cn.datax.service.data.visual.api.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class ChartConfig implements Serializable {
private static final long serialVersionUID=1L;
}
package cn.datax.service.data.visual.api.dto;
import cn.datax.common.validate.ValidationGroups;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* <p>
* 可视化图表配置信息表 实体DTO
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@ApiModel(value = "可视化图表配置信息表Model")
@Data
public class ChartDto implements Serializable {
private static final long serialVersionUID=1L;
@ApiModelProperty(value = "主键ID")
@NotBlank(message = "主键ID不能为空", groups = {ValidationGroups.Update.class})
private String id;
@ApiModelProperty(value = "图表名称")
@NotBlank(message = "图表名称不能为空", groups = {ValidationGroups.Insert.class, ValidationGroups.Update.class})
private String chartName;
@ApiModelProperty(value = "图表缩略图(图片base64)")
private String chartThumbnail;
@ApiModelProperty(value = "图表配置")
@Valid
private ChartConfig chartConfig;
}
package cn.datax.service.data.visual.api.entity;
import cn.datax.common.base.DataScopeBaseEntity;
import cn.datax.service.data.visual.api.dto.BoardConfig;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 可视化看板配置信息表
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName(value = "visual_board", autoResultMap = true)
public class BoardEntity extends DataScopeBaseEntity {
private static final long serialVersionUID=1L;
/**
* 看板名称
*/
private String boardName;
/**
* 看板缩略图(图片base64)
*/
private String boardThumbnail;
/**
* 看板配置
*/
@TableField(value = "board_json", typeHandler = JacksonTypeHandler.class)
private BoardConfig boardConfig;
}
package cn.datax.service.data.visual.api.entity;
import cn.datax.common.base.DataScopeBaseEntity;
import cn.datax.service.data.visual.api.dto.ChartConfig;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
* 可视化图表配置信息表
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName(value = "visual_chart", autoResultMap = true)
public class ChartEntity extends DataScopeBaseEntity {
private static final long serialVersionUID=1L;
/**
* 图表名称
*/
private String chartName;
/**
* 图表缩略图(图片base64)
*/
private String chartThumbnail;
/**
* 图表配置
*/
@TableField(value = "chart_json", typeHandler = JacksonTypeHandler.class)
private ChartConfig chartConfig;
}
package cn.datax.service.data.visual.api.query;
import cn.datax.common.base.BaseQueryParams;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 可视化看板配置信息表 查询实体
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BoardQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
private String boardName;
}
package cn.datax.service.data.visual.api.query;
import cn.datax.common.base.BaseQueryParams;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 可视化图表配置信息表 查询实体
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ChartQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
private String chartName;
}
package cn.datax.service.data.visual.api.vo;
import cn.datax.service.data.visual.api.dto.BoardConfig;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 可视化看板配置信息表 实体VO
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
public class BoardVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
private String remark;
private String boardName;
private String boardThumbnail;
private BoardConfig boardConfig;
}
package cn.datax.service.data.visual.api.vo;
import cn.datax.service.data.visual.api.dto.ChartConfig;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* <p>
* 可视化图表配置信息表 实体VO
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Data
public class ChartVo implements Serializable {
private static final long serialVersionUID=1L;
private String id;
private String status;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;
private String remark;
private String chartName;
private String chartThumbnail;
private ChartConfig chartConfig;
}
package cn.datax.service.data.visual.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.data.visual.api.dto.BoardDto;
import cn.datax.service.data.visual.api.entity.BoardEntity;
import cn.datax.service.data.visual.api.vo.BoardVo;
import cn.datax.service.data.visual.api.query.BoardQuery;
import cn.datax.service.data.visual.mapstruct.BoardMapper;
import cn.datax.service.data.visual.service.BoardService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 可视化看板配置信息表 前端控制器
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Api(tags = {"可视化看板配置信息表"})
@RestController
@RequestMapping("/boards")
public class BoardController extends BaseController {
@Autowired
private BoardService boardService;
@Autowired
private BoardMapper boardMapper;
/**
* 通过ID查询信息
*
* @param id
* @return
*/
@ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
public R getBoardById(@PathVariable String id) {
BoardEntity boardEntity = boardService.getBoardById(id);
return R.ok().setData(boardMapper.toVO(boardEntity));
}
/**
* 分页查询信息
*
* @param boardQuery
* @return
*/
@ApiOperation(value = "分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "boardQuery", value = "查询实体boardQuery", required = true, dataTypeClass = BoardQuery.class)
})
@GetMapping("/page")
public R getBoardPage(BoardQuery boardQuery) {
QueryWrapper<BoardEntity> queryWrapper = new QueryWrapper<>();
IPage<BoardEntity> page = boardService.page(new Page<>(boardQuery.getPageNum(), boardQuery.getPageSize()), queryWrapper);
List<BoardVo> collect = page.getRecords().stream().map(boardMapper::toVO).collect(Collectors.toList());
JsonPage<BoardVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
return R.ok().setData(jsonPage);
}
/**
* 添加
* @param board
* @return
*/
@ApiOperation(value = "添加信息", notes = "根据board对象添加信息")
@ApiImplicitParam(name = "board", value = "详细实体board", required = true, dataType = "BoardDto")
@PostMapping()
public R saveBoard(@RequestBody @Validated({ValidationGroups.Insert.class}) BoardDto board) {
BoardEntity boardEntity = boardService.saveBoard(board);
return R.ok().setData(boardMapper.toVO(boardEntity));
}
/**
* 修改
* @param board
* @return
*/
@ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "board", value = "详细实体board", required = true, dataType = "BoardDto")
})
@PutMapping("/{id}")
public R updateBoard(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) BoardDto board) {
BoardEntity boardEntity = boardService.updateBoard(board);
return R.ok().setData(boardMapper.toVO(boardEntity));
}
/**
* 删除
* @param id
* @return
*/
@ApiOperation(value = "删除", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
public R deleteBoardById(@PathVariable String id) {
boardService.deleteBoardById(id);
return R.ok();
}
/**
* 批量删除
* @param ids
* @return
*/
@ApiOperation(value = "批量删除", notes = "根据url的ids来批量删除对象")
@ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path")
@DeleteMapping("/batch/{ids}")
public R deleteBoardBatch(@PathVariable List<String> ids) {
boardService.deleteBoardBatch(ids);
return R.ok();
}
@PostMapping("/copy/{id}")
public R copyBoard(@PathVariable String id) {
boardService.copyBoard(id);
return R.ok();
}
}
package cn.datax.service.data.visual.controller;
import cn.datax.common.core.JsonPage;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidationGroups;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.vo.ChartVo;
import cn.datax.service.data.visual.api.query.ChartQuery;
import cn.datax.service.data.visual.mapstruct.ChartMapper;
import cn.datax.service.data.visual.service.ChartService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 可视化图表配置信息表 前端控制器
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Api(tags = {"可视化图表配置信息表"})
@RestController
@RequestMapping("/charts")
public class ChartController extends BaseController {
@Autowired
private ChartService chartService;
@Autowired
private ChartMapper chartMapper;
/**
* 通过ID查询信息
*
* @param id
* @return
*/
@ApiOperation(value = "获取详细信息", notes = "根据url的id来获取详细信息")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@GetMapping("/{id}")
public R getChartById(@PathVariable String id) {
ChartEntity chartEntity = chartService.getChartById(id);
return R.ok().setData(chartMapper.toVO(chartEntity));
}
/**
* 分页查询信息
*
* @param chartQuery
* @return
*/
@ApiOperation(value = "分页查询", notes = "")
@ApiImplicitParams({
@ApiImplicitParam(name = "chartQuery", value = "查询实体chartQuery", required = true, dataTypeClass = ChartQuery.class)
})
@GetMapping("/page")
public R getChartPage(ChartQuery chartQuery) {
QueryWrapper<ChartEntity> queryWrapper = new QueryWrapper<>();
IPage<ChartEntity> page = chartService.page(new Page<>(chartQuery.getPageNum(), chartQuery.getPageSize()), queryWrapper);
List<ChartVo> collect = page.getRecords().stream().map(chartMapper::toVO).collect(Collectors.toList());
JsonPage<ChartVo> jsonPage = new JsonPage<>(page.getCurrent(), page.getSize(), page.getTotal(), collect);
return R.ok().setData(jsonPage);
}
/**
* 添加
* @param chart
* @return
*/
@ApiOperation(value = "添加信息", notes = "根据chart对象添加信息")
@ApiImplicitParam(name = "chart", value = "详细实体chart", required = true, dataType = "ChartDto")
@PostMapping()
public R saveChart(@RequestBody @Validated({ValidationGroups.Insert.class}) ChartDto chart) {
ChartEntity chartEntity = chartService.saveChart(chart);
return R.ok().setData(chartMapper.toVO(chartEntity));
}
/**
* 修改
* @param chart
* @return
*/
@ApiOperation(value = "修改信息", notes = "根据url的id来指定修改对象,并根据传过来的信息来修改详细信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path"),
@ApiImplicitParam(name = "chart", value = "详细实体chart", required = true, dataType = "ChartDto")
})
@PutMapping("/{id}")
public R updateChart(@PathVariable String id, @RequestBody @Validated({ValidationGroups.Update.class}) ChartDto chart) {
ChartEntity chartEntity = chartService.updateChart(chart);
return R.ok().setData(chartMapper.toVO(chartEntity));
}
/**
* 删除
* @param id
* @return
*/
@ApiOperation(value = "删除", notes = "根据url的id来指定删除对象")
@ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "String", paramType = "path")
@DeleteMapping("/{id}")
public R deleteChartById(@PathVariable String id) {
chartService.deleteChartById(id);
return R.ok();
}
/**
* 批量删除
* @param ids
* @return
*/
@ApiOperation(value = "批量删除", notes = "根据url的ids来批量删除对象")
@ApiImplicitParam(name = "ids", value = "ID集合", required = true, dataType = "List", paramType = "path")
@DeleteMapping("/batch/{ids}")
public R deleteChartBatch(@PathVariable List<String> ids) {
chartService.deleteChartBatch(ids);
return R.ok();
}
@PostMapping("/copy/{id}")
public R copyChart(@PathVariable String id) {
chartService.copyChart(id);
return R.ok();
}
}
package cn.datax.service.data.visual.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.data.visual.api.entity.BoardEntity;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.io.Serializable;
/**
* <p>
* 可视化看板配置信息表 Mapper 接口
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Mapper
public interface BoardDao extends BaseDao<BoardEntity> {
@Override
BoardEntity selectById(Serializable id);
@Override
<E extends IPage<BoardEntity>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<BoardEntity> queryWrapper);
}
package cn.datax.service.data.visual.dao;
import cn.datax.common.base.BaseDao;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.io.Serializable;
/**
* <p>
* 可视化图表配置信息表 Mapper 接口
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Mapper
public interface ChartDao extends BaseDao<ChartEntity> {
@Override
ChartEntity selectById(Serializable id);
@Override
<E extends IPage<ChartEntity>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<ChartEntity> queryWrapper);
}
package cn.datax.service.data.visual.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.data.visual.api.dto.BoardDto;
import cn.datax.service.data.visual.api.entity.BoardEntity;
import cn.datax.service.data.visual.api.vo.BoardVo;
import org.mapstruct.Mapper;
/**
* <p>
* 可视化看板配置信息表 Mapper 实体映射
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Mapper(componentModel = "spring")
public interface BoardMapper extends EntityMapper<BoardDto, BoardEntity, BoardVo> {
}
package cn.datax.service.data.visual.mapstruct;
import cn.datax.common.mapstruct.EntityMapper;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.vo.ChartVo;
import org.mapstruct.Mapper;
/**
* <p>
* 可视化图表配置信息表 Mapper 实体映射
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Mapper(componentModel = "spring")
public interface ChartMapper extends EntityMapper<ChartDto, ChartEntity, ChartVo> {
}
package cn.datax.service.data.visual.service;
import cn.datax.service.data.visual.api.entity.BoardEntity;
import cn.datax.service.data.visual.api.dto.BoardDto;
import cn.datax.common.base.BaseService;
import java.util.List;
/**
* <p>
* 可视化看板配置信息表 服务类
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
public interface BoardService extends BaseService<BoardEntity> {
BoardEntity saveBoard(BoardDto board);
BoardEntity updateBoard(BoardDto board);
BoardEntity getBoardById(String id);
void deleteBoardById(String id);
void deleteBoardBatch(List<String> ids);
void copyBoard(String id);
}
package cn.datax.service.data.visual.service;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.common.base.BaseService;
import java.util.List;
/**
* <p>
* 可视化图表配置信息表 服务类
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
public interface ChartService extends BaseService<ChartEntity> {
ChartEntity saveChart(ChartDto chart);
ChartEntity updateChart(ChartDto chart);
ChartEntity getChartById(String id);
void deleteChartById(String id);
void deleteChartBatch(List<String> ids);
void copyChart(String id);
}
package cn.datax.service.data.visual.service.impl;
import cn.datax.common.core.DataConstant;
import cn.datax.common.exception.DataException;
import cn.datax.service.data.visual.api.entity.BoardEntity;
import cn.datax.service.data.visual.api.dto.BoardDto;
import cn.datax.service.data.visual.service.BoardService;
import cn.datax.service.data.visual.mapstruct.BoardMapper;
import cn.datax.service.data.visual.dao.BoardDao;
import cn.datax.common.base.BaseServiceImpl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
/**
* <p>
* 可视化看板配置信息表 服务实现类
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class BoardServiceImpl extends BaseServiceImpl<BoardDao, BoardEntity> implements BoardService {
@Autowired
private BoardDao boardDao;
@Autowired
private BoardMapper boardMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public BoardEntity saveBoard(BoardDto boardDto) {
BoardEntity board = boardMapper.toEntity(boardDto);
boardDao.insert(board);
return board;
}
@Override
@Transactional(rollbackFor = Exception.class)
public BoardEntity updateBoard(BoardDto boardDto) {
BoardEntity board = boardMapper.toEntity(boardDto);
boardDao.updateById(board);
return board;
}
@Override
public BoardEntity getBoardById(String id) {
BoardEntity boardEntity = super.getById(id);
return boardEntity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteBoardById(String id) {
boardDao.deleteById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteBoardBatch(List<String> ids) {
boardDao.deleteBatchIds(ids);
}
@Override
public void copyBoard(String id) {
BoardEntity boardEntity = Optional.ofNullable(super.getById(id)).orElseThrow(() -> new DataException("获取失败"));
BoardEntity copy = new BoardEntity();
copy.setBoardName(boardEntity.getBoardName() + "_副本" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
copy.setBoardThumbnail(boardEntity.getBoardThumbnail());
copy.setBoardConfig(boardEntity.getBoardConfig());
copy.setStatus(DataConstant.EnableState.ENABLE.getKey());
boardDao.insert(copy);
}
}
package cn.datax.service.data.visual.service.impl;
import cn.datax.common.core.DataConstant;
import cn.datax.common.exception.DataException;
import cn.datax.service.data.visual.api.entity.ChartEntity;
import cn.datax.service.data.visual.api.dto.ChartDto;
import cn.datax.service.data.visual.service.ChartService;
import cn.datax.service.data.visual.mapstruct.ChartMapper;
import cn.datax.service.data.visual.dao.ChartDao;
import cn.datax.common.base.BaseServiceImpl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
/**
* <p>
* 可视化图表配置信息表 服务实现类
* </p>
*
* @author yuwei
* @since 2020-11-04
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ChartServiceImpl extends BaseServiceImpl<ChartDao, ChartEntity> implements ChartService {
@Autowired
private ChartDao chartDao;
@Autowired
private ChartMapper chartMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public ChartEntity saveChart(ChartDto chartDto) {
ChartEntity chart = chartMapper.toEntity(chartDto);
chartDao.insert(chart);
return chart;
}
@Override
@Transactional(rollbackFor = Exception.class)
public ChartEntity updateChart(ChartDto chartDto) {
ChartEntity chart = chartMapper.toEntity(chartDto);
chartDao.updateById(chart);
return chart;
}
@Override
public ChartEntity getChartById(String id) {
ChartEntity chartEntity = super.getById(id);
return chartEntity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteChartById(String id) {
chartDao.deleteById(id);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteChartBatch(List<String> ids) {
chartDao.deleteBatchIds(ids);
}
@Override
public void copyChart(String id) {
ChartEntity chartEntity = Optional.ofNullable(super.getById(id)).orElseThrow(() -> new DataException("获取失败"));
ChartEntity copy = new ChartEntity();
copy.setChartName(chartEntity.getChartName() + "_副本" + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN));
copy.setChartThumbnail(chartEntity.getChartThumbnail());
copy.setChartConfig(chartEntity.getChartConfig());
copy.setStatus(DataConstant.EnableState.ENABLE.getKey());
chartDao.insert(copy);
}
}
<?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="cn.datax.service.data.visual.dao.BoardDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.data.visual.api.entity.BoardEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="create_dept" property="createDept" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="remark" property="remark" />
<result column="board_name" property="boardName" />
<result column="board_thumbnail" property="boardThumbnail" />
</resultMap>
<resultMap id="ExtendResultMap" type="cn.datax.service.data.visual.api.entity.BoardEntity" extends="BaseResultMap">
<result column="board_json" property="boardConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
create_by,
create_time,
update_by,
update_time,
remark,
create_dept, board_name, board_thumbnail
</sql>
<sql id="Extend_Column_List">
id,
status,
create_by,
create_time,
update_by,
update_time,
remark,
create_dept, board_name, board_thumbnail, board_json
</sql>
<select id="selectById" resultMap="ExtendResultMap">
SELECT
<include refid="Extend_Column_List"></include>
FROM visual_board
WHERE 1=1 AND id = #{id}
</select>
<select id="selectPage" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"></include>
FROM visual_board
${ew.customSqlSegment}
</select>
</mapper>
<?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="cn.datax.service.data.visual.dao.ChartDao">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.data.visual.api.entity.ChartEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="create_dept" property="createDept" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="remark" property="remark" />
<result column="chart_name" property="chartName" />
<result column="chart_thumbnail" property="chartThumbnail" />
</resultMap>
<resultMap id="ExtendResultMap" type="cn.datax.service.data.visual.api.entity.ChartEntity" extends="BaseResultMap">
<result column="chart_json" property="chartConfig" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
create_by,
create_time,
update_by,
update_time,
remark,
create_dept, chart_name, chart_thumbnail
</sql>
<sql id="Extend_Column_List">
id,
status,
create_by,
create_time,
update_by,
update_time,
remark,
create_dept, chart_name, chart_thumbnail, chart_json
</sql>
<select id="selectById" resultMap="ExtendResultMap">
SELECT
<include refid="Extend_Column_List"></include>
FROM visual_chart
WHERE 1=1 AND id = #{id}
</select>
<select id="selectPage" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"></include>
FROM visual_chart
${ew.customSqlSegment}
</select>
</mapper>
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
"echarts": "^4.8.0", "echarts": "^4.8.0",
"element-ui": "2.13.2", "element-ui": "2.13.2",
"good-storage": "^1.1.1", "good-storage": "^1.1.1",
"html2canvas": "^1.0.0-rc.7",
"jsplumb": "^2.14.6", "jsplumb": "^2.14.6",
"moment": "^2.29.1", "moment": "^2.29.1",
"normalize.css": "7.0.0", "normalize.css": "7.0.0",
......
import request from '@/utils/request'
export function pageDataBoard(data) {
return request({
url: '/data/visual/boards/page',
method: 'get',
params: data
})
}
export function getDataBoard(id) {
return request({
url: '/data/visual/boards/' + id,
method: 'get'
})
}
export function delDataBoard(id) {
return request({
url: '/data/visual/boards/' + id,
method: 'delete'
})
}
export function addDataBoard(data) {
return request({
url: '/data/visual/boards',
method: 'post',
data: data
})
}
export function updateDataBoard(data) {
return request({
url: '/data/visual/boards/' + data.id,
method: 'put',
data: data
})
}
export function copyDataBoard(id) {
return request({
url: '/data/visual/boards/copy/' + id,
method: 'post'
})
}
import request from '@/utils/request'
export function pageDataChart(data) {
return request({
url: '/data/visual/charts/page',
method: 'get',
params: data
})
}
export function getDataChart(id) {
return request({
url: '/data/visual/charts/' + id,
method: 'get'
})
}
export function delDataChart(id) {
return request({
url: '/data/visual/charts/' + id,
method: 'delete'
})
}
export function addDataChart(data) {
return request({
url: '/data/visual/charts',
method: 'post',
data: data
})
}
export function updateDataChart(data) {
return request({
url: '/data/visual/charts/' + data.id,
method: 'put',
data: data
})
}
export function copyDataChart(id) {
return request({
url: '/data/visual/charts/copy/' + id,
method: 'post'
})
}
...@@ -67,6 +67,18 @@ export const constantRoutes = [ ...@@ -67,6 +67,18 @@ export const constantRoutes = [
}, },
{ {
path: '/visual/chart/build/:id',
component: () => import('@/views/visual/datachart/chart'),
hidden: true
},
{
path: '/visual/board/build/:id',
component: () => import('@/views/visual/databoard/board'),
hidden: true
},
{
path: '/', path: '/',
component: Layout, component: Layout,
redirect: '/dashboard', redirect: '/dashboard',
...@@ -78,67 +90,6 @@ export const constantRoutes = [ ...@@ -78,67 +90,6 @@ export const constantRoutes = [
}] }]
} }
// {
// path: '/nested',
// component: Layout,
// redirect: '/nested/menu1/menu1-1',
// name: 'Nested',
// meta: {
// title: 'Nested Routes',
// icon: 'nested'
// },
// children: [
// {
// path: 'menu1',
// component: () => import('@/views/nested/menu1/index'), // Parent router-view
// name: 'Menu1',
// meta: { title: 'Menu 1' },
// redirect: '/nested/menu1/menu1-1',
// children: [
// {
// path: 'menu1-1',
// component: () => import('@/views/nested/menu1/menu1-1'),
// name: 'Menu1-1',
// meta: { title: 'Menu 1-1' }
// },
// {
// path: 'menu1-2',
// component: () => import('@/views/nested/menu1/menu1-2'),
// name: 'Menu1-2',
// redirect: '/nested/menu1/menu1-2/menu1-2-1',
// meta: { title: 'Menu 1-2' },
// children: [
// {
// path: 'menu1-2-1',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
// name: 'Menu1-2-1',
// meta: { title: 'Menu 1-2-1' }
// },
// {
// path: 'menu1-2-2',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
// name: 'Menu1-2-2',
// meta: { title: 'Menu 1-2-2' }
// }
// ]
// },
// {
// path: 'menu1-3',
// component: () => import('@/views/nested/menu1/menu1-3'),
// name: 'Menu1-3',
// meta: { title: 'Menu 1-3' }
// }
// ]
// },
// {
// path: 'menu2',
// name: 'Menu2',
// component: () => import('@/views/nested/menu2/index'),
// meta: { title: 'Menu 2' }
// }
// ]
// }
// 404 page must be placed at the end !!! // 404 page must be placed at the end !!!
// { path: '*', redirect: '/404', hidden: true } // { path: '*', redirect: '/404', hidden: true }
] ]
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<script> <script>
import { log } from '@/api/system/user' import { log } from '@/api/system/user'
import background from '@/assets/images/background.jpg' import background from '@/assets/images/login-bg.jpg'
export default { export default {
name: 'Login', name: 'Login',
...@@ -91,7 +91,10 @@ export default { ...@@ -91,7 +91,10 @@ export default {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-repeat: no-repeat;
background-size: cover; background-size: cover;
background-position: center center;
transition: background-image 3s;
.title-container { .title-container {
margin: 0 auto 30px auto; margin: 0 auto 30px auto;
text-align: center; text-align: center;
...@@ -99,8 +102,8 @@ export default { ...@@ -99,8 +102,8 @@ export default {
} }
.login-form { .login-form {
border-radius: 6px; border-radius: 6px;
background: rgba(74, 74, 82, .5); background: rgba(94, 94, 187, .5);
box-shadow: 0 0 25px rgba(206, 33, 33, .5); box-shadow: 0 0 25px rgba(223, 220, 239, .5);
width: 385px; width: 385px;
padding: 25px 25px 5px 25px; padding: 25px 25px 5px 25px;
.el-input { .el-input {
......
...@@ -317,11 +317,18 @@ export default { ...@@ -317,11 +317,18 @@ export default {
}, },
/** 接口拷贝 */ /** 接口拷贝 */
handleCopy(row) { handleCopy(row) {
copyDataApi(row.id).then(response => { this.$confirm('确认拷贝当前接口, 是否继续?', '提示', {
if (response.success) { confirmButtonText: '确定',
this.$message.success('拷贝成功') cancelButtonText: '取消',
this.getList() type: 'warning'
} }).then(() => {
copyDataApi(row.id).then(response => {
if (response.success) {
this.$message.success('拷贝成功')
this.getList()
}
})
}).catch(() => {
}) })
}, },
/** 接口发布 */ /** 接口发布 */
......
<template>
<div class="chart-container">
<el-row>
<el-col>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="queryParams.pageNum"
:page-size.sync="queryParams.pageSize"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="6">
<el-card :body-style="{ padding: '0px' }" class="box-card-item">
<div class="box-card-item-add" @click="handleAdd">
<div class="icon-block">
<i class="el-icon-plus" />
</div>
</div>
</el-card>
</el-col>
<el-col v-for="(item, index) in tableDataList" :key="item.id" :span="6">
<el-card :body-style="{ padding: '0px' }" class="box-card-item">
<div class="box-card-item-body" @mouseenter="mouseEnter(item)" @mouseleave="mouseLeave(item)">
<el-image :src="item.boardThumbnail ? ('data:image/png;base64,' + item.boardThumbnail) : ''">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline" />
</div>
</el-image>
<div class="box-card-item-edit" :style="{display: (item.show ? 'block' : 'none')}">
<el-button type="primary" @click="handleConfig(item)">编辑</el-button>
</div>
</div>
<div class="box-card-item-footer">
<div class="box-card-item-footer-text">{{ item.boardName }}</div>
<div class="clearfix">
<i class="el-icon-edit-outline" @click="handleEdit(item)" />
<i class="el-icon-view" @click="handleView(item)" />
<i class="el-icon-delete" @click="handleDelete(item)" />
<i class="el-icon-copy-document" @click="handleCopy(item)" />
</div>
</div>
</el-card>
</el-col>
</el-row>
<board-form v-if="dialogFormVisible" :visible.sync="dialogFormVisible" :data="currentBoard" @handleBoardFormFinished="getList" />
</div>
</template>
<script>
import { pageDataBoard, delDataBoard, copyDataBoard } from '@/api/visual/databoard'
import BoardForm from './components/BoardForm'
export default {
name: 'DataBoardList',
components: { BoardForm },
data() {
return {
// 表格数据
tableDataList: [],
// 总数据条数
total: 0,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10
},
dialogFormVisible: false,
currentBoard: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询数据列表 */
getList() {
pageDataBoard(this.queryParams).then(response => {
if (response.success) {
const { data } = response
this.tableDataList = data.data
this.total = data.total
}
})
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`)
this.queryParams.pageNum = 1
this.queryParams.pageSize = val
this.getList()
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`)
this.queryParams.pageNum = val
this.getList()
},
mouseEnter(data) {
this.$set(data, 'show', true)
},
mouseLeave(data) {
this.$set(data, 'show', false)
},
handleAdd() {
this.dialogFormVisible = true
this.currentBoard = {}
},
handleConfig(data) {
console.log(data)
},
handleEdit(data) {
this.dialogFormVisible = true
this.currentBoard = Object.assign({}, data)
},
handleView(data) {
console.log(data)
},
handleDelete(data) {
this.$confirm('选中数据将被永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delDataBoard(data.id).then(response => {
if (response.success) {
this.$message.success('删除成功')
this.getList()
}
})
}).catch(() => {
})
},
handleCopy(data) {
this.$confirm('确认拷贝当前图表, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
copyDataBoard(data.id).then(response => {
if (response.success) {
this.$message.success('拷贝成功')
this.getList()
}
})
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
.el-pagination {
text-align: center;
}
.box-card-item {
width: 260px;
height: 185px;
margin-bottom: 20px;
.box-card-item-body {
display: flex;
justify-content: center;
align-items: center;
.box-card-item-edit {
width: 260px;
height: 150px;
text-align: center;
position: absolute;
background: rgba(4, 11, 28, 0.7);
opacity: 0.8;
button {
margin-top: 55px;
}
}
}
.el-image{
width: 260px;
height: 150px;
display: block;
::v-deep .image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
}
}
.box-card-item-add {
width: 260px;
height: 185px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
i {
font-size: 30px;
}
}
.box-card-item-footer {
padding: 8px 5px;
background-color: #dcdcdc;
display: flex;
justify-content: space-between;
.box-card-item-footer-text {
width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
i {
margin-right: 5px;
cursor: pointer;
}
}
}
</style>
<template>
<el-dialog title="看板" width="50%" :visible.sync="dialogVisible" :show-close="false" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="看板名称" prop="boardName">
<el-input v-model="form.boardName" placeholder="请输入看板名称" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</span>
</el-dialog>
</template>
<script>
import { addDataBoard, updateDataBoard } from '@/api/visual/databoard'
export default {
name: 'BoardForm',
props: {
visible: {
type: Boolean,
default: function() {
return false
}
},
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
form: {
boardName: undefined
},
rules: {
boardName: [
{ required: true, message: '看板名称不能为空', trigger: 'blur' }
]
}
}
},
computed: {
dialogVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
created() {
this.form = this.data
},
methods: {
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id) {
updateDataBoard(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
this.dialogVisible = false
this.$emit('handleBoardFormFinished')
}
}).catch(error => {
this.$message.error(error.msg || '保存失败')
})
} else {
addDataBoard(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
this.dialogVisible = false
this.$emit('handleBoardFormFinished')
}
}).catch(error => {
this.$message.error(error.msg || '保存失败')
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template> <template>
<div class="app-container"> <div class="app-container">
DataBoard <transition name="el-zoom-in-center">
<data-board-list v-if="options.showList" @showCard="showCard" />
</transition>
</div> </div>
</template> </template>
<script> <script>
import DataBoardList from './DataBoardList'
export default { export default {
name: 'DataBoard' name: 'DataBoard',
components: { DataBoardList },
data() {
return {
options: {
data: {},
showList: true
}
}
},
methods: {
showCard(data) {
Object.assign(this.options, data)
}
}
} }
</script> </script>
......
<template>
<div class="chart-container">
<el-row>
<el-col>
<el-pagination
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:current-page.sync="queryParams.pageNum"
:page-size.sync="queryParams.pageSize"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-col>
</el-row>
<el-divider />
<el-row :gutter="20">
<el-col :span="6">
<el-card :body-style="{ padding: '0px' }" class="box-card-item">
<div class="box-card-item-add" @click="handleAdd">
<div class="icon-block">
<i class="el-icon-plus" />
</div>
</div>
</el-card>
</el-col>
<el-col v-for="(item, index) in tableDataList" :key="item.id" :span="6">
<el-card :body-style="{ padding: '0px' }" class="box-card-item">
<div class="box-card-item-body" @mouseenter="mouseEnter(item)" @mouseleave="mouseLeave(item)">
<el-image :src="item.chartThumbnail ? ('data:image/png;base64,' + item.chartThumbnail) : ''">
<div slot="error" class="image-slot">
<i class="el-icon-picture-outline" />
</div>
</el-image>
<div class="box-card-item-edit" :style="{display: (item.show ? 'block' : 'none')}">
<el-button type="primary" @click="handleConfig(item)">编辑</el-button>
</div>
</div>
<div class="box-card-item-footer">
<span class="box-card-item-footer-text">{{ item.chartName }}</span>
<div class="clearfix">
<i class="el-icon-edit-outline" @click="handleEdit(item)" />
<i class="el-icon-delete" @click="handleDelete(item)" />
<i class="el-icon-copy-document" @click="handleCopy(item)" />
</div>
</div>
</el-card>
</el-col>
</el-row>
<chart-form v-if="dialogFormVisible" :visible.sync="dialogFormVisible" :data="currentChart" @handleChartFormFinished="getList" />
</div>
</template>
<script>
import { pageDataChart, delDataChart, copyDataChart } from '@/api/visual/datachart'
import ChartForm from './components/ChartForm'
export default {
name: 'DataChartList',
components: { ChartForm },
data() {
return {
// 表格数据
tableDataList: [],
// 总数据条数
total: 0,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10
},
dialogFormVisible: false,
currentChart: {}
}
},
created() {
this.getList()
},
methods: {
/** 查询数据列表 */
getList() {
pageDataChart(this.queryParams).then(response => {
if (response.success) {
const { data } = response
this.tableDataList = data.data
this.total = data.total
}
})
},
handleSizeChange(val) {
console.log(`每页 ${val} 条`)
this.queryParams.pageNum = 1
this.queryParams.pageSize = val
this.getList()
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`)
this.queryParams.pageNum = val
this.getList()
},
mouseEnter(data) {
this.$set(data, 'show', true)
},
mouseLeave(data) {
this.$set(data, 'show', false)
},
handleAdd() {
this.dialogFormVisible = true
this.currentChart = {}
},
handleConfig(data) {
const route = this.$router.resolve({ path: `/visual/chart/build/${data.id}` })
window.open(route.href, '_blank')
},
handleEdit(data) {
this.dialogFormVisible = true
this.currentChart = Object.assign({}, data)
},
handleDelete(data) {
this.$confirm('选中数据将被永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delDataChart(data.id).then(response => {
if (response.success) {
this.$message.success('删除成功')
this.getList()
}
})
}).catch(() => {
})
},
handleCopy(data) {
this.$confirm('确认拷贝当前图表, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
copyDataChart(data.id).then(response => {
if (response.success) {
this.$message.success('拷贝成功')
this.getList()
}
})
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
.el-pagination {
text-align: center;
}
.box-card-item {
width: 260px;
height: 185px;
margin-bottom: 20px;
.box-card-item-body {
display: flex;
justify-content: center;
align-items: center;
.box-card-item-edit {
width: 260px;
height: 150px;
text-align: center;
position: absolute;
background: rgba(4, 11, 28, 0.7);
opacity: 0.8;
button {
margin-top: 55px;
}
}
}
.el-image{
width: 260px;
height: 150px;
display: block;
::v-deep .image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: #f5f7fa;
color: #909399;
}
}
.box-card-item-add {
width: 260px;
height: 185px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
i {
font-size: 30px;
}
}
.box-card-item-footer {
padding: 8px 5px;
background-color: #dcdcdc;
display: flex;
justify-content: space-between;
.box-card-item-footer-text {
width: 150px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
i {
margin-right: 5px;
cursor: pointer;
}
}
}
</style>
...@@ -5,21 +5,21 @@ ...@@ -5,21 +5,21 @@
<el-card class="box-card" shadow="always" style="height: 100%;"> <el-card class="box-card" shadow="always" style="height: 100%;">
<div slot="header" class="clearfix"> <div slot="header" class="clearfix">
<span>数据集</span> <span>数据集</span>
<el-dropdown trigger="click" @command="handleCommand" style="float: right; color: #499df3;"> <el-dropdown trigger="click" style="float: right; color: #499df3;" @command="handleCommand">
<span class="el-dropdown-link"> <span class="el-dropdown-link">
切换<i class="el-icon-arrow-down el-icon--right"></i> 切换<i class="el-icon-arrow-down el-icon--right" />
</span> </span>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item v-for="item in datasetOptions" :command="item.id">{{item.setName}}</el-dropdown-item> <el-dropdown-item v-for="item in datasetOptions" :command="item.id" :key="item.id">{{ item.setName }}</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
</div> </div>
<div style="margin: -20px;"> <div style="margin: -20px;">
<div class="field-widget-cate"><i class="icon iconfont icon-weidu"></i><span>维度列</span></div> <div class="field-widget-cate"><i class="icon iconfont icon-weidu" /><span>维度列</span></div>
<draggable v-model="dimensions" class="field-widget-tag" :options="{sort: false, ghostClass: 'ghost', group: {name: 'dimensions', pull: true, put: false}}"> <draggable v-model="dimensions" class="field-widget-tag" :options="{sort: false, ghostClass: 'ghost', group: {name: 'dimensions', pull: true, put: false}}">
<el-tag v-for="(item, index) in dimensions" :key="index" class="field-widget-label"><div>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</div></el-tag> <el-tag v-for="(item, index) in dimensions" :key="index" class="field-widget-label"><div>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</div></el-tag>
</draggable> </draggable>
<div class="field-widget-cate"><i class="icon iconfont icon-zhibiao"></i><span>指标列</span></div> <div class="field-widget-cate"><i class="icon iconfont icon-zhibiao" /><span>指标列</span></div>
<draggable v-model="measures" class="field-widget-tag" :options="{sort: false, ghostClass: 'ghost', group: {name: 'measures', pull: true, put: false}}"> <draggable v-model="measures" class="field-widget-tag" :options="{sort: false, ghostClass: 'ghost', group: {name: 'measures', pull: true, put: false}}">
<el-tag v-for="(item, index) in measures" :key="index" class="field-widget-label"><div>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</div></el-tag> <el-tag v-for="(item, index) in measures" :key="index" class="field-widget-label"><div>{{ item.alias ? item.alias + '(' + item.col + ')' : item.col }}</div></el-tag>
</draggable> </draggable>
...@@ -73,8 +73,8 @@ ...@@ -73,8 +73,8 @@
<draggable group="measures" :list="form.values" @change="handleValueDragChange"> <draggable group="measures" :list="form.values" @change="handleValueDragChange">
<div v-for="(item, index) in form.values" :key="index" class="draggable-item"> <div v-for="(item, index) in form.values" :key="index" class="draggable-item">
<el-tag>{{ item.alias ? item.aggregate_type + '(' + item.col + ') -> ' + item.alias : item.aggregate_type + '(' + item.col + ')' }}</el-tag> <el-tag>{{ item.alias ? item.aggregate_type + '(' + item.col + ') -> ' + item.alias : item.aggregate_type + '(' + item.col + ')' }}</el-tag>
<span class="draggable-item-handle" v-if="item.radio"> <span v-if="item.radio" class="draggable-item-handle">
<el-radio-group size="mini" v-model="item.aggregate_type" @change="((label)=>{handleValueChangeTagType(label, index, item)})"> <el-radio-group v-model="item.aggregate_type" size="mini" @change="((label)=>{handleValueChangeTagType(label, index, item)})">
<el-radio label="sum" size="mini">求和</el-radio> <el-radio label="sum" size="mini">求和</el-radio>
<el-radio label="count" size="mini">计数</el-radio> <el-radio label="count" size="mini">计数</el-radio>
<el-radio label="avg" size="mini">平均值</el-radio> <el-radio label="avg" size="mini">平均值</el-radio>
...@@ -82,8 +82,8 @@ ...@@ -82,8 +82,8 @@
<el-radio label="min" size="mini">最小值</el-radio> <el-radio label="min" size="mini">最小值</el-radio>
</el-radio-group> </el-radio-group>
</span> </span>
<span class="draggable-item-handle" v-else @click="handleValueTagType(index, item)"><i class="el-icon-edit-outline"></i></span> <span v-else class="draggable-item-handle" @click="handleValueTagType(index, item)"><i class="el-icon-edit-outline" /></span>
<span class="draggable-item-handle" @click="handleValueTagClose(index, item)"><i class="el-icon-delete"></i></span> <span class="draggable-item-handle" @click="handleValueTagClose(index, item)"><i class="el-icon-delete" /></span>
</div> </div>
</draggable> </draggable>
</div> </div>
...@@ -91,16 +91,15 @@ ...@@ -91,16 +91,15 @@
</el-row> </el-row>
<el-row> <el-row>
<el-divider>预览区</el-divider> <el-divider>预览区</el-divider>
<el-tabs type="card"> <el-tabs type="card">
<el-tab-pane label="预览"> <el-tab-pane label="预览">
<div class="data-tab-pane">预览</div> <div class="data-tab-pane">预览</div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="查询脚本"> <el-tab-pane label="查询脚本">
<div class="script-tab-pane">查询脚本</div> <div class="script-tab-pane">查询脚本</div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
<el-col> <el-col />
</el-col>
</el-row> </el-row>
</el-main> </el-main>
</el-container> </el-container>
...@@ -125,6 +124,7 @@ ...@@ -125,6 +124,7 @@
</template> </template>
<script> <script>
import { getDataChart } from '@/api/visual/datachart'
import { getDataSet, listDataSet } from '@/api/visual/dataset' import { getDataSet, listDataSet } from '@/api/visual/dataset'
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
...@@ -133,32 +133,42 @@ export default { ...@@ -133,32 +133,42 @@ export default {
components: { components: {
draggable draggable
}, },
data () { data() {
return { return {
datachart: {},
form: { form: {
keys: [], keys: [],
groups: [], groups: [],
values: [] values: []
}, },
datasetOptions: [],
dataset: {}, dataset: {},
datasetOptions : [],
dimensions: [], dimensions: [],
measures: [] measures: []
} }
}, },
created () { created() {
this.getDataChart(this.$route.params.id)
this.getDataSetList() this.getDataSetList()
}, },
methods: { methods: {
getDataSetList () { getDataChart(id) {
getDataChart(id).then(response => {
if (response.success) {
this.datachart = response.data
console.log(this.datachart)
}
})
},
getDataSetList() {
listDataSet().then(response => { listDataSet().then(response => {
if (response.success) { if (response.success) {
this.datasetOptions = response.data this.datasetOptions = response.data
} }
}) })
}, },
handleCommand (command) { handleCommand(id) {
getDataSet(command).then(response => { getDataSet(id).then(response => {
if (response.success) { if (response.success) {
this.dataset = response.data this.dataset = response.data
this.dimensions = this.dataset.schemaConfig.dimensions this.dimensions = this.dataset.schemaConfig.dimensions
...@@ -166,26 +176,26 @@ export default { ...@@ -166,26 +176,26 @@ export default {
} }
}) })
}, },
handleKeyTagClose (index, tag) { handleKeyTagClose(index, tag) {
this.form.keys.splice(index, 1) this.form.keys.splice(index, 1)
this.dimensions.push(tag) this.dimensions.push(tag)
}, },
handleGroupTagClose (index, tag) { handleGroupTagClose(index, tag) {
this.form.groups.splice(index, 1) this.form.groups.splice(index, 1)
this.dimensions.push(tag) this.dimensions.push(tag)
}, },
handleValueDragChange (tag) { handleValueDragChange(tag) {
if (tag.added) { if (tag.added) {
this.$set(tag.added.element, 'aggregate_type', 'sum') this.$set(tag.added.element, 'aggregate_type', 'sum')
} }
}, },
handleValueChangeTagType (label, index, tag) { handleValueChangeTagType(label, index, tag) {
this.$delete(tag, 'radio') this.$delete(tag, 'radio')
}, },
handleValueTagType (index, tag) { handleValueTagType(index, tag) {
this.$set(tag, 'radio', true) this.$set(tag, 'radio', true)
}, },
handleValueTagClose (index, tag) { handleValueTagClose(index, tag) {
this.form.values.splice(index, 1) this.form.values.splice(index, 1)
tag.aggregate_type = '' tag.aggregate_type = ''
this.measures.push(tag) this.measures.push(tag)
......
<template>
<el-dialog title="图表" width="50%" :visible.sync="dialogVisible" :show-close="false" :close-on-click-modal="false">
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-form-item label="图表名称" prop="chartName">
<el-input v-model="form.chartName" placeholder="请输入图表名称" />
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确定</el-button>
<el-button @click="dialogVisible = false">取消</el-button>
</span>
</el-dialog>
</template>
<script>
import { addDataChart, updateDataChart } from '@/api/visual/datachart'
export default {
name: 'ChartForm',
props: {
visible: {
type: Boolean,
default: function() {
return false
}
},
data: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
form: {
chartName: undefined
},
rules: {
chartName: [
{ required: true, message: '图表名称不能为空', trigger: 'blur' }
]
}
}
},
computed: {
dialogVisible: {
get() {
return this.visible
},
set(val) {
this.$emit('update:visible', val)
}
}
},
created() {
this.form = this.data
},
methods: {
submitForm() {
this.$refs['form'].validate(valid => {
if (valid) {
if (this.form.id) {
updateDataChart(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
this.dialogVisible = false
this.$emit('handleChartFormFinished')
}
}).catch(error => {
this.$message.error(error.msg || '保存失败')
})
} else {
addDataChart(this.form).then(response => {
if (response.success) {
this.$message.success('保存成功')
this.dialogVisible = false
this.$emit('handleChartFormFinished')
}
}).catch(error => {
this.$message.error(error.msg || '保存失败')
})
}
}
})
}
}
}
</script>
<style lang="scss" scoped>
</style>
<template> <template>
<div class="app-container"> <div class="app-container">
DataChart <transition name="el-zoom-in-center">
<data-chart-list v-if="options.showList" @showCard="showCard" />
</transition>
</div> </div>
</template> </template>
<script> <script>
import DataChartList from './DataChartList'
export default { export default {
name: 'DataChart' name: 'DataChart',
components: { DataChartList },
data() {
return {
options: {
data: {},
showList: true
}
}
},
methods: {
showCard(data) {
Object.assign(this.options, data)
}
}
} }
</script> </script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment