ソースを参照

自定义菜单相关功能开发

lideyin 5 年 前
コミット
726f3d66a2

+ 130 - 45
examcloud-core-basic-api-provider/src/main/java/cn/com/qmth/examcloud/core/basic/api/controller/OrgController.java

@@ -1,49 +1,5 @@
 package cn.com.qmth.examcloud.core.basic.api.controller;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.persistence.criteria.Predicate;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Hex;
-import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.fileupload.disk.DiskFileItem;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.multipart.commons.CommonsMultipartFile;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
 import cn.com.qmth.examcloud.api.commons.exchange.PageInfo;
 import cn.com.qmth.examcloud.api.commons.security.bean.User;
 import cn.com.qmth.examcloud.commons.exception.ExamCloudRuntimeException;
@@ -82,7 +38,37 @@ import cn.com.qmth.examcloud.web.redis.RedisClient;
 import cn.com.qmth.examcloud.web.support.ApiId;
 import cn.com.qmth.examcloud.web.support.ControllerSupport;
 import cn.com.qmth.examcloud.web.support.Naked;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.jpa.domain.Specification;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import javax.persistence.criteria.Predicate;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * {@link StatusException} 状态码范围:001XXX<br>
@@ -1187,7 +1173,6 @@ public class OrgController extends ControllerSupport {
 	 * 方法注释
 	 *
 	 * @author WANGWEI
-	 * @param id
 	 * @param request
 	 * @param file
 	 * @throws IOException
@@ -1318,4 +1303,104 @@ public class OrgController extends ControllerSupport {
 		return map;
 	}
 
+	/**
+	 * 导入自定义菜单logo
+	 *
+	 * @author lideyin
+	 * @param request
+	 * @param file
+	 * @throws IOException
+	 */
+	@ApiOperation(value = "导入自定义菜单logo", notes = "导入自定义菜单logo")
+	@PostMapping("importCusMenuLogo/{orgId}")
+	@Transactional
+	public String importCusMenuLogo(@PathVariable Long orgId, HttpServletRequest request,
+							 @RequestParam CommonsMultipartFile file) throws IOException {
+
+		OrgEntity orgEntity = GlobalHelper.getEntity(orgRepo, orgId, OrgEntity.class);
+		if (null == orgEntity) {
+			throw new StatusException("140002", "orgEntity is null");
+		}
+
+		validateRootOrgIsolation(orgEntity.getRootId());
+
+		DiskFileItem fileItem = (DiskFileItem) file.getFileItem();
+		File storeLocation = fileItem.getStoreLocation();
+		String name = file.getOriginalFilename();
+
+		System.out.println(storeLocation.length());
+		if (999999 < storeLocation.length()) {
+			throw new StatusException("140082", "文件过大");
+		}
+
+		String fileSuffix = null;
+		if (name.endsWith(".jpg")) {
+			fileSuffix = ".jpg";
+		} else if (name.endsWith(".gif")) {
+			fileSuffix = ".gif";
+		} else if (name.endsWith(".png")) {
+			fileSuffix = ".png";
+		} else {
+			throw new StatusException("101001", "文件格式错误");
+		}
+
+		byte[] byteArray = null;
+		InputStream inputStream = null;
+		try {
+			inputStream = new FileInputStream(storeLocation);
+			byteArray = IOUtils.toByteArray(inputStream);
+		} finally {
+			IOUtils.closeQuietly(inputStream);
+		}
+
+		String hexString = Hex.encodeHexString(byteArray);
+
+		DynamicEnumManager manager = OrgProperty.getDynamicEnumManager();
+		DynamicEnum logoFile = manager.getByName("CUS_MENU_LOGO_FILE");
+		DynamicEnum logoFileSuffix = manager.getByName("CUS_MENU_LOGO_FILE_SUFFIX");
+		DynamicEnum logoFileUrl = manager.getByName("CUS_MENU_LOGO_FILE_URL");
+
+		OrgPropertyEntity fileEntity = orgPropertyRepo.findByOrgIdAndKeyId(orgId, logoFile.getId());
+		if (null == fileEntity) {
+			fileEntity = new OrgPropertyEntity();
+			fileEntity.setKeyId(logoFile.getId());
+			fileEntity.setOrgId(orgId);
+		}
+		fileEntity.setValue(hexString);
+		orgPropertyRepo.save(fileEntity);
+
+		OrgPropertyEntity fileSuffixEntity = orgPropertyRepo.findByOrgIdAndKeyId(orgId,
+				logoFileSuffix.getId());
+		if (null == fileSuffixEntity) {
+			fileSuffixEntity = new OrgPropertyEntity();
+			fileSuffixEntity.setKeyId(logoFileSuffix.getId());
+			fileSuffixEntity.setOrgId(orgId);
+		}
+		fileSuffixEntity.setValue(fileSuffix);
+		orgPropertyRepo.save(fileSuffixEntity);
+
+		String path = systemConfig.getTempDataDir() + "/cusMenuLogo/" + orgId
+				+ fileSuffixEntity.getValue();
+
+		FileUtils.copyFile(storeLocation, new File(path));
+
+		//通用存储
+		FileStoragePathEnvInfo env=new FileStoragePathEnvInfo();
+		env.setFileSuffix(fileSuffix);
+		env.setRootOrgId(orgEntity.getRootId().toString());
+		YunPathInfo pi=FileStorageUtil.saveFile("orgLogo", env, storeLocation,null);
+		String url =pi.getUrl();
+
+		OrgPropertyEntity logoFileUrlEntity = orgPropertyRepo.findByOrgIdAndKeyId(orgId,
+				logoFileUrl.getId());
+		if (null == logoFileUrlEntity) {
+			logoFileUrlEntity = new OrgPropertyEntity();
+			logoFileUrlEntity.setKeyId(logoFileUrl.getId());
+			logoFileUrlEntity.setOrgId(orgId);
+		}
+		logoFileUrlEntity.setValue(url);
+		orgPropertyRepo.save(logoFileUrlEntity);
+
+		return url;
+	}
 }

