具体配置
uni-app 前端页面开发: https://ext.dcloud.net.cn/ (插件广场) + vue 基础基本知识开发
后端-管理端开发:ruoyi 框架 (基本可以直接用)
前端开发
api 配置
基本的网络请求
uni.request({
url: BASE_URL + url,
method:'get'
data: params,
header: {
...header,
'Authorization': token ? 'Bearer ' + token : 'Basic ' + BASE.encode(user),
},
success(res) {}
fail(res) {}
})
page 页面配置
图片上传功能
可以先写一个view或者button调用打开相册选择图片的函数。
chooseImg() {
uni.chooseImage({ //上传图片的内置方法
count: 1, //在h5浏览器限制不住
sourceType: ['album', 'camera'], //从相册选择
success: res => {
let itemLength = res.tempFilePaths.length
console.log(itemLength)
if (itemLength > 8) {
uni.showToast({
title: '最多上传8项!',
icon: 'none'
})
} else {
this.uploadFileData(res.tempFilePaths)
console.log(res.tempFilePaths)
}
}
})
},
uploadFileData是上传图片到指定URL的函数
uploadFileData(tempFiles) {
uni.uploadFile({
url: this.baseUrl + '/actionAuth/user/head_img',
filePath: tempFiles[0], //tempFiles是图片路径,字符串,每次只能上传一个
name: 'file', //后端定义的文件的名字
formData: {
// 也可以传一些数据进行对应
'id': JSON.stringify(this.person.id) //将表单数据转化为字符串
}
}).then(res => {
console.log("上传图片到服务器", res)
let response = JSON.parse(res[1].data)
console.log(response.code)
if (response.code == 200) {
this.upload=false
// this.imgshowArray.push(tempFiles[0])
// console.log(this.imgshowArray)
} else {
uni.showToast({
icon: 'none',
title: response.msg,
});
}
});
},
},
pdf文件上传功能
微信官方提供了chooseMessageFile方法进行上传图片、pdf之类的文件
wx.chooseMessageFile({
count: 10, //最多可以选择的文件个数,可以 0~100
type: 'file', //所选的文件的类型,具体看官方文档
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFiles[0].path
let filename = res.tempFiles[0].name; //用于页面显示的名字
// 这一步判断可以省略,如果需求没有格式要求的话
if (filename.indexOf(".pdf") == -1) {
uni.showToast({
title:"暂时仅支持pdf格式的文件",
icon:'error'
})
return
} else {
uni.showLoading({
title:'上传中',
})
wx.uploadFile({
url: _that.baseUrl + "/guidefiles/upload", //上传的路径
filePath: tempFilePaths, //刚刚在data保存的文件路径
name: 'file', //后台获取的凭据
header:{
Authorization:'wx'+uni.getStorageSync('token')
},
formData: { //如果是需要带参数,请在formData里面添加,不需要就去掉这个就可以的
// "userId": 1,
"filename": filename
},
success(res) {
console.log(res)
uni.hideLoading()
_that.getAllfiles() //上传成功后,用于页面展示,所以在此在服务器拉取一次文件展示前端
}
})
}
}
})
pdf 预览功能
兼容Android + ios 预览pdf功能,后续后端可以开发文件上传功能
template 里面必须有一个 view,里面配置一个 webview 并加上 url。
<template>
<view class="index">
<view>
<web-view :src="url"></web-view>
</view>
</view>
</template>
js 代码判断
uni.getSystemInfo({
success: res => {
console.log(res.platform);
if (res.platform === 'android' ) {
wx.downloadFile({
url: this.fileUrl,
success: function(res) {
const filePath = res.tempFilePath;
uni.openDocument({
showMenu:true,
filePath: filePath,
success: function(res) {
console.log('打开文档成功');
}
});
}
});
} else {
this.url = this.fileUrl
}
}
});
ucharts图表导出
导入ucharts(qiun-data-charts)图表,在ref调用子组件函数
<button class=“button” type=“default”
@click=“saveImage2()”>导出图像 最后编写按钮,通过调用函数去调用子组件里面的函数
saveImage2() {
// console.log(this. r e f s . u c h a r t s 1. g e t I m a g e ( ) ) t h i s . refs.ucharts1.getImage()) this. refs.ucharts1.getImage())this.refs.ucharts2.saveImage()
// console.log() },
Excel文件导出
函数转换,可以将List列表转换为xml文件,再从xml文件转换为xlsx文件
//json数据转xlsx
json2xls(XMLSheets, header) {
//XMLSheets 为Json数组, Header为字符串数组
// excel 头部
var XMLString = `
<?xml version="1.0" encoding="UTF-8"?>
<?mso-application progid= "Excel.Sheet"?>`
XMLString += `<Workbook
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">`
XMLString += `<Worksheet ss:Name="sheet 1">`
// Table 头部
XMLString += '<Table>'
//遍历header插入Frist Row, Header
XMLString += '<Row>'
header.forEach((hd, i) => {
XMLString += '<Cell>' + `<Data ss:Type="String">` + hd + '</Data></Cell>'
})
XMLString += '</Row>'
// 遍历Data,插入数据Row
// 检查是否有数据
if (XMLSheets) {
XMLSheets.forEach((row) => {
// 遍历数组,插入行
console.log(row)
XMLString += '<Row>'
// 遍历Json,插入单元格
for (var p in row) {
// Cell 头部
XMLString += `<Cell><Data ss:Type="String">${row[p]}</Data></Cell>`
}
XMLString += '</Row>'
}) // 遍历 Cell
}
// Table 尾部
XMLString += '</Table>'
// Worksheet 尾部
XMLString += '</Worksheet></Workbook>'
return XMLString
},
然后就是微信的文件写入和文件打开。
//导出xlsx
async tableToExcel() {
let header = this.rankingList.menu //表头数据
let jsonData = this.rankingList.data
//自定义json数据
// let fieldtable = "作风排名" + new Date(); //需要导出的文件名
let xlsdata = this.json2xls(jsonData, header);
var filePath = `${wx.env.USER_DATA_PATH}/`+ "作风排名" + `${+new Date}.xls`
const fsm = wx.getFileSystemManager();
fsm.writeFile({
filePath,
data: xlsdata,
encoding: 'utf8',
success: res => {
uni.showModal({
title: '提示',
content: '如遇到文档格式显示问题,建议您使用金山文档或PC端office打开',
confirmText: '我知道了',
showCancel: false,
success: function(res) {
if (res.confirm) {
wx.openDocument({
filePath,
success: function(res) {
console.log('打开文档成功')
},
fail: function() {
console.log('打开失败');
}
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
fail: res => {
console.info(res)
}
})
},
后端开发
后续可以考虑配置 mybatisplus 进行编写
文件操作
文件获取
首先配置一下路由转发,也就是经过当前接口的请求转发到指定目录下。
配置在Controller同目录的config文件夹下的Webconfig.js 文件
这一步是为了方便前端进行指定文件夹文件的访问,不然获取不到文件,
package com.ruoyi.wxservice.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/guidefiles/**"). //接口
addResourceLocations("file:G://A/"); //转发的文件夹
registry.addResourceHandler("/icons/**").
addResourceLocations("classpath:/static/icons/"); //系统后端的文件
super.addResourceHandlers(registry);
}
}
之后在ruoyi-framework的java-…-config-SecurityConfig的位置配置文件,在configuer函数里面配置。
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception
{
httpSecurity
// CSRF禁用,因为不使用session
.csrf().disable()
// 认证失败处理类
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token,所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/captchaImage").anonymous()
.antMatchers("/**/*.png").anonymous()
.antMatchers(
"/guidefiles/*.pdf" //添加的是这个接口
).anonymous()
.antMatchers("/wx/user/passwordLogin","/wx/user/forgetPwd","/wx/user/register").anonymous()
.antMatchers(
HttpMethod.GET,
"/",
"/wx/user/*/login",
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/profile/**",
"/**/*.png"
).permitAll()
.antMatchers("/swagger-ui.html").anonymous()
.antMatchers("/swagger-resources/**").anonymous()
.antMatchers("/webjars/**").anonymous()
.antMatchers("/*/api-docs").anonymous()
.antMatchers("/druid/**").anonymous()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated()
.and()
.headers().frameOptions().disable();
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
// 添加JWT filter
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// 添加CORS filter
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class);
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
}
配置好路由之后,此时我们就可以不需要token直接访问接口下的文件了。紧接着获取G盘下A文件夹下的所有文件。这里定义了一个实体PdfFile,存了我仅需要的信息:path、name、time,作为一个对象列表返回给前端。前端界面渲染,根据pdf预览。
@GetMapping("/getAllfiles")
public R getAllfiles() {
List<PdfFile> list = new ArrayList<PdfFile>();
File baseFile = new File("G:\\A");
// System.out.println(baseFile);
if (baseFile.isFile() || !baseFile.exists()) {
return null;
}
File[] files = baseFile.listFiles();
for (File file : files) {
PdfFile pdfFile = new PdfFile();
pdfFile.setFilePath(file.getAbsolutePath());
pdfFile.setFilename(file.getName());
Date date = new Date(file.lastModified());
pdfFile.setCreTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
list.add(pdfFile);
}
// System.out.println(list);
return R.success(list);
}
文件上传
文件上传这个是很基础的一个功能,我用的应该是比较简洁的。因为我们是固定了一个文件夹进行存储,所以多余的功能并没有,就是在所在路径创建一个文件,然后替换。
//文件的上传
@PostMapping("/upload")
public R upload(MultipartFile file,@RequestParam String filename) throws IOException {
String filepath = "G:\\A\\"+filename;
System.out.println(filepath);
//设置文件上传路径
try {
File dest = new File(filepath);
//创建父级目录:事件类型-事件人姓名-报告人姓名
file.transferTo(dest);
return R.success("上传成功");
} catch (Exception e) {
return R.success("上传失败");
}
}
文件删除
前端传给后端一个名字,然后在指定目录下删除。本来是想直接传路径的,后面发现盘符的’/'无法识别,同事说了一下用base64方法加密解密的方法,应该挺简单,引一个包就ok了,下次再试试吧。
/**
* 文件删除
*
* @param filename 文件路径
*/
@GetMapping("/delete/{filename}")
public static R delete(@PathVariable String filename) {
String filePath = "G:\\A\\"+filename;
// System.out.println(filename);
// System.out.println(filePath);
File file = new File(filePath);
System.out.println(filePath);
if (file.exists()) {
file.delete();
System.out.println("===========删除成功=================");
return R.success();
} else {
System.out.println("===============删除失败==============");
return R.error();
}
}
ruoyi 配置
B 站视频: https://www.bilibili.com/video/BV1KK4y1E74u?p=5&spm_id_from=333.880.my_history.page.click&vd_source=68258ace75b4d0400ef6963a43bf7797
主要是表单的配置,框架跑起来主要看 ruoyi 教程即可