1.初始化操作
①跳转到同意协议页面
[1]准备页面
/distribution-crowd-7-webui/src/main/resources/templates/project-1-start.html
[2]跳转页面
所在工程:distribution-crowd-7-web
接口全类名:com.rgh.crowd.config.SpringMVCConfig
urlPath = "/project/to/agree/page";
viewName = "project-1-start";
registry.addViewController(urlPath).setViewName(viewName);
②点击同意协议按钮
[1]将同意协议按钮放在form标签内
[2]将project-manager的Controller抽取接口
所在工程:distribution-crowd-1-common
接口全类名:com.rgh.crowd.api.ProjectOperationRemoteService
@FeignClient("project-manager")
public interface ProjectOperationRemoteService {
@RequestMapping("/project/manager/save/whole/project")
public ResultEntity saveWholeProject(
@RequestParam("memberSignToken") String memberSignToken,
@RequestParam("projectTempToken") String projectTempToken);
@RequestMapping("/project/manager/save/confirm/infomation")
public ResultEntity saveConfirmInfomation(
@RequestBody MemberConfirmInfoVO memberConfirmInfoVO);
@RequestMapping("/project/manager/save/return/infromation")
public ResultEntity saveReturnInfromation(
@RequestBody ReturnVO returnVO);
@RequestMapping("/project/manager/save/project/information")
public ResultEntity saveProjectInformation(
@RequestBody ProjectVO projectVOFront);
@RequestMapping("/project/manager/save/detail/picture/path/list")
public ResultEntity saveDetailPicturePathList(@RequestParam("memberSignToken") String memberSignToken,
@RequestParam("projectTempToken") String projectTempToken,
@RequestParam("detailPicturePathList") List detailPicturePathList);
@RequestMapping("/project/manager/save/head/picture/path")
public ResultEntity saveHeadPicturePath(@RequestParam("memberSignToken") String memberSignToken,
@RequestParam("projectTempToken") String projectTempToken,
@RequestParam("headerPicturePath") String headerPicturePath);
@RequestMapping("/project/manager/initCreation")
public ResultEntity initCreation(
@RequestParam("memberSignToken") String memberSignToken);
}
[3]Controller方法
所在工程:distribution-crowd-7-webui
所在类:com.rgh.crowd.handler.ProjectHandler
public static final String ATTR_NAME_INITED_PROJECT = "INITED-PROJECT";
@RequestMapping("/project/agree/protocol")
public String agreeProtocol(HttpSession session, Model model) {
// 1.登录检查
MemberSignSuccessVO signVO = (MemberSignSuccessVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
if(signVO == null) {
model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_ACCESS_DENIED);
return "member-login";
}
// 2.从当前signVO对象中获取token
String token = signVO.getToken();
// 3.调用远程方法初始化Project
ResultEntity resultEntity = projectOperationRemoteService.initCreation(token);
String result = resultEntity.getResult();
if(ResultEntity.FAILED.equals(result)) {
throw new RuntimeException(resultEntity.getMessage());
}
// ※补充操作:将初始化项目的信息存入Session
ProjectVO projectVO = resultEntity.getData();
session.setAttribute(CrowdConstant.ATTR_NAME_INITED_PROJECT, projectVO);
return "redirect:/project/to/create/project/page";
}
2.跳转到step-1页面
※以前保存项目相关数据时功能调整※
所在工程:distribution-crowd-3-database-provider
所在类:com.rgh.crowd.service.impl.ProjectServiceImpl
所在方法:saveProject()
代码:
……
// 6.保存MemberLaunchInfoPO
MemberLauchInfoVO memberLauchInfoVO = projectVO.getMemberLauchInfoVO();
if(memberLauchInfoVO != null) {
// ※※※※※※※※※※※补充功能※※※※※※※※※※※
// 将旧的用户发起人信息删除
MemberLaunchInfoPOExample example = new MemberLaunchInfoPOExample();
example.createCriteria().andMemberidEqualTo(Integer.parseInt(memberId));
memberLaunchInfoPOMapper.deleteByExample(example);
// ※※※※※※※※※※※※※※※※※※※※※※※※※※
MemberLaunchInfoPO memberLaunchInfoPO = new MemberLaunchInfoPO();
BeanUtils.copyProperties(memberLauchInfoVO, memberLaunchInfoPO);
memberLaunchInfoPO.setMemberid(Integer.parseInt(memberId));
memberLaunchInfoPOMapper.insert(memberLaunchInfoPO);
}
……
①准备页面
/distribution-crowd-7-webui/src/main/resources/templates/project_2_stepOne.html
②查询目标页面所需要的数据
webui工程→member-manager工程→根据token查询memberId(redis)→根据memberId查询MemberLaunchInfo(database)
[1]database-provider
接口:com.rgh.crowd.api.DataBaseOperationRemoteService
@RequestMapping("/retrieve/member/launch/info/po")
ResultEntity retrieveMemberLaunchInfoPO(@RequestParam("memberId") String memberId);
Controller:
@RequestMapping("/retrieve/member/launch/info/po")
public ResultEntity retrieveMemberLaunchInfoPO(@RequestParam("memberId") String memberId) {
MemberLaunchInfoPO memberLaunchInfoPO = memberService.getMemberLaunchInfoPO(memberId);
return ResultEntity.successWithData(memberLaunchInfoPO);
}
Service:
@Override
public MemberLaunchInfoPO getMemberLaunchInfoPO(String memberId) {
MemberLaunchInfoPOExample example = new MemberLaunchInfoPOExample();
example.createCriteria().andMemberidEqualTo(Integer.parseInt(memberId));
List list = memberLaunchInfoPOMapper.selectByExample(example);
if(CrowdUtils.collectionEffectiveCheck(list)) {
return list.get(0);
}else {
return null;
}
}
[2]member-manager
接口:com.rgh.crowd.api.MemberManagerRemoteService
@RequestMapping("/retrieve/member/launch/info/by/member/token")
public ResultEntity retrieveMemberLaunchInfoByMemberToken(@RequestParam("token") String token);
Controller:
@RequestMapping("/retrieve/member/launch/info/by/member/token")
public ResultEntity retrieveMemberLaunchInfoByMemberToken(@RequestParam("token") String token) {
// 1.根据token查询memberId
ResultEntity resultEntity = redisRemoteService.retrieveStringValueByStringKey(token);
String memberId = resultEntity.getData();
if(memberId == null) {
return ResultEntity.failed(CrowdConstant.MESSAGE_ACCESS_DENIED);
}
// 2.根据memberId查询MemberLaunchInfoPO
return dataBaseOperationRemoteService.retrieveMemberLaunchInfoPO(memberId);
}
[3]webui
@RequestMapping("/project/to/create/project/page")
public String toCreateProjectPage(HttpSession session, Model model) {
// 1.获取当前登录的用户
MemberSignSuccessVO signVO = (MemberSignSuccessVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
// 2.检查signVO为null
if(signVO == null) {
model.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_ACCESS_DENIED);
return "member-login";
}
// 3.获取token数据
String token = signVO.getToken();
// 4.根据token查询MemberLaunchInfo信息
ResultEntity resultEntity = memberManagerRemoteService.retrieveMemberLaunchInfoByMemberToken(token);
// 5.检查结果
String result = resultEntity.getResult();
if(ResultEntity.FAILED.equals(result)) {
throw new RuntimeException(resultEntity.getMessage());
}
// 6.获取查询结果
MemberLaunchInfoPO memberLaunchInfoPO = resultEntity.getData();
// 7.存入模型
model.addAttribute("memberLaunchInfoPO", memberLaunchInfoPO);
return "project-create";
}
③页面回显已加载的数据
textarea标签没有value属性,所以不能使用th:value,需要设置标签体,所以使用了th:text
如果考虑到memberLauchInfoVO有可能为null,可以进行相关判断
${(memberLauchInfoVO==null)?'':memberLauchInfoVO.descriptionSimple}
${(memberLauchInfoVO==null)?'':memberLauchInfoVO.descriptionDetail}
${(memberLauchInfoVO==null)?'':memberLauchInfoVO.phoneNum}
${(memberLauchInfoVO==null)?'':memberLauchInfoVO.serviceNum}
3.上传项目头图
①点击“上传”按钮直接弹出文件选择框
增加文件上传框
给#headPictureBtn按钮绑定单击响应函数
$("#headPictureBtn").click(function(){
// 调用click()函数而不传入回调函数,就表示对#headPictureInput单击
$("#headPictureInput").click();
});
②选中文件后直接上传
// 用户选择了具体要上传的文件后,文件上传框会触发值改变事件
$("#headPictureInput").change(function(){
// 获取实际选中的文件数组
var file = this.files[0];
// 创建FormData()对象
var formData = new FormData();
// 封装文件数据
formData.append("headPicture", file);
// 发送ajax请求执行上传
$.ajax({
"url":"/project/upload/head/picture",
"type":"post",
"data":formData,
"contentType":false,
"processData":false,
"success":function(){
alert("上传成功!");
}
});
});
③上传文件到OSS
[1]引入依赖到common工程中
com.aliyun.oss
aliyun-sdk-oss
2.8.3
[2]上传文件的工具方法
所在工程:distribution-crowd-1-common
全类名:com.rgh.crowd.util.UploadUtil
/**
* 上传单个文件到OSS
* @param endpoint
* @param accessKeyId
* @param accessKeySecret
* @param fileName
* @param folderName
* @param bucketName
* @param inputStream
*/
public static void uploadSingleFile(
String endpoint,
String accessKeyId,
String accessKeySecret,
String fileName,
String folderName,
String bucketName,
InputStream inputStream) {
try {
// 创建OSSClient实例。
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
// 存入对象的名称=目录名称+"/"+文件名
String objectName = folderName + "/" + fileName;
ossClient.putObject(bucketName, objectName, inputStream);
// 关闭OSSClient。
ossClient.shutdown();
} catch (OSSException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
} catch (ClientException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
另外两个工具方法:
/**
* 生成文件名
* @param originalFileName 原始文件名
* @return
*/
public static String generateFileName(String originalFileName) {
// 截取扩展名部分
String extensibleName = "";
if(originalFileName.contains(".")) {
extensibleName = originalFileName.substring(originalFileName.lastIndexOf("."));
}
return UUID.randomUUID().toString().replaceAll("-", "")+extensibleName;
}
/**
* 根据日期生成目录名称
* @param ossProjectParentFolder
* @return
*/
public static String generateFolderNameByDate(String ossProjectParentFolder) {
return ossProjectParentFolder + "/" + new SimpleDateFormat("yyyyMMdd").format(new Date());
}
[3]在yml文件中需要维护的参数
oss.project.parent.folder: project
oss.endpoint: http://oss-cn-shenzhen.aliyuncs.com
oss.accessKeyId: LTAI4FtYZMNYk58XeZh5f8Hm
oss.accessKeySecret: AZUMRWaSCEmTIFTGg2HAx59gOPdzhg
oss.bucketName: crowd191225
oss.bucket.domain: http://crowd191225.oss-cn-shenzhen.aliyuncs.com
[4]在Controller类中引用yml中的参数
@Value(value="${oss.project.parent.folder}")
private String ossProjectParentFolder;
@Value(value="${oss.endpoint}")
private String endpoint;
@Value(value="${oss.accessKeyId}")
private String accessKeyId;
@Value(value="${oss.accessKeySecret}")
private String accessKeySecret;
@Value(value="${oss.bucketName}")
private String bucketName;
@Value(value="${oss.bucket.domain}")
private String bucketDomain;
[5]Controller中执行文件上传
public static final String MESSAGE_UPLOAD_FILE_EMPTY = "未检测到上传文件!";
@ResponseBody
@RequestMapping("/project/upload/head/picture")
public ResultEntity uploadHeadPicture(
HttpSession session,
@RequestParam("headPicture") MultipartFile headPicture) throws IOException {
// 登录检查
MemberSignSuccessVO signVO = (MemberSignSuccessVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
if(signVO == null) {
return ResultEntity.failed(CrowdConstant.MESSAGE_ACCESS_DENIED);
}
// 排除上传文件为空的情况
if(headPicture.isEmpty()) {
return ResultEntity.failed(CrowdConstant.MESSAGE_UPLOAD_FILE_EMPTY);
}
// 准备工作
String originalFileName = headPicture.getOriginalFilename();
String fileName = CrowdUtils.generateFileName(originalFileName);
String folderName = CrowdUtils.generateFolderNameByDate(ossProjectParentFolder);
InputStream inputStream = headPicture.getInputStream();
// 执行上传
CrowdUtils.uploadSingleFile(endpoint, accessKeyId, accessKeySecret, fileName, folderName, bucketName, inputStream);
// 拼接headerPicturePath
String headerPicturePath = bucketDomain + "/" + folderName + "/" + fileName;
// 获取保存头图所需要的相关信息
String memberSignToken = signVO.getToken();
ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_INITED_PROJECT);
String projectTempToken = projectVO.getProjectTempToken();
// 保存头图相关信息
return projectOperationRemoteService.saveHeadPicturePath(memberSignToken, projectTempToken, headerPicturePath);
}
实体类都加上序列化
测试图片是否上传成功
4.上传详情图片
给input type="file"设置multiple="multiple"属性就可以让文件选择框能够选择多个文件。
①jQuery代码
$("#detailPictureBtn").click(function(){
$("#detailPictureInput").click();
});
$("#detailPictureInput").change(function(){
// 获取用户选择的多个文件的数组
var files = this.files;
// 创建FormData对象
var formData = new FormData();
// 将上传的文件添加到formData中
for(var i = 0; i < files.length; i++) {
var file = files[i];
formData.append("detailPicture", file);
}
// 执行上传
$.ajax({
"url":"/project/upload/detail/picture",
"type":"post",
"data":formData,
"contentType":false,
"processData":false,
"success":function(){
alert("上传成功!");
}
});
});
②Controller代码
@ResponseBody
@RequestMapping("/project/upload/detail/picture")
public ResultEntity uploadDetailPicture(
HttpSession session,
@RequestParam("detailPicture") List detailPictureList
) throws IOException {
// 登录检查
MemberSignSuccessVO signVO = (MemberSignSuccessVO) session.getAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER);
if(signVO == null) {
return ResultEntity.failed(CrowdConstant.MESSAGE_ACCESS_DENIED);
}
// 遍历用户上传的文件
if(!CrowdUtils.collectionEffectiveCheck(detailPictureList)) {
return ResultEntity.failed(CrowdConstant.MESSAGE_UPLOAD_FILE_EMPTY);
}
List detailPicturePathList = new ArrayList<>();
for (MultipartFile detailPicture : detailPictureList) {
boolean empty = detailPicture.isEmpty();
if(empty) {
continue ;
}
InputStream inputStream = detailPicture.getInputStream();
String originalFileName = detailPicture.getOriginalFilename();
String fileName = CrowdUtils.generateFileName(originalFileName);
String folderName = CrowdUtils.generateFolderNameByDate(ossProjectParentFolder);
CrowdUtils.uploadSingleFile(endpoint, accessKeyId, accessKeySecret, fileName, folderName, bucketName, inputStream);
String detailPicturePath = bucketDomain + "/" + folderName + "/" + fileName;
detailPicturePathList.add(detailPicturePath);
}
// 获取保存头图所需要的相关信息
String memberSignToken = signVO.getToken();
ProjectVO projectVO = (ProjectVO) session.getAttribute(CrowdConstant.ATTR_NAME_INITED_PROJECT);
String projectTempToken = projectVO.getProjectTempToken();
return projectOperationRemoteService.saveDetailPicturePathList(memberSignToken, projectTempToken, detailPicturePathList);
}