1
0

feat(web): 修复逻辑删除,增加可选查询

This commit is contained in:
2024-12-05 17:58:38 +08:00
parent 6a68085870
commit 28d70e5f9a
17 changed files with 183 additions and 165 deletions

View File

@@ -1,5 +1,5 @@
const information = { export const information = {
debug: true, debug: false,
// baseUrl: '', // baseUrl: '',
baseUrl: 'http://127.0.0.1:20080', baseUrl: 'http://127.0.0.1:20080',
title: '可信供给中心', title: '可信供给中心',
@@ -17,6 +17,7 @@ export function useAmis(amisObject) {
struct, struct,
{ {
data: { data: {
debug: information.debug,
base: information.baseUrl, base: information.baseUrl,
}, },
}, },

View File

@@ -6,6 +6,7 @@ import {
formInputClearable, formInputClearable,
formInputMultiFileStatic, formInputMultiFileStatic,
horizontalFormOptions, horizontalFormOptions,
information,
inputFileFormItemCommonOptions, inputFileFormItemCommonOptions,
size100MB size100MB
} from "../constants.js"; } from "../constants.js";
@@ -15,9 +16,9 @@ import {resourceDetailDialog} from "../resource/dialog-resource.js";
const CONFIRMATION_TYPE = 'confirmation' const CONFIRMATION_TYPE = 'confirmation'
const AUTHENTICATION_TYPE = 'authentication' const AUTHENTICATION_TYPE = 'authentication'
function detailForm(showCreatedUserAndModifiedUser = false) { function detailForm(pickerApi = apiGet('${base}/data_resource/list'), showCreatedUserAndModifiedUser = false) {
return { return {
debug: true, debug: information.debug,
id: 'permission_form', id: 'permission_form',
type: 'form', type: 'form',
...horizontalFormOptions(), ...horizontalFormOptions(),
@@ -38,7 +39,7 @@ function detailForm(showCreatedUserAndModifiedUser = false) {
size: 'md', size: 'md',
valueField: 'id', valueField: 'id',
labelField: 'name', labelField: 'name',
source: apiGet('${base}/data_resource/list'), source: pickerApi,
pickerSchema: { pickerSchema: {
...resourceList(), ...resourceList(),
}, },
@@ -59,6 +60,7 @@ function detailForm(showCreatedUserAndModifiedUser = false) {
}, },
{ {
type: 'textarea', type: 'textarea',
placeholder: '请输入确权说明',
label: '确权说明', label: '确权说明',
name: 'description', name: 'description',
...formInputClearable, ...formInputClearable,
@@ -123,7 +125,7 @@ function permissionAddDialog(type) {
} }
], ],
body: { body: {
...detailForm(), ...detailForm(generateApi(type)),
api: apiPost(`\${base}/${type}/save`), api: apiPost(`\${base}/${type}/save`),
data: data, data: data,
} }
@@ -149,7 +151,7 @@ function permissionDetailDialog(type, field = 'id', actions = []) {
size: 'md', size: 'md',
actions: actions, actions: actions,
body: { body: {
...detailForm(true), ...detailForm(generateApi(type), true),
initApi: apiGet(`\${base}/${type}/detail/\${${field}}`), initApi: apiGet(`\${base}/${type}/detail/\${${field}}`),
static: true, static: true,
data: data, data: data,
@@ -186,7 +188,7 @@ function permissionEditeDialog(type, field = 'id') {
} }
], ],
body: { body: {
...detailForm(), ...detailForm(generateApi(type)),
api: apiPost(`\${base}/${type}/save`), api: apiPost(`\${base}/${type}/save`),
initApi: apiGet(`\${base}/${type}/detail/\${${field}}`), initApi: apiGet(`\${base}/${type}/detail/\${${field}}`),
data: data, data: data,
@@ -194,3 +196,12 @@ function permissionEditeDialog(type, field = 'id') {
} }
} }
} }
function generateApi(type) {
switch (type) {
case AUTHENTICATION_TYPE:
return apiGet('${base}/data_resource/list_no_authentication')
case CONFIRMATION_TYPE:
return apiGet('${base}/data_resource/list_no_confirmation')
}
}

View File

@@ -1,7 +1,6 @@
package com.eshore.gringotts.web.domain.base.controller; package com.eshore.gringotts.web.domain.base.controller;
import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery;
/** /**
* @author lanyuanxiaoyao * @author lanyuanxiaoyao
@@ -9,5 +8,4 @@ import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery;
*/ */
public interface DetailController<DETAIL_ITEM> { public interface DetailController<DETAIL_ITEM> {
AmisResponse<DETAIL_ITEM> detail(Long id) throws Exception; AmisResponse<DETAIL_ITEM> detail(Long id) throws Exception;
AmisResponse<DETAIL_ITEM> detail(DetailQuery query) throws Exception;
} }

View File

@@ -1,7 +1,7 @@
package com.eshore.gringotts.web.domain.base.controller; package com.eshore.gringotts.web.domain.base.controller;
import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ImmutableList;
/** /**
@@ -10,5 +10,6 @@ import org.eclipse.collections.api.list.ImmutableList;
*/ */
public interface ListController<LIST_ITEM> { public interface ListController<LIST_ITEM> {
AmisResponse<ImmutableList<LIST_ITEM>> list() throws Exception; AmisResponse<ImmutableList<LIST_ITEM>> list() throws Exception;
AmisResponse<ImmutableList<LIST_ITEM>> list(ListQuery query) throws Exception;
AmisResponse<ImmutableList<LIST_ITEM>> list(Query query) throws Exception;
} }

View File

@@ -1,10 +1,12 @@
package com.eshore.gringotts.web.domain.base.controller; package com.eshore.gringotts.web.domain.base.controller;
import cn.hutool.core.util.ObjectUtil;
import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport; import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ImmutableList;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
@@ -15,11 +17,11 @@ import org.springframework.web.bind.annotation.RequestBody;
* @author lanyuanxiaoyao * @author lanyuanxiaoyao
* @date 2024-11-26 * @date 2024-11-26
*/ */
@Slf4j
public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> implements SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> { public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> implements SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> {
protected static final String SAVE = "/save"; protected static final String SAVE = "/save";
protected static final String LIST = "/list"; protected static final String LIST = "/list";
protected static final String DETAIL_ID = "/detail/{id}"; protected static final String DETAIL = "/detail/{id}";
protected static final String DETAIL = "/detail";
protected static final String REMOVE = "/remove/{id}"; protected static final String REMOVE = "/remove/{id}";
private final SimpleServiceSupport<ENTITY> service; private final SimpleServiceSupport<ENTITY> service;
@@ -48,22 +50,25 @@ public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity, SAVE_
@PostMapping(LIST) @PostMapping(LIST)
@Override @Override
public AmisResponse<ImmutableList<LIST_ITEM>> list(@RequestBody ListQuery query) throws Exception { public AmisResponse<ImmutableList<LIST_ITEM>> list(@RequestBody Query query) throws Exception {
return null; if (ObjectUtil.isNull(query)) {
return AmisResponse.responseSuccess(Lists.immutable.empty());
}
return AmisResponse.responseSuccess(service.list(query).collect(entity -> {
try {
return toListItem(entity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
} }
@GetMapping(DETAIL_ID) @GetMapping(DETAIL)
@Override @Override
public AmisResponse<DETAIL_ITEM> detail(@PathVariable Long id) throws Exception { public AmisResponse<DETAIL_ITEM> detail(@PathVariable Long id) throws Exception {
return AmisResponse.responseSuccess(toDetailItem(service.detail(id))); return AmisResponse.responseSuccess(toDetailItem(service.detail(id)));
} }
@PostMapping(DETAIL)
@Override
public AmisResponse<DETAIL_ITEM> detail(@RequestBody DetailQuery query) throws Exception {
return null;
}
@GetMapping(REMOVE) @GetMapping(REMOVE)
@Override @Override
public AmisResponse<Object> remove(@PathVariable Long id) { public AmisResponse<Object> remove(@PathVariable Long id) {

View File

@@ -1,53 +0,0 @@
package com.eshore.gringotts.web.domain.base.controller.query;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.eclipse.collections.api.list.ImmutableList;
/**
* @author lanyuanxiaoyao
* @date 2024-12-03
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class ListQuery extends DetailQuery {
private ImmutableList<Sortable> sort;
private Pageable page;
public ListQuery(Queryable query) {
super(query);
}
public ListQuery(Queryable query, ImmutableList<Sortable> sort, Pageable page) {
super(query);
this.sort = sort;
this.page = page;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Sortable {
private String column;
private Direction direction;
public enum Direction {
ASC,
DESC,
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class Pageable {
private Integer page = 1;
private Integer size = 10;
}
}

View File

@@ -1,9 +1,6 @@
package com.eshore.gringotts.web.domain.base.controller.query; package com.eshore.gringotts.web.domain.base.controller.query;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ImmutableList;
import org.eclipse.collections.api.map.ImmutableMap; import org.eclipse.collections.api.map.ImmutableMap;
@@ -14,15 +11,12 @@ import org.eclipse.collections.api.map.ImmutableMap;
* @date 2024-12-03 * @date 2024-12-03
*/ */
@Data @Data
@NoArgsConstructor public class Query {
@AllArgsConstructor
public class DetailQuery {
private Queryable query; private Queryable query;
private ImmutableList<Sortable> sort;
private Pageable page;
@Data @Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class Queryable { public static class Queryable {
private ImmutableList<String> nullEqual; private ImmutableList<String> nullEqual;
private ImmutableList<String> notNullEqual; private ImmutableList<String> notNullEqual;
@@ -42,11 +36,26 @@ public class DetailQuery {
private ImmutableMap<String, Between> notBetween; private ImmutableMap<String, Between> notBetween;
@Data @Data
@NoArgsConstructor
@AllArgsConstructor
public static class Between { public static class Between {
private String start; private String start;
private String end; private String end;
} }
} }
@Data
public static class Sortable {
private String column;
private Direction direction;
public enum Direction {
ASC,
DESC,
}
}
@Data
public static class Pageable {
private Integer page;
private Integer size;
}
} }

View File

@@ -1,7 +1,6 @@
package com.eshore.gringotts.web.domain.base.service; package com.eshore.gringotts.web.domain.base.service;
import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import java.util.Optional; import java.util.Optional;
import org.eclipse.collections.api.list.ImmutableList; import org.eclipse.collections.api.list.ImmutableList;
@@ -18,23 +17,15 @@ public interface SimpleService<ENTITY extends SimpleEntity> {
ImmutableList<ENTITY> list(ImmutableSet<Long> ids) throws Exception; ImmutableList<ENTITY> list(ImmutableSet<Long> ids) throws Exception;
ImmutableList<ENTITY> list(ListQuery query) throws Exception; ImmutableList<ENTITY> list(Query query) throws Exception;
Optional<ENTITY> detailOptional(Long id) throws Exception; Optional<ENTITY> detailOptional(Long id) throws Exception;
Optional<ENTITY> detailOptional(DetailQuery query) throws Exception;
ENTITY detail(Long id) throws Exception; ENTITY detail(Long id) throws Exception;
ENTITY detail(DetailQuery query) throws Exception;
ENTITY detailOrThrow(Long id) throws Exception; ENTITY detailOrThrow(Long id) throws Exception;
ENTITY detailOrThrow(DetailQuery query) throws Exception;
ENTITY detailOrNull(Long id) throws Exception; ENTITY detailOrNull(Long id) throws Exception;
ENTITY detailOrNull(DetailQuery query) throws Exception;
void remove(Long id) throws Exception; void remove(Long id) throws Exception;
} }

View File

@@ -2,10 +2,10 @@ package com.eshore.gringotts.web.domain.base.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.user.entity.User; import com.eshore.gringotts.web.domain.user.entity.User;
@@ -13,6 +13,7 @@ import com.eshore.gringotts.web.domain.user.service.UserService;
import java.util.Optional; import java.util.Optional;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.transaction.Transactional; import javax.transaction.Transactional;
@@ -51,11 +52,6 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
); );
entity = targetEntity; entity = targetEntity;
} }
User user = userService.currentLoginUser();
if (ObjectUtil.isNull(entity.getCreatedUser())) {
entity.setCreatedUser(user);
}
entity.setModifiedUser(user);
entity = repository.save(entity); entity = repository.save(entity);
return entity.getId(); return entity.getId();
} }
@@ -76,59 +72,83 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
)); ));
} }
private <Y> Path<Y> column(Root<ENTITY> root, String column) {
String[] columns = StrUtil.splitToArray(column, "/");
Path<Y> path = root.get(columns[0]);
for (int i = 1; i < columns.length; i++) {
path = path.get(columns[i]);
}
return path;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private <Y> Object value(Path<Y> column, Object value) {
Class<?> javaType = column.getJavaType();
if (EnumUtil.isEnum(javaType)) {
return EnumUtil.fromString((Class<Enum>) javaType, (String) value);
}
return value;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ImmutableList<Predicate> queryPredicates(DetailQuery.Queryable queryable, Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) { private ImmutableList<Predicate> queryPredicates(Query.Queryable queryable, Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
MutableList<Predicate> predicates = Lists.mutable.empty(); MutableList<Predicate> predicates = Lists.mutable.empty();
if (ObjectUtil.isEmpty(queryable)) { if (ObjectUtil.isEmpty(queryable)) {
return predicates.toImmutable(); return predicates.toImmutable();
} }
if (ObjectUtil.isNotEmpty(queryable.getNullEqual())) { if (ObjectUtil.isNotEmpty(queryable.getNullEqual())) {
queryable.getNullEqual().forEach(column -> predicates.add(builder.isNull(root.get(column)))); queryable.getNullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
} }
if (ObjectUtil.isNotEmpty(queryable.getNotNullEqual())) { if (ObjectUtil.isNotEmpty(queryable.getNotNullEqual())) {
queryable.getNotNullEqual().forEach(column -> predicates.add(builder.isNull(root.get(column)))); queryable.getNotNullEqual().forEach(column -> predicates.add(builder.isNull(column(root, column))));
} }
if (ObjectUtil.isNotEmpty(queryable.getEmpty())) { if (ObjectUtil.isNotEmpty(queryable.getEmpty())) {
queryable.getEmpty().forEach(column -> predicates.add(builder.isEmpty(root.get(column)))); queryable.getEmpty().forEach(column -> predicates.add(builder.isEmpty(column(root, column))));
} }
if (ObjectUtil.isNotEmpty(queryable.getNotEmpty())) { if (ObjectUtil.isNotEmpty(queryable.getNotEmpty())) {
queryable.getNotEmpty().forEach(column -> predicates.add(builder.isNotEmpty(root.get(column)))); queryable.getNotEmpty().forEach(column -> predicates.add(builder.isNotEmpty(column(root, column))));
} }
if (ObjectUtil.isNotEmpty(queryable.getEqual())) { if (ObjectUtil.isNotEmpty(queryable.getEqual())) {
queryable.getEqual().forEachKeyValue((column, value) -> predicates.add(builder.equal(root.get(column), value))); queryable.getEqual().forEachKeyValue((column, value) -> {
Path<Object> path = column(root, column);
predicates.add(builder.equal(path, value(path, value)));
});
} }
if (ObjectUtil.isNotEmpty(queryable.getNotEqual())) { if (ObjectUtil.isNotEmpty(queryable.getNotEqual())) {
queryable.getEqual().forEachKeyValue((column, value) -> predicates.add(builder.notEqual(root.get(column), value))); queryable.getEqual().forEachKeyValue((column, value) -> {
Path<Object> path = column(root, column);
predicates.add(builder.notEqual(path, value(path, value)));
});
} }
if (ObjectUtil.isNotEmpty(queryable.getLike())) { if (ObjectUtil.isNotEmpty(queryable.getLike())) {
queryable.getLike().forEachKeyValue((column, value) -> predicates.add(builder.like(root.get(column), value))); queryable.getLike().forEachKeyValue((column, value) -> predicates.add(builder.like(column(root, column), value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getNotLike())) { if (ObjectUtil.isNotEmpty(queryable.getNotLike())) {
queryable.getNotLike().forEachKeyValue((column, value) -> predicates.add(builder.notLike(root.get(column), value))); queryable.getNotLike().forEachKeyValue((column, value) -> predicates.add(builder.notLike(column(root, column), value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getGreat())) { if (ObjectUtil.isNotEmpty(queryable.getGreat())) {
queryable.getGreat().forEachKeyValue((column, value) -> predicates.add(builder.greaterThan(root.get(column), (Comparable<Object>) value))); queryable.getGreat().forEachKeyValue((column, value) -> predicates.add(builder.greaterThan(column(root, column), (Comparable<Object>) value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getLess())) { if (ObjectUtil.isNotEmpty(queryable.getLess())) {
queryable.getLess().forEachKeyValue((column, value) -> predicates.add(builder.lessThan(root.get(column), (Comparable<Object>) value))); queryable.getLess().forEachKeyValue((column, value) -> predicates.add(builder.lessThan(column(root, column), (Comparable<Object>) value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getGreatEqual())) { if (ObjectUtil.isNotEmpty(queryable.getGreatEqual())) {
queryable.getGreatEqual().forEachKeyValue((column, value) -> predicates.add(builder.greaterThanOrEqualTo(root.get(column), (Comparable<Object>) value))); queryable.getGreatEqual().forEachKeyValue((column, value) -> predicates.add(builder.greaterThanOrEqualTo(column(root, column), (Comparable<Object>) value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getLessEqual())) { if (ObjectUtil.isNotEmpty(queryable.getLessEqual())) {
queryable.getLessEqual().forEachKeyValue((column, value) -> predicates.add(builder.lessThanOrEqualTo(root.get(column), (Comparable<Object>) value))); queryable.getLessEqual().forEachKeyValue((column, value) -> predicates.add(builder.lessThanOrEqualTo(column(root, column), (Comparable<Object>) value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getIn())) { if (ObjectUtil.isNotEmpty(queryable.getIn())) {
queryable.getIn().forEachKeyValue((column, value) -> predicates.add(builder.in(root.get(column)).value(value))); queryable.getIn().forEachKeyValue((column, value) -> predicates.add(builder.in(column(root, column)).value(value)));
} }
if (ObjectUtil.isNotEmpty(queryable.getNotIn())) { if (ObjectUtil.isNotEmpty(queryable.getNotIn())) {
queryable.getNotIn().forEachKeyValue((column, value) -> predicates.add(builder.in(root.get(column)).value(value).not())); queryable.getNotIn().forEachKeyValue((column, value) -> predicates.add(builder.in(column(root, column)).value(value).not()));
} }
if (ObjectUtil.isNotEmpty(queryable.getBetween())) { if (ObjectUtil.isNotEmpty(queryable.getBetween())) {
queryable.getBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(root.get(column), value.getStart(), value.getEnd()))); queryable.getBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(column(root, column), value.getStart(), value.getEnd())));
} }
if (ObjectUtil.isNotEmpty(queryable.getNotBetween())) { if (ObjectUtil.isNotEmpty(queryable.getNotBetween())) {
queryable.getNotBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(root.get(column), value.getStart(), value.getEnd()))); queryable.getNotBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(column(root, column), value.getStart(), value.getEnd())));
} }
return predicates.toImmutable(); return predicates.toImmutable();
} }
@@ -143,7 +163,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
} }
@Override @Override
public ImmutableList<ENTITY> list(ListQuery listQuery) throws Exception { public ImmutableList<ENTITY> list(Query listQuery) throws Exception {
return Lists.immutable.ofAll(repository.findAll( return Lists.immutable.ofAll(repository.findAll(
(root, query, builder) -> { (root, query, builder) -> {
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicates(root, query, builder)); MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicates(root, query, builder));
@@ -168,47 +188,21 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
); );
} }
@Override
public Optional<ENTITY> detailOptional(DetailQuery detailQuery) throws Exception {
return repository.findOne(
(root, query, builder) -> {
MutableList<Predicate> predicates = Lists.mutable.ofAll(listPredicates(root, query, builder));
predicates.addAllIterable(queryPredicates(detailQuery.getQuery(), root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}
);
}
@Override @Override
public ENTITY detail(Long id) { public ENTITY detail(Long id) {
return detailOrNull(id); return detailOrNull(id);
} }
@Override
public ENTITY detail(DetailQuery query) throws Exception {
return detailOrNull(query);
}
@Override @Override
public ENTITY detailOrThrow(Long id) { public ENTITY detailOrThrow(Long id) {
return detailOptional(id).orElseThrow(() -> new IdNotFoundException(id)); return detailOptional(id).orElseThrow(() -> new IdNotFoundException(id));
} }
@Override
public ENTITY detailOrThrow(DetailQuery query) throws Exception {
return detailOptional(query).orElseThrow(IdNotFoundException::new);
}
@Override @Override
public ENTITY detailOrNull(Long id) { public ENTITY detailOrNull(Long id) {
return detailOptional(id).orElse(null); return detailOptional(id).orElse(null);
} }
@Override
public ENTITY detailOrNull(DetailQuery query) throws Exception {
return detailOptional(query).orElse(null);
}
@Transactional(rollbackOn = Throwable.class) @Transactional(rollbackOn = Throwable.class)
@Override @Override
public void remove(Long id) { public void remove(Long id) {

View File

@@ -2,7 +2,7 @@ package com.eshore.gringotts.web.domain.check.controller;
import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.ListController; import com.eshore.gringotts.web.domain.base.controller.ListController;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.check.entity.CheckOrder; import com.eshore.gringotts.web.domain.check.entity.CheckOrder;
import com.eshore.gringotts.web.domain.check.service.CheckOrderService; import com.eshore.gringotts.web.domain.check.service.CheckOrderService;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
@@ -17,6 +17,8 @@ import org.eclipse.collections.api.map.ImmutableMap;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -44,8 +46,9 @@ public class CheckOrderController implements ListController<CheckOrderController
return AmisResponse.responseSuccess(checkOrderService.list().collect(this::toListItem)); return AmisResponse.responseSuccess(checkOrderService.list().collect(this::toListItem));
} }
@PostMapping("/list")
@Override @Override
public AmisResponse<ImmutableList<ListItem>> list(ListQuery query) throws Exception { public AmisResponse<ImmutableList<ListItem>> list(@RequestBody Query query) throws Exception {
return AmisResponse.responseSuccess(checkOrderService.list().collect(this::toListItem)); return AmisResponse.responseSuccess(checkOrderService.list().collect(this::toListItem));
} }

View File

@@ -55,11 +55,9 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
public class Confirmation extends CheckingNeededEntity { public class Confirmation extends CheckingNeededEntity {
@OneToOne(fetch = FetchType.EAGER) @OneToOne(fetch = FetchType.EAGER)
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private DataResource target; private DataResource target;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinTable(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT), inverseForeignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private Set<DataFile> evidences; private Set<DataFile> evidences;
} }

View File

@@ -2,6 +2,7 @@ package com.eshore.gringotts.web.domain.resource.controller;
import cn.hutool.core.util.EnumUtil; import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.eshore.gringotts.web.configuration.amis.AmisResponse;
import com.eshore.gringotts.web.domain.base.controller.SimpleControllerSupport; import com.eshore.gringotts.web.domain.base.controller.SimpleControllerSupport;
import com.eshore.gringotts.web.domain.base.entity.FileInfo; import com.eshore.gringotts.web.domain.base.entity.FileInfo;
import com.eshore.gringotts.web.domain.base.entity.SimpleListItem; import com.eshore.gringotts.web.domain.base.entity.SimpleListItem;
@@ -30,7 +31,9 @@ import java.util.Map;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.list.ImmutableList;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -45,14 +48,38 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/data_resource") @RequestMapping("/data_resource")
public class DataResourceController extends SimpleControllerSupport<DataResource, DataResourceController.SaveItem, DataResourceController.ListItem, DataResourceController.DetailItem> { public class DataResourceController extends SimpleControllerSupport<DataResource, DataResourceController.SaveItem, DataResourceController.ListItem, DataResourceController.DetailItem> {
private final ObjectMapper mapper; private final ObjectMapper mapper;
private final DataResourceService dataResourceService;
private final DataFileService dataFileService; private final DataFileService dataFileService;
public DataResourceController(DataResourceService dataResourceService, DataFileService dataFileService, Jackson2ObjectMapperBuilder builder) { public DataResourceController(DataResourceService dataResourceService, DataFileService dataFileService, Jackson2ObjectMapperBuilder builder) {
super(dataResourceService); super(dataResourceService);
this.dataResourceService = dataResourceService;
this.dataFileService = dataFileService; this.dataFileService = dataFileService;
this.mapper = builder.build(); this.mapper = builder.build();
} }
@GetMapping(LIST + "_no_confirmation")
public AmisResponse<ImmutableList<ListItem>> listNoConfirmation() {
return AmisResponse.responseSuccess(dataResourceService.listNoConfirmation().collect(entity -> {
try {
return toListItem(entity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
@GetMapping(LIST + "_no_authentication")
public AmisResponse<ImmutableList<ListItem>> listNoAuthentication() {
return AmisResponse.responseSuccess(dataResourceService.listNoAuthentication().collect(entity -> {
try {
return toListItem(entity);
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
@Override @Override
protected DataResource fromSaveItem(SaveItem item) throws JsonProcessingException { protected DataResource fromSaveItem(SaveItem item) throws JsonProcessingException {
ResourceType type = generateResourceType(item); ResourceType type = generateResourceType(item);

View File

@@ -59,24 +59,19 @@ public class DataResource extends LogicDeleteEntity {
@OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY) @OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private ResourceType type; private ResourceType type;
@OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY) @OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private ResourceFormat format; private ResourceFormat format;
@OneToOne(fetch = FetchType.LAZY) @OneToOne(fetch = FetchType.LAZY)
@JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JoinColumn(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private DataFile example; private DataFile example;
@OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "target") @OneToOne(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "target")
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private Confirmation confirmation; private Confirmation confirmation;
@OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "target") @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "target")
@ToString.Exclude @ToString.Exclude
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private Set<Authentication> authentications; private Set<Authentication> authentications;
} }

View File

@@ -12,10 +12,17 @@ import org.springframework.stereotype.Repository;
@SuppressWarnings("NullableProblems") @SuppressWarnings("NullableProblems")
@Repository @Repository
public interface DataResourceRepository extends SimpleRepository<DataResource, Long> { public interface DataResourceRepository extends SimpleRepository<DataResource, Long> {
@Override
@EntityGraph(value = "data_resource.list", type = EntityGraph.EntityGraphType.FETCH)
List<DataResource> findAll(Specification<DataResource> specification);
@Override @Override
@EntityGraph(value = "data_resource.list", type = EntityGraph.EntityGraphType.FETCH) @EntityGraph(value = "data_resource.list", type = EntityGraph.EntityGraphType.FETCH)
List<DataResource> findAll(Specification<DataResource> specification, Sort sort); List<DataResource> findAll(Specification<DataResource> specification, Sort sort);
@EntityGraph(value = "data_resource.list", type = EntityGraph.EntityGraphType.FETCH)
List<DataResource> findAllByConfirmationIsNull();
@Override @Override
@EntityGraph(value = "data_resource.detail", type = EntityGraph.EntityGraphType.FETCH) @EntityGraph(value = "data_resource.detail", type = EntityGraph.EntityGraphType.FETCH)
Optional<DataResource> findOne(Specification<DataResource> specification); Optional<DataResource> findOne(Specification<DataResource> specification);

View File

@@ -1,14 +1,23 @@
package com.eshore.gringotts.web.domain.resource.service; package com.eshore.gringotts.web.domain.resource.service;
import com.eshore.gringotts.web.domain.authentication.entity.Authentication;
import com.eshore.gringotts.web.domain.base.entity.CheckingNeededEntity;
import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport; import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport;
import com.eshore.gringotts.web.domain.confirmation.entity.Confirmation;
import com.eshore.gringotts.web.domain.resource.entity.DataResource; import com.eshore.gringotts.web.domain.resource.entity.DataResource;
import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat; import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat;
import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType; import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType;
import com.eshore.gringotts.web.domain.resource.repository.DataResourceRepository; import com.eshore.gringotts.web.domain.resource.repository.DataResourceRepository;
import com.eshore.gringotts.web.domain.resource.repository.ResourceFormatRepository; import com.eshore.gringotts.web.domain.resource.repository.ResourceFormatRepository;
import com.eshore.gringotts.web.domain.resource.repository.ResourceTypeRepository; import com.eshore.gringotts.web.domain.resource.repository.ResourceTypeRepository;
import com.eshore.gringotts.web.domain.user.entity.User;
import com.eshore.gringotts.web.domain.user.service.UserService; import com.eshore.gringotts.web.domain.user.service.UserService;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.SetJoin;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
@@ -19,13 +28,34 @@ import org.springframework.stereotype.Service;
@Slf4j @Slf4j
@Service @Service
public class DataResourceService extends SimpleServiceSupport<DataResource> { public class DataResourceService extends SimpleServiceSupport<DataResource> {
private final DataResourceRepository dataResourceRepository;
private final ResourceTypeRepository resourceTypeRepository; private final ResourceTypeRepository resourceTypeRepository;
private final ResourceFormatRepository resourceFormatRepository; private final ResourceFormatRepository resourceFormatRepository;
private final UserService userService;
public DataResourceService(DataResourceRepository repository, ResourceTypeRepository resourceTypeRepository, ResourceFormatRepository resourceFormatRepository, UserService userService) { public DataResourceService(DataResourceRepository repository, ResourceTypeRepository resourceTypeRepository, ResourceFormatRepository resourceFormatRepository, UserService userService) {
super(repository, userService); super(repository, userService);
this.dataResourceRepository = repository;
this.resourceTypeRepository = resourceTypeRepository; this.resourceTypeRepository = resourceTypeRepository;
this.resourceFormatRepository = resourceFormatRepository; this.resourceFormatRepository = resourceFormatRepository;
this.userService = userService;
}
public ImmutableList<DataResource> listNoConfirmation() {
return Lists.immutable.ofAll(dataResourceRepository.findAllByConfirmationIsNull());
}
public ImmutableList<DataResource> listNoAuthentication() {
User user = userService.currentLoginUser();
return Lists.immutable.ofAll(dataResourceRepository.findAll(
(root, query, builder) -> {
SetJoin<DataResource, Authentication> authenticationJoin = root.joinSet("authentications", JoinType.LEFT);
authenticationJoin.on(builder.notEqual(authenticationJoin.get("createdUser"), user));
Join<DataResource, Confirmation> confirmationJoin = root.join("confirmation", JoinType.LEFT);
confirmationJoin.on(builder.equal(confirmationJoin.get("state"), CheckingNeededEntity.State.NORMAL));
return null;
}
));
} }
@Override @Override

View File

@@ -17,6 +17,8 @@ spring:
multipart: multipart:
max-file-size: 10MB max-file-size: 10MB
max-request-size: 20MB max-request-size: 20MB
jackson:
date-format: 'yyyy-MM-dd HH:mm:ss'
fenix: fenix:
print-banner: false print-banner: false
print-sql: false print-sql: false

View File

@@ -1,7 +1,6 @@
package com.eshore.gringotts.web; package com.eshore.gringotts.web;
import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; import com.eshore.gringotts.web.domain.base.controller.query.Query;
import com.eshore.gringotts.web.domain.base.controller.query.ListQuery;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.eclipsecollections.EclipseCollectionsModule; import com.fasterxml.jackson.datatype.eclipsecollections.EclipseCollectionsModule;
@@ -17,7 +16,7 @@ public class TestQueryParse {
mapper.registerModule(new EclipseCollectionsModule()); mapper.registerModule(new EclipseCollectionsModule());
mapper.registerModule(new JavaTimeModule()); mapper.registerModule(new JavaTimeModule());
// language=JSON // language=JSON
System.out.println(mapper.readValue("{}", DetailQuery.class)); System.out.println(mapper.readValue("{}", Query.class));
// language=JSON // language=JSON
System.out.println(mapper.readValue("{\n" + System.out.println(mapper.readValue("{\n" +
" \"query\": {\n" + " \"query\": {\n" +
@@ -25,7 +24,7 @@ public class TestQueryParse {
" \"name\": \"lanyuanxiaoyao\"\n" + " \"name\": \"lanyuanxiaoyao\"\n" +
" }\n" + " }\n" +
" }\n" + " }\n" +
"}", DetailQuery.class)); "}", Query.class));
// language=JSON // language=JSON
System.out.println(mapper.readValue("{\n" + System.out.println(mapper.readValue("{\n" +
" \"query\": {\n" + " \"query\": {\n" +
@@ -64,6 +63,6 @@ public class TestQueryParse {
" \"size\": 10,\n" + " \"size\": 10,\n" +
" \"page\": 1\n" + " \"page\": 1\n" +
" }\n" + " }\n" +
"}", ListQuery.class)); "}", Query.class));
} }
} }