Merge remote-tracking branch 'origin/dev' into dev
# Conflicts: # frontend/src/i18n/zh-CN.js
This commit is contained in:
commit
bc294c354c
|
@ -27,4 +27,6 @@ public interface UserMapper {
|
|||
int updateByPrimaryKeySelective(User record);
|
||||
|
||||
int updateByPrimaryKey(User record);
|
||||
|
||||
int updatePassword(User record);
|
||||
}
|
|
@ -303,4 +303,12 @@
|
|||
phone = #{phone,jdbcType=VARCHAR}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
<!--修改密码-->
|
||||
<update id="updatePassword" parameterType="io.metersphere.base.domain.User">
|
||||
update user
|
||||
set
|
||||
password=#{password,jdbcType=VARCHAR},
|
||||
update_time = #{updateTime,jdbcType=BIGINT}
|
||||
where id=#{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -25,10 +25,10 @@
|
|||
inner join test_case on test_plan_test_case.case_id = test_case.id
|
||||
<where>
|
||||
<if test="request.name != null">
|
||||
and test_plan_test_case.name like CONCAT('%', #{request.name},'%')
|
||||
and test_case.name like CONCAT('%', #{request.name},'%')
|
||||
</if>
|
||||
<if test="request.nodeIds != null and request.nodeIds.size() > 0">
|
||||
and test_plan_test_case.node_id in
|
||||
and test_case.node_id in
|
||||
<foreach collection="request.nodeIds" item="nodeId" separator="," open="(" close=")">
|
||||
#{nodeId}
|
||||
</foreach>
|
||||
|
|
|
@ -8,4 +8,5 @@ import java.util.List;
|
|||
public interface ExtUserMapper {
|
||||
|
||||
List<User> getUserList(@Param("userRequest") UserRequest request);
|
||||
int updatePassword(User record);
|
||||
}
|
||||
|
|
|
@ -33,4 +33,13 @@
|
|||
</where>
|
||||
</select>
|
||||
|
||||
<!--修改密码-->
|
||||
<update id="updatePassword" parameterType="io.metersphere.base.domain.User">
|
||||
update user
|
||||
set
|
||||
password=#{password,jdbcType=VARCHAR},
|
||||
update_time = #{updateTime,jdbcType=BIGINT}
|
||||
where id=#{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
||||
</mapper>
|
|
@ -9,6 +9,7 @@ import io.metersphere.commons.utils.Pager;
|
|||
import io.metersphere.controller.request.OrganizationRequest;
|
||||
import io.metersphere.dto.OrganizationMemberDTO;
|
||||
import io.metersphere.service.OrganizationService;
|
||||
import io.metersphere.service.UserService;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
@ -22,6 +23,8 @@ public class OrganizationController {
|
|||
|
||||
@Resource
|
||||
private OrganizationService organizationService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@PostMapping("/add")
|
||||
@RequiresRoles(RoleConstants.ADMIN)
|
||||
|
@ -45,6 +48,7 @@ public class OrganizationController {
|
|||
@GetMapping("/delete/{organizationId}")
|
||||
@RequiresRoles(RoleConstants.ADMIN)
|
||||
public void deleteOrganization(@PathVariable(value = "organizationId") String organizationId) {
|
||||
userService.refreshSessionUser("organization", organizationId);
|
||||
organizationService.deleteOrganization(organizationId);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,17 +7,20 @@ import io.metersphere.commons.constants.RoleConstants;
|
|||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.ReportRequest;
|
||||
import io.metersphere.dto.LogDetailDTO;
|
||||
import io.metersphere.dto.ReportDTO;
|
||||
import io.metersphere.report.base.*;
|
||||
import io.metersphere.service.ReportService;
|
||||
import io.metersphere.user.SessionUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = "performance/report")
|
||||
|
@ -97,7 +100,16 @@ public class PerformanceReportController {
|
|||
}
|
||||
|
||||
@GetMapping("log/{reportId}")
|
||||
public Map<String, String> stop(@PathVariable String reportId) {
|
||||
return reportService.log(reportId);
|
||||
public List<LogDetailDTO> logs(@PathVariable String reportId) {
|
||||
return reportService.logs(reportId);
|
||||
}
|
||||
|
||||
@GetMapping("log/download/{logId}")
|
||||
public ResponseEntity<byte[]> downloadLog(@PathVariable String logId) {
|
||||
byte[] bytes = reportService.downloadLog(logId);
|
||||
return ResponseEntity.ok()
|
||||
.contentType(MediaType.parseMediaType("application/octet-stream"))
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"jmeter.log\"")
|
||||
.body(bytes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import io.metersphere.commons.utils.PageUtils;
|
|||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.UserRequest;
|
||||
import io.metersphere.controller.request.member.AddMemberRequest;
|
||||
import io.metersphere.controller.request.member.EditPassWordRequest;
|
||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||
import io.metersphere.controller.request.organization.AddOrgMemberRequest;
|
||||
import io.metersphere.controller.request.organization.QueryOrgMemberRequest;
|
||||
|
@ -23,6 +24,7 @@ import org.apache.shiro.authz.annotation.Logical;
|
|||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -115,7 +117,7 @@ public class UserController {
|
|||
// admin api
|
||||
|
||||
@GetMapping("/list")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN,RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN, RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
public List<User> getUserList() {
|
||||
return userService.getUserList();
|
||||
}
|
||||
|
@ -132,17 +134,24 @@ public class UserController {
|
|||
@PostMapping("/switch/source/org/{sourceId}")
|
||||
@RequiresRoles(RoleConstants.ORG_ADMIN)
|
||||
public UserDTO switchOrganization(@PathVariable(value = "sourceId") String sourceId) {
|
||||
userService.switchUserRole("organization",sourceId);
|
||||
userService.switchUserRole("organization", sourceId);
|
||||
return SessionUtils.getUser();
|
||||
}
|
||||
|
||||
@PostMapping("/switch/source/ws/{sourceId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER,RoleConstants.TEST_VIEWER,RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_VIEWER, RoleConstants.TEST_USER}, logical = Logical.OR)
|
||||
public UserDTO switchWorkspace(@PathVariable(value = "sourceId") String sourceId) {
|
||||
userService.switchUserRole("workspace", sourceId);
|
||||
return SessionUtils.getUser();
|
||||
}
|
||||
|
||||
@PostMapping("/refresh/{sign}/{sourceId}")
|
||||
@RequiresRoles(RoleConstants.ADMIN)
|
||||
public UserDTO refreshSessionUser(@PathVariable String sign, @PathVariable String sourceId) {
|
||||
userService.refreshSessionUser(sign, sourceId);
|
||||
return SessionUtils.getUser();
|
||||
}
|
||||
|
||||
@GetMapping("/info/{userId}")
|
||||
public User getUserInfo(@PathVariable(value = "userId") String userId) {
|
||||
return userService.getUserInfo(userId);
|
||||
|
@ -152,8 +161,8 @@ public class UserController {
|
|||
* 获取工作空间成员用户
|
||||
*/
|
||||
@PostMapping("/ws/member/list/{goPage}/{pageSize}")
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN,RoleConstants.TEST_MANAGER,
|
||||
RoleConstants.TEST_USER,RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER,
|
||||
RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
public Pager<List<User>> getMemberList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryMemberRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, userService.getMemberList(request));
|
||||
|
@ -163,8 +172,8 @@ public class UserController {
|
|||
* 获取工作空间成员用户 不分页
|
||||
*/
|
||||
@PostMapping("/ws/member/list/all")
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN,RoleConstants.TEST_MANAGER,
|
||||
RoleConstants.TEST_USER,RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER,
|
||||
RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR)
|
||||
public List<User> getMemberList(@RequestBody QueryMemberRequest request) {
|
||||
return userService.getMemberList(request);
|
||||
}
|
||||
|
@ -173,7 +182,7 @@ public class UserController {
|
|||
* 添加工作空间成员
|
||||
*/
|
||||
@PostMapping("/ws/member/add")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER,RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
public void addMember(@RequestBody AddMemberRequest request) {
|
||||
String wsId = request.getWorkspaceId();
|
||||
workspaceService.checkWorkspaceOwner(wsId);
|
||||
|
@ -184,7 +193,7 @@ public class UserController {
|
|||
* 删除工作空间成员
|
||||
*/
|
||||
@GetMapping("/ws/member/delete/{workspaceId}/{userId}")
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER,RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.ORG_ADMIN}, logical = Logical.OR)
|
||||
public void deleteMember(@PathVariable String workspaceId, @PathVariable String userId) {
|
||||
workspaceService.checkWorkspaceOwner(workspaceId);
|
||||
String currentUserId = SessionUtils.getUser().getId();
|
||||
|
@ -222,7 +231,7 @@ public class UserController {
|
|||
* 查询组织成员列表
|
||||
*/
|
||||
@PostMapping("/org/member/list/{goPage}/{pageSize}")
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN,RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public Pager<List<User>> getOrgMemberList(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryOrgMemberRequest request) {
|
||||
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
|
||||
return PageUtils.setPageInfo(page, userService.getOrgMemberList(request));
|
||||
|
@ -232,7 +241,7 @@ public class UserController {
|
|||
* 组织成员列表不分页
|
||||
*/
|
||||
@PostMapping("/org/member/list/all")
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN,RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
@RequiresRoles(value = {RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public List<User> getOrgMemberList(@RequestBody QueryOrgMemberRequest request) {
|
||||
return userService.getOrgMemberList(request);
|
||||
}
|
||||
|
@ -242,4 +251,18 @@ public class UserController {
|
|||
return userService.getBesideOrgMemberList(orgId);
|
||||
}
|
||||
|
||||
/*
|
||||
* 修改当前用户密码
|
||||
* */
|
||||
@PostMapping("/update/password")
|
||||
public int updateCurrentUserPassword(@RequestBody EditPassWordRequest request) {
|
||||
return userService.updateCurrentUserPassword(request);
|
||||
}
|
||||
|
||||
/*管理员修改用户密码*/
|
||||
@PostMapping("/special/password")
|
||||
public int updateUserPassword(@RequestBody EditPassWordRequest request) {
|
||||
return userService.updateUserPassword(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,12 +10,12 @@ import io.metersphere.controller.request.WorkspaceRequest;
|
|||
import io.metersphere.dto.WorkspaceDTO;
|
||||
import io.metersphere.dto.WorkspaceMemberDTO;
|
||||
import io.metersphere.service.OrganizationService;
|
||||
import io.metersphere.service.UserService;
|
||||
import io.metersphere.service.WorkspaceService;
|
||||
import io.metersphere.user.SessionUtils;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.apache.shiro.authz.annotation.RequiresRoles;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -26,6 +26,8 @@ public class WorkspaceController {
|
|||
private WorkspaceService workspaceService;
|
||||
@Resource
|
||||
private OrganizationService organizationService;
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@PostMapping("add")
|
||||
@RequiresRoles(RoleConstants.ORG_ADMIN)
|
||||
|
@ -51,12 +53,13 @@ public class WorkspaceController {
|
|||
@PostMapping("special/update")
|
||||
@RequiresRoles(RoleConstants.ADMIN)
|
||||
public void updateWorkspaceByAdmin(@RequestBody Workspace workspace) {
|
||||
workspaceService.updateWorkspacebyAdmin(workspace);
|
||||
workspaceService.updateWorkspaceByAdmin(workspace);
|
||||
}
|
||||
|
||||
@GetMapping("special/delete/{workspaceId}")
|
||||
@RequiresRoles(RoleConstants.ADMIN)
|
||||
public void deleteWorkspaceByAdmin(@PathVariable String workspaceId) {
|
||||
userService.refreshSessionUser("workspace", workspaceId);
|
||||
workspaceService.deleteWorkspace(workspaceId);
|
||||
}
|
||||
|
||||
|
@ -64,6 +67,7 @@ public class WorkspaceController {
|
|||
@RequiresRoles(RoleConstants.ORG_ADMIN)
|
||||
public void deleteWorkspace(@PathVariable String workspaceId) {
|
||||
workspaceService.checkWorkspaceOwnerByOrgAdmin(workspaceId);
|
||||
userService.refreshSessionUser("workspace", workspaceId);
|
||||
workspaceService.deleteWorkspace(workspaceId);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package io.metersphere.controller.request.member;
|
||||
|
||||
import lombok.Data;
|
||||
@Data
|
||||
public class EditPassWordRequest {
|
||||
private String password;
|
||||
private String newpassword;
|
||||
private String id;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class LogDetailDTO {
|
||||
private String id;
|
||||
private String resourceName;
|
||||
private String content;
|
||||
}
|
|
@ -109,12 +109,8 @@ public class OrganizationService {
|
|||
}
|
||||
|
||||
public void updateOrgMember(OrganizationMemberDTO memberDTO) {
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(memberDTO, user);
|
||||
userMapper.updateByPrimaryKeySelective(user);
|
||||
//
|
||||
String orgId = memberDTO.getOrganizationId();
|
||||
String userId = user.getId();
|
||||
String userId = memberDTO.getId();
|
||||
// 已有角色
|
||||
List<Role> memberRoles = extUserRoleMapper.getOrganizationMemberRoles(orgId, userId);
|
||||
// 修改后的角色
|
||||
|
|
|
@ -13,6 +13,7 @@ import io.metersphere.commons.constants.ReportKeys;
|
|||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.controller.request.ReportRequest;
|
||||
import io.metersphere.dto.LogDetailDTO;
|
||||
import io.metersphere.dto.ReportDTO;
|
||||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.engine.EngineFactory;
|
||||
|
@ -22,6 +23,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -157,35 +159,45 @@ public class ReportService {
|
|||
return extLoadTestReportMapper.selectByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public Map<String, String> log(String reportId) {
|
||||
Map<String, String> logMap = new HashMap<>();
|
||||
public List<LogDetailDTO> logs(String reportId) {
|
||||
LoadTestReportLogExample example = new LoadTestReportLogExample();
|
||||
example.createCriteria().andReportIdEqualTo(reportId);
|
||||
List<LoadTestReportLog> loadTestReportLogs = loadTestReportLogMapper.selectByExampleWithBLOBs(example);
|
||||
loadTestReportLogs.stream().map(log -> {
|
||||
Map<String, String> result = new HashMap<>();
|
||||
return loadTestReportLogs.stream().map(log -> {
|
||||
LogDetailDTO detailDTO = new LogDetailDTO();
|
||||
detailDTO.setId(log.getId());
|
||||
TestResource testResource = testResourceService.getTestResource(log.getResourceId());
|
||||
String content = log.getContent();
|
||||
// 显示前 2048
|
||||
content = StringUtils.substring(content, 0, 2048);
|
||||
detailDTO.setContent(content);
|
||||
if (testResource == null) {
|
||||
result.put(log.getResourceId(), log.getContent());
|
||||
return result;
|
||||
detailDTO.setResourceName(log.getResourceId());
|
||||
return detailDTO;
|
||||
}
|
||||
String configuration = testResource.getConfiguration();
|
||||
if (StringUtils.isBlank(configuration)) {
|
||||
detailDTO.setResourceName(log.getResourceId());
|
||||
return detailDTO;
|
||||
}
|
||||
JSONObject object = JSON.parseObject(configuration);
|
||||
if (StringUtils.isNotBlank(object.getString("masterUrl"))) {
|
||||
result.put(object.getString("masterUrl"), log.getContent());
|
||||
return result;
|
||||
detailDTO.setResourceName(object.getString("masterUrl"));
|
||||
return detailDTO;
|
||||
}
|
||||
if (StringUtils.isNotBlank(object.getString("ip"))) {
|
||||
result.put(object.getString("ip"), log.getContent());
|
||||
return result;
|
||||
|
||||
detailDTO.setResourceName(object.getString("ip"));
|
||||
return detailDTO;
|
||||
}
|
||||
result.put(log.getResourceId(), log.getContent());
|
||||
return result;
|
||||
}).forEach(log -> logMap.putAll(log.entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)))
|
||||
);
|
||||
return detailDTO;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return logMap;
|
||||
public byte[] downloadLog(String logId) {
|
||||
LoadTestReportLog loadTestReportLog = loadTestReportLogMapper.selectByPrimaryKey(logId);
|
||||
if (loadTestReportLog != null) {
|
||||
return loadTestReportLog.getContent().getBytes();
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import io.metersphere.commons.exception.MSException;
|
|||
import io.metersphere.commons.utils.CodingUtil;
|
||||
import io.metersphere.controller.request.UserRequest;
|
||||
import io.metersphere.controller.request.member.AddMemberRequest;
|
||||
import io.metersphere.controller.request.member.EditPassWordRequest;
|
||||
import io.metersphere.controller.request.member.QueryMemberRequest;
|
||||
import io.metersphere.controller.request.organization.AddOrgMemberRequest;
|
||||
import io.metersphere.controller.request.organization.QueryOrgMemberRequest;
|
||||
|
@ -47,11 +48,19 @@ public class UserService {
|
|||
|
||||
public UserDTO insert(User user) {
|
||||
checkUserParam(user);
|
||||
createUser(user);
|
||||
//
|
||||
String id = user.getId();
|
||||
User user1 = userMapper.selectByPrimaryKey(id);
|
||||
if (user1 != null) {
|
||||
MSException.throwException(Translator.get("user_id_already_exists"));
|
||||
} else {
|
||||
createUser(user);
|
||||
}
|
||||
return getUserDTO(user.getId());
|
||||
}
|
||||
|
||||
private void checkUserParam(User user) {
|
||||
|
||||
if (StringUtils.isBlank(user.getName())) {
|
||||
MSException.throwException(Translator.get("user_name_is_null"));
|
||||
}
|
||||
|
@ -256,4 +265,63 @@ public class UserService {
|
|||
SessionUtils.getUser().setLanguage(lang);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshSessionUser(String sign, String sourceId) {
|
||||
SessionUser sessionUser = SessionUtils.getUser();
|
||||
// 获取最新UserDTO
|
||||
UserDTO user = getUserDTO(sessionUser.getId());
|
||||
User newUser = new User();
|
||||
if (StringUtils.equals("organization", sign) && StringUtils.equals(sourceId, user.getLastOrganizationId())) {
|
||||
user.setLastOrganizationId("");
|
||||
user.setLastWorkspaceId("");
|
||||
}
|
||||
if (StringUtils.equals("workspace", sign) && StringUtils.equals(sourceId, user.getLastWorkspaceId())) {
|
||||
user.setLastWorkspaceId("");
|
||||
}
|
||||
|
||||
BeanUtils.copyProperties(user, newUser);
|
||||
|
||||
SessionUtils.putUser(SessionUser.fromUser(user));
|
||||
userMapper.updateByPrimaryKeySelective(newUser);
|
||||
}
|
||||
|
||||
|
||||
/*修改当前用户用户密码*/
|
||||
private User updateCurrentUserPwd(EditPassWordRequest request) {
|
||||
if (SessionUtils.getUser() != null) {
|
||||
User user = userMapper.selectByPrimaryKey(SessionUtils.getUser().getId());
|
||||
String pwd = user.getPassword();
|
||||
String prepwd = CodingUtil.md5(request.getPassword(), "utf-8");
|
||||
String newped = request.getNewpassword();
|
||||
if (StringUtils.isNotBlank(prepwd)) {
|
||||
if (prepwd.trim().equals(pwd.trim())) {
|
||||
user.setPassword(CodingUtil.md5(newped));
|
||||
user.setUpdateTime(System.currentTimeMillis());
|
||||
return user;
|
||||
}
|
||||
}
|
||||
MSException.throwException(Translator.get("password_modification_failed"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int updateCurrentUserPassword(EditPassWordRequest request) {
|
||||
User user = updateCurrentUserPwd(request);
|
||||
return extUserMapper.updatePassword(user);
|
||||
}
|
||||
|
||||
/*管理员修改用户密码*/
|
||||
private User updateUserPwd(EditPassWordRequest request) {
|
||||
User user = userMapper.selectByPrimaryKey(request.getId());
|
||||
String newped = request.getNewpassword();
|
||||
user.setPassword(CodingUtil.md5(newped));
|
||||
user.setUpdateTime(System.currentTimeMillis());
|
||||
return user;
|
||||
}
|
||||
|
||||
public int updateUserPassword(EditPassWordRequest request) {
|
||||
User user = updateUserPwd(request);
|
||||
return extUserMapper.updatePassword(user);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -200,12 +201,8 @@ public class WorkspaceService {
|
|||
}
|
||||
|
||||
public void updateWorkspaceMember(WorkspaceMemberDTO memberDTO) {
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(memberDTO, user);
|
||||
userMapper.updateByPrimaryKeySelective(user);
|
||||
//
|
||||
String workspaceId = memberDTO.getWorkspaceId();
|
||||
String userId = user.getId();
|
||||
String userId = memberDTO.getId();
|
||||
// 已有角色
|
||||
List<Role> memberRoles = extUserRoleMapper.getWorkspaceMemberRoles(workspaceId, userId);
|
||||
// 修改后的角色
|
||||
|
@ -234,11 +231,11 @@ public class WorkspaceService {
|
|||
}
|
||||
}
|
||||
|
||||
public Integer checkSourceRole(String orgId, String userId, String roleId) {
|
||||
return extOrganizationMapper.checkSourceRole(orgId, userId, roleId);
|
||||
public Integer checkSourceRole(String workspaceId, String userId, String roleId) {
|
||||
return extOrganizationMapper.checkSourceRole(workspaceId, userId, roleId);
|
||||
}
|
||||
|
||||
public void updateWorkspacebyAdmin(Workspace workspace) {
|
||||
public void updateWorkspaceByAdmin(Workspace workspace) {
|
||||
workspace.setCreateTime(null);
|
||||
workspace.setUpdateTime(System.currentTimeMillis());
|
||||
workspaceMapper.updateByPrimaryKeySelective(workspace);
|
||||
|
|
|
@ -30,4 +30,6 @@ user_email_is_null=User email cannot be null
|
|||
password_is_null=Password cannot be null
|
||||
workspace_not_exists=Workspace is not exists
|
||||
#api
|
||||
api_load_script_error="Load script error"
|
||||
api_load_script_error=Load script error
|
||||
user_id_already_exists=User ID already exists
|
||||
password_modification_failed=Password modification failed
|
|
@ -30,4 +30,6 @@ user_email_is_null=用户邮箱不能为空
|
|||
password_is_null=密码不能为空
|
||||
workspace_not_exists=工作空间不存在
|
||||
#api
|
||||
api_load_script_error="读取脚本失败"
|
||||
api_load_script_error=读取脚本失败
|
||||
user_id_already_exists=用户id已存在
|
||||
password_modification_failed=密码修改失败
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="container" v-loading="result.loading">
|
||||
<div class="main-content">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" :title="$t('commons.test')"
|
||||
:show-create="false"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="container" v-loading="result.loading">
|
||||
<div class="main-content">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" :title="$t('commons.test')"
|
||||
@create="create" :createTip="$t('load_test.create')"/>
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
</span>
|
||||
<template v-slot:dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="personal">个人信息</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">退出系统</el-dropdown-item>
|
||||
<el-dropdown-item command="personal">{{$t('commons.personal_information')}}</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">{{$t('commons.exit_system')}}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
@ -51,7 +51,7 @@
|
|||
TokenKey,
|
||||
WORKSPACE_ID
|
||||
} from '../../../../common/js/constants';
|
||||
import {hasRoles, saveLocalStorage} from "../../../../common/js/utils";
|
||||
import {getCurrentUser, hasRoles, saveLocalStorage} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
|
@ -62,23 +62,21 @@
|
|||
data() {
|
||||
return {
|
||||
organizationList: [
|
||||
{index: '7-1', name: '无组织'},
|
||||
{name: this.$t('organization.none')},
|
||||
],
|
||||
workspaceList: [
|
||||
{index: '2-1', name: '无工作空间'},
|
||||
{name: this.$t('workspace.none')},
|
||||
],
|
||||
currentUserInfo: {},
|
||||
currentUserId: JSON.parse(localStorage.getItem(TokenKey)).id,
|
||||
currentUserId: getCurrentUser().id,
|
||||
workspaceIds: [],
|
||||
currentOrganizationName: '选择组织',
|
||||
currentWorkspaceName: '选择工作空间'
|
||||
currentOrganizationName: this.$t('organization.select'),
|
||||
currentWorkspaceName: this.$t('workspace.select')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
// window.console.log(user);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -115,7 +113,7 @@
|
|||
this.$get("/workspace/list/orgworkspace/", response => {
|
||||
let data = response.data;
|
||||
if (data.length === 0) {
|
||||
this.workspaceList = [{index: '1-1', name: '无工作区间'}]
|
||||
this.workspaceList = [{name: this.$t('workspace.none')}]
|
||||
} else {
|
||||
this.workspaceList = data;
|
||||
let workspace = data.filter(r => r.id === this.currentUser.lastWorkspaceId);
|
||||
|
@ -124,7 +122,6 @@
|
|||
localStorage.setItem(WORKSPACE_ID, workspace[0].id);
|
||||
}
|
||||
}
|
||||
// this.workspaceIds = response.data.map(r = r.id);
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -135,11 +132,14 @@
|
|||
},
|
||||
changeOrg(data) {
|
||||
let orgId = data.id;
|
||||
if (!orgId) {
|
||||
return false;
|
||||
}
|
||||
this.$post("/user/switch/source/org/" + orgId, {}, response => {
|
||||
saveLocalStorage(response);
|
||||
this.$router.push('/');
|
||||
window.location.reload();
|
||||
})
|
||||
});
|
||||
},
|
||||
changeWs(data) {
|
||||
let workspaceId = data.id;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="container" v-loading="result.loading">
|
||||
|
||||
<div class="main-content">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<div>
|
||||
<el-row type="flex" justify="space-between" align="middle">
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-tabs type="border-card" :stretch="true">
|
||||
<el-tab-pane v-for="(item, key) in logContent" :key="key" :label="key" class="logging-content">
|
||||
{{item.substring(0, 2048) }}...
|
||||
<el-tab-pane v-for="item in logContent" :key="item.id" :label="item.resourceName" class="logging-content">
|
||||
{{item.content}}...
|
||||
<el-link type="primary" @click="downloadLogFile(item)">{{$t('load_test.download_log_file')}}</el-link>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
@ -25,21 +25,28 @@
|
|||
this.logContent = res.data;
|
||||
})
|
||||
},
|
||||
downloadLogFile(content) {
|
||||
const filename = 'jmeter.log'
|
||||
const blob = new Blob([content]);
|
||||
if ("download" in document.createElement("a")) {
|
||||
// 非IE下载
|
||||
// chrome/firefox
|
||||
let aTag = document.createElement('a');
|
||||
aTag.download = filename;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(aTag.href)
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
downloadLogFile(item) {
|
||||
let config = {
|
||||
url: '/performance/report/log/download/' + item.id,
|
||||
method: 'get',
|
||||
responseType: 'blob'
|
||||
};
|
||||
this.result = this.$request(config).then(response => {
|
||||
const filename = 'jmeter.log'
|
||||
const blob = new Blob([response.data]);
|
||||
if ("download" in document.createElement("a")) {
|
||||
// 非IE下载
|
||||
// chrome/firefox
|
||||
let aTag = document.createElement('a');
|
||||
aTag.download = filename;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(aTag.href)
|
||||
} else {
|
||||
// IE10+下载
|
||||
navigator.msSaveBlob(blob, filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="container" v-loading="result.loading">
|
||||
<div class="main-content">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<div>
|
||||
<el-row type="flex" justify="space-between" align="middle">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="container">
|
||||
<div class="main-content">
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" @create="create"
|
||||
:create-tip="btnTips" :title="title"/>
|
||||
|
@ -44,11 +44,11 @@
|
|||
<script>
|
||||
import MsCreateBox from "../settings/CreateBox";
|
||||
import {Message} from "element-ui";
|
||||
import {TokenKey} from "../../../common/js/constants";
|
||||
import MsTablePagination from "../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../common/components/MsTableHeader";
|
||||
import MsTableOperator from "../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../common/components/MsDialogFooter";
|
||||
import {getCurrentUser} from "../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsProject",
|
||||
|
@ -97,8 +97,7 @@
|
|||
},
|
||||
computed: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import {TokenKey} from "../../../common/js/constants";
|
||||
import {getCurrentUser} from "../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsCurrentUser",
|
||||
|
@ -30,8 +30,7 @@
|
|||
},
|
||||
computed: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.member')"/>
|
||||
|
@ -65,13 +65,13 @@
|
|||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
<el-input v-model="form.name" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="form.email" autocomplete="off"/>
|
||||
<el-input v-model="form.email" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="form.phone" autocomplete="off"/>
|
||||
<el-input v-model="form.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="form.roleIds" multiple :placeholder="$t('role.please_choose_role')" class="select-width">
|
||||
|
@ -95,12 +95,12 @@
|
|||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsOrganizationMember",
|
||||
|
@ -134,8 +134,7 @@
|
|||
},
|
||||
methods: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
},
|
||||
initTableData() {
|
||||
let param = {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="list" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.workspace')"/>
|
||||
|
@ -112,13 +112,13 @@
|
|||
<el-input v-model="memberForm.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="memberForm.name" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.name" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="memberForm.email" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.email" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="memberForm.phone" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="memberForm.roleIds" multiple :placeholder="$t('role.please_choose_role')"
|
||||
|
@ -145,12 +145,13 @@
|
|||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {Message} from "element-ui";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import {DEFAULT} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsOrganizationWorkspace",
|
||||
|
@ -160,8 +161,7 @@
|
|||
},
|
||||
computed: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -197,6 +197,12 @@
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$get('/workspace/delete/' + row.id, () => {
|
||||
let lastWorkspaceId = getCurrentWorkspaceId();
|
||||
let sourceId = row.id;
|
||||
if (lastWorkspaceId === sourceId) {
|
||||
let sign = DEFAULT;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.list();
|
||||
});
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-card>
|
||||
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<div>
|
||||
<el-row type="flex" justify="space-between" align="middle">
|
||||
<el-row type="flex" just ify="space-between" align="middle">
|
||||
<span class="title">{{$t('commons.personal_info')}}</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!--Personal information menu-->
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID"/>
|
||||
<el-table-column prop="name" :label="$t('commons.username')" width="120"/>
|
||||
|
@ -22,54 +22,80 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<ms-table-operator-button :tip="$t('member.edit_information')" icon="el-icon-edit"
|
||||
type="primary" @exec="edit(scope.row)"/>
|
||||
<ms-table-operator-button :tip="$t('member.edit_password')" icon="el-icon-s-tools"
|
||||
type="success" @exec="editPassword(scope.row)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog :title="$t('member.modify_personal_info')" :visible.sync="updateVisible" width="30%"
|
||||
:destroy-on-close="true" @close="handleClose">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule"
|
||||
ref="updateUserForm">
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="form.email" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="form.phone" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.password')" prop="password">
|
||||
<el-input v-model="form.password" autocomplete="off" show-password/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="updateVisible = false"
|
||||
@confirm="updateUser('updateUserForm')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</el-card>
|
||||
|
||||
<!--Modify personal details-->
|
||||
<el-dialog :title="$t('member.modify_personal_info')" :visible.sync="updateVisible" width="30%"
|
||||
:destroy-on-close="true" @close="handleClose">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule"
|
||||
ref="updateUserForm">
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="form.email" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="form.phone" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="updateVisible = false"
|
||||
@confirm="updateUser('updateUserForm')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!--Change personal password-->
|
||||
<el-dialog :title="$t('member.edit_password')" :visible.sync="editPasswordVisible" width="30%" left>
|
||||
<el-form :model="ruleForm" :rules="rules" ref="editPasswordForm" label-width="100px" class="demo-ruleForm">
|
||||
<el-form-item :label="$t('member.old_password')" prop="password">
|
||||
<el-input v-model="ruleForm.password" autocomplete="off" show-password/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('member.new_password')" prop="newpassword">
|
||||
<el-input v-model="ruleForm.newpassword" autocomplete="off" show-password/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<ms-dialog-footer
|
||||
@cancel="editPasswordVisible = false"
|
||||
@confirm="updatePassword('editPasswordForm')"/>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
|
||||
export default {
|
||||
name: "MsPersonSetting",
|
||||
components: {MsDialogFooter, MsTableOperatorButton},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
updateVisible: false,
|
||||
editPasswordVisible: false,
|
||||
tableData: [],
|
||||
updatePath: '/user/update/current',
|
||||
updatePasswordPath: '/user/update/password',
|
||||
form: {},
|
||||
ruleForm: {},
|
||||
rule: {
|
||||
name: [
|
||||
{required: true, message: this.$t('member.input_name'), trigger: 'blur'},
|
||||
|
@ -98,32 +124,44 @@
|
|||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
},
|
||||
rules:{
|
||||
password: [
|
||||
{required: true, message: this.$t('user.input_password'), trigger: 'blur'},
|
||||
{
|
||||
required:true,
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
newpassword: [
|
||||
{required: true, message: this.$t('user.input_password'), trigger: 'blur'},
|
||||
{
|
||||
required: true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "MsPersonSetting",
|
||||
components: {MsDialogFooter},
|
||||
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
methods: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
},
|
||||
edit(row) {
|
||||
this.updateVisible = true;
|
||||
this.form = Object.assign({}, row);
|
||||
},
|
||||
editPassword(row) {
|
||||
this.editPasswordVisible = true;
|
||||
},
|
||||
updateUser(updateUserForm) {
|
||||
this.$refs[updateUserForm].validate(valide => {
|
||||
if (valide) {
|
||||
|
@ -139,6 +177,20 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
updatePassword(editPasswordForm) {
|
||||
this.$refs[editPasswordForm].validate(valide => {
|
||||
if (valide) {
|
||||
this.result = this.$post(this.updatePasswordPath, this.ruleForm, response => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.editPasswordVisible = false;
|
||||
this.initTableData();
|
||||
window.location.reload();
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
initTableData() {
|
||||
this.result = this.$get("/user/info/" + this.currentUser().id, response => {
|
||||
let data = response.data;
|
||||
|
@ -149,6 +201,7 @@
|
|||
},
|
||||
handleClose() {
|
||||
this.form = {};
|
||||
this.ruleForm = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.organization')"/>
|
||||
|
@ -138,13 +138,13 @@
|
|||
<el-input v-model="memberForm.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="memberForm.name" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.name" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="memberForm.email" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.email" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="memberForm.phone" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="memberForm.roleIds" multiple :placeholder="$t('role.please_choose_role')"
|
||||
|
@ -175,6 +175,8 @@
|
|||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentOrganizationId, getCurrentUser, refreshSessionAndCookies} from "../../../../common/js/utils";
|
||||
import {DEFAULT, ORGANIZATION} from "../../../../common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "MsOrganization",
|
||||
|
@ -311,6 +313,12 @@
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get(this.deletePath + row.id, () => {
|
||||
let lastOrganizationId = getCurrentOrganizationId();
|
||||
let sourceId = row.id;
|
||||
if (lastOrganizationId === sourceId) {
|
||||
let sign = DEFAULT;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.initTableData();
|
||||
});
|
||||
|
@ -325,6 +333,13 @@
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get('/user/special/org/member/delete/' + this.currentRow.id + '/' + row.id, () => {
|
||||
let sourceId = this.currentRow.id;
|
||||
let currentUser = getCurrentUser();
|
||||
let userId = row.id;
|
||||
if (currentUser.id === userId) {
|
||||
let sign = ORGANIZATION;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.delete_success'))
|
||||
this.cellClick(this.currentRow);
|
||||
});
|
||||
|
@ -395,6 +410,9 @@
|
|||
organizationId: this.currentRow.id
|
||||
};
|
||||
this.result = this.$post("user/special/org/member/add", param, () => {
|
||||
let sign = "other";
|
||||
let sourceId = this.currentRow.id;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
this.cellClick(this.currentRow);
|
||||
this.dialogOrgMemberAddVisible = false;
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="list" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.workspace')"/>
|
||||
|
@ -156,13 +156,13 @@
|
|||
<el-input v-model="memberForm.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="memberForm.name" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.name" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="memberForm.email" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.email" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="memberForm.phone" autocomplete="off"/>
|
||||
<el-input v-model="memberForm.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="memberForm.roleIds" multiple :placeholder="$t('role.please_choose_role')"
|
||||
|
@ -195,6 +195,8 @@
|
|||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
|
||||
import {DEFAULT, WORKSPACE} from "../../../../common/js/constants";
|
||||
|
||||
export default {
|
||||
name: "MsSystemWorkspace",
|
||||
|
@ -307,6 +309,12 @@
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$get('/workspace/special/delete/' + row.id, () => {
|
||||
let lastWorkspaceId = getCurrentWorkspaceId();
|
||||
let sourceId = row.id;
|
||||
if (lastWorkspaceId === sourceId) {
|
||||
let sign = DEFAULT;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
Message.success(this.$t('commons.delete_success'));
|
||||
this.list();
|
||||
});
|
||||
|
@ -374,6 +382,13 @@
|
|||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.result = this.$get('/user/special/ws/member/delete/' + this.currentWorkspaceRow.id + '/' + row.id, () => {
|
||||
let sourceId = this.currentWorkspaceRow.id;
|
||||
let userId = row.id;
|
||||
let user = getCurrentUser();
|
||||
if (user.id === userId) {
|
||||
let sign = WORKSPACE;
|
||||
refreshSessionAndCookies(sign, sourceId);
|
||||
}
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.cellClick(this.currentWorkspaceRow);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
|
||||
<el-card>
|
||||
<div>
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.test_resource_pool')"/>
|
||||
|
@ -46,11 +45,11 @@
|
|||
:total="total"/>
|
||||
</el-card>
|
||||
|
||||
<el-dialog v-loading="result.loading"
|
||||
:title="$t('test_resource_pool.create_resource_pool')"
|
||||
:visible.sync="createVisible" width="70%"
|
||||
@closed="closeFunc"
|
||||
:destroy-on-close="true">
|
||||
<el-dialog
|
||||
:title="$t('test_resource_pool.create_resource_pool')"
|
||||
:visible.sync="createVisible" width="70%"
|
||||
@closed="closeFunc"
|
||||
:destroy-on-close="true">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule"
|
||||
ref="createTestResourcePoolForm">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="search" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.member')"/>
|
||||
</template>
|
||||
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column type="selection" width="55"/>
|
||||
<el-table-column prop="id" label="ID"/>
|
||||
|
@ -30,16 +31,21 @@
|
|||
</el-table-column>
|
||||
<el-table-column :label="$t('commons.operating')">
|
||||
<template v-slot:default="scope">
|
||||
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="del(scope.row)"/>
|
||||
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="del(scope.row)">
|
||||
<template v-slot:behind>
|
||||
<ms-table-operator-button :tip="$t('member.edit_password')" icon="el-icon-s-tools"
|
||||
type="success" @exec="editPassword(scope.row)"/>
|
||||
</template>
|
||||
</ms-table-operator>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
:total="total"/>
|
||||
|
||||
</el-card>
|
||||
|
||||
<!--Create user-->
|
||||
<el-dialog :title="$t('user.create')" :visible.sync="createVisible" width="30%" @closed="handleClose"
|
||||
:destroy-on-close="true">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule" ref="createUserForm">
|
||||
|
@ -66,6 +72,7 @@
|
|||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!--Modify user information in system settings-->
|
||||
<el-dialog :title="$t('user.modify')" :visible.sync="updateVisible" width="30%" :destroy-on-close="true"
|
||||
@close="handleClose">
|
||||
<el-form :model="form" label-position="right" label-width="100px" size="small" :rules="rule" ref="updateUserForm">
|
||||
|
@ -81,10 +88,6 @@
|
|||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="form.phone" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.password')" prop="password">
|
||||
<el-input v-model="form.password" autocomplete="off" show-password/>
|
||||
</el-form-item>
|
||||
<!--<el-input placeholder="请输入密码" v-model="input" show-password></el-input>-->
|
||||
</el-form>
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
|
@ -92,6 +95,22 @@
|
|||
@confirm="updateUser('updateUserForm')"/>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!--Changing user password in system settings-->
|
||||
<el-dialog :title="$t('member.edit_password')" :visible.sync="editPasswordVisible" width="30%" left>
|
||||
<el-form :model="ruleForm" label-position="right" label-width="100px" size="small" :rules="rule" ref="editPasswordForm" class="demo-ruleForm">
|
||||
<el-form-item :label="$t('member.new_password')" prop="newpassword">
|
||||
<el-input type="password" v-model="ruleForm.newpassword" autocomplete="off" show-password></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item >
|
||||
<el-input v-model="ruleForm.id" autocomplete="off" :disabled="true" style="display:none"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<ms-dialog-footer
|
||||
@cancel="editPasswordVisible = false"
|
||||
@confirm="editUserPassword('editPasswordForm')"/>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
@ -102,20 +121,22 @@
|
|||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
|
||||
|
||||
export default {
|
||||
name: "MsUser",
|
||||
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsTableOperator, MsDialogFooter},
|
||||
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsTableOperator, MsDialogFooter, MsTableOperatorButton},
|
||||
data() {
|
||||
return {
|
||||
/*input:'',*/
|
||||
queryPath: '/user/special/list',
|
||||
deletePath: '/user/special/delete/',
|
||||
createPath: '/user/special/add',
|
||||
updatePath: '/user/special/update',
|
||||
editPasswordPath: '/user/special/password',
|
||||
result: {},
|
||||
createVisible: false,
|
||||
updateVisible: false,
|
||||
editPasswordVisible:false,
|
||||
multipleSelection: [],
|
||||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
|
@ -124,6 +145,7 @@
|
|||
condition: {},
|
||||
tableData: [],
|
||||
form: {},
|
||||
ruleForm: {},
|
||||
rule: {
|
||||
id: [
|
||||
{required: true, message: this.$t('user.input_id'), trigger: 'blur'},
|
||||
|
@ -164,6 +186,15 @@
|
|||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
newpassword: [
|
||||
{required: true, message: this.$t('user.input_password'), trigger: 'blur'},
|
||||
{
|
||||
required:true,
|
||||
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[^]{8,16}$/,
|
||||
message: this.$t('member.password_format_is_incorrect'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +210,10 @@
|
|||
this.updateVisible = true;
|
||||
this.form = Object.assign({}, row);
|
||||
},
|
||||
editPassword(row){
|
||||
this.editPasswordVisible=true;
|
||||
this.ruleForm = Object.assign({}, row);
|
||||
},
|
||||
del(row) {
|
||||
this.$confirm(this.$t('user.delete_confirm'), '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
|
@ -219,6 +254,20 @@
|
|||
}
|
||||
})
|
||||
},
|
||||
editUserPassword(editPasswordForm){
|
||||
this.$refs[editPasswordForm].validate(valide=>{
|
||||
if(valide){
|
||||
this.result = this.$post(this.editPasswordPath, this.ruleForm, response => {
|
||||
this.$success(this.$t('commons.modify_success'));
|
||||
this.editPasswordVisible = false;
|
||||
this.search() ;
|
||||
window.location.reload();
|
||||
});
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
},
|
||||
search() {
|
||||
this.result = this.$post(this.buildPagePath(this.queryPath), this.condition, response => {
|
||||
let data = response.data;
|
||||
|
@ -245,5 +294,4 @@
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div v-loading="result.loading">
|
||||
<el-card>
|
||||
<el-card class="table-card">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" @create="create"
|
||||
:create-tip="btnTips" :title="$t('commons.member')"/>
|
||||
|
@ -66,13 +66,13 @@
|
|||
<el-input v-model="form.id" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.username')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
<el-input v-model="form.name" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.email')" prop="email">
|
||||
<el-input v-model="form.email" autocomplete="off"/>
|
||||
<el-input v-model="form.email" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.phone')" prop="phone">
|
||||
<el-input v-model="form.phone" autocomplete="off"/>
|
||||
<el-input v-model="form.phone" autocomplete="off" :disabled="true"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="form.roleIds" multiple :placeholder="$t('role.please_choose_role')" class="select-width">
|
||||
|
@ -97,12 +97,12 @@
|
|||
|
||||
<script>
|
||||
import MsCreateBox from "../CreateBox";
|
||||
import {TokenKey} from "../../../../common/js/constants";
|
||||
import MsTablePagination from "../../common/pagination/TablePagination";
|
||||
import MsTableHeader from "../../common/components/MsTableHeader";
|
||||
import MsRolesTag from "../../common/components/MsRolesTag";
|
||||
import MsTableOperator from "../../common/components/MsTableOperator";
|
||||
import MsDialogFooter from "../../common/components/MsDialogFooter";
|
||||
import {getCurrentUser} from "../../../../common/js/utils";
|
||||
|
||||
export default {
|
||||
name: "MsMember",
|
||||
|
@ -136,8 +136,7 @@
|
|||
},
|
||||
methods: {
|
||||
currentUser: () => {
|
||||
let user = localStorage.getItem(TokenKey);
|
||||
return JSON.parse(user);
|
||||
return getCurrentUser();
|
||||
},
|
||||
initTableData() {
|
||||
if (this.currentUser().lastWorkspaceId === null) {
|
||||
|
|
|
@ -115,6 +115,7 @@
|
|||
|
||||
.el-dialog__body {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.download-template {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
|
||||
<div>
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
<template>
|
||||
|
||||
<div v-loading="result.loading">
|
||||
<el-input :placeholder="$t('test_track.module.search')" v-model="filterText"
|
||||
size="small">
|
||||
<el-input :placeholder="$t('test_track.module.search')" v-model="filterText" size="small">
|
||||
<template v-if="type == 'edit'" v-slot:append>
|
||||
<el-button icon="el-icon-folder-add" @click="openEditNodeDialog('add')"></el-button>
|
||||
</template>
|
||||
|
@ -17,100 +15,130 @@
|
|||
:expand-on-click-node="false"
|
||||
highlight-current
|
||||
draggable
|
||||
ref="tree">
|
||||
|
||||
ref="tree"
|
||||
>
|
||||
<template v-slot:default="{node,data}">
|
||||
|
||||
<span class="custom-tree-node father" @click="handleNodeSelect(node)">
|
||||
<span class="node-icon">
|
||||
<i class="el-icon-folder"></i>
|
||||
</span>
|
||||
|
||||
<span>{{node.label}}</span>
|
||||
<span class="node-title">{{node.label}}</span>
|
||||
|
||||
<el-dropdown v-if="type == 'edit'" class="node-dropdown child">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-folder-add"></i>
|
||||
</span>
|
||||
<el-dropdown-menu v-slot:default>
|
||||
<el-dropdown-item>
|
||||
<div @click="openEditNodeDialog('edit', data)">{{$t('test_track.module.rename')}}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div @click="openEditNodeDialog('add', data)">{{$t('test_track.module.add_submodule')}}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div @click="remove(node, data)">{{$t('commons.delete')}}</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<span v-if="type == 'edit'" class="node-operate child">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
open-delay="200"
|
||||
:content="$t('test_track.module.rename')"
|
||||
placement="top"
|
||||
>
|
||||
<i @click="openEditNodeDialog('edit', data)" class="el-icon-edit"></i>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
open-delay="200"
|
||||
:content="$t('test_track.module.add_submodule')"
|
||||
placement="top"
|
||||
>
|
||||
<i @click="openEditNodeDialog('add', data)" class="el-icon-circle-plus-outline"></i>
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark"
|
||||
open-delay="200" :content="$t('commons.delete')" placement="top">
|
||||
<i @click="remove(node, data)" class="el-icon-delete"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
|
||||
<!-- <el-dropdown v-if="type == 'edit'" class="node-dropdown child">
|
||||
<span class="el-dropdown-link">
|
||||
<i class="el-icon-folder-add"></i>
|
||||
</span>
|
||||
<el-dropdown-menu v-slot:default>
|
||||
<el-dropdown-item>
|
||||
<div @click="openEditNodeDialog('edit', data)">{{$t('test_track.module.rename')}}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div
|
||||
@click="openEditNodeDialog('add', data)"
|
||||
>{{$t('test_track.module.add_submodule')}}</div>
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item>
|
||||
<div @click="remove(node, data)">{{$t('commons.delete')}}</div>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>-->
|
||||
</span>
|
||||
|
||||
</template>
|
||||
</el-tree>
|
||||
|
||||
<node-edit ref="nodeEdit" :tree-nodes="treeNodes" @refresh="refreshNode"/>
|
||||
|
||||
<node-edit ref="nodeEdit" :tree-nodes="treeNodes" @refresh="refreshNode" />
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NodeEdit from "./NodeEdit";
|
||||
|
||||
import NodeEdit from './NodeEdit';
|
||||
|
||||
export default {
|
||||
name: "NodeTree",
|
||||
components: {NodeEdit},
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
filterText: '',
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'view'
|
||||
},
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
selectNode: {
|
||||
type: Object
|
||||
export default {
|
||||
name: "NodeTree",
|
||||
components: { NodeEdit },
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
filterText: "",
|
||||
defaultProps: {
|
||||
children: "children",
|
||||
label: "label"
|
||||
}
|
||||
};
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: "view"
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
treeNodes: {
|
||||
type: Array
|
||||
},
|
||||
methods: {
|
||||
handleDragEnd(draggingNode, dropNode, dropType, ev) {
|
||||
let param = {};
|
||||
param.id = draggingNode.data.id;
|
||||
if (dropType === 'inner') {
|
||||
param.parentId = dropNode.data.id;
|
||||
param.level = dropNode.data.level + 1;
|
||||
selectNode: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.tree.filter(val);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleDragEnd(draggingNode, dropNode, dropType, ev) {
|
||||
let param = {};
|
||||
param.id = draggingNode.data.id;
|
||||
if (dropType === "inner") {
|
||||
param.parentId = dropNode.data.id;
|
||||
param.level = dropNode.data.level + 1;
|
||||
} else {
|
||||
if (dropNode.parent.id === 0) {
|
||||
param.parentId = 0;
|
||||
param.level = 1;
|
||||
} else {
|
||||
if (dropNode.parent.id === 0) {
|
||||
param.parentId = 0;
|
||||
param.level = 1;
|
||||
} else {
|
||||
param.parentId = dropNode.parent.data.id;
|
||||
param.level = dropNode.parent.data.level + 1;
|
||||
}
|
||||
param.parentId = dropNode.parent.data.id;
|
||||
param.level = dropNode.parent.data.level + 1;
|
||||
}
|
||||
this.$post('/case/node/edit', param);
|
||||
},
|
||||
remove(node, data) {
|
||||
this.$alert(this.$t('test_track.module.delete_confirm') + data.label + "," +
|
||||
this.$t('test_track.module.delete_all_resource') + "?", '', {
|
||||
confirmButtonText: this.$t('commons.confirm'),
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
}
|
||||
this.$post("/case/node/edit", param);
|
||||
},
|
||||
remove(node, data) {
|
||||
this.$alert(
|
||||
this.$t("test_track.module.delete_confirm") +
|
||||
data.label +
|
||||
"," +
|
||||
this.$t("test_track.module.delete_all_resource") +
|
||||
"?",
|
||||
"",
|
||||
{
|
||||
confirmButtonText: this.$t("commons.confirm"),
|
||||
callback: action => {
|
||||
if (action === "confirm") {
|
||||
let nodeIds = [];
|
||||
this.getChildNodeId(node, nodeIds);
|
||||
this.$post("/case/node/delete", nodeIds, () => {
|
||||
|
@ -118,81 +146,94 @@
|
|||
const children = parent.data.children || parent.data;
|
||||
const index = children.findIndex(d => d.id === data.id);
|
||||
children.splice(index, 1);
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.$success(this.$t("commons.delete_success"));
|
||||
this.$emit("refresh");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
handleNodeSelect(node) {
|
||||
let nodeIds = [];
|
||||
let nodeNames = [];
|
||||
this.getChildNodeId(node, nodeIds);
|
||||
this.getParentNodeName(node, nodeNames);
|
||||
this.$emit("nodeSelectEvent", nodeIds, nodeNames);
|
||||
this.$emit("update:selectNode", node);
|
||||
},
|
||||
getChildNodeId(rootNode, nodeIds) {
|
||||
//递归获取所有子节点ID
|
||||
nodeIds.push(rootNode.data.id);
|
||||
for (let i = 0; i < rootNode.childNodes.length; i++) {
|
||||
this.getChildNodeId(rootNode.childNodes[i], nodeIds);
|
||||
}
|
||||
},
|
||||
getParentNodeName(rootNode, nodeNames) {
|
||||
if (rootNode.parent && rootNode.parent.id != 0) {
|
||||
this.getParentNodeName(rootNode.parent, nodeNames)
|
||||
}
|
||||
if (rootNode.data.name && rootNode.data.name != '') {
|
||||
nodeNames.push(rootNode.data.name);
|
||||
}
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
openEditNodeDialog(type, data) {
|
||||
this.$refs.nodeEdit.open(type, data);
|
||||
},
|
||||
refreshNode() {
|
||||
this.$emit('refresh');
|
||||
);
|
||||
},
|
||||
handleNodeSelect(node) {
|
||||
let nodeIds = [];
|
||||
let nodeNames = [];
|
||||
this.getChildNodeId(node, nodeIds);
|
||||
this.getParentNodeName(node, nodeNames);
|
||||
this.$emit("nodeSelectEvent", nodeIds, nodeNames);
|
||||
this.$emit("update:selectNode", node);
|
||||
},
|
||||
getChildNodeId(rootNode, nodeIds) {
|
||||
//递归获取所有子节点ID
|
||||
nodeIds.push(rootNode.data.id);
|
||||
for (let i = 0; i < rootNode.childNodes.length; i++) {
|
||||
this.getChildNodeId(rootNode.childNodes[i], nodeIds);
|
||||
}
|
||||
},
|
||||
getParentNodeName(rootNode, nodeNames) {
|
||||
if (rootNode.parent && rootNode.parent.id != 0) {
|
||||
this.getParentNodeName(rootNode.parent, nodeNames);
|
||||
}
|
||||
if (rootNode.data.name && rootNode.data.name != "") {
|
||||
nodeNames.push(rootNode.data.name);
|
||||
}
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) return true;
|
||||
return data.label.indexOf(value) !== -1;
|
||||
},
|
||||
openEditNodeDialog(type, data) {
|
||||
this.$refs.nodeEdit.open(type, data);
|
||||
},
|
||||
refreshNode() {
|
||||
this.$emit("refresh");
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.el-dropdown-link {
|
||||
cursor: pointer;
|
||||
color: #409EFF;
|
||||
}
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
}
|
||||
.custom-tree-node {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 14px;
|
||||
padding-right: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
.node-tree {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.node-tree {
|
||||
margin-top: 15px;
|
||||
}
|
||||
.father .child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.father .child {
|
||||
display: none;
|
||||
}
|
||||
.father:hover .child {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.father:hover .child {
|
||||
display: block;
|
||||
}
|
||||
.node-title {
|
||||
width: 0px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1 1 auto;
|
||||
padding: 0px 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.node-operate > i {
|
||||
color: #409eff;
|
||||
margin: 0px 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="container">
|
||||
<el-main class="main-content">
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" @create="testPlanCreate"
|
||||
:create-tip="$t('test_track.plan.create_plan')" :title="$t('test_track.plan.test_plan')"/>
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
<el-dialog :title="$t('test_track.plan_view.relevance_test_case')"
|
||||
:visible.sync="dialogFormVisible"
|
||||
@close="close"
|
||||
width="50%">
|
||||
width="60%"
|
||||
top="50px">
|
||||
|
||||
<el-container class="main-content">
|
||||
<el-aside class="tree-aside" width="250px">
|
||||
|
@ -18,12 +19,13 @@
|
|||
|
||||
<el-container>
|
||||
<el-main class="case-content" v-loading="result.loading">
|
||||
<el-scrollbar>
|
||||
<!-- <el-scrollbar> -->
|
||||
<el-table
|
||||
:data="testCases"
|
||||
row-key="id"
|
||||
@select-all="handleSelectAll"
|
||||
@select="handleSelectionChange"
|
||||
height="70vh"
|
||||
ref="table">
|
||||
|
||||
<el-table-column
|
||||
|
@ -38,7 +40,7 @@
|
|||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-scrollbar>
|
||||
<!-- </el-scrollbar> -->
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
@ -185,17 +187,18 @@
|
|||
}
|
||||
|
||||
.case-content {
|
||||
height: 500px;
|
||||
padding: 0px 20px;
|
||||
height: 100%;
|
||||
/*border: 1px solid #EBEEF5;*/
|
||||
}
|
||||
|
||||
.tree-aside {
|
||||
min-height: 300px;
|
||||
max-height: 100%;
|
||||
}
|
||||
.main-content {
|
||||
min-height: 300px;
|
||||
/*border: 1px solid #EBEEF5;*/
|
||||
}
|
||||
|
||||
.el-scrollbar {
|
||||
height: 100%;
|
||||
/*border: 1px solid #EBEEF5;*/
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card v-loading="result.loading">
|
||||
<el-card class="table-card" v-loading="result.loading">
|
||||
<template v-slot:header>
|
||||
<ms-table-header :condition.sync="condition" @search="initTableData" :show-create="false">
|
||||
<template v-slot:title>
|
||||
|
|
|
@ -32,3 +32,7 @@ body {
|
|||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.table-card > .el-card__body {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
|
|
@ -8,3 +8,8 @@ export const ROLE_TEST_VIEWER = 'test_viewer';
|
|||
|
||||
export const WORKSPACE_ID = 'workspace_id';
|
||||
export const CURRENT_PROJECT = 'current_project';
|
||||
|
||||
export const REFRESH_SESSION_USER_URL = 'user/refresh';
|
||||
export const WORKSPACE = 'workspace';
|
||||
export const ORGANIZATION = 'organization';
|
||||
export const DEFAULT = 'default';
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import {ROLE_ORG_ADMIN, ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER, TokenKey} from "./constants";
|
||||
import {
|
||||
REFRESH_SESSION_USER_URL,
|
||||
ROLE_ORG_ADMIN,
|
||||
ROLE_TEST_MANAGER,
|
||||
ROLE_TEST_USER,
|
||||
ROLE_TEST_VIEWER,
|
||||
TokenKey
|
||||
} from "./constants";
|
||||
import axios from "axios";
|
||||
|
||||
export function hasRole(role) {
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
let user = getCurrentUser();
|
||||
let roles = user.roles.map(r => r.id);
|
||||
return roles.indexOf(role) > -1;
|
||||
}
|
||||
|
||||
export function hasRoles(...roles) {
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
let user = getCurrentUser();
|
||||
let rs = user.roles.map(r => r.id);
|
||||
for (let item of roles) {
|
||||
if (rs.indexOf(item) > -1) {
|
||||
|
@ -18,17 +26,31 @@ export function hasRoles(...roles) {
|
|||
}
|
||||
|
||||
export function checkoutCurrentOrganization() {
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
let user = getCurrentUser();
|
||||
// 查看当前用户是否是 lastOrganizationId 的组织管理员
|
||||
return user.userRoles.filter(ur => hasRole(ROLE_ORG_ADMIN) && user.lastOrganizationId === ur.sourceId).length > 0;
|
||||
}
|
||||
|
||||
export function checkoutCurrentWorkspace() {
|
||||
let user = JSON.parse(localStorage.getItem(TokenKey));
|
||||
let user = getCurrentUser();
|
||||
// 查看当前用户是否是 lastWorkspaceId 的工作空间用户
|
||||
return user.userRoles.filter(ur => hasRoles(ROLE_TEST_MANAGER, ROLE_TEST_USER, ROLE_TEST_VIEWER) && user.lastWorkspaceId === ur.sourceId).length > 0;
|
||||
}
|
||||
|
||||
export function getCurrentOrganizationId() {
|
||||
let user = getCurrentUser();
|
||||
return user.lastOrganizationId;
|
||||
}
|
||||
|
||||
export function getCurrentWorkspaceId() {
|
||||
let user = getCurrentUser();
|
||||
return user.lastWorkspaceId;
|
||||
}
|
||||
|
||||
export function getCurrentUser() {
|
||||
return JSON.parse(localStorage.getItem(TokenKey));
|
||||
}
|
||||
|
||||
export function saveLocalStorage(response) {
|
||||
// 登录信息保存 cookie
|
||||
localStorage.setItem(TokenKey, JSON.stringify(response.data));
|
||||
|
@ -38,19 +60,26 @@ export function saveLocalStorage(response) {
|
|||
localStorage.setItem("roles", roles);
|
||||
}
|
||||
|
||||
export function refreshSessionAndCookies(sign, sourceId) {
|
||||
axios.post(REFRESH_SESSION_USER_URL + "/" + sign + "/" + sourceId).then(r => {
|
||||
saveLocalStorage(r.data);
|
||||
window.location.reload();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function jsonToMap(jsonStr) {
|
||||
let obj = JSON.parse(jsonStr);
|
||||
let strMap = new Map();
|
||||
for (let k of Object.keys(obj)) {
|
||||
strMap.set(k,obj[k]);
|
||||
strMap.set(k, obj[k]);
|
||||
}
|
||||
return strMap;
|
||||
}
|
||||
|
||||
export function mapToJson(strMap){
|
||||
let obj= Object.create(null);
|
||||
for (let[k,v] of strMap) {
|
||||
export function mapToJson(strMap) {
|
||||
let obj = Object.create(null);
|
||||
for (let [k, v] of strMap) {
|
||||
obj[k] = v;
|
||||
}
|
||||
return JSON.stringify(obj);
|
||||
|
@ -58,5 +87,5 @@ export function mapToJson(strMap){
|
|||
|
||||
// 驼峰转换下划线
|
||||
export function humpToLine(name) {
|
||||
return name.replace(/([A-Z])/g,"_$1").toLowerCase();
|
||||
return name.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ export default {
|
|||
'delete': 'Delete',
|
||||
'not_filled': 'Not filled',
|
||||
'search_by_name': 'Search by name',
|
||||
'personal_information': 'Personal Information',
|
||||
'exit_system': 'Exit System',
|
||||
},
|
||||
workspace: {
|
||||
'create': 'Create Workspace',
|
||||
|
@ -62,6 +64,8 @@ export default {
|
|||
'organization_name': 'Organization Name',
|
||||
'please_choose_organization': 'Please Choose Organization',
|
||||
'please_select_a_workspace_first': 'Please select a workspace first!',
|
||||
'none': 'None Workspace',
|
||||
'select': 'Select Workspace',
|
||||
},
|
||||
organization: {
|
||||
'create': 'Create',
|
||||
|
@ -71,6 +75,8 @@ export default {
|
|||
'select_organization': 'Please select organization',
|
||||
'search_by_name': 'Search by name',
|
||||
'special_characters_are_not_supported': 'Special characters are not supported',
|
||||
'none': 'None Organization',
|
||||
'select': 'Select Organization',
|
||||
},
|
||||
project: {
|
||||
'recent': 'Recent Projects',
|
||||
|
@ -89,12 +95,16 @@ export default {
|
|||
'please_choose_member': 'Please Choose Member',
|
||||
'search_by_name': 'Search by name',
|
||||
'modify_personal_info': 'Modify Personal Information',
|
||||
'edit_password':'Edit_Password',
|
||||
'edit_information':'Edit_Information',
|
||||
'input_name': 'Please enter a user name',
|
||||
'input_email': 'Please enter a email',
|
||||
'special_characters_are_not_supported': 'Special characters are not supported',
|
||||
'mobile_number_format_is_incorrect': 'Mobile number format is incorrect',
|
||||
'email_format_is_incorrect': 'Email format is incorrect',
|
||||
'password_format_is_incorrect': 'Password format is incorrect (At least 8-16 characters, at least 1 uppercase letter, 1 lowercase letter and 1 number)',
|
||||
'old_password':'Old Password',
|
||||
'new_password':'New Password',
|
||||
},
|
||||
user: {
|
||||
'create': 'Create',
|
||||
|
@ -399,7 +409,7 @@ export default {
|
|||
'fill_the_data': 'Please complete the data',
|
||||
'delete_prompt': 'This operation will permanently delete the resource pool, continue?',
|
||||
'status_change_success': 'Successfully changed the status!',
|
||||
'status_change_failed': 'Failed to change the status!',
|
||||
'status_change_failed': 'Failed to change the status, resource pool is invalid!',
|
||||
},
|
||||
i18n: {
|
||||
'home': 'Home'
|
||||
|
|
|
@ -53,6 +53,8 @@ export default {
|
|||
'not_filled': '未填写',
|
||||
'please_select': '请选择',
|
||||
'search_by_name': '根据名称搜索',
|
||||
'personal_information': '个人信息',
|
||||
'exit_system': '退出系统',
|
||||
},
|
||||
workspace: {
|
||||
'create': '创建工作空间',
|
||||
|
@ -64,6 +66,8 @@ export default {
|
|||
'organization_name': '所属组织',
|
||||
'please_choose_organization': '请选择组织',
|
||||
'please_select_a_workspace_first': '请先选择工作空间!',
|
||||
'none': '无工作空间',
|
||||
'select': '选择工作空间',
|
||||
},
|
||||
organization: {
|
||||
'create': '创建组织',
|
||||
|
@ -73,6 +77,8 @@ export default {
|
|||
'select_organization': '请选择组织',
|
||||
'search_by_name': '根据名称搜索',
|
||||
'special_characters_are_not_supported': '不支持特殊字符',
|
||||
'none': '无组织',
|
||||
'select': '选择组织',
|
||||
},
|
||||
project: {
|
||||
'recent': '最近的项目',
|
||||
|
@ -91,12 +97,16 @@ export default {
|
|||
'please_choose_member': '请选择成员',
|
||||
'search_by_name': '根据名称搜索',
|
||||
'modify_personal_info': '修改个人信息',
|
||||
'edit_password': '修改密码',
|
||||
'edit_information': '编辑信息',
|
||||
'input_name': '请输入名称',
|
||||
'input_email': '请输入邮箱',
|
||||
'special_characters_are_not_supported': '不支持特殊字符',
|
||||
'mobile_number_format_is_incorrect': '手机号码格式不正确',
|
||||
'email_format_is_incorrect': '邮箱格式不正确',
|
||||
'password_format_is_incorrect': '密码格式不正确(至少8-16个字符,至少1个大写字母,1个小写字母和1个数字)',
|
||||
'old_password': '旧密码',
|
||||
'new_password': '新密码',
|
||||
},
|
||||
user: {
|
||||
'create': '创建用户',
|
||||
|
@ -400,7 +410,7 @@ export default {
|
|||
'fill_the_data': '请完善数据',
|
||||
'delete_prompt': '此操作将永久删除该资源池, 是否继续?',
|
||||
'status_change_success': '状态修改成功!',
|
||||
'status_change_failed': '状态修改失败!',
|
||||
'status_change_failed': '状态修改失败, 校验不通过!',
|
||||
},
|
||||
i18n: {
|
||||
'home': '首页'
|
||||
|
|
Loading…
Reference in New Issue