diff --git a/.gitignore b/.gitignore index 634d1aca52f39958550dfaddd7ccff62ad64c188..d2918cd9ff10008ea01e8a82406229027f7bb259 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,7 @@ build/ # 排除mac本地文件 *.DS_Store - +*.properties venv/ /docker/ **/assembly/ diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/api/account/ForgetPasswordApi.java b/board/board-service/src/main/java/com/welab/wefe/board/service/api/account/ForgetPasswordApi.java new file mode 100644 index 0000000000000000000000000000000000000000..a0d6d7a554d92ce8197f3c897ced6272a1c86d7e --- /dev/null +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/api/account/ForgetPasswordApi.java @@ -0,0 +1,84 @@ +/** + * Copyright 2021 Tianmian Tech. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.welab.wefe.board.service.api.account; + +import com.welab.wefe.board.service.service.account.AccountService; +import com.welab.wefe.common.exception.StatusCodeWithException; +import com.welab.wefe.common.fieldvalidate.annotation.Check; +import com.welab.wefe.common.web.api.base.AbstractApi; +import com.welab.wefe.common.web.api.base.Api; +import com.welab.wefe.common.web.dto.AbstractApiInput; +import com.welab.wefe.common.web.dto.ApiResult; +import com.welab.wefe.common.web.dto.NoneApiOutput; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; + +/** + * forget password + * + * @author aaron.li + * @date 2021/11/10 14:08 + **/ +@Api(path = "account/forget_password", name = "forgetPassword", login = false) +public class ForgetPasswordApi extends AbstractApi { + @Autowired + private AccountService accountService; + + @Override + protected ApiResult handle(Input input) throws StatusCodeWithException, IOException { + accountService.forgetPassword(input); + return success(); + } + + public static class Input extends AbstractApiInput { + @Check(require = true) + private String phoneNumber; + + @Check(require = true, regex = "^.{6,128}$") + private String password; + + @Check(require = true) + private String smsVerificationCode; + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getSmsVerificationCode() { + return smsVerificationCode; + } + + public void setSmsVerificationCode(String smsVerificationCode) { + this.smsVerificationCode = smsVerificationCode; + } + } + + +} diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/api/union/SendForgetPasswordSmsCodeApi.java b/board/board-service/src/main/java/com/welab/wefe/board/service/api/union/SendForgetPasswordSmsCodeApi.java new file mode 100644 index 0000000000000000000000000000000000000000..756d14f4f0b8ccbe52533e40a435b96f8f84dea8 --- /dev/null +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/api/union/SendForgetPasswordSmsCodeApi.java @@ -0,0 +1,59 @@ +/** + * Copyright 2021 Tianmian Tech. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.welab.wefe.board.service.api.union; + +import com.welab.wefe.board.service.sdk.UnionService; +import com.welab.wefe.common.enums.SmsBusinessType; +import com.welab.wefe.common.exception.StatusCodeWithException; +import com.welab.wefe.common.fieldvalidate.annotation.Check; +import com.welab.wefe.common.web.api.base.AbstractApi; +import com.welab.wefe.common.web.api.base.Api; +import com.welab.wefe.common.web.dto.AbstractApiInput; +import com.welab.wefe.common.web.dto.ApiResult; +import com.welab.wefe.common.web.dto.NoneApiOutput; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.IOException; + +/** + * @author aaron.li + * @date 2021/11/11 09:45 + **/ +@Api(path = "union/send_forget_password_sms_code", name = "send sms verification code", login = false) +public class SendForgetPasswordSmsCodeApi extends AbstractApi { + @Autowired + private UnionService unionService; + + @Override + protected ApiResult handle(Input input) throws StatusCodeWithException, IOException { + unionService.sendVerificationCode(input.phoneNumber, SmsBusinessType.AccountForgetPasswordVerificationCode); + return success(); + } + + public static class Input extends AbstractApiInput { + @Check(require = true) + private String phoneNumber; + + public String getPhoneNumber() { + return phoneNumber; + } + + public void setPhoneNumber(String phoneNumber) { + this.phoneNumber = phoneNumber; + } + } +} diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/database/entity/job/ProjectFlowMySqlModel.java b/board/board-service/src/main/java/com/welab/wefe/board/service/database/entity/job/ProjectFlowMySqlModel.java index 53265900655c71efcff4f542ca58d4a15fcb4240..02aba4b78a95fe76a02a6444b071b5e420a9ee83 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/database/entity/job/ProjectFlowMySqlModel.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/database/entity/job/ProjectFlowMySqlModel.java @@ -63,6 +63,10 @@ public class ProjectFlowMySqlModel extends AbstractBaseMySqlModel { * 画布中编辑的图 */ private String graph; + /** + * 创建此流程的成员的ID + */ + private String creatorMemberId; /** * 流程的状态 @@ -168,6 +172,15 @@ public class ProjectFlowMySqlModel extends AbstractBaseMySqlModel { public void setStatusUpdatedTime(Date statusUpdatedTime) { this.statusUpdatedTime = statusUpdatedTime; } + + public String getCreatorMemberId() { + return creatorMemberId; + } + + public void setCreatorMemberId(String creatorMemberId) { + this.creatorMemberId = creatorMemberId; + } + //endregion } diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowListOutputModel.java b/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowListOutputModel.java index 652c11095a128e6825408315acc0f2a3d6a7f405..893099053aa3d9445c1ee738f25a715dba7dcf4a 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowListOutputModel.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowListOutputModel.java @@ -17,6 +17,7 @@ package com.welab.wefe.board.service.dto.entity.project; import com.welab.wefe.board.service.dto.entity.AbstractOutputModel; +import com.welab.wefe.board.service.service.CacheObjects; import com.welab.wefe.common.enums.FederatedLearningType; import com.welab.wefe.common.enums.JobMemberRole; import com.welab.wefe.common.enums.ProjectFlowStatus; @@ -70,7 +71,14 @@ public class ProjectFlowListOutputModel extends AbstractOutputModel { * 任务进度 */ private Integer jobProgress; + /** + * 创建此流程的成员的ID + */ + private String creatorMemberId; + public String getCreatorMemberName() { + return CacheObjects.getMemberName(creatorMemberId); + } //region getter/setter @@ -171,6 +179,14 @@ public class ProjectFlowListOutputModel extends AbstractOutputModel { this.isCreator = isCreator; } + public String getCreatorMemberId() { + return creatorMemberId; + } + + public void setCreatorMemberId(String creatorMemberId) { + this.creatorMemberId = creatorMemberId; + } + //endregion } diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowOutputModel.java b/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowOutputModel.java index 92e1b2efe76abc8c251d60d13eb0296bdea101cf..a7a12d4ed783880b12804f051cac627e8fd75386 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowOutputModel.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/dto/entity/project/ProjectFlowOutputModel.java @@ -19,6 +19,7 @@ package com.welab.wefe.board.service.dto.entity.project; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.welab.wefe.board.service.dto.entity.AbstractOutputModel; +import com.welab.wefe.board.service.service.CacheObjects; import com.welab.wefe.common.enums.FederatedLearningType; import com.welab.wefe.common.enums.JobMemberRole; import com.welab.wefe.common.enums.ProjectFlowStatus; @@ -57,6 +58,10 @@ public class ProjectFlowOutputModel extends AbstractOutputModel { * 画布中编辑的图 */ private JSONObject graph; + /** + * 创建此流程的成员的ID + */ + private String creatorMemberId; /** * 流程的状态 @@ -78,6 +83,10 @@ public class ProjectFlowOutputModel extends AbstractOutputModel { } } + public String getCreatorMemberName() { + return CacheObjects.getMemberName(creatorMemberId); + } + //region getter/setter @@ -174,5 +183,12 @@ public class ProjectFlowOutputModel extends AbstractOutputModel { this.projectModelingOutputModel = projectModelingOutputModel; } + public String getCreatorMemberId() { + return creatorMemberId; + } + + public void setCreatorMemberId(String creatorMemberId) { + this.creatorMemberId = creatorMemberId; + } //endregion } diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/FlowService.java b/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/FlowService.java index 80d72ff5b24e12134e95f859eacda8ed62361623..69668a087282eb577b0bf6b0544ca50cc582d66c 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/FlowService.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/FlowService.java @@ -1,12 +1,12 @@ /** * Copyright 2021 Tianmian Tech. All Rights Reserved. - *

+ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

+ * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/UnionService.java b/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/UnionService.java index 66c1c2db8f84e251226bd4e4564f01577d2abaeb..02773dbf61be611131db8282a4d7980cda1c5e83 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/UnionService.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/sdk/UnionService.java @@ -1,12 +1,12 @@ /** * Copyright 2021 Tianmian Tech. All Rights Reserved. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -34,6 +34,7 @@ import com.welab.wefe.board.service.service.globalconfig.GlobalConfigService; import com.welab.wefe.common.CommonThreadPool; import com.welab.wefe.common.StatusCode; import com.welab.wefe.common.enums.DataSetPublicLevel; +import com.welab.wefe.common.enums.SmsBusinessType; import com.welab.wefe.common.exception.StatusCodeWithException; import com.welab.wefe.common.http.HttpRequest; import com.welab.wefe.common.http.HttpResponse; @@ -339,6 +340,50 @@ public class UnionService extends AbstractService { return data.toJavaObject(DataSetOutputModel.class); } + public void sendVerificationCode(String mobile, SmsBusinessType smsBusinessType) throws StatusCodeWithException { + if (!StringUtil.checkPhoneNumber(mobile)) { + throw new StatusCodeWithException("非法的手机号", StatusCode.PARAMETER_VALUE_INVALID); + } + JObject params = JObject.create() + .append("mobile", mobile) + .append("smsBusinessType", smsBusinessType); + try { + request("sms/send_verification_code", params, true); + } catch (StatusCodeWithException e) { + throw new StatusCodeWithException(getUnionOrigExceptionMsg(e), StatusCode.SYSTEM_ERROR); + } catch (Exception e) { + throw new StatusCodeWithException(e.getMessage(), StatusCode.SYSTEM_ERROR); + } + } + + /** + * Check verification code + */ + public void checkVerificationCode(String mobile, String code, SmsBusinessType smsBusinessType) throws StatusCodeWithException { + JObject params = JObject.create() + .append("mobile", mobile) + .append("code", code) + .append("smsBusinessType", smsBusinessType); + try { + request("sms/check_verification_code", params, true); + } catch (StatusCodeWithException e) { + throw new StatusCodeWithException(getUnionOrigExceptionMsg(e), StatusCode.SYSTEM_ERROR); + } catch (Exception e) { + throw new StatusCodeWithException(e.getMessage(), StatusCode.SYSTEM_ERROR); + } + } + + private String getUnionOrigExceptionMsg(StatusCodeWithException e) { + String errorMsg = e.getMessage(); + if (StringUtil.isNotEmpty(errorMsg)) { + int index = errorMsg.indexOf(":"); + if (index != -1) { + errorMsg = errorMsg.substring(index + 1); + } + } + return errorMsg; + } + private JSONObject request(String api, JSONObject params) throws StatusCodeWithException { return request(api, params, true); } diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/service/ProjectFlowService.java b/board/board-service/src/main/java/com/welab/wefe/board/service/service/ProjectFlowService.java index ea5b9be446d798299d16341e43085dbc8a9b586d..c067d1c3969cd16a054a0ef6d7e7f47b503a3ec8 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/service/ProjectFlowService.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/service/ProjectFlowService.java @@ -154,6 +154,7 @@ public class ProjectFlowService extends AbstractService { flow.setFlowDesc(input.getDesc()); flow.setFlowStatus(ProjectFlowStatus.editing); flow.setMyRole(input.fromGateway() ? project.getMyRole() : JobMemberRole.promoter); + flow.setCreatorMemberId(input.fromGateway() ? input.callerMemberInfo.getMemberId() : CacheObjects.getMemberId()); if (StringUtils.isNotBlank(input.getTemplateId())) { FlowTemplateMySqlModel template = flowTemplateService.findById(input.getTemplateId()); @@ -429,6 +430,7 @@ public class ProjectFlowService extends AbstractService { targetProjectFlow.setFlowStatus(ProjectFlowStatus.editing); targetProjectFlow.setCreatedTime(new Date()); targetProjectFlow.setCreatedBy(input); + targetProjectFlow.setCreatorMemberId(sourceProjectFlow.getCreatorMemberId()); projectFlowRepo.save(targetProjectFlow); for (ProjectFlowNodeOutputModel sourceProjectFlowNode : sourceProjectFlowNodeList) { diff --git a/board/board-service/src/main/java/com/welab/wefe/board/service/service/account/AccountService.java b/board/board-service/src/main/java/com/welab/wefe/board/service/service/account/AccountService.java index ef80694ebe7d9fbee24b42b5d4b55fe11e221df2..6c732c6e271c5d0e1850b7affb05e6aea6ebe275 100644 --- a/board/board-service/src/main/java/com/welab/wefe/board/service/service/account/AccountService.java +++ b/board/board-service/src/main/java/com/welab/wefe/board/service/service/account/AccountService.java @@ -1,12 +1,12 @@ /** * Copyright 2021 Tianmian Tech. All Rights Reserved. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -24,6 +24,7 @@ import com.welab.wefe.board.service.dto.base.PagingOutput; import com.welab.wefe.board.service.dto.entity.AccountOutputModel; import com.welab.wefe.board.service.dto.vo.AccountInputModel; import com.welab.wefe.board.service.dto.vo.OnlineAccountOutput; +import com.welab.wefe.board.service.sdk.UnionService; import com.welab.wefe.board.service.service.AbstractService; import com.welab.wefe.board.service.service.CacheObjects; import com.welab.wefe.board.service.service.GatewayService; @@ -31,10 +32,7 @@ import com.welab.wefe.board.service.service.WebSocketServer; import com.welab.wefe.board.service.service.globalconfig.GlobalConfigService; import com.welab.wefe.common.StatusCode; import com.welab.wefe.common.data.mysql.Where; -import com.welab.wefe.common.enums.AuditStatus; -import com.welab.wefe.common.enums.BoardUserSource; -import com.welab.wefe.common.enums.JobMemberRole; -import com.welab.wefe.common.enums.OrderBy; +import com.welab.wefe.common.enums.*; import com.welab.wefe.common.exception.StatusCodeWithException; import com.welab.wefe.common.util.*; import com.welab.wefe.common.web.CurrentAccount; @@ -66,6 +64,9 @@ public class AccountService extends AbstractService { @Autowired private GlobalConfigService globalConfigService; + @Autowired + private UnionService unionService; + /** * Paging query account */ @@ -467,4 +468,33 @@ public class AccountService extends AbstractService { // Cancel the super administrator privileges of the current account accountRepository.cancelSuperAdmin(CurrentAccount.id()); } + + public void forgetPassword(ForgetPasswordApi.Input input) throws StatusCodeWithException { + if (StringUtil.isEmpty(input.getPhoneNumber())) { + throw new StatusCodeWithException("手机号不能为空。", StatusCode.PARAMETER_VALUE_INVALID); + } + if (StringUtil.isEmpty(input.getPassword())) { + throw new StatusCodeWithException("密码不能为空。", StatusCode.PARAMETER_VALUE_INVALID); + } + if (StringUtil.isEmpty(input.getSmsVerificationCode())) { + throw new StatusCodeWithException("短信验证码不能为空。", StatusCode.PARAMETER_VALUE_INVALID); + } + + AccountMySqlModel model = accountRepository.findOne("phoneNumber", input.getPhoneNumber(), AccountMySqlModel.class); + // phone number error + if (model == null) { + throw new StatusCodeWithException("手机号错误,该用户不存在。", StatusCode.PARAMETER_VALUE_INVALID); + } + if (!model.getEnable()) { + throw new StatusCodeWithException("用户被禁用,请联系管理员。", StatusCode.PERMISSION_DENIED); + } + + unionService.checkVerificationCode(input.getPhoneNumber(), input.getSmsVerificationCode(), SmsBusinessType.AccountForgetPasswordVerificationCode); + + // Regenerate salt + String salt = createRandomSalt(); + model.setSalt(salt); + model.setPassword(Sha1.of(input.getPassword() + salt)); + accountRepository.save(model); + } } diff --git a/board/board-website/src/components/Common/TitleNavigator.vue b/board/board-website/src/components/Common/TitleNavigator.vue index bc5cc3beb99160cd045dd3185fc29008c30cadf1..5462566ca73dc0fc593f4c5aac6546625fce365f 100644 --- a/board/board-website/src/components/Common/TitleNavigator.vue +++ b/board/board-website/src/components/Common/TitleNavigator.vue @@ -6,7 +6,6 @@ > {{ item.title }} diff --git a/board/board-website/src/components/views/flow-status-tag.vue b/board/board-website/src/components/views/flow-status-tag.vue index 1ed40607c37c37c7db49cbfce7e1244161d0827f..769b8d9c504209b337c149c36f2eb83b4bff4754 100644 --- a/board/board-website/src/components/views/flow-status-tag.vue +++ b/board/board-website/src/components/views/flow-status-tag.vue @@ -43,6 +43,11 @@ title: 'wait_stop', effect: 'dark', }, + wait_run: { + type: 'warning', + title: 'wait_run', + effect: 'dark', + }, wait_success: { type: 'success', title: 'wait_success', diff --git a/board/board-website/src/store/modules/base.js b/board/board-website/src/store/modules/base.js index 7613905e3d46c54a31a8445113b20e690ea8018b..b5f9e5deeab9c873acb733aaced290feea13a807 100644 --- a/board/board-website/src/store/modules/base.js +++ b/board/board-website/src/store/modules/base.js @@ -1,4 +1,3 @@ - function setStorage () { /* let keepAlive = localStorage.getItem(KEEPALIVE); @@ -58,7 +57,7 @@ export default _ => { }, 'UPDATE_USERINFO' (state, data) { state.userInfo = data; - setStorage().setItem(USERINFO, JSON.stringify(data)); + setStorage().setItem(USERINFO, data ? JSON.stringify(data) : ''); }, // update tag list 'UPDATE_TAGSLIST' (state, list) { diff --git a/board/board-website/src/views/sign/find-password.vue b/board/board-website/src/views/sign/find-password.vue index a842b3f27d0303cc343a6e4bab3d5124bd0877a3..10daba5b3e5a976330b0d5bab05fe8ef4484ebbb 100644 --- a/board/board-website/src/views/sign/find-password.vue +++ b/board/board-website/src/views/sign/find-password.vue @@ -1,14 +1,14 @@