目录

1. springboot后端

1.1 FileController.java

 1.2 listener文件的ErpApplicationListener.java

1.3  【重点!】FileServiceImpl层

 1.4 IFileService

1.5 StringUtil通用类

 1.6 主程序加一个监听器

 1.7 oss是什么和怎么创建(application.yml文件)

2. 微信小程序端

2.1 TDesign的upload组件

1. app.json全局引用一下

2. wxml

3. js

1. springboot后端

具体框架如下所示:

接下来依次也是Controller层、listener层、service层、util层代码 

1.1 FileController.java

 如上图可以看到,微信小程序的请求url要传来一个type值,

controller全部代码如下,直接复制粘贴就行:

package com.huashang.controller;

import com.huashang.common.BaseController;

import com.huashang.service.IFileService;

import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.InputStream;

import java.io.OutputStream;

import java.math.BigDecimal;

import java.net.URL;

import java.net.URLConnection;

import java.net.URLEncoder;

@RestController

public class FileController extends BaseController {

@Resource

private IFileService fileService;

@RequestMapping(value = "/files/{type}", method = RequestMethod.POST)

public String uploadFile(@PathVariable String type ,HttpServletRequest request) throws Exception {

return fileService.uploadFiles(request, type);

}

}

 1.2 listener文件的ErpApplicationListener.java

你的主程序添加监听器

ErpApplicationListener代码如下:

实现了

ApplicationListener接口

重写了

onApplicationEvent方法

package com.huashang.listener;

import com.huashang.service.IFileService;

import org.springframework.context.ApplicationListener;

import org.springframework.context.event.ContextRefreshedEvent;

public class ErpApplicationListener implements ApplicationListener {

@Override

public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {

IFileService fileService = contextRefreshedEvent.getApplicationContext().getBean(IFileService.class);

fileService.initClient();

}

}

获取getBean的的IFileService.class

主要就是监听该类的调用

1.3  【重点!】FileServiceImpl层

FileServiceImpl是IFileService的实现类,先看实现类,接口放最后了

以下代码不要直接复制粘贴到serviceImpl层,是原始代码,需要修改并添加一个引用才能使用

package com.huashang.serviceImpl;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.time.LocalDate;

import java.util.Arrays;

import java.util.Date;

import java.util.List;

import java.util.Objects;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.springframework.util.MultiValueMap;

import org.springframework.web.multipart.MultipartFile;

import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.aliyun.oss.ClientException;

import com.aliyun.oss.OSSClient;

import com.aliyun.oss.OSSException;

import com.huashang.common.Constants;

import com.huashang.model.Alioss;

import com.huashang.service.IFileService;

import cn.hutool.core.date.DateUtil;

@Service

public class FileServiceImpl implements IFileService {

private Alioss alioss;

private final static List FILE_TYPE = Arrays.asList("product", "biz", "color", "qa", "mes_qa", "oa", "model");

@Autowired

public void setAlioss(Alioss alioss) {

this.alioss = alioss;

}

public static OSSClient ossClient;

private final static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);

@Override

public void initClient() {

// 实例化客户端

logger.info("**************************初始化阿里云文件上传服务服务端--START****************************");

ossClient = new OSSClient(alioss.getEndpoint(), alioss.getAccessKeyId(), alioss.getAcceddKeySecret());

logger.info("**************************初始化阿里云文件上传服务服务端--END****************************");

}

@Transactional

@Override

public String uploadFiles(HttpServletRequest request, String type) throws IOException {

String picUrl = "";

if (request instanceof MultipartHttpServletRequest) {

MultiValueMap multiMap = ((MultipartHttpServletRequest) request).getMultiFileMap();

Set keys = multiMap.keySet();

for (String key : keys) {

List mutiFiles = multiMap.get(key);

for (int i = 0; i < mutiFiles.size(); i++) {

if (!FILE_TYPE.contains(type)) {

return "可以上传的文件类型:" + FILE_TYPE.toString();

}

MultipartFile file = mutiFiles.get(i);

String originalFilename = this.getFileOldName(file);

LocalDate now = LocalDate.now();

String dir = type + "/" + now.getYear() + "/" + now.getMonthValue() + "/" + now.getDayOfMonth() + "/";

String path = dir + originalFilename;

try {

ossClient.putObject(alioss.getBucketName(), path, mutiFiles.get(i).getInputStream());

} catch (OSSException | ClientException | IOException e) {

e.printStackTrace();

}

if (mutiFiles.size() - i == 1) {

picUrl += "https://" + alioss.getUrl() + "/" + path;

} else {

picUrl += "https://" + alioss.getUrl() + "/" + path + ",";

}

}

}

}

return picUrl;

}

