创建数据库
分类表
CREATE TABLE `t_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT '分类名称',
`remark` varchar(255) DEFAULT NULL COMMENT '分类介绍',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
项目分类中间表
CREATE TABLE `t_project_type` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`projectid` int(11) DEFAULT NULL,
`typeid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
标签表
CREATE TABLE `t_tag` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
项目标签中间表
CREATE TABLE `t_project_tag` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`projectid` int(11) DEFAULT NULL,
`tagid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
项目表
CREATE TABLE `t_project` ( `id` int(11) NOT NULL AUTO_INCREMENT, `project_name` varchar(255) DEFAULT NULL COMMENT '项目名称', `project_description` varchar(255) DEFAULT NULL COMMENT '项目描述', `money` bigint(11) DEFAULT NULL COMMENT '筹集金额', `day` int(11) DEFAULT NULL COMMENT '筹集天数', `status` int(4) DEFAULT NULL COMMENT '0-即将开始,1-众筹中,2-众筹成功,3-众筹失败\n', `deploydate` varchar(10) DEFAULT NULL COMMENT '项目发起时间', `supportmoney` bigint(11) DEFAULT NULL COMMENT '已筹集到的金额', `supporter` int(11) DEFAULT NULL COMMENT '支持人数', `completion` int(3) DEFAULT NULL COMMENT '百分比完成度', `memberid` int(11) DEFAULT NULL COMMENT '发起人的会员 id', `createdate` varchar(19) DEFAULT NULL COMMENT '项目创建时间', `follower` int(11) DEFAULT NULL COMMENT '关注人数', `header_picture_path` varchar(255) DEFAULT NULL COMMENT '头图路径', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
项目表项目详情图片表
CREATE TABLE `t_project_item_pic` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`projectid` int(11) DEFAULT NULL,
`item_pic_path` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
项目发起人信息表
CREATE TABLE `t_member_launch_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `memberid` int(11) DEFAULT NULL COMMENT '会员 id', `description_simple` varchar(255) DEFAULT NULL COMMENT '简单介绍', `description_detail` varchar(255) DEFAULT NULL COMMENT '详细介绍', `phone_num` varchar(255) DEFAULT NULL COMMENT '联系电话', `service_num` varchar(255) DEFAULT NULL COMMENT '客服电话', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
回报信息表
CREATE TABLE `t_return` ( `id` int(11) NOT NULL AUTO_INCREMENT, `projectid` int(11) DEFAULT NULL, `type` int(4) DEFAULT NULL COMMENT '0 - 实物回报, 1 虚拟物品回报', `supportmoney` int(11) DEFAULT NULL COMMENT '支持金额', `content` varchar(255) DEFAULT NULL COMMENT '回报内容', `count` int(11) DEFAULT NULL COMMENT '回报产品限额,“0”为不限回报数量', `signalpurchase` int(11) DEFAULT NULL COMMENT '是否设置单笔限购', `purchase` int(11) DEFAULT NULL COMMENT '具体限购数量', `freight` int(11) DEFAULT NULL COMMENT '运费,“0”为包邮', `invoice` int(4) DEFAULT NULL COMMENT '0 - 不开发票, 1 - 开发票', `returndate` int(11) DEFAULT NULL COMMENT '项目结束后多少天向支持者发送回报', `describ_pic_path` varchar(255) DEFAULT NULL COMMENT '说明图片路径', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
发起人确认信息表
CREATE TABLE `t_member_confirm_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `memberid` int(11) DEFAULT NULL COMMENT '会员 id', `paynum` varchar(200) DEFAULT NULL COMMENT '易付宝企业账号', `cardnum` varchar(200) DEFAULT NULL COMMENT '法人身份证号', PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8
逆向工程
生成的数据
各归各位
再建一个ProjectService、ProjectServiceImpl、ProjectProviderHandler
创建 VO 对象
ProjectVO、ReturnVO、MemberConfirmInfoVO、MemberLauchInfoVO
代码
配置文件
创建类
代码
Constants
新建类
代码
package com.xlgl.wzy.handler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import com.xlgl.wzy.config.OSSProperties;
import com.xlgl.wzy.constant.Constants;
import com.xlgl.wzy.entity.vo.ProjectVO;
import com.xlgl.wzy.utils.CasUtils;
import com.xlgl.wzy.utils.ResultEntity;
@Controller
public class ProjectConsumerHandler {
@Autowired
private OSSProperties ossProperties;
@RequestMapping("/create/project/information")
public String saveProjectBasicInfo(
// 接收除了上传图片之外的其他普通数据
ProjectVO projectVO,
// 接收上传的头图
MultipartFile headerPicture,
// 接收上传的详情图片
List<MultipartFile> detailPictureList,
// 用来将收集了一部分数据的ProjectVO对象存入Session域
HttpSession session,
// 用来在当前操作失败后返回上一个表单页面时携带提示消息
ModelMap modelMap
) throws IOException {
// 一、完成头图上传
// 1.获取当前headerPicture对象是否为空
boolean headerPictureIsEmpty = headerPicture.isEmpty();
if(headerPictureIsEmpty) {
// 2.如果没有上传头图则返回到表单页面并显示错误消息
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, Constants.MESSAGE_HEADER_PIC_EMPTY);
return "project-launch";
}
// 3.如果用户确实上传了有内容的文件,则执行上传
ResultEntity<String> uploadHeaderPicResultEntity = CasUtils.uploadFileToOss(
ossProperties.getEndPoint(),
ossProperties.getAccessKeyId(),
ossProperties.getAccessKeySecret(),
headerPicture.getInputStream(),
ossProperties.getBucketName(),
ossProperties.getBucketDomain(),
headerPicture.getOriginalFilename());
String result = uploadHeaderPicResultEntity.getResult();
// 4.判断头图是否上传成功
if(ResultEntity.SUCCESS.equals(result)) {
// 5.如果成功则从返回的数据中获取图片访问路径
String headerPicturePath = uploadHeaderPicResultEntity.getData();
// 6.存入ProjectVO对象中
projectVO.setHeaderPicturePath(headerPicturePath);
} else {
// 7.如果上传失败则返回到表单页面并显示错误消息
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, Constants.MESSAGE_HEADER_PIC_UPLOAD_FAILED);
return "project-launch";
}
// 二、上传详情图片
// 1.创建一个用来存放详情图片路径的集合
List<String> detailPicturePathList = new ArrayList<String>();
// 2.检查detailPictureList是否有效
if(detailPictureList == null || detailPictureList.size() == 0) {
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, Constants.MESSAGE_DETAIL_PIC_EMPTY);
return "project-launch";
}
// 3.遍历detailPictureList集合
for (MultipartFile detailPicture : detailPictureList) {
// 4.当前detailPicture是否为空
if(detailPicture.isEmpty()) {
// 5.检测到详情图片中单个文件为空也是回去显示错误消息
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, Constants.MESSAGE_DETAIL_PIC_EMPTY);
return "project-launch";
}
// 6.执行上传
ResultEntity<String> detailUploadResultEntity = CasUtils.uploadFileToOss(
ossProperties.getEndPoint(),
ossProperties.getAccessKeyId(),
ossProperties.getAccessKeySecret(),
detailPicture.getInputStream(),
ossProperties.getBucketName(),
ossProperties.getBucketDomain(),
detailPicture.getOriginalFilename());
// 7.检查上传结果
String detailUploadResult = detailUploadResultEntity.getResult();
if(ResultEntity.SUCCESS.equals(detailUploadResult)) {
String detailPicturePath = detailUploadResultEntity.getData();
// 8.收集刚刚上传的图片的访问路径
detailPicturePathList.add(detailPicturePath);
} else {
// 9.如果上传失败则返回到表单页面并显示错误消息
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, Constants.MESSAGE_DETAIL_PIC_UPLOAD_FAILED);
return "project-launch";
}
}
// 10.将存放了详情图片访问路径的集合存入ProjectVO中
projectVO.setDetailPicturePathList(detailPicturePathList);
// 三、后续操作
// 1.将ProjectVO对象存入Session域
session.setAttribute(Constants.ATTR_NAME_TEMPLE_PROJECT, projectVO);
// 2.以完整的访问路径前往下一个收集回报信息的页面
return "redirect:http:// localhost/project/return/info/page";
}
}
页面代码添加后,启动测试,出现的问题
缺少
写错
继续完成代码
Constants添加内容
ProjectPOMapper添加方法
ProjectPOMapper.xml添加
ReturnPOMapper添加
ReturnPOMapper.xml添加
<insert id="insertReturnPOBatch">
insert into t_return (
projectid,
type,
supportmoney,
content,
count,
signalpurchase,
purchase,
freight,
invoice,
returndate,
describ_pic_path
)
values
<foreach collection="returnPOList" item="returnPO" separator=",">
(
#{projectId},
#{returnPO.type},
#{returnPO.supportmoney},
#{returnPO.content},
#{returnPO.count},
#{returnPO.signalpurchase},
#{returnPO.purchase},
#{returnPO.freight},
#{returnPO.invoice},
#{returnPO.returndate},
#{returnPO.describPicPath}
)
</foreach>
</insert>
ProjectItemPicPOMapper添加
ProjectItemPicPOMapper.xml添加
MySQLRemoteService添加接口
ProjectService接口添加
接口实现
@Transactional(readOnly = true)
@Service
public class ProjectServiceImpl implements ProjectService {
@Autowired
private ReturnPOMapper returnPOMapper;
@Autowired
private MemberConfirmInfoPOMapper memberConfirmInfoPOMapper;
@Autowired
private MemberLaunchInfoPOMapper memberLaunchInfoPOMapper;
@Autowired
private ProjectPOMapper projectPOMapper;
@Autowired
private ProjectItemPicPOMapper projectItemPicPOMapper;
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
@Override
public void saveProject(ProjectVO projectVO, Integer memberId) {
// 一、保存ProjectPO对象
// 1.创建空的ProjectPO对象
ProjectPO projectPO = new ProjectPO();
// 2.把projectVO中的属性复制到projectPO中
BeanUtils.copyProperties(projectVO, projectPO);
// 修复bug:把memberId设置到projectPO中
projectPO.setMemberid(memberId);
// 修复bug:生成创建时间存入
String createdate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
projectPO.setCreatedate(createdate);
// 修复bug:status设置成0,表示即将开始
projectPO.setStatus(0);
// 3.保存projectPO
// 为了能够获取到projectPO保存后的自增主键,需要到ProjectPOMapper.xml文件中进行相关设置
// <insert id="insertSelective" useGeneratedKeys="true" keyProperty="id" ……
projectPOMapper.insertSelective(projectPO);
// 4.从projectPO对象这里获取自增主键
Integer projectId = projectPO.getId();
// 二、保存项目、分类的关联关系信息
// 1.从ProjectVO对象中获取typeIdList
List<Integer> typeIdList = projectVO.getTypeIdList();
projectPOMapper.insertTypeRelationship(typeIdList, projectId);
// 三、保存项目、标签的关联关系信息
List<Integer> tagIdList = projectVO.getTagIdList();
projectPOMapper.insertTagRelationship(tagIdList, projectId);
// 四、保存项目中详情图片路径信息
List<String> detailPicturePathList = projectVO.getDetailPicturePathList();
projectItemPicPOMapper.insertPathList(projectId, detailPicturePathList);
// 五、保存项目发起人信息
MemberLauchInfoVO memberLauchInfoVO = projectVO.getMemberLauchInfoVO();
MemberLaunchInfoPO memberLaunchInfoPO = new MemberLaunchInfoPO();
BeanUtils.copyProperties(memberLauchInfoVO, memberLaunchInfoPO);
memberLaunchInfoPO.setMemberid(memberId);
memberLaunchInfoPOMapper.insert(memberLaunchInfoPO);
// 六、保存项目回报信息
List<ReturnVO> returnVOList = projectVO.getReturnVOList();
List<ReturnPO> returnPOList = new ArrayList<>();
for (ReturnVO returnVO : returnVOList) {
ReturnPO returnPO = new ReturnPO();
BeanUtils.copyProperties(returnVO, returnPO);
returnPOList.add(returnPO);
}
returnPOMapper.insertReturnPOBatch(returnPOList, projectId);
// 七、保存项目确认信息
MemberConfirmInfoVO memberConfirmInfoVO = projectVO.getMemberConfirmInfoVO();
MemberConfirmInfoPO memberConfirmInfoPO = new MemberConfirmInfoPO();
BeanUtils.copyProperties(memberConfirmInfoVO, memberConfirmInfoPO);
memberConfirmInfoPO.setMemberid(memberId);
memberConfirmInfoPOMapper.insert(memberConfirmInfoPO);
}
}
ProjectConsumerHandler添加方法
ProjectConsumerHandler添加方法
@Autowired
private MySQLRemoteService mySQLRemoteService;
@RequestMapping("/create/confirm")
public String saveConfirm(ModelMap modelMap, HttpSession session, MemberConfirmInfoVO memberConfirmInfoVO) {
// 1.从Session域读取之前临时存储的ProjectVO对象
ProjectVO projectVO = (ProjectVO) session.getAttribute(Constants.ATTR_NAME_TEMPLE_PROJECT);
// 2.如果projectVO为null
if(projectVO == null) {
throw new RuntimeException(Constants.MESSAGE_TEMPLE_PROJECT_MISSING);
}
// 3.将确认信息数据设置到projectVO对象中
projectVO.setMemberConfirmInfoVO(memberConfirmInfoVO);
// 4.从Session域读取当前登录的用户
MemberLoginVO memberLoginVO = (MemberLoginVO) session.getAttribute(Constants.ATTR_NAME_LOGIN_MEMBER);
Integer memberId = memberLoginVO.getId();
// 5.调用远程方法保存projectVO对象
ResultEntity<String> saveResultEntity = mySQLRemoteService.saveProjectVORemote(projectVO, memberId);
// 6.判断远程的保存操作是否成功
String result = saveResultEntity.getResult();
if(ResultEntity.FAILED.equals(result)) {
modelMap.addAttribute(Constants.ATTR_NAME_MESSAGE, saveResultEntity.getMessage());
return "project-confirm";
}
// 7.将临时的ProjectVO对象从Session域移除
session.removeAttribute(Constants.ATTR_NAME_TEMPLE_PROJECT);
// 8.如果远程保存成功则跳转到最终完成页面
return "redirect:http://localhost/project/create/success";
}
@ResponseBody
@RequestMapping("/create/save/return.json")
public ResultEntity<String> saveReturn(ReturnVO returnVO, HttpSession session) {
try {
// 1.从session域中读取之前缓存的ProjectVO对象
ProjectVO projectVO = (ProjectVO) session.getAttribute(Constants.ATTR_NAME_TEMPLE_PROJECT);
// 2.判断projectVO是否为null
if(projectVO == null) {
return ResultEntity.failed(Constants.MESSAGE_TEMPLE_PROJECT_MISSING);
}
// 3.从projectVO对象中获取存储回报信息的集合
List<ReturnVO> returnVOList = projectVO.getReturnVOList();
// 4.判断returnVOList集合是否有效
if(returnVOList == null || returnVOList.size() == 0) {
// 5.创建集合对象对returnVOList进行初始化
returnVOList = new ArrayList<>();
// 6.为了让以后能够正常使用这个集合,设置到projectVO对象中
projectVO.setReturnVOList(returnVOList);
}
// 7.将收集了表单数据的returnVO对象存入集合
returnVOList.add(returnVO);
// 8.把数据有变化的ProjectVO对象重新存入Session域,以确保新的数据最终能够存入Redis
session.setAttribute(Constants.ATTR_NAME_TEMPLE_PROJECT, projectVO);
// 9.所有操作成功完成返回成功
return ResultEntity.successWithoutData();
} catch (Exception e) {
e.printStackTrace();
return ResultEntity.failed(e.getMessage());
}
}
// JavaScript代码:formData.append("returnPicture", file);
// returnPicture是请求参数的名字
// file是请求参数的值,也就是要上传的文件
@ResponseBody
@RequestMapping("/create/upload/return/picture.json")
public ResultEntity<String> uploadReturnPicture(
// 接收用户上传的文件
@RequestParam("returnPicture") MultipartFile returnPicture) throws IOException {
// 1.执行文件上传
ResultEntity<String> uploadReturnPicResultEntity = CasUtils.uploadFileToOss(
ossProperties.getEndPoint(),
ossProperties.getAccessKeyId(),
ossProperties.getAccessKeySecret(),
returnPicture.getInputStream(),
ossProperties.getBucketName(),
ossProperties.getBucketDomain(),
returnPicture.getOriginalFilename());
// 2.返回上传的结果
return uploadReturnPicResultEntity;
}
ProjectProviderHandler添加方法
这个地方ProjectPOMapper.xml改了一下
WebMvcConfig添加