diff --git a/gringotts-frontend/components/constants.js b/gringotts-frontend/components/constants.js index 4383c21..9e60d52 100644 --- a/gringotts-frontend/components/constants.js +++ b/gringotts-frontend/components/constants.js @@ -98,6 +98,7 @@ export function inputFileFormItemCommonOptions(accept = '*', maxSize = size5MB) accept: accept, maxSize: maxSize, autoUpload: false, + drag: true, startChunkApi: apiPost('${base}/upload/start'), chunkApi: apiPost('${base}/upload/slice'), finishChunkApi: apiPost('${base}/upload/finish'), @@ -197,7 +198,7 @@ export function stringField(field, label, width = undefined, wrap = false) { if (width) { data['width'] = width } - if (wrap) { + if (!wrap) { data['className'] = 'nowrap' } return data @@ -247,10 +248,11 @@ export const userStateMapping = [ mappingItem('禁用', 'DISABLED', 'bg-danger'), ] -export const confirmationStateMapping = [ +export const permissionStateMapping = [ mappingItem('未确权', 'NONE'), mappingItem('草稿', 'DRAFT', 'bg-primary'), mappingItem('审查中', 'CHECKING', 'bg-warning'), + mappingItem('用户审查中', 'USER_CHECKING', 'bg-warning'), mappingItem('通过', 'NORMAL', 'bg-success'), mappingItem('驳回', 'REJECT', 'bg-danger'), ] diff --git a/gringotts-frontend/components/permission/dialog-permission.js b/gringotts-frontend/components/permission/dialog-permission.js index 53352e5..2dd762c 100644 --- a/gringotts-frontend/components/permission/dialog-permission.js +++ b/gringotts-frontend/components/permission/dialog-permission.js @@ -12,8 +12,12 @@ import { import {resourceList} from "../../pages/index/tab-data.js"; import {resourceDetailDialog} from "../resource/dialog-resource.js"; +const CONFIRMATION_TYPE = 'confirmation' +const AUTHENTICATION_TYPE = 'authentication' + function detailForm(showCreatedUserAndModifiedUser = false) { return { + debug: true, id: 'permission_form', type: 'form', ...horizontalFormOptions(), @@ -70,12 +74,38 @@ function detailForm(showCreatedUserAndModifiedUser = false) { joinValues: false, ...inputFileFormItemCommonOptions(undefined, size100MB), }, + { + visibleOn: `\${${AUTHENTICATION_TYPE}}`, + type: 'input-datetime-range', + name: 'activeTime', + extraName: 'expiredTime', + label: '授权时间', + required: true, + format: 'YYYY-MM-DD HH:mm:ss', + shortcuts: [ + '7dayslater', + '14dayslater', + '30dayslater', + '180dayslater', + '365dayslater', + ] + }, ...(showCreatedUserAndModifiedUser ? formCreatedUserAndModifiedUser() : []) ] } } -export function permissionAddDialog() { +export function confirmationAddDialog() { + return permissionAddDialog(CONFIRMATION_TYPE) +} + +export function authenticationAddDialog() { + return permissionAddDialog(AUTHENTICATION_TYPE) +} + +function permissionAddDialog(type) { + let data = {add: true} + data[type] = true return { actionType: 'dialog', dialog: { @@ -94,16 +124,24 @@ export function permissionAddDialog() { ], body: { ...detailForm(), - api: apiPost('${base}/confirmation/save'), - data: { - add: true, - }, + api: apiPost(`\${base}/${type}/save`), + data: data, } } } } -export function permissionDetailDialog(field = 'id', actions = []) { +export function confirmationDetailDialog(field = 'id', actions = []) { + return permissionDetailDialog(CONFIRMATION_TYPE, field, actions) +} + +export function authenticationDetailDialog(field = 'id', actions = []) { + return permissionDetailDialog(AUTHENTICATION_TYPE, field, actions) +} + +function permissionDetailDialog(type, field = 'id', actions = []) { + let data = {detail: true} + data[type] = true return { actionType: 'dialog', dialog: { @@ -112,17 +150,25 @@ export function permissionDetailDialog(field = 'id', actions = []) { actions: actions, body: { ...detailForm(true), - initApi: apiGet(`\${base}/confirmation/detail/\${${field}}`), + initApi: apiGet(`\${base}/${type}/detail/\${${field}}`), static: true, - data: { - detail: true, - }, + data: data, } } } } -export function permissionEditeDialog(field = 'id') { +export function confirmationEditeDialog(field = 'id') { + return permissionEditeDialog(CONFIRMATION_TYPE, field) +} + +export function authenticationEditeDialog(field = 'id') { + return permissionEditeDialog(CONFIRMATION_TYPE, field) +} + +function permissionEditeDialog(type, field = 'id') { + let data = {edit: true} + data[type] = true return { actionType: 'dialog', dialog: { @@ -141,11 +187,9 @@ export function permissionEditeDialog(field = 'id') { ], body: { ...detailForm(), - api: apiPost('${base}/confirmation/save'), - initApi: apiGet(`\${base}/confirmation/detail/\${${field}}`), - data: { - edit: true, - } + api: apiPost(`\${base}/${type}/save`), + initApi: apiGet(`\${base}/${type}/detail/\${${field}}`), + data: data, }, } } diff --git a/gringotts-frontend/pages/index/main.js b/gringotts-frontend/pages/index/main.js index 54c098f..08aaf4f 100644 --- a/gringotts-frontend/pages/index/main.js +++ b/gringotts-frontend/pages/index/main.js @@ -59,9 +59,9 @@ useAmis(information => { tabs: [ // tabOverview(), // tabMarket(), + tabPermissions(), tabCheck(), tabData(), - tabPermissions(), tabUser(), tabSettings(), ] diff --git a/gringotts-frontend/pages/index/tab-check.js b/gringotts-frontend/pages/index/tab-check.js index dc4e77d..d44549e 100644 --- a/gringotts-frontend/pages/index/tab-check.js +++ b/gringotts-frontend/pages/index/tab-check.js @@ -9,7 +9,7 @@ import { stringField, timeField, } from "../../components/constants.js"; -import {permissionDetailDialog} from "../../components/permission/dialog-permission.js"; +import {confirmationDetailDialog} from "../../components/permission/dialog-permission.js"; export function tabCheck() { return { @@ -40,7 +40,7 @@ export function tabCheck() { type: 'action', label: '处理', level: 'link', - ...permissionDetailDialog( + ...confirmationDetailDialog( 'parameters.confirmationId', [ { @@ -67,7 +67,7 @@ export function tabCheck() { type: 'action', label: '查看', level: 'link', - ...permissionDetailDialog('parameters.confirmationId'), + ...confirmationDetailDialog('parameters.confirmationId'), }, ]), ], diff --git a/gringotts-frontend/pages/index/tab-data.js b/gringotts-frontend/pages/index/tab-data.js index 06d0230..8cea4f1 100644 --- a/gringotts-frontend/pages/index/tab-data.js +++ b/gringotts-frontend/pages/index/tab-data.js @@ -8,10 +8,10 @@ import { arrayInCheck, arrayOutCheck, confirmationState, - confirmationStateMapping, crudCommonOptions, mappingField, operationField, + permissionStateMapping, timeField, userOnly } from "../../components/constants.js"; @@ -40,7 +40,7 @@ export function resourceList() { label: '描述', name: 'description', }, - mappingField('confirmationState', '确权状态', confirmationStateMapping), + mappingField('confirmationState', '确权状态', permissionStateMapping), timeField('createdTime', '创建时间'), operationField('操作', undefined, [ { diff --git a/gringotts-frontend/pages/index/tab-permissions.js b/gringotts-frontend/pages/index/tab-permissions.js index 08ce223..0c3cdd5 100644 --- a/gringotts-frontend/pages/index/tab-permissions.js +++ b/gringotts-frontend/pages/index/tab-permissions.js @@ -1,9 +1,10 @@ import { apiGet, - confirmationStateMapping, crudCommonOptions, + customerOnly, mappingField, operationField, + permissionStateMapping, providerOnly, stringField, stringWrapField, @@ -11,9 +12,12 @@ import { userOnly, } from "../../components/constants.js"; import { - permissionAddDialog, - permissionDetailDialog, - permissionEditeDialog, + authenticationAddDialog, + authenticationDetailDialog, + authenticationEditeDialog, + confirmationAddDialog, + confirmationDetailDialog, + confirmationEditeDialog, } from "../../components/permission/dialog-permission.js"; export function tabPermissions() { @@ -25,6 +29,85 @@ export function tabPermissions() { body: { type: 'tabs', tabs: [ + { + visibleOn: customerOnly, + title: '授权管理', + body: { + type: 'crud', + api: { + ...apiGet('${base}/authentication/list') + }, + ...crudCommonOptions(), + headerToolbar: [ + 'reload', + { + type: 'action', + label: '', + icon: 'fa fa-plus', + ...authenticationAddDialog() + }, + ], + columns: [ + stringField('name', '名称', 200), + stringWrapField('description', '描述'), + mappingField('state', '状态', permissionStateMapping), + timeField('createdTime', '创建时间'), + operationField('操作', undefined, [ + { + type: 'action', + label: '查看', + level: 'link', + ...authenticationDetailDialog(), + }, + { + visibleOn: "${state === 'CHECKING'}", + type: 'action', + label: '撤销', + level: 'link', + confirmTitle: '确认撤销', + confirmText: '确认撤销名称为「${name}」的确权申请吗?', + actionType: 'ajax', + api: apiGet('${base}/authentication/retract/${id}'), + }, + { + visibleOn: "${state === 'DRAFT' || state === 'REJECT'}", + type: 'action', + label: '提交', + level: 'link', + confirmTitle: '确认提交', + confirmText: '确认提交名称为「${name}」的确权申请吗?', + actionType: 'ajax', + api: apiGet('${base}/authentication/submit/${id}'), + }, + { + type: 'dropdown-button', + level: 'link', + icon: 'fa fa-ellipsis-h', + hideCaret: true, + trigger: 'hover', + buttons: [ + { + disabledOn: "${state !== 'DRAFT'}", + type: 'action', + label: '编辑', + level: 'link', + ...authenticationEditeDialog(), + }, + { + disabledOn: "${state === 'CHECKING'}", + type: 'action', + label: "删除", + confirmTitle: '确认删除', + confirmText: '确认删除名称为「${name}」的确权申请吗?删除后对应的数据资源处于未确权状态。', + actionType: 'ajax', + api: apiGet('${base}/authentication/remove/${id}'), + }, + ] + }, + ]), + ] + } + }, { visibleOn: providerOnly, title: '确权管理', @@ -40,20 +123,20 @@ export function tabPermissions() { type: 'action', label: '', icon: 'fa fa-plus', - ...permissionAddDialog() + ...confirmationAddDialog() }, ], columns: [ stringField('name', '名称', 200), stringWrapField('description', '描述'), - mappingField('state', '状态', confirmationStateMapping), + mappingField('state', '状态', permissionStateMapping), timeField('createdTime', '创建时间'), operationField('操作', undefined, [ { type: 'action', label: '查看', level: 'link', - ...permissionDetailDialog(), + ...confirmationDetailDialog(), }, { visibleOn: "${state === 'CHECKING'}", @@ -87,7 +170,7 @@ export function tabPermissions() { type: 'action', label: '编辑', level: 'link', - ...permissionEditeDialog(), + ...confirmationEditeDialog(), }, { disabledOn: "${state === 'CHECKING'}", @@ -104,10 +187,6 @@ export function tabPermissions() { ] } }, - { - title: '授权管理', - body: [] - } ] } } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java new file mode 100644 index 0000000..4dec07c --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java @@ -0,0 +1,87 @@ +package com.eshore.gringotts.web.domain.authentication.controller; + +import com.eshore.gringotts.web.domain.authentication.entity.Authentication; +import com.eshore.gringotts.web.domain.authentication.service.AuthenticationService; +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.SimpleListItem; +import com.eshore.gringotts.web.domain.base.entity.SimpleSaveItem; +import com.eshore.gringotts.web.domain.resource.service.DataResourceService; +import com.eshore.gringotts.web.domain.upload.service.DataFileService; +import java.time.LocalDateTime; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.collections.api.set.ImmutableSet; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author lanyuanxiaoyao + * @date 2024-12-02 + */ +@Slf4j +@RestController +@RequestMapping("authentication") +public class AuthenticationController extends SimpleControllerSupport { + private final AuthenticationService authenticationService; + private final DataResourceService dataResourceService; + private final DataFileService dataFileService; + + public AuthenticationController(AuthenticationService service, DataResourceService dataResourceService, DataFileService dataFileService) { + super(service); + this.authenticationService = service; + this.dataResourceService = dataResourceService; + this.dataFileService = dataFileService; + } + + @Override + protected Authentication fromSaveItem(SaveItem item) { + Authentication authentication = new Authentication(); + authentication.setId(item.getId()); + authentication.setDescription(item.getDescription()); + authentication.setTarget(dataResourceService.detailOrThrow(item.getTargetId())); + authentication.setEvidences(dataFileService.list(item.getEvidenceFiles().collect(FileInfo::getValue)).toSet()); + authentication.setActiveTime(item.getActiveTime()); + authentication.setExpiredTime(item.getExpiredTime()); + return null; + } + + @Override + protected ListItem toListItem(Authentication entity) { + ListItem item = new ListItem(); + item.setId(entity.getId()); + item.setName(entity.getTarget().getName()); + item.setDescription(entity.getDescription()); + item.setState(entity.getState().name()); + item.setCreatedUsername(entity.getCreatedUser().getUsername()); + item.setCreatedTime(entity.getCreatedTime()); + return item; + } + + @Override + protected DetailItem toDetailItem(Authentication entity) { + return null; + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static final class SaveItem extends SimpleSaveItem { + private Long targetId; + private String description; + private ImmutableSet evidenceFiles; + private LocalDateTime activeTime; + private LocalDateTime expiredTime; + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static final class ListItem extends SimpleListItem { + private String name; + private String description; + private String state; + } + + @Data + public static final class DetailItem {} +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/entity/Authentication.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/entity/Authentication.java index 90bf0be..10de288 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/entity/Authentication.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/entity/Authentication.java @@ -5,8 +5,10 @@ import com.eshore.gringotts.web.domain.base.entity.CheckingNeededEntity; import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity; import com.eshore.gringotts.web.domain.resource.entity.DataResource; import com.eshore.gringotts.web.domain.upload.entity.DataFile; +import java.time.LocalDateTime; import java.util.Set; import javax.persistence.CascadeType; +import javax.persistence.Column; import javax.persistence.ConstraintMode; import javax.persistence.Entity; import javax.persistence.EntityListeners; @@ -59,4 +61,14 @@ public class Authentication extends CheckingNeededEntity { @ToString.Exclude @Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE) private Set evidences; + /** + * 生效时间 + */ + @Column(nullable = false) + private LocalDateTime activeTime = LocalDateTime.now(); + /** + * 过期时间 + */ + @Column(nullable = false) + private LocalDateTime expiredTime = LocalDateTime.now().plusDays(1); } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/repository/AuthenticationRepository.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/repository/AuthenticationRepository.java new file mode 100644 index 0000000..96f685d --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/repository/AuthenticationRepository.java @@ -0,0 +1,13 @@ +package com.eshore.gringotts.web.domain.authentication.repository; + +import com.eshore.gringotts.web.domain.authentication.entity.Authentication; +import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; +import org.springframework.stereotype.Repository; + +/** + * @author lanyuanxiaoyao + * @date 2024-12-02 + */ +@Repository +public interface AuthenticationRepository extends SimpleRepository { +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/service/AuthenticationService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/service/AuthenticationService.java new file mode 100644 index 0000000..746d562 --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/service/AuthenticationService.java @@ -0,0 +1,31 @@ +package com.eshore.gringotts.web.domain.authentication.service; + +import com.eshore.gringotts.web.domain.authentication.entity.Authentication; +import com.eshore.gringotts.web.domain.authentication.repository.AuthenticationRepository; +import com.eshore.gringotts.web.domain.base.service.CheckingService; +import com.eshore.gringotts.web.domain.base.service.LogicDeleteService; +import com.eshore.gringotts.web.domain.check.entity.CheckOrder; +import com.eshore.gringotts.web.domain.user.service.UserService; +import javax.persistence.EntityManager; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.collections.api.map.ImmutableMap; +import org.springframework.stereotype.Service; + +/** + * @author lanyuanxiaoyao + * @date 2024-12-02 + */ +@Slf4j +@Service +public class AuthenticationService extends LogicDeleteService implements CheckingService { + private final AuthenticationRepository authenticationRepository; + + public AuthenticationService(AuthenticationRepository repository, UserService userService, EntityManager manager) { + super(repository, userService, manager); + this.authenticationRepository = repository; + } + + @Override + public void onChecked(CheckOrder order, CheckOrder.Operation operation, ImmutableMap parameters) { + } +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/CheckingNeededEntity.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/CheckingNeededEntity.java index 4053c84..98b1c7c 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/CheckingNeededEntity.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/entity/CheckingNeededEntity.java @@ -35,6 +35,10 @@ public class CheckingNeededEntity extends LogicDeleteEntity { * 审查中 */ CHECKING, + /** + * 用户审核 + */ + USER_CHECKING, /** * 正常 */