@Override

public String uploadTmpFile(String filePath, String fileName) throws FileNotFoundException {

StringBuilder dirBuilder = new StringBuilder("tmp/");

dirBuilder.append(DateUtil.format(new Date(), Constants.DATE_yyyyMMdd)).append("/");

StringBuilder fileLinkBuilder = new StringBuilder();

fileLinkBuilder.append("https://").append(alioss.getUrl()).append("/").append(dirBuilder.toString()).append(fileName);

ossClient.putObject(alioss.getBucketName(), dirBuilder.toString() + fileName, new FileInputStream(filePath + fileName));

return fileLinkBuilder.toString();

}

private String getFileOldName(MultipartFile file) {

return Objects.requireNonNull(file.getOriginalFilename()).replaceAll("[^a-zA-Z0-9.]", "^_^");

}

}

接下来教大家怎么修改文件

 看不清楚没关系,如下图片是你唯一需要修改的地方

以下代码直接复制粘贴到FileServiceImpl

package com.huashang.serviceImpl;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.time.LocalDate;

import java.util.Arrays;

import java.util.Date;

import java.util.List;

import java.util.Objects;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import com.huashang.util.StringUtil;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import org.springframework.util.MultiValueMap;

import org.springframework.web.multipart.MultipartFile;

import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.aliyun.oss.ClientException;

import com.aliyun.oss.OSSClient;

import com.aliyun.oss.OSSException;

import com.huashang.common.Constants;

import com.huashang.model.Alioss;

import com.huashang.service.IFileService;

import cn.hutool.core.date.DateUtil;

@Service

public class FileServiceImpl implements IFileService {

private Alioss alioss;

private final static List FILE_TYPE = Arrays.asList("product", "biz", "color", "qa", "mes_qa", "oa", "model");

@Autowired

public void setAlioss(Alioss alioss) {

this.alioss = alioss;

}

public static OSSClient ossClient;

private final static Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);

@Override

public void initClient() {

// 实例化客户端

logger.info("**************************初始化阿里云文件上传服务服务端--START****************************");

ossClient = new OSSClient(alioss.getEndpoint(), alioss.getAccessKeyId(), alioss.getAcceddKeySecret());

logger.info("**************************初始化阿里云文件上传服务服务端--END****************************");

}

@Transactional

@Override

public String uploadFiles(HttpServletRequest request, String type) throws IOException {

if(StringUtil.stringBlank(type)){

throw new RuntimeException("type must not be empty");

}

if(!Arrays.asList("user", "house", "project").contains(type)){

throw new RuntimeException("type is not supported");

}

StringBuilder picUrl = new StringBuilder();

if (request instanceof MultipartHttpServletRequest) {

MultiValueMap multiMap = ((MultipartHttpServletRequest) request).getMultiFileMap();

Set keys = multiMap.keySet();

for (String key : keys) {

List mutiFiles = multiMap.get(key);

for (int i = 0; i < mutiFiles.size(); i++) {

String fileOldName = StringUtil.getFileOldName(mutiFiles.get(i));

String fileName = StringUtil.randomString(20) + fileOldName;

String dir = type + "/" + DateUtil.format(new Date(), "yyMMddHH") + "/";

String path = dir + fileName;

try {

ossClient.putObject(alioss.getBucketName(), path, mutiFiles.get(i).getInputStream());

} catch (OSSException | ClientException | IOException e) {

e.printStackTrace();

}

if (mutiFiles.size() - i == 1) {

picUrl.append("https://").append(alioss.getUrl()).append("/").append(path);

} else {

picUrl.append("https://").append(alioss.getUrl()).append("/").append(path).append(",");

}

}

}

}

return picUrl.toString();

}

@Override

public String uploadTmpFile(String filePath, String fileName) throws FileNotFoundException {

StringBuilder dirBuilder = new StringBuilder("tmp/");

dirBuilder.append(DateUtil.format(new Date(), Constants.DATE_yyyyMMdd)).append("/");

StringBuilder fileLinkBuilder = new StringBuilder();

fileLinkBuilder.append("https://").append(alioss.getUrl()).append("/").append(dirBuilder.toString()).append(fileName);

ossClient.putObject(alioss.getBucketName(), dirBuilder.toString() + fileName, new FileInputStream(filePath + fileName));

return fileLinkBuilder.toString();

}

}

 1.4 IFileService

package com.huashang.service;

import java.io.FileNotFoundException;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

