mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-11-29 18:48:23 +08:00
refactor(dashboard): refactor create
This commit is contained in:
parent
e5863b6762
commit
f9287a0342
9
configure/schema/2024.4.0/schema.sql
Normal file
9
configure/schema/2024.4.0/schema.sql
Normal file
@ -0,0 +1,9 @@
|
||||
USE
|
||||
`datacap`;
|
||||
|
||||
ALTER TABLE `datacap_dashboard`
|
||||
ADD COLUMN `version` VARCHAR(100) DEFAULT NULL;
|
||||
|
||||
UPDATE `datacap_dashboard`
|
||||
SET `version` = '1.0'
|
||||
WHERE `version` IS NULL;
|
@ -12,9 +12,8 @@ import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -42,14 +41,30 @@ public abstract class BaseController<T extends BaseEntity>
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes
|
||||
* Create new resource
|
||||
*/
|
||||
@RequestMapping(method = {RequestMethod.POST, RequestMethod.PUT})
|
||||
public CommonResponse<T> saveAndUpdate(@RequestBody T configure)
|
||||
@PostMapping
|
||||
@JsonView(value = {EntityView.UserView.class})
|
||||
public CommonResponse<T> create(@RequestBody T configure)
|
||||
{
|
||||
return service.saveOrUpdate(repository, configure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing resource
|
||||
*/
|
||||
@PutMapping
|
||||
@JsonView(value = {EntityView.UserView.class})
|
||||
public CommonResponse<T> update(@RequestBody T configure)
|
||||
{
|
||||
return repository.findByCode(configure.getCode())
|
||||
.map(entity -> {
|
||||
configure.setId(entity.getId());
|
||||
return service.saveOrUpdate(repository, configure);
|
||||
})
|
||||
.orElseGet(() -> CommonResponse.failure("Resource [ " + configure.getCode() + " ] not found"));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@DeleteMapping
|
||||
public CommonResponse<Long> delete(@RequestParam(value = "id") Long id)
|
||||
|
@ -52,6 +52,10 @@ public class DashboardEntity
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private AvatarEntity avatar;
|
||||
|
||||
@Column(name = "version")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String version;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "datacap_dashboard_user_relation",
|
||||
joinColumns = @JoinColumn(name = "dashboard_id"),
|
||||
|
@ -1,8 +1,10 @@
|
||||
package io.edurt.datacap.service.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import io.edurt.datacap.common.enums.DataSetState;
|
||||
import io.edurt.datacap.common.view.EntityView;
|
||||
import io.edurt.datacap.service.converter.ListConverter;
|
||||
import io.edurt.datacap.service.enums.SyncMode;
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -38,50 +40,65 @@ public class DataSetEntity
|
||||
extends BaseEntity
|
||||
{
|
||||
@Column(name = "description")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String description;
|
||||
|
||||
@Column(name = "query")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String query;
|
||||
|
||||
@Column(name = "sync_mode")
|
||||
@Enumerated(EnumType.STRING)
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private SyncMode syncMode = SyncMode.MANUAL;
|
||||
|
||||
@Column(name = "expression")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String expression; // only for TIMING
|
||||
|
||||
@Column(name = "state")
|
||||
@Convert(converter = ListConverter.class)
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private List<DataSetState> state;
|
||||
|
||||
@Column(name = "message")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String message;
|
||||
|
||||
@Column(name = "table_name")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String tableName;
|
||||
|
||||
@Column(name = "code")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String code;
|
||||
|
||||
@Column(name = "scheduler")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String scheduler;
|
||||
|
||||
@Column(name = "executor")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String executor;
|
||||
|
||||
@Column(name = "total_rows")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String totalRows;
|
||||
|
||||
@Column(name = "total_size")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String totalSize;
|
||||
|
||||
@Column(name = "life_cycle")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String lifeCycle;
|
||||
|
||||
@Column(name = "life_cycle_column")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String lifeCycleColumn;
|
||||
|
||||
@Column(name = "life_cycle_type")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String lifeCycleType;
|
||||
|
||||
@ManyToOne
|
||||
@ -89,6 +106,7 @@ public class DataSetEntity
|
||||
joinColumns = @JoinColumn(name = "dataset_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "source_id"))
|
||||
@JsonIgnoreProperties(value = {"user"})
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private SourceEntity source;
|
||||
|
||||
@ManyToOne
|
||||
@ -96,6 +114,7 @@ public class DataSetEntity
|
||||
joinColumns = @JoinColumn(name = "dataset_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "user_id"))
|
||||
@JsonIgnoreProperties(value = {"roles", "thirdConfigure", "avatarConfigure"})
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private UserEntity user;
|
||||
|
||||
@Transient
|
||||
|
@ -1,7 +1,8 @@
|
||||
package io.edurt.datacap.service.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIncludeProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import io.edurt.datacap.common.view.EntityView;
|
||||
import io.edurt.datacap.service.enums.ReportType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
@ -35,39 +36,44 @@ public class ReportEntity
|
||||
extends BaseEntity
|
||||
{
|
||||
@Column(name = "configure")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String configure;
|
||||
|
||||
@Column(name = "realtime")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private boolean realtime;
|
||||
|
||||
@Column(name = "type")
|
||||
@Enumerated(EnumType.STRING)
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private ReportType type;
|
||||
|
||||
@Column(name = "query")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String query;
|
||||
|
||||
@Column(name = "description")
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private String description;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "datacap_report_user_relation",
|
||||
joinColumns = @JoinColumn(name = "report_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "user_id"))
|
||||
@JsonIncludeProperties(value = {"id", "name", "username", "code"})
|
||||
@JsonView(value = {EntityView.AdminView.class})
|
||||
private UserEntity user;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "datacap_report_source_relation",
|
||||
joinColumns = @JoinColumn(name = "report_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "source_id"))
|
||||
@JsonIncludeProperties(value = {"id", "code", "name", "type"})
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private SourceEntity source;
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "datacap_report_dataset_relation",
|
||||
joinColumns = @JoinColumn(name = "report_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "dataset_id"))
|
||||
@JsonIncludeProperties(value = {"id", "code", "name", "query", "description"})
|
||||
@JsonView(value = {EntityView.UserView.class, EntityView.AdminView.class})
|
||||
private DataSetEntity dataset;
|
||||
}
|
||||
|
@ -9,7 +9,4 @@ import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
public interface DashboardService
|
||||
extends BaseService<DashboardEntity>
|
||||
{
|
||||
CommonResponse<PageEntity<DashboardEntity>> getAll(FilterBody filter);
|
||||
|
||||
CommonResponse<DashboardEntity> saveOrUpdate(PagingAndSortingRepository<DashboardEntity, Long> repository, DashboardEntity configure);
|
||||
}
|
||||
|
@ -5,11 +5,12 @@ import io.edurt.datacap.service.adapter.PageRequestAdapter;
|
||||
import io.edurt.datacap.service.body.FilterBody;
|
||||
import io.edurt.datacap.service.entity.DashboardEntity;
|
||||
import io.edurt.datacap.service.entity.PageEntity;
|
||||
import io.edurt.datacap.service.repository.BaseRepository;
|
||||
import io.edurt.datacap.service.repository.DashboardRepository;
|
||||
import io.edurt.datacap.service.repository.ReportRepository;
|
||||
import io.edurt.datacap.service.security.UserDetailsService;
|
||||
import io.edurt.datacap.service.service.DashboardService;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@ -17,23 +18,31 @@ public class DashboardServiceImpl
|
||||
implements DashboardService
|
||||
{
|
||||
private final DashboardRepository repository;
|
||||
private final ReportRepository reportRepository;
|
||||
|
||||
public DashboardServiceImpl(DashboardRepository repository)
|
||||
public DashboardServiceImpl(DashboardRepository repository, ReportRepository reportRepository)
|
||||
{
|
||||
this.repository = repository;
|
||||
this.reportRepository = reportRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<PageEntity<DashboardEntity>> getAll(FilterBody filter)
|
||||
public CommonResponse<PageEntity<DashboardEntity>> getAll(BaseRepository<DashboardEntity, Long> baseRepository, FilterBody filter)
|
||||
{
|
||||
Pageable pageable = PageRequestAdapter.of(filter);
|
||||
return CommonResponse.success(PageEntity.build(repository.findAllByUser(UserDetailsService.getUser(), pageable)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<DashboardEntity> saveOrUpdate(PagingAndSortingRepository<DashboardEntity, Long> repository, DashboardEntity configure)
|
||||
public CommonResponse<DashboardEntity> saveOrUpdate(BaseRepository<DashboardEntity, Long> baseRepository, DashboardEntity configure)
|
||||
{
|
||||
configure.setUser(UserDetailsService.getUser());
|
||||
configure.getReports()
|
||||
.forEach(entity -> reportRepository.findByCode(entity.getCode())
|
||||
.ifPresentOrElse(
|
||||
report -> entity.setId(report.getId()),
|
||||
() -> {throw new RuntimeException("Report [ " + entity.getCode() + " ] not found");}
|
||||
));
|
||||
return CommonResponse.success(repository.save(configure));
|
||||
}
|
||||
}
|
||||
|
@ -44,15 +44,9 @@ public class ExecuteServiceImpl
|
||||
@Override
|
||||
public CommonResponse<Object> execute(ExecuteEntity configure)
|
||||
{
|
||||
try {
|
||||
return sourceRepository.findById(Long.valueOf(configure.getName()))
|
||||
.map(entity -> handleSourceEntity(entity, configure.getContent()))
|
||||
.orElse(CommonResponse.failure(ServiceState.SOURCE_NOT_FOUND));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
log.error("Invalid source id: {}", configure.getName(), e);
|
||||
return CommonResponse.failure(ServiceState.INVALID_PARAMETER, "Invalid source id");
|
||||
}
|
||||
return sourceRepository.findByCode(configure.getName())
|
||||
.map(entity -> handleSourceEntity(entity, configure.getContent()))
|
||||
.orElse(CommonResponse.failure(ServiceState.SOURCE_NOT_FOUND));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ export interface BaseModel
|
||||
id?: number
|
||||
name?: string
|
||||
active?: boolean
|
||||
code?: string
|
||||
createTime?: string
|
||||
updateTime?: string
|
||||
}
|
@ -143,7 +143,7 @@ export default defineComponent({
|
||||
default: () => '400px'
|
||||
},
|
||||
original: {
|
||||
type: Number
|
||||
type: String
|
||||
}
|
||||
},
|
||||
data()
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="relative">
|
||||
<ShadcnSpin v-model="loading" fixed/>
|
||||
|
||||
<DashboardEditor v-if="dataInfo" :info="dataInfo"/>
|
||||
<DashboardEditor :info="dataInfo"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -21,7 +21,8 @@ export default defineComponent({
|
||||
return {
|
||||
loading: false,
|
||||
saving: false,
|
||||
dataInfo: null as DashboardModel | null
|
||||
dataInfo: null as DashboardModel | null,
|
||||
version: '2'
|
||||
}
|
||||
},
|
||||
created()
|
||||
@ -40,6 +41,7 @@ export default defineComponent({
|
||||
.then(response => {
|
||||
if (response.status) {
|
||||
this.dataInfo = response.data
|
||||
this.version = response.data.version
|
||||
}
|
||||
else {
|
||||
this.$Message.error({
|
||||
|
@ -12,7 +12,7 @@
|
||||
<ShadcnToggleGroup v-model="report" multiple>
|
||||
<ShadcnRow gutter="8">
|
||||
<ShadcnCol v-for="item of data" span="4">
|
||||
<ShadcnToggle :key="item.id" class="px-1 py-1" :value="item.id">
|
||||
<ShadcnToggle :key="item.code" class="px-1 py-1" :value="item.code">
|
||||
<ShadcnCard :title="item.name">
|
||||
<template #extra>
|
||||
<ShadcnTooltip v-if="item.description" :content="item.description">
|
||||
@ -25,7 +25,7 @@
|
||||
:configuration="JSON.parse(item.configure as string)"
|
||||
:type="item.type"
|
||||
:query="item.type === 'DATASET' ? JSON.parse(item.query as string) : item.query"
|
||||
:original="item?.source?.id"/>
|
||||
:original="item?.source?.code"/>
|
||||
</ShadcnCard>
|
||||
</ShadcnToggle>
|
||||
</ShadcnCol>
|
||||
@ -71,7 +71,6 @@ import ReportService from '@/services/report.ts'
|
||||
import { FilterModel } from '@/model/filter.ts'
|
||||
import { ReportModel } from '@/model/report.ts'
|
||||
import VisualView from '@/views/components/visual/VisualView.vue'
|
||||
import { toNumber } from 'lodash'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ChartContainer',
|
||||
@ -158,7 +157,7 @@ export default defineComponent({
|
||||
onSubmit()
|
||||
{
|
||||
const nodes = this.data.filter(item =>
|
||||
this.report.some((reportId: number) => toNumber(item.id) === toNumber(reportId))
|
||||
this.report.some((reportId: string) => item.code === reportId)
|
||||
)
|
||||
this.$emit('change', nodes)
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
||||
:configuration="JSON.parse(item.node.configure)"
|
||||
:type="item.original?.type"
|
||||
:query="item.original.type === 'DATASET' ? JSON.parse(item.original.query as string) : item.original.query"
|
||||
:original="item?.original?.source?.id"/>
|
||||
:original="item?.original?.source?.code"/>
|
||||
|
||||
<VisualView v-else
|
||||
:width="calculateWidth(item)"
|
||||
@ -219,7 +219,7 @@ export default defineComponent({
|
||||
i: 'new-' + Date.now(),
|
||||
title: node.name,
|
||||
node: {
|
||||
id: node.id,
|
||||
id: node.code,
|
||||
configure: node.configure,
|
||||
code: node.dataset?.code,
|
||||
query: node?.query
|
||||
@ -233,9 +233,10 @@ export default defineComponent({
|
||||
{
|
||||
if (this.formState) {
|
||||
this.formState.configure = JSON.stringify(this.layouts)
|
||||
this.layouts.forEach((item: { node: { id: any; }; }) => {
|
||||
this.formState?.reports?.push({ id: item.node.id })
|
||||
this.layouts.forEach((item: { original: { code: any; }; }) => {
|
||||
this.formState?.reports?.push({ code: item.original.code })
|
||||
})
|
||||
this.formState.version = '1.0'
|
||||
this.loading = true
|
||||
DashboardService.saveOrUpdate(this.formState)
|
||||
.then(response => {
|
||||
|
@ -0,0 +1,6 @@
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
</script>
|
@ -37,7 +37,7 @@
|
||||
:configuration="JSON.parse(item.node.configure)"
|
||||
:type="item.original?.type"
|
||||
:query="item.original.type === 'DATASET' ? JSON.parse(item.original.query as string) : item.original.query"
|
||||
:original="item?.original?.source?.id"/>
|
||||
:original="item?.original?.source?.code"/>
|
||||
|
||||
<VisualView v-else
|
||||
:width="calculateWidth(item)"
|
||||
|
84
docs/docs/api/dashboard/save.md
Normal file
84
docs/docs/api/dashboard/save.md
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
title: 保存仪表盘
|
||||
---
|
||||
|
||||
请求地址:`/api/v1/dashboard`
|
||||
|
||||
请求方式:`POST`
|
||||
|
||||
## Body
|
||||
|
||||
=== "示例"
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "M 1.0",
|
||||
"configure": "[...]",
|
||||
"version": "1.0",
|
||||
"description": "随意修改的仪表盘",
|
||||
"reports": [
|
||||
{
|
||||
"code": "24f38722eb6d432a9ee574e675bd0509"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== "参数"
|
||||
|
||||
|参数|类型| 描述 |
|
||||
|---|---|---------------------|
|
||||
|`name`|String| 仪表盘名称 |
|
||||
|`configure`|String| 仪表盘配置 |
|
||||
|`version`|String| 仪表盘版本 |
|
||||
|`description`|String| 仪表盘描述 |
|
||||
|`reports`|Array| 报表列表,结构 `[{"code": "24f38722eb6d432a9ee574e675bd0509"}]` |
|
||||
|
||||
## Response
|
||||
|
||||
=== "示例"
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "M 1.0",
|
||||
"code": "9e78e83f55864da7a4802e0989ae1f33",
|
||||
"active": true,
|
||||
"createTime": "2024-11-25 13:48:27",
|
||||
"updateTime": "2024-11-25 13:48:27",
|
||||
"configure": "[...]",
|
||||
"description": "随意修改的仪表盘",
|
||||
"avatar": {},
|
||||
"version": "1.0",
|
||||
"reports": [
|
||||
{
|
||||
"name": null,
|
||||
"code": "24f38722eb6d432a9ee574e675bd0509",
|
||||
"active": true,
|
||||
"createTime": null,
|
||||
"updateTime": null,
|
||||
"configure": null,
|
||||
"realtime": false,
|
||||
"type": null,
|
||||
"query": null,
|
||||
"description": null,
|
||||
"source": null,
|
||||
"dataset": null
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
=== "参数"
|
||||
|
||||
|参数|类型| 描述 |
|
||||
|---|---|---------------------|
|
||||
|`name`|String| 仪表盘名称 |
|
||||
|`code`|String| 仪表盘编码 |
|
||||
|`active`|Boolean| 是否激活 |
|
||||
|`createTime`|String| 创建时间 |
|
||||
|`updateTime`|String| 更新时间 |
|
||||
|`configure`|String| 仪表盘配置 |
|
||||
|`description`|String| 仪表盘描述 |
|
||||
|`avatar`|Object| 仪表盘头像 |
|
||||
|`version`|String| 仪表盘版本 |
|
||||
|`reports`|Array| 报表列表详见[报表](../report/list.md) |
|
@ -295,5 +295,6 @@ nav:
|
||||
- api/plugin/uninstall.md
|
||||
- ApiDashboard:
|
||||
- api/dashboard/list.md
|
||||
- api/dashboard/save.md
|
||||
- useCases.md
|
||||
- partners.md
|
||||
|
Loading…
Reference in New Issue
Block a user