+ 22 - 10
examcloud-core-basic-api-provider/src/main/java/cn/com/qmth/examcloud/core/basic/api/controller/RolePrivilegeController.java

@@ -7,6 +7,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import cn.com.qmth.examcloud.core.basic.api.controller.bean.*;
 import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -30,11 +31,6 @@ import cn.com.qmth.examcloud.api.commons.security.enums.RoleMeta;
 import cn.com.qmth.examcloud.commons.exception.StatusException;
 import cn.com.qmth.examcloud.commons.util.RegExpUtil;
 import cn.com.qmth.examcloud.core.basic.api.bean.RoleBean;
-import cn.com.qmth.examcloud.core.basic.api.controller.bean.PrivilegeDomain;
-import cn.com.qmth.examcloud.core.basic.api.controller.bean.PrivilegeGroupDomain;
-import cn.com.qmth.examcloud.core.basic.api.controller.bean.RoleDomain;
-import cn.com.qmth.examcloud.core.basic.api.controller.bean.UpdateRolePrivilegeRelationsDomain;
-import cn.com.qmth.examcloud.core.basic.api.controller.bean.UpdateRootOrgPrivilegeRelationsDomain;
 import cn.com.qmth.examcloud.core.basic.base.constants.BasicConsts;
 import cn.com.qmth.examcloud.core.basic.dao.PrivilegeGroupRepo;
 import cn.com.qmth.examcloud.core.basic.dao.PrivilegeRepo;
@@ -258,7 +254,7 @@ public class RolePrivilegeController extends ControllerSupport {
 	 * 2020年2月19日
 	 *
 	 * @author WANGWEI
-	 * @param groupId
+	 * @param rootOrgId
 	 * @param includeDisabledCodes
 	 * @return
 	 */
@@ -266,12 +262,13 @@ public class RolePrivilegeController extends ControllerSupport {
 	@GetMapping("getStudentClientMenuTree/{rootOrgId}")
 	@GlobalSequenceLock
 	@Transactional
-	public EleTreeNode getStudentClientMenuTree(@PathVariable Long rootOrgId,
-			@RequestParam(required = false) Boolean includeDisabledCodes) {
+	public OrgPrivilegeTreeDomain getStudentClientMenuTree(@PathVariable Long rootOrgId,
+														   @RequestParam(required = false) Boolean includeDisabledCodes) {
 
 		PrivilegeGroupEntity group = privilegeGroupRepo.findByRootOrgIdAndType(rootOrgId,
 				PrivilegeGroupType.STUDENT_CLIENT_MENU);
 
+		//如果考生自定义菜单未初始化,默认初始化一份
 		if (null == group) {
 			PrivilegeGroupEntity globalGroup = privilegeGroupRepo
 					.findByCode(PrivilegeGroupType.STUDENT_CLIENT_MENU.name());
@@ -316,6 +313,8 @@ public class RolePrivilegeController extends ControllerSupport {
 				PrivilegeEntity saved = privilegeRepo.save(privilegeEntity);
 				privilegeList.add(saved);
 
+				privilegeIdSet.add(saved.getId());
+
 			}
 
 			for (int i = 0; i < globalPrivilegeList.size(); i++) {
@@ -347,7 +346,20 @@ public class RolePrivilegeController extends ControllerSupport {
 			TreeUtil.convert2OneEleTreeNode(rootNode, privilegeList, disabledPrivilegeCodeList);
 		}
 
-		return rootNode;
+		OrgPrivilegeTreeDomain domain= new OrgPrivilegeTreeDomain();
+		domain.setPrivilegeGroupId(group.getId());
+		domain.setPrivilegeGroupType(group.getType().name());
+		domain.setTreeData(rootNode);
+
+		List<RootOrgPrivilegeRelationEntity> roprlist = rootOrgPrivilegeRelationRepo
+				.findAllByRootOrgIdAndGroupId(rootOrgId, group.getId());
+
+		List<Long> pList = roprlist.stream().map(RootOrgPrivilegeRelationEntity::getPrivilegeId)
+				.collect(Collectors.toList());
+
+		domain.setOwnedPrivilegeIds(pList);
+
+		return domain;
 	}
 
 	/**
@@ -400,7 +412,7 @@ public class RolePrivilegeController extends ControllerSupport {
 		List<PrivilegeDomain> privilegeInfoList = Lists.newArrayList();
 
 		for (PrivilegeEntity cur : privilegeList) {
-			boolean hasPrivilege = undefined ? true : pList.contains(cur.getId());
+			boolean hasPrivilege = undefined ? true : (pList!=null && pList.contains(cur.getId()));
 
 			if (!hasPrivilege) {
 				continue;

+ 73 - 0
examcloud-core-basic-api-provider/src/main/java/cn/com/qmth/examcloud/core/basic/api/controller/bean/OrgPrivilegeTreeDomain.java

@@ -0,0 +1,73 @@
+package cn.com.qmth.examcloud.core.basic.api.controller.bean;
+
+import cn.com.qmth.examcloud.api.commons.enums.PrivilegeGroupType;
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+import cn.com.qmth.examcloud.web.helpers.tree.EleTreeNode;
+import cn.com.qmth.examcloud.web.helpers.tree.TreeNode;
+import java.util.List;
+
+import java.util.Date;
+
+/**
+ * @Description 组织机构权限树
+ * @Author lideyin
+ * @Date 2020/5/11 15:50
+ * @Version 1.0
+ */
+public class OrgPrivilegeTreeDomain implements JsonSerializable {
+
+	private static final long serialVersionUID = 6079872470102312782L;
+
+
+	/**
+	 * 权限组ID
+	 */
+	private Long privilegeGroupId;
+
+	/**
+	 * 权限组类型
+	 */
+	private String privilegeGroupType;
+
+	/**
+	 * 组织机构拥有的权限id
+	 */
+	private List<Long> ownedPrivilegeIds;
+
+	/**
+	 * 权限树
+	 */
+	private EleTreeNode treeData;
+
+	public Long getPrivilegeGroupId() {
+		return privilegeGroupId;
+	}
+
+	public void setPrivilegeGroupId(Long privilegeGroupId) {
+		this.privilegeGroupId = privilegeGroupId;
+	}
+
+	public String getPrivilegeGroupType() {
+		return privilegeGroupType;
+	}
+
+	public void setPrivilegeGroupType(String privilegeGroupType) {
+		this.privilegeGroupType = privilegeGroupType;
+	}
+
+	public EleTreeNode getTreeData() {
+		return treeData;
+	}
+
+	public void setTreeData(EleTreeNode treeData) {
+		this.treeData = treeData;
+	}
+
+	public List<Long> getOwnedPrivilegeIds() {
+		return ownedPrivilegeIds;
+	}
+
+	public void setOwnedPrivilegeIds(List<Long> ownedPrivilegeIds) {
+		this.ownedPrivilegeIds = ownedPrivilegeIds;
+	}
+}

+ 6 - 0
examcloud-core-basic-starter/src/main/resources/org-properties.xml

@@ -150,4 +150,10 @@
 		<desc>机构自定义菜单图标URL</desc>
 		<valueType>STRING</valueType>
 	</enum>
+	<enum>
+		<id>25</id>
+		<name>IS_CUSTOM_MENU_LOGO</name>
+		<desc>机构是否自定义菜单</desc>
+		<valueType>BOOLEAN</valueType>
+	</enum>
 </enums>