public interface IFileService {

void initClient();

String uploadFiles(HttpServletRequest request, String type) throws IOException;

String uploadTmpFile(String filePath, String fileName) throws FileNotFoundException;

}

1.5 StringUtil通用类

都是定义好的,复制粘贴就行

package com.huashang.util;

import java.math.BigDecimal;

import java.nio.charset.StandardCharsets;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.Random;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import org.springframework.stereotype.Component;

import org.springframework.web.multipart.MultipartFile;

@Component("stringUtil")

public class StringUtil {

private static final String ALL_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

private static final String ALL_NUMBERS = "0123456789";

/**

* 将换行处理为空

*

*/

public static String n2Null(String myString) {

if (myString == null) {

return myString;

}

String newString = null;

Pattern CRLF = Pattern.compile("(\r\n|\r|\n|\n\r)");

Matcher m = CRLF.matcher(myString);

if (m.find()) {

newString = m.replaceAll(" ");

} else {

newString = myString;

}

return newString;

}

public static String randomString(int length) {

StringBuffer sb = new StringBuffer();

Random random = new Random();

for (int i = 0; i < length; i++) {

sb.append(ALL_CHARS.charAt(random.nextInt(ALL_CHARS.length())));

}

return sb.toString();

}

public static String randomNumber(int length) {

StringBuffer sb = new StringBuffer();

Random random = new Random();

for (int i = 0; i < length; i++) {

sb.append(ALL_NUMBERS.charAt(random.nextInt(ALL_NUMBERS.length())));

}

return sb.toString();

}

public static boolean stringBlank(String str) {

return str == null || "".equals(str.trim());

}

public static String getFileOldName(MultipartFile file) {

return file.getOriginalFilename().replaceAll("[^a-zA-Z0-9.]", "^_^");

}

public static String humb2UnderLine(String s) {

if (s == null) {

return null;

}

StringBuilder sb = new StringBuilder();

boolean upperCase = false;

for (int i = 0; i < s.length(); i++) {

char c = s.charAt(i);

boolean nextUpperCase = true;

if (i < (s.length() - 1)) {

nextUpperCase = Character.isUpperCase(s.charAt(i + 1));

}

if (Character.isUpperCase(c)) {

if (!upperCase || !nextUpperCase) {

if (i > 0) {

sb.append("_");

}

}

upperCase = true;

} else {

upperCase = false;

}

sb.append(Character.toLowerCase(c));

}

return sb.toString();

}

public static String firstImage(String images) {

List ia = imageArray(images);

return ia.isEmpty() ? null : ia.get(0);

}

public static List imageArray(String images) {

List is = new ArrayList<>();

for (String i : split(images, ";")) {

if (!"".equals(i.trim())) {

is.add(i.trim());

}

}

return is;

}

public static List split(String images, String splitor) {

if (images == null || "".equals(images.trim())) {

return new ArrayList<>();

}

return Arrays.asList(images.split(splitor));

}

public static String nullString(Object obj) {

return obj == null ? "" : obj.toString();

}

/**

* 图片的字符串,将其中的eshangying的连接替换为支持https协议的简赢域名

* http://files.eshangying.com/2015-06-03/ctgge_518h0aZN0DL._UL1500_.jpg;

* esyfiles.lrerp.com

*/

public static String dealImageEwin2Jy(String images) {

if (StringUtil.stringBlank(images)) {

return images;

}

images = images.replace("files.eshangying.com", "esyfiles.lrerp.com");

return images;

}

/**

* 将字符串text中由openToken和closeToken组成的占位符依次替换为args数组中的值

*

* @param openToken

* @param closeToken

* @param text

* @param args

* @return

*/

public static String parseInner(String openToken, String closeToken, String text, Object... args) {

if (args == null || args.length <= 0) {

return text;

}

int argsIndex = 0;

if (text == null || text.isEmpty()) {

return "";

}

char[] src = text.toCharArray();

int offset = 0;

// search open token

int start = text.indexOf(openToken, offset);

if (start == -1) {

return text;

}

final StringBuilder builder = new StringBuilder();

StringBuilder expression = null;

while (start > -1) {

if (start > 0 && src[start - 1] == '\\') {

// this open token is escaped. remove the backslash and continue.

builder.append(src, offset, start - offset - 1).append(openToken);

offset = start + openToken.length();

} else {

// found open token. let's search close token.

if (expression == null) {

expression = new StringBuilder();

} else {

expression.setLength(0);

}

builder.append(src, offset, start - offset);

offset = start + openToken.length();

int end = text.indexOf(closeToken, offset);

while (end > -1) {

if (end > offset && src[end - 1] == '\\') {

// this close token is escaped. remove the backslash and continue.

expression.append(src, offset, end - offset - 1).append(closeToken);

offset = end + closeToken.length();

end = text.indexOf(closeToken, offset);

} else {

expression.append(src, offset, end - offset);

offset = end + closeToken.length();

break;

}

}

if (end == -1) {

// close token was not found.

builder.append(src, start, src.length - start);

offset = src.length;

} else {

///仅仅修改了该else分支下的个别行代码

String value = (argsIndex <= args.length - 1) ?

(args[argsIndex] == null ? "" : args[argsIndex].toString()) : expression.toString();

builder.append(value);

offset = end + closeToken.length();

argsIndex++;

}

}

start = text.indexOf(openToken, offset);

}

if (offset < src.length) {

builder.append(src, offset, src.length - offset);

}

return builder.toString();

}

public static String parseWith$(String text, Object... args) {

return parseInner("${", "}", text, args);

}

public static String parse(String text, Object... args) {

return parseInner("{", "}", text, args);

}

/**

* 数组指定位置插入元素

*

* @param after 在数组哪个元素后面 特殊: index0 代表 插入最开始

* @param item 需要插入的元素

* @param arr 操作的数组

* @return 插入后的数组

*/

public static String[] arrPushItem(String after, String item, String[] arr) {

ArrayList list = new ArrayList<>(Arrays.asList(arr));

if (after == null) {

list.add(item);

} else if ("index0".equals(after)) {

list.add(0, item);

} else {

int i = list.indexOf(after) + 1;

list.add(i, item);

}

String[] strings = new String[list.size()];

list.toArray(strings);

return strings;

}

/**

* 字符串转换为BigDecimal

*

* @param number

* @return

*/

public static BigDecimal string2BigDecimal(String number) {

if (stringBlank(number)) {

return null;

}

return new BigDecimal(number);

}

public static boolean isNumeric(String str) {

if (stringBlank(str)) {

return false;

}

return str.matches("-?[0-9]+.?[0-9]*");

}

/**

* 替换掉html 标签

*

* @param myString

* @return

*/

public static String filterHtml(String myString) {

if (myString == null) {

return myString;

}

String newString = myString;

Pattern BREND = Pattern.compile("(
|
|
|
)", Pattern.CASE_INSENSITIVE);

Matcher me = BREND.matcher(newString);

if (me.find()) {

newString = me.replaceAll("\r\n");

}

Pattern SPANEND = Pattern.compile("(|)", Pattern.CASE_INSENSITIVE);

Matcher se = SPANEND.matcher(newString);

if (se.find()) {

newString = se.replaceAll(" ");

}

// 过滤html标签

Pattern pHtml = Pattern.compile("<[^>]+>", Pattern.CASE_INSENSITIVE);

Matcher mHtml = pHtml.matcher(newString);

if (mHtml.find()) {

newString = mHtml.replaceAll("");

}

return newString;

}

public static String firstToLowerCase(String str) {

if (stringBlank(str)) {

return str;

}

return str.replaceFirst(String.valueOf(str.charAt(0)), String.valueOf(str.charAt(0)).toLowerCase());

}

public static List stringArr2List(String[] stringArr) {

List resultList = new ArrayList<>();

if (stringArr == null) {

return resultList;

}

for (String string : stringArr) {

if (StringUtil.stringBlank(string)) {

continue;

}

resultList.add(string);

}

return resultList;

}

public static byte[] s2BytesUTF8(String str) {

if (stringBlank(str)) {

return null;

}

return str.getBytes(StandardCharsets.UTF_8);

}

/**

* 解码

* 编码字符串 --> 文本字符串

* 支持对 ASCII与UNICODE混合编码的(脏文本)字符串解码

* Eg : "\"2ABRT3425\\u884C\\u653F\\u590D\\u8BAE\\u8868436FDGDSD\"" --> 2ABRT3425行政复议表

*

* @param unicode

* @return

*/

public static String unicodetoString(String unicode) {

if (unicode == null || "".equals(unicode)) {

return null;

}

StringBuilder sb = new StringBuilder();

for (int pos = 0; pos < unicode.length(); ) {

//"\"2ABRT3425\\u884C\\u653F\\u590D\\u8BAE\\u8868436FDGDSD\"";

//System.out.println("pos:"+unicode.substring(pos,pos+1)+" - "+pos);

//System.out.println("index:"+unicode.indexOf("\\u", pos)+"\n");

if (unicode.indexOf("\\u", pos) - pos == 0) {//unicode编码 Eg: \\2435

//System.out.println("pos2:"+unicode.substring(pos,pos+6));

if (pos + 6 <= unicode.length()) {

Character ch = (char) Integer.parseInt(unicode.substring(pos + 2, pos + 6), 16);

//System.out.println("char:"+ch);

sb.append(ch);

pos += 6;

} else {// \\u

sb.append(unicode, pos, pos + 2);

pos += 2;

}

} else {//非unicode编码

sb.append(unicode.charAt(pos));

pos += 1;

}

}

return sb.toString();

}

public static boolean integerBlank(Integer integer) {

return integer == null || integer <= 0;

}

}

 1.6 主程序加一个监听器

