stjdydayou 4 år sedan
förälder
incheckning
95e6d08462

+ 14 - 0
pom.xml

@@ -32,6 +32,9 @@
         <okhttp.version>4.9.3</okhttp.version>
 
 
+        <afirma-lib-jmimemagic.version>0.0.6</afirma-lib-jmimemagic.version>
+        <thumbnailator.version>0.4.14</thumbnailator.version>
+
         <framework.version>1.0.18</framework.version>
         <db-migration.version>1.0.0</db-migration.version>
     </properties>
@@ -121,6 +124,17 @@
             <artifactId>okhttp</artifactId>
             <version>${okhttp.version}</version>
         </dependency>
+
+        <dependency>
+            <groupId>es.gob.afirma.lib</groupId>
+            <artifactId>afirma-lib-jmimemagic</artifactId>
+            <version>${afirma-lib-jmimemagic.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>net.coobird</groupId>
+            <artifactId>thumbnailator</artifactId>
+            <version>${thumbnailator.version}</version>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 68 - 63
src/main/java/com/zhiqiyun/open/config/WebMvcConfig.java

@@ -11,6 +11,7 @@ import com.zhiqiyun.open.core.enmus.IBaseEnum;
 import com.zhiqiyun.open.utils.ServletContext;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@@ -36,68 +37,72 @@ import java.util.List;
 @Configuration
 public class WebMvcConfig extends DelegatingWebMvcConfiguration {
 
-    @Autowired
-    private OauthInterceptor oauthInterceptor;
-
-    @Override
-    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
-        registry.addResourceHandler("/**").addResourceLocations("classpath:/public/");
-        super.addResourceHandlers(registry);
-    }
-
-    @Override
-    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
-        converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
-        ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
-
-        objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
-
-        SimpleModule module = new SimpleModule();
-        module.addSerializer(IBaseEnum.class, new JsonSerializer<IBaseEnum>() {
-            @Override
-            public void serialize(IBaseEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
-                gen.writeStartObject();
-                gen.writeObjectField("value", value.getValue());
-                gen.writeStringField("text", value.getText());
-                gen.writeStringField("name", value.getName());
-                gen.writeEndObject();
-            }
-        });
-        objectMapper.registerModule(module);
-
-        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
-        converters.add(converter);
-        log.info("{}", converters.size());
-        super.configureMessageConverters(converters);
-    }
-
-
-    @Override
-    public void addInterceptors(InterceptorRegistry registry) {
-        registry.addInterceptor(new HandlerInterceptor() {
-            @Override
-            public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) {
-                ServletContext.init(request, response);
-                return true;
-            }
-
-            @Override
-            public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) {
-                ServletContext.clean();
-            }
-        }).addPathPatterns("/**").excludePathPatterns("/static/**", "/index.html");
-        registry.addInterceptor(this.oauthInterceptor).addPathPatterns("/**").excludePathPatterns("/static/**", "/index.html");
-        super.addInterceptors(registry);
-    }
-
-    @Override
-    public void addCorsMappings(CorsRegistry registry) {
-        registry.addMapping("/**")
-                .allowedOriginPatterns("*")
-                .allowCredentials(true)
-                .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
-                .maxAge(3600);
-        super.addCorsMappings(registry);
-    }
+	@Value("${uploader.save-path}")
+	private String uploaderSavePath;
+
+	@Autowired
+	private OauthInterceptor oauthInterceptor;
+
+	@Override
+	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
+		registry.addResourceHandler("/**").addResourceLocations("classpath:/public/");
+		registry.addResourceHandler("/src/**").addResourceLocations(String.format("file:%s/", this.uploaderSavePath));
+		super.addResourceHandlers(registry);
+	}
+
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);
+		ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build();
+
+		objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
+
+		SimpleModule module = new SimpleModule();
+		module.addSerializer(IBaseEnum.class, new JsonSerializer<IBaseEnum>() {
+			@Override
+			public void serialize(IBaseEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+				gen.writeStartObject();
+				gen.writeObjectField("value", value.getValue());
+				gen.writeStringField("text", value.getText());
+				gen.writeStringField("name", value.getName());
+				gen.writeEndObject();
+			}
+		});
+		objectMapper.registerModule(module);
+
+		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
+		converters.add(converter);
+		log.info("{}", converters.size());
+		super.configureMessageConverters(converters);
+	}
+
+
+	@Override
+	public void addInterceptors(InterceptorRegistry registry) {
+		registry.addInterceptor(new HandlerInterceptor() {
+			@Override
+			public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) {
+				ServletContext.init(request, response);
+				return true;
+			}
+
+			@Override
+			public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) {
+				ServletContext.clean();
+			}
+		}).addPathPatterns("/**").excludePathPatterns("/src/**", "/index.html");
+		registry.addInterceptor(this.oauthInterceptor).addPathPatterns("/**").excludePathPatterns("/src/**", "/index.html");
+		super.addInterceptors(registry);
+	}
+
+	@Override
+	public void addCorsMappings(CorsRegistry registry) {
+		registry.addMapping("/**")
+				.allowedOriginPatterns("*")
+				.allowCredentials(true)
+				.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH")
+				.maxAge(3600);
+		super.addCorsMappings(registry);
+	}
 }
 

+ 9 - 0
src/main/java/com/zhiqiyun/open/core/mapper/VenueInfoMapper.java

@@ -0,0 +1,9 @@
+package com.zhiqiyun.open.core.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zhiqiyun.open.core.models.bz.VenueInfo;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface VenueInfoMapper extends BaseMapper<VenueInfo> {
+}

+ 98 - 0
src/main/java/com/zhiqiyun/open/core/models/UploadResult.java

@@ -0,0 +1,98 @@
+package com.zhiqiyun.open.core.models;
+
+import java.io.Serializable;
+
+public class UploadResult implements Serializable {
+	private static final long serialVersionUID = -9105589442902748697L;
+
+	private Long id;
+
+	private boolean success;
+
+	private String message;
+
+	private String src;
+
+	private String domain;
+
+	private String extension;
+
+	private String mimeType;
+
+	public String getDomain() {
+		return domain;
+	}
+
+	public void setDomain(String domain) {
+		this.domain = domain;
+	}
+
+	private long size;
+
+	private String originalFileName;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public boolean isSuccess() {
+		return success;
+	}
+
+	public void setSuccess(boolean success) {
+		this.success = success;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	public String getExtension() {
+		return extension;
+	}
+
+	public void setExtension(String extension) {
+		this.extension = extension;
+	}
+
+	public String getMimeType() {
+		return mimeType;
+	}
+
+	public void setMimeType(String mimeType) {
+		this.mimeType = mimeType;
+	}
+
+	public long getSize() {
+		return size;
+	}
+
+	public void setSize(long size) {
+		this.size = size;
+	}
+
+	public String getSrc() {
+		return src;
+	}
+
+	public void setSrc(String src) {
+		this.src = src;
+	}
+
+	public String getOriginalFileName() {
+		return originalFileName;
+	}
+
+	public void setOriginalFileName(String originalFileName) {
+		this.originalFileName = originalFileName;
+	}
+
+}

+ 29 - 0
src/main/java/com/zhiqiyun/open/core/models/bz/VenueInfo.java

@@ -0,0 +1,29 @@
+package com.zhiqiyun.open.core.models.bz;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.zhiqiyun.open.core.typeHandler.FastjsonTypeHandler;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Data
+@TableName(value = "bz_venue_info", autoResultMap = true)
+public class VenueInfo {
+	@TableId(type = IdType.INPUT)
+	private Long id;
+	private String name;
+	@TableField(typeHandler = FastjsonTypeHandler.class)
+	private List<String> litpics;
+	private String describe;
+	private String brief;
+	private String address;
+	private String contacts;
+	private String contactNumber;
+	private String businessHours;
+	private BigDecimal lng;
+	private BigDecimal lat;
+}

+ 7 - 0
src/main/java/com/zhiqiyun/open/core/service/VenueInfoService.java

@@ -0,0 +1,7 @@
+package com.zhiqiyun.open.core.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhiqiyun.open.core.models.bz.VenueInfo;
+
+public interface VenueInfoService extends IService<VenueInfo> {
+}

+ 11 - 0
src/main/java/com/zhiqiyun/open/core/service/impl/VenueInfoServiceImpl.java

@@ -0,0 +1,11 @@
+package com.zhiqiyun.open.core.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhiqiyun.open.core.mapper.VenueInfoMapper;
+import com.zhiqiyun.open.core.models.bz.VenueInfo;
+import com.zhiqiyun.open.core.service.VenueInfoService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class VenueInfoServiceImpl extends ServiceImpl<VenueInfoMapper, VenueInfo> implements VenueInfoService {
+}

+ 136 - 0
src/main/java/com/zhiqiyun/open/mvc/manager/controller/UploaderController.java

@@ -0,0 +1,136 @@
+package com.zhiqiyun.open.mvc.manager.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.zhiqiyun.open.annotation.Permission;
+import com.zhiqiyun.open.core.models.UploadResult;
+import com.zhiqiyun.open.exception.UploadException;
+import com.zhiqiyun.open.mvc.Result;
+import com.zhiqiyun.open.mvc.manager.params.UploaderBase64Param;
+import com.zhiqiyun.open.utils.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import net.coobird.thumbnailator.Thumbnails;
+import net.sf.jmimemagic.Magic;
+import net.sf.jmimemagic.MagicMatch;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping
+public class UploaderController {
+
+	@Value("${uploader.max-size}")
+	private long maxSize;
+
+	@Value("${uploader.file-host}")
+	private String fileHost;
+
+	@Value("${uploader.allow-file-types}")
+	private String[] allowExtensions;
+
+	@Value("${uploader.save-path}")
+	private String savePath;
+
+
+	@Permission(tags = "上传图片")
+	@PostMapping(value = "/uploader/handle/base64File")
+	public Object handleBase64File(@RequestBody UploaderBase64Param param) throws IOException {
+
+		if (StringUtils.isBlank(param.getBase64File())) {
+			log.warn("没有添加上传文件");
+			return Result.instance("没有添加上传文件");
+		}
+		byte[] fileBuff = Base64.decodeBase64(param.getBase64File());
+
+		String originalFilename = param.getFilename();
+		if (StringUtils.isBlank(originalFilename)) {
+			originalFilename = String.format("%s.%s", DigestUtils.md5Hex(fileBuff), "png");
+		}
+
+		UploadResult uploadResult = this.handle(originalFilename, fileBuff);
+		if (uploadResult.isSuccess()) {
+			return Result.instance(Result.Code.SUCCESS).setData(uploadResult);
+		} else {
+			return Result.instance(Result.Code.MESSAGE_ERROR, uploadResult.getMessage());
+		}
+	}
+
+	public UploadResult handle(String originalFilename, byte[] fileBuff) {
+		UploadResult result = new UploadResult();
+		result.setSuccess(false);
+		result.setOriginalFileName(originalFilename);
+		try {
+			// 验证文件件大小
+			if (fileBuff.length > maxSize * 1024) {
+				throw new UploadException("上传文件大小不能超过" + (maxSize / 1024) + "M");
+			}
+
+			MagicMatch magicMatch = Magic.getMagicMatch(fileBuff);
+
+			String extension = magicMatch.getExtension();
+			String mimeType = magicMatch.getMimeType();
+
+			// 验证文件类型
+			if (extension == null) {
+				throw new UploadException("无的文件扩展名,请重新上传");
+			}
+
+			extension = extension.toLowerCase();
+			List<String> listAllowExtensions = Arrays.asList(allowExtensions);
+			if (!listAllowExtensions.contains(extension)) {
+				throw new UploadException(String.format("只能上传%s类型的文件", String.join(",", allowExtensions)));
+			}
+
+			String filePath = String.format("%s/%s", savePath, DateUtil.format("yyyy/MM/dd"));
+			File fileDir = new File(filePath);
+			if (!fileDir.exists()) {
+				boolean mkdirResult = fileDir.mkdirs();
+				if (!mkdirResult) {
+					log.warn("mkdir save file path error {}", filePath);
+					throw new UploadException("创建上传目录失败");
+				}
+			}
+			filePath = String.format("%s/%s.%s", filePath, DigestUtils.md5Hex(fileBuff), extension);
+			File file = new File(filePath);
+
+
+			try {
+				ByteArrayInputStream in = new ByteArrayInputStream(fileBuff);
+				BufferedImage bi = ImageIO.read(in);
+				Thumbnails.of(bi).size(1200, 1200).toFile(file);
+			} catch (IOException e) {
+				log.warn("upload is not image file", e);
+				throw new UploadException("只能上传图片文件");
+			}
+
+			result.setSuccess(true);
+			result.setMessage("上传文件成功");
+			result.setMimeType(mimeType);
+			// 获取服务地址和端口
+			String url = filePath.replaceFirst(this.savePath, "");
+			result.setSrc(url);
+			result.setSize(fileBuff.length);
+			result.setExtension(extension);
+			result.setId(0L);
+		} catch (UploadException e) {
+			result.setMessage(e.getMessage());
+		} catch (Exception e) {
+			log.error("upload file error", e);
+			result.setMessage("服务异常,请稍后再试");
+		}
+		return result;
+	}
+}

+ 44 - 0
src/main/java/com/zhiqiyun/open/mvc/manager/controller/VenueInfoController.java

@@ -0,0 +1,44 @@
+package com.zhiqiyun.open.mvc.manager.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhiqiyun.open.annotation.Permission;
+import com.zhiqiyun.open.core.models.app.AppKeyInfo;
+import com.zhiqiyun.open.core.models.bz.VenueInfo;
+import com.zhiqiyun.open.core.service.VenueInfoService;
+import com.zhiqiyun.open.mvc.Result;
+import com.zhiqiyun.open.mvc.manager.params.QueryAppKeyInfoParams;
+import com.zhiqiyun.open.mvc.manager.params.QueryVenueInfoParams;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/bz/base/venue")
+public class VenueInfoController {
+
+	@Autowired
+	private VenueInfoService venueInfoService;
+
+	@Permission(value = "bz.base.venue.find", tags = "查询")
+	@PostMapping("/findPage")
+	public Result findPage(@RequestBody QueryVenueInfoParams params) {
+
+		QueryWrapper<VenueInfo> queryWrapper = new QueryWrapper<>();
+
+		if (StringUtils.isNotBlank(params.getContactNumber())) {
+			queryWrapper.like("contact_number", params.getContactNumber());
+		}
+
+		Page<VenueInfo> page = params.getPage();
+		page.addOrder(OrderItem.desc("id"));
+
+		Page<VenueInfo> resultData = this.venueInfoService.page(page, queryWrapper);
+
+		return Result.instance(Result.Code.SUCCESS).setData(resultData);
+	}
+}

+ 11 - 0
src/main/java/com/zhiqiyun/open/mvc/manager/params/QueryVenueInfoParams.java

@@ -0,0 +1,11 @@
+package com.zhiqiyun.open.mvc.manager.params;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class QueryVenueInfoParams extends QueryPageParams {
+	private String keyword;
+	private String contactNumber;
+}

+ 19 - 0
src/main/java/com/zhiqiyun/open/mvc/manager/params/UploaderBase64Param.java

@@ -0,0 +1,19 @@
+package com.zhiqiyun.open.mvc.manager.params;
+
+import lombok.Data;
+
+@Data
+public class UploaderBase64Param {
+	private String filename;
+	private String base64File;
+
+	public String getBase64File() {
+		if (this.base64File != null) {
+			String[] array = this.base64File.split("base64,");
+			if (array.length > 1) {
+				return array[1];
+			}
+		}
+		return base64File;
+	}
+}

+ 6 - 0
src/main/resources/application.properties

@@ -35,3 +35,9 @@ spring.oap.security.service-access-controller-class=com.zhiqiyun.open.router.con
 #spring.oap.upload.file-types=jpg,png,doc,zip
 #\u7CFB\u7EDF\u914D\u7F6E
 #spring.oap.service.timeout-seconds=60
+####################### uploader config ###############################
+uploader.max-size=20480000
+uploader.file-host=ss.zlanli.com
+uploader.allow-file-types=jpg,jpeg,png,gif
+uploader.save-path=/tmp/uploads
+

+ 24 - 12
src/main/resources/db/migration/V1.0.3__bz.sql

@@ -1,3 +1,27 @@
+DROP TABLE IF EXISTS `bz_venue_info`;
+CREATE TABLE `bz_venue_info`
+(
+    `id`             BIGINT(20) NOT NULL COMMENT 'ID',
+    `name`           VARCHAR(50)  NOT NULL COMMENT '名称',
+    `litpics`        VARCHAR(500) NOT NULL COMMENT '图片',
+    `describe`       VARCHAR(200) NOT NULL COMMENT '描述',
+    `brief`          VARCHAR(500) NOT NULL COMMENT '简介',
+    `address`        VARCHAR(100) NOT NULL COMMENT '地址',
+    `contacts`       VARCHAR(50)  NOT NULL COMMENT '联系人',
+    `contact_number` VARCHAR(50)  NOT NULL COMMENT '联系电话',
+    `business_hours` VARCHAR(200) NOT NULL COMMENT '开放时间',
+    `lng`            FLOAT        NOT NULL COMMENT '经度(坐标)',
+    `lat`            FLOAT        NOT NULL COMMENT '纬度(坐标)',
+    PRIMARY KEY (`id`)
+) COMMENT='场馆信息表' ENGINE=InnoDB;
+
+REPLACE INTO `authority_info` (`id`, `parent_id`, `name`, `remark`)
+VALUES (1400, 0, 'bz.base.venue', '场馆基本信息管理'),
+       (1401, 1400, 'bz.base.venue.find', '查询'),
+       (1402, 1400, 'bz.base.venue.add', '添加'),
+       (1403, 1400, 'bz.base.venue.edit', '修改'),
+       (1404, 1400, 'bz.base.venue.delete', '删除');
+
 DROP TABLE IF EXISTS `bz_weather_info`;
 CREATE TABLE `bz_weather_info`
 (
@@ -58,18 +82,6 @@ CREATE TABLE `bz_holiday_resort_info`
     PRIMARY KEY (`id`)
 ) COMMENT='度假区信息表' ENGINE=InnoDB;
 
-DROP TABLE IF EXISTS `bz_venue_info`;
-CREATE TABLE `bz_venue_info`
-(
-    `id`             BIGINT(30) NOT NULL COMMENT 'ID',
-    `name`           VARCHAR(50)  NOT NULL COMMENT '名称',
-    `address`        VARCHAR(50)  NOT NULL COMMENT '地址',
-    `summary`        VARCHAR(500) NOT NULL COMMENT '简介',
-    `business_hours` VARCHAR(200) NOT NULL COMMENT '开放时间',
-    `longitude`      FLOAT        NOT NULL COMMENT '取票地点',
-    `latitude`       FLOAT        NOT NULL COMMENT '排序值',
-    PRIMARY KEY (`id`)
-) COMMENT='场馆信息表' ENGINE=InnoDB;
 
 DROP TABLE IF EXISTS `bz_scenery_info`;
 CREATE TABLE `bz_scenery_info`