package com.huashang;

import com.huashang.listener.ErpApplicationListener;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

import org.springframework.scheduling.annotation.EnableAsync;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication

@EnableAsync

@EnableScheduling

@EnableTransactionManagement

@EnableAspectJAutoProxy(proxyTargetClass = true)

@MapperScan("com.huashang.mapper")

@ComponentScan("com.huashang")

public class ErpApplication {

public static void main(String[] args) {

SpringApplication springApplication = new SpringApplication(ErpApplication.class);

// 添加监听器,执行需要在服务启动时执行的业务逻辑

springApplication.addListeners(new ErpApplicationListener());

springApplication.run(args);

}

}

 1.7 oss是什么和怎么创建(application.yml文件)

只需要修改一下这里就行,是你oss的配置,我这里是阿里的oss

 oss是什么和怎么创建看视频就行:

如何使用OSS控制台、ossutil、ossbrowser、OSSSDK_对象存储 OSS-阿里云帮助中心 (aliyun.com)

创建好了以后,对

以上2个文件都进行以下修改

spring:

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

username: 'lrerp'

password: 'By*****23'

url: jdbc:mysql://pc-uf6fv9vxz81ws1y53.rwlb.rds.aliyuncs.com:3306/lingrong?useUnicode=yes&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai

servlet:

multipart:

enabled: true

max-file-size: 10MB

max-request-size: 20MB

aop:

auto: true

cross:

origin: 'lrerp.com'

audience:

clientId: cbde72f64*****************00d3b

base64Secret: ZWExZjcxNzFi*********E2NGUwZTEzZjgxYmRkMzU=

name: restapiuser

expiresSecond: 172800000

liteflow:

print-banner: false

rule-source-ext-data-map:

driverClassName: com.mysql.cj.jdbc.Driver

username: 'lrerp'

password: '******3'

url: jdbc:mysql://pc-uf6fv9vxz81ws1y53.rwlb.rds.aliyuncs.com:3306/lingrong?useUnicode=yes&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai

applicationName: lingrong

chainTableName: chain

chainApplicationNameField: application_name

chainNameField: chain_name

elDataField: el_data

alioss:

url: file.lrerp.com

endpoint: http://oss-cn-shanghai.aliyuncs.com

accessKeyId: LT#****************PPM

acceddKeySecret: UVg***************C6L

bucketName: lrerp

2. 微信小程序端

2.1 TDesign的upload组件

TDesign的upload组件 (tencent.com)https://tdesign.tencent.com/miniprogram/components/upload

1. app.json全局引用一下

2. wxml

如图可以看到mediaType中我只保留了模版中的image,bind:add事件我定义了一个handleCertificateAdd(),用于上传我的房屋产权图片,max修改为0,可以上传任意个图片

3. js

js页面主要修改了

1. data的数据:

定义一个数组 `certificateList:[ ]`就行

2. 【重点!】uploadFile(file,updateProgress,updateSuccess)方法

 token

这个token就是数据库中的token的值 

3. handleCertificateAdd()方法

 遍历上传的所有图片,通过调用上面的uploadFile方法

下面来分析这几个红框中的代码

1. 

this.setData({

certificateList: [...(this.data.certificateList), {

...file,

status: 'loading'

}],

});

2.  

每个file都遍历调用uploadFile(file,updateProgress,updateSuccess)方法实现上传,

把方法体作为参数,回调,

方框中的方法,是uploadFile(file,updateProgress,updateSuccess)中的updateProgress参数

可以看到task的返回值参数res.progress为100

3.  

(ue) => {

console.log('certificateList:' + ue)

this.setData({

[`certificateList[${length}].status`]: 'done',

[`certificateList[${length}].remoteUrl`]: ue.data

});

}

如下图 方框中的方法,就是作为uploadFile(file,updateProgress,updateSuccess)中的updateSuccess参数

[`certificateList[${length}].status`]: 'done'

就是把图片的status属性设置为done,图片显示出来不会一直转圈

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: