day16【前台】项目展示

day16【前台】项目展示

1、首页显示项目

1.1、整体思路

image-20201002143134654

1.2、创建VO

1.2.1、PortalTypeVO
  • 数据库表

image-20200706161543688

  • 实体类如下:封装List<PortalProjectVO>字段,用于返回项目信息

image-20200705211529676

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PortalTypeVO {
	
	private Integer id;
	private String name;
	private String remark;
	
	private List<PortalProjectVO> portalProjectVOList;

}
1.2.2、PortalProjectVO
  • 与首页中显示的信息一一对应

image-20200705211625691

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PortalProjectVO {
	
	private Integer projectId;
	private String projectName;
	private String headerPicturePath;
	private Integer money;
	private String deployDate;
	private Integer percentage;
	private Integer supporter;

}

1.3、mysql-provider暴露接口

1.3.1、Mapper层
1、Mapper接口
  • 查询分类信息(分类信息中包含项目信息)

image-20200705211755218

List<PortalTypeVO> selectPortalTypeVOList();
2、Mapper映射文件
  • selectPortalTypeVOList对应着Mapper接口中声明的方法,由于还需查询t_project项目表和t_project_type项目分类中间表,封装resultMap指定PortalTypeVO类中的各个字段该如何查询
  • loadPortalProjectListResultMap返回类型为PortalTypeVO类的对象(或PortalTypeVO类的集合)
    • <id .../>指定主键列
    • <result .../>指定普通列
    • <collection .../>用于封装List<PortalProjectVO>集合
      • property指定该集合对应的属性名
      • column="id":用列名为id的列作为参数进行查询
      • ofType:该集合中每个元素是PortalProjectVO类型
      • select:指定select查询语句(如何查询出这个集合)
  • selectPortalProjectVOList查询语句使用左外连接查询
    • resultType:查询出来的数据封装至PortalProjectVO对象中
    • 可以这样理解:根据typeId查询中间表可以得到projectId,再根据projectId即可查询到项目信息
    • #{id}:传入的参数(typeId

image-20200705211817346

<select id="selectPortalTypeVOList" resultMap="loadPortalProjectListResultMap">
	select id,name,remark from t_type
</select>

<resultMap type="com.atguigu.crowd.entity.vo.PortalTypeVO" id="loadPortalProjectListResultMap">

	<!-- 分类数据的常规属性 -->
	<id column="id" property="id"/>
	<result column="name" property="name"/>
	<result column="remark" property="remark"/>
	
	<!-- 分类数据中包含的项目数据的List -->
	<!-- property属性:对应PortalTypeVO中分类数据中的项目数据的List属性 -->
	<!-- column属性:接下来查询项目时需要用到分类id,就是通过column属性把值传入 -->
	<!-- ofType属性:项目数据的实体类型PortalProjectVO -->
	<collection 
		property="portalProjectVOList" 
		column="id" 
		ofType="com.atguigu.crowd.entity.vo.PortalProjectVO" 
		select="com.atguigu.crowd.mapper.ProjectPOMapper.selectPortalProjectVOList"/>
</resultMap>

<select id="selectPortalProjectVOList" resultType="com.atguigu.crowd.entity.vo.PortalProjectVO">
	SELECT 
		t_project.id projectId,
		project_name projectName,
		money,
		deploydate deployDate,
		supportmoney/money*100 percentage,
		supporter supporter,
		header_picture_path headerPicturePath 
		FROM t_project LEFT JOIN t_project_type ON t_project.id=t_project_type.projectid
	WHERE t_project_type.typeid=#{id}
	ORDER BY t_project.id DESC
	LIMIT 0,4
</select>
3、测试SQL
  • 创建测试方法

image-20200705212444843

@Test
public void testLoadTypeData() {
    List<PortalTypeVO> typeVOList = projectPOMapper.selectPortalTypeVOList();

    for (PortalTypeVO portalTypeVO : typeVOList) {
        String name = portalTypeVO.getName();
        String remark = portalTypeVO.getRemark();
        logger.info("name="+name+" remark="+remark);

        List<PortalProjectVO> projectVOList = portalTypeVO.getPortalProjectVOList();
        for (PortalProjectVO portalProjectVO : projectVOList) {

            if(portalProjectVO == null) {
                continue;
            }

            logger.info(portalProjectVO.toString());
        }

    }
}
  • 测试结果
2020-07-05 21:48:30.736 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalTypeVOList         : ==>  Preparing: select id,name,remark from t_type 
2020-07-05 21:48:30.757 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalTypeVOList         : ==> Parameters: 
2020-07-05 21:48:30.775 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====>  Preparing: SELECT t_project.id projectId, project_name projectName, money, deploydate deployDate, supportmoney/money*100 percentage, supporter supporter, header_picture_path headerPicturePath FROM t_project LEFT JOIN t_project_type ON t_project.id=t_project_type.projectid WHERE t_project_type.typeid=? ORDER BY t_project.id DESC LIMIT 0,4 
2020-07-05 21:48:30.776 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====> Parameters: 1(Integer)
2020-07-05 21:48:30.778 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : <====      Total: 4
2020-07-05 21:48:30.779 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====>  Preparing: SELECT t_project.id projectId, project_name projectName, money, deploydate deployDate, supportmoney/money*100 percentage, supporter supporter, header_picture_path headerPicturePath FROM t_project LEFT JOIN t_project_type ON t_project.id=t_project_type.projectid WHERE t_project_type.typeid=? ORDER BY t_project.id DESC LIMIT 0,4 
2020-07-05 21:48:30.779 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====> Parameters: 2(Integer)
2020-07-05 21:48:30.780 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : <====      Total: 4
2020-07-05 21:48:30.780 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====>  Preparing: SELECT t_project.id projectId, project_name projectName, money, deploydate deployDate, supportmoney/money*100 percentage, supporter supporter, header_picture_path headerPicturePath FROM t_project LEFT JOIN t_project_type ON t_project.id=t_project_type.projectid WHERE t_project_type.typeid=? ORDER BY t_project.id DESC LIMIT 0,4 
2020-07-05 21:48:30.781 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====> Parameters: 3(Integer)
2020-07-05 21:48:30.782 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : <====      Total: 4
2020-07-05 21:48:30.782 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====>  Preparing: SELECT t_project.id projectId, project_name projectName, money, deploydate deployDate, supportmoney/money*100 percentage, supporter supporter, header_picture_path headerPicturePath FROM t_project LEFT JOIN t_project_type ON t_project.id=t_project_type.projectid WHERE t_project_type.typeid=? ORDER BY t_project.id DESC LIMIT 0,4 
2020-07-05 21:48:30.783 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : ====> Parameters: 4(Integer)
2020-07-05 21:48:30.785 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalProjectVOList      : <====      Total: 4
2020-07-05 21:48:30.785 DEBUG 14960 --- [           main] c.a.c.m.P.selectPortalTypeVOList         : <==      Total: 4
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : name=科技 remark=开启智障未来
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=6, projectName=四合一04, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=5, projectName=四合一03, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=4, projectName=四合一02, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=3, projectName=四合一01, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : name=设计 remark=设计,开启智障未来
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=6, projectName=四合一04, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=5, projectName=四合一03, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=4, projectName=四合一02, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=3, projectName=四合一01, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : name=农业 remark=我会种辣椒
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=6, projectName=四合一04, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=5, projectName=四合一03, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=4, projectName=四合一02, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=3, projectName=四合一01, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : name=工艺 remark=讲个笑话,红十字会
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=6, projectName=四合一04, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=5, projectName=四合一03, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=4, projectName=四合一02, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
2020-07-05 21:48:30.786  INFO 14960 --- [           main] com.atguigu.crowd.test.MyBatisTest       : PortalProjectVO(projectId=3, projectName=四合一01, headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg, money=100000, deployDate=2020-07-05, percentage=10, supporter=50)
  • 数据库中有四个分类,每个分类包含四个众筹项目

image-20200705215021554

1.3.2、Service层
  • Service层调用Mapper层方法,获取分类数据

image-20200706155804027

@Override
public List<PortalTypeVO> getPortalTypeVO() {
    return projectPOMapper.selectPortalTypeVOList();
}
1.3.3、Handler层
  • Handler层调用Service层,获取分类信息,并返回json字符串,供consumer端调用

image-20200706160011615

@RequestMapping("/get/portal/type/project/data/remote")
public ResultEntity<List<PortalTypeVO>> getPortalTypeProjectDataRemote() {

    try {
        List<PortalTypeVO> portalTypeVOList = projectService.getPortalTypeVO();

        return ResultEntity.successWithData(portalTypeVOList);
    } catch (Exception e) {
        e.printStackTrace();

        return ResultEntity.failed(e.getMessage());
    }

}
1.3.4、测试接口
  • 访问地址:http://localhost:2000/get/portal/type/project/data/remote

image-20200706160256004

1.4、api远程方法声明

  • api工程中声明远程方法(需与mysql-provider中的声明一致)

image-20200706160517306

@RequestMapping("/get/portal/type/project/data/remote")
public ResultEntity<List<PortalTypeVO>> getPortalTypeProjectDataRemote();

1.5、常量定义

  • 定义工程中所需要用到的常量

image-20200706160649702

public class CrowdConstant {
	
	public static final String MESSAGE_LOGIN_FAILED = "抱歉!账号密码错误!请重新输入!";
	public static final String MESSAGE_LOGIN_ACCT_ALREADY_IN_USE = "抱歉!这个账号已经被使用了!";
	public static final String MESSAGE_ACCESS_FORBIDEN = "请登录以后再访问!";
	public static final String MESSAGE_STRING_INVALIDATE = "字符串不合法!请不要传入空字符串!";
	public static final String MESSAGE_SYSTEM_ERROR_LOGIN_NOT_UNIQUE = "系统错误:登录账号不唯一!";
	public static final String MESSAGE_ACCESS_DENIED = "抱歉!您不能访问这个资源!";
	public static final String MESSAGE_CODE_NOT_EXISTS = "验证码已过期!请检查手机号是否正确或重新发送!";
	public static final String MESSAGE_CODE_INVALID = "验证码不正确!";
	public static final String MESSAGE_HEADER_PIC_UPLOAD_FAILED = "头图上传失败!";
	public static final String MESSAGE_HEADER_PIC_EMPTY = "头图不可为空!";
	public static final String MESSAGE_DETAIL_PIC_EMPTY = "详情图片不可为空!";
	public static final String MESSAGE_DETAIL_PIC_UPLOAD_FAILED = "详情图片上传失败!";
	public static final String MESSAGE_TEMPLE_PROJECT_MISSING = "临时存储的Project对象丢失!";
	
	public static final String ATTR_NAME_EXCEPTION = "exception";
	public static final String ATTR_NAME_LOGIN_ADMIN = "loginAdmin";
	public static final String ATTR_NAME_LOGIN_MEMBER = "loginMember";
	public static final String ATTR_NAME_PAGE_INFO = "pageInfo";
	public static final String ATTR_NAME_MESSAGE = "message";
	public static final String ATTR_NAME_TEMPLE_PROJECT = "tempProject";
	public static final String ATTR_NAME_PORTAL_DATA = "portal_data";
	
	public static final String REDIS_CODE_PREFIX = "REDIS_CODE_PREFIX_";

}

1.6、auth-consumer调用接口

  • auth-consumer工程中调用mysql-provider中的远程方法获取分类数据,并放在Model域中,以供页面显示

image-20200706160748096

@Controller
public class PortalHandler {
	
	@Autowired
	private MySQLRemoteService mySQLRemoteService;
	
	@RequestMapping("/")
	public String showPortalPage(Model model) {
		
		// 1、调用MySQLRemoteService提供的方法查询首页要显示的数据
		ResultEntity<List<PortalTypeVO>> resultEntity = 
				mySQLRemoteService.getPortalTypeProjectDataRemote();
		
		// 2.检查查询结果
		String result = resultEntity.getResult();
		if(ResultEntity.SUCCESS.equals(result)) {
			
			// 3.获取查询结果数据
			List<PortalTypeVO> list = resultEntity.getData();
			
			// 4.存入模型
			model.addAttribute(CrowdConstant.ATTR_NAME_PORTAL_DATA, list);
			
		}
		
		return "portal";
	}

}

1.7、首页显示数据

  • 在首页中,从request域中取出数据,并显示

image-20200706161047342

<div th:if="${#strings.isEmpty(portal_data)}">没有加载到任何分类信息</div>
<div th:if="${not #strings.isEmpty(portal_data)}">
	<div th:each="type : ${portal_data}" class="container">
		<div class="row clearfix">
			<div class="col-md-12 column">
				<div class="box ui-draggable" id="mainBox">
					<div class="mHd" style="">
						<div class="path">
							<a href="projects.html">更多...</a>
						</div>
						<h3>
							<label th:text="${type.name}">科技</label> <small style="color: #FFF;" th:text="${type.remark}">开启智慧未来</small>
						</h3>
					</div>
					<div class="mBd" style="padding-top: 10px;">
						<div class="row">
							<div th:if="${#strings.isEmpty(type.portalProjectVOList)}">该分类下还没有任何项目</div>
							<div th:if="${not #strings.isEmpty(type.portalProjectVOList)}">
								<div th:each="project : ${type.portalProjectVOList}" class="col-md-3">
									<div class="thumbnail">
										<img alt="300x200" th:src="${project.headerPicturePath}" src="img/product-1.jpg" />
										<div class="caption">
											<h3 class="break">
												<a th:href="'http://www.crowd.com/project/get/project/detail/'+${project.projectId}" href="project.html" th:text="${project.projectName}">活性富氢净水直饮机</a>
											</h3>
											<div style="float: left;">
												<i class="glyphicon glyphicon-screenshot" title="目标金额"></i>
												$<span th:text="${project.money}">20,000</span>
											</div>
											<div style="float: right;">
												<i title="截至日期" class="glyphicon glyphicon-calendar"></i>
												<span th:text="${project.deployDate}">2017-20-20</span>
											</div>
											<br>
											<div class="progress" style="margin-bottom: 4px;">
												<div class="progress-bar progress-bar-success"
													role="progressbar" th:aria-valuenow="${project.percentage}" aria-valuenow="40" aria-valuemin="0"
													aria-valuemax="100" th:style="'width: '+${project.percentage}+'%'" style="width: 40%">
													<span th:text="${project.percentage}+'% '">40% </span>
												</div>
											</div>
											<div>
												<span style="float: right;"><i
													class="glyphicon glyphicon-star-empty"></i></span> <span><i
													class="glyphicon glyphicon-user" title="支持人数"></i> <span th:text="${project.supporter}">12345</span></span>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>

			</div>
		</div>
	</div>
</div>

1.8、测试首页项目显示

  • 成功

image-20200706161430933

2、显示项目详情

2.1、整体思路

image-20201002143158472

2.2、创建VO

2.2.1、回报VO
  • DetailReturnVO:页面回报信息VO

image-20200706165128600

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DetailReturnVO {
	
	// 回报信息主键
	private Integer returnId;
	
	// 当前档位需支持的金额
	private Integer supportMoney;
	
	// 单笔限购,取值为0时无限额,取值为1时有限额
	private Integer signalPurchase;
	
	// 具体限额数量
	private Integer purchase;
	
	// 当前该档位支持者数量
	private Integer supporterCount;
	
	// 运费,取值为0时表示包邮
	private Integer freight;
	
	// 众筹成功后多少天发货
	private Integer returnDate;
	
	// 回报内容
	private String content;

}
2.2.2、项目VO
  • DetailProjectVO:页面项目信息VOList<DetailReturnVO>:回报信息的List

image-20200706165209387

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DetailProjectVO {
	
	private Integer projectId;
	private String projectName;
	private String projectDesc;
	private Integer followerCount;
	private Integer status;
	private Integer day;
	private String statusText;
	private Integer money;
	private Integer supportMoney;
	private Integer percentage;
	private String deployDate;
	private Integer lastDay;
	private Integer supporterCount;
	private String headerPicturePath;
	private List<String> detailPicturePathList;
	private List<DetailReturnVO> detailReturnVOList;

}

2.3、Mapper层

2.3.1、Mapper接口
  • Mapper接口中声明方法

image-20200706165431104

DetailProjectVO selectDetailProjectVO(Integer projectId);
2.3.2、Mapper映射文件
  • Mapper.xml映射文件中编写SQL语句
    • 由于需要查询多张表,并封装为VO对象,用resultMap="loadProjectDetailResultMap"指定数据库查询得到的数据与Java实体类之间的对应关系
    • resultMap="loadProjectDetailResultMap"
      • <id .../>:主键列
        • column:列名
        • property:属性名
      • <result .../>:普通列
        • column:列名
        • property:属性名
      • <collection .../>:集合列
        • property:属性名
        • select:查询的SQL语句
        • column:使用那个列作为参数进行查询
        • 由于select中会指定resultType,所以这里我们无须指定oftype属性

image-20200706165729275

<select id="selectDetailProjectVO" resultMap="loadProjectDetailResultMap">
	select 
		id,
		project_name,
		project_description ,
		money,
		status,
		day,
		deploydate,
		supportmoney,
		supporter,
		supportmoney/money*100 percentage,
		follower,
		header_picture_path
	from 
		t_project
	where id=#{projectId}
</select>

<resultMap type="com.atguigu.crowd.entity.vo.DetailProjectVO" id="loadProjectDetailResultMap">
	<id column="id" property="projectId"/>
	<result column="project_name" property="projectName"/>
	<result column="project_description" property="projectDesc"/>
	<result column="money" property="money"/>
	<result column="status" property="status"/>
	<result column="day" property="day"/>
	<result column="deploydate" property="deployDate"/>
	<result column="supportmoney" property="supportMoney"/>
	<result column="follower" property="followerCount"/>
	<result column="supporter" property="supporterCount"/>
	<result column="header_picture_path" property="headerPicturePath"/>
	<collection 
		property="detailPicturePathList" 
		select="com.atguigu.crowd.mapper.ProjectPOMapper.selectDetailPicturePath" 
		column="id"/>
		
	<collection 
		property="detailReturnVOList" 
		select="com.atguigu.crowd.mapper.ProjectPOMapper.selectDeatailReturnVO" 
		column="id"/>
</resultMap>

<select id="selectDetailPicturePath" resultType="string">
	SELECT item_pic_path FROM t_project_item_pic WHERE projectid=#{id}
</select>

<select id="selectDeatailReturnVO" resultType="com.atguigu.crowd.entity.vo.DetailReturnVO">
	select
		id returnId,
		supportmoney supportMoney, 
		content, 
		signalpurchase signalPurchase, 
		purchase, 
		freight, 
		returndate returnDate
	from t_return
	where projectid=#{id}
</select>
2.3.3、测试SQL
1、测试代码

image-20200706172534912

@Test
public void testLoadDetailProjectVO() {
	
	Integer projectId = 6;
	
	DetailProjectVO detailProjectVO = projectPOMapper.selectDetailProjectVO(projectId);
	
	logger.info("projectId=" + detailProjectVO.getProjectId());
	logger.info("projectName=" + detailProjectVO.getProjectName());
	logger.info("projectDesc=" + detailProjectVO.getProjectDesc());
	logger.info("followerCount=" + detailProjectVO.getFollowerCount());
	logger.info("status:" + detailProjectVO.getStatus());
	logger.info("money=" + detailProjectVO.getMoney());
	logger.info("supportMoney=" + detailProjectVO.getSupportMoney());
	logger.info("percentage=" + detailProjectVO.getPercentage());
	logger.info("deployDate=" + detailProjectVO.getDeployDate());
	logger.info("supporterCount=" + detailProjectVO.getSupporterCount());
	logger.info("headerPicturePath=" + detailProjectVO.getHeaderPicturePath());
	
	List<String> detailPicturePathList = detailProjectVO.getDetailPicturePathList();
	for (String path : detailPicturePathList) {
		logger.info("detail path="+path);
	}
	
	List<DetailReturnVO> detailReturnVOList = detailProjectVO.getDetailReturnVOList();
	for (DetailReturnVO detailReturnVO : detailReturnVOList) {
		logger.info("detail return="+detailReturnVO.toString());
	}
	
}
2、测试结果
2020-07-06 17:16:51.525 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailProjectVO          : ==>  Preparing: select id, project_name, project_description , money, status, day, deploydate, supportmoney, supporter, supportmoney/money*100 percentage, follower, header_picture_path from t_project where id=? 
2020-07-06 17:16:51.543 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailProjectVO          : ==> Parameters: 6(Integer)
2020-07-06 17:16:51.559 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailPicturePath        : ====>  Preparing: SELECT item_pic_path FROM t_project_item_pic WHERE projectid=? 
2020-07-06 17:16:51.559 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailPicturePath        : ====> Parameters: 6(Integer)
2020-07-06 17:16:51.561 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailPicturePath        : <====      Total: 1
2020-07-06 17:16:51.561 DEBUG 29044 --- [           main] c.a.c.m.P.selectDeatailReturnVO          : ====>  Preparing: select id returnId, supportmoney supportMoney, content, signalpurchase signalPurchase, purchase, freight, returndate returnDate from t_return where projectid=? 
2020-07-06 17:16:51.561 DEBUG 29044 --- [           main] c.a.c.m.P.selectDeatailReturnVO          : ====> Parameters: 6(Integer)
2020-07-06 17:16:51.562 DEBUG 29044 --- [           main] c.a.c.m.P.selectDeatailReturnVO          : <====      Total: 2
2020-07-06 17:16:51.563 DEBUG 29044 --- [           main] c.a.c.m.P.selectDetailProjectVO          : <==      Total: 1
2020-07-06 17:16:51.563  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : projectId=6
2020-07-06 17:16:51.563  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : projectName=四合一04
2020-07-06 17:16:51.563  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : projectDesc=就是帅!
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : followerCount=50
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : status:0
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : money=100000
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : supportMoney=10000
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : percentage=10
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : deployDate=2020-07-05
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : supporterCount=50
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : headerPicturePath=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/9c779c13200c40369f325ab25c2787dc.jpg
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : detail path=http://heygo.oss-cn-shanghai.aliyuncs.com/20200705/ea81b7599b4e44fb86388d24deb53ab3.jpg
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : detail return=DetailReturnVO(returnId=12, supportMoney=10, signalPurchase=0, purchase=8, supporterCount=null, freight=0, returnDate=15, content=以身相许)
2020-07-06 17:16:51.564  INFO 29044 --- [           main] com.atguigu.crowd.test.MyBatisTest       : detail return=DetailReturnVO(returnId=13, supportMoney=10, signalPurchase=0, purchase=8, supporterCount=null, freight=0, returnDate=15, content=精神鼓励)
  • 第一条SQL查询的主键列projectId=6,作为参数传入了之后的两条SQL语句中,所以说一共执行了三条SQL语句
==>  Preparing: select id, project_name, project_description , money, status, day, deploydate, supportmoney, supporter, supportmoney/money*100 percentage, follower, header_picture_path from t_project where id=? 
==> Parameters: 6(Integer)
====>  Preparing: SELECT item_pic_path FROM t_project_item_pic WHERE projectid=? 
====> Parameters: 6(Integer)
<====      Total: 1
====>  Preparing: select id returnId, supportmoney supportMoney, content, signalpurchase signalPurchase, purchase, freight, returndate returnDate from t_return where projectid=? 
====> Parameters: 6(Integer)
<====      Total: 2
<==      Total: 1

2.4、mysql-provider暴露接口

2.4.1、Service方法
  • getDetailProjectVO方法:根据projectId查询项目信息(包含回报信息)

image-20200706185808101

@Override
public DetailProjectVO getDetailProjectVO(Integer projectId) {
	
	// 1.查询得到DetailProjectVO对象
	DetailProjectVO detailProjectVO = projectPOMapper.selectDetailProjectVO(projectId);
	
	// 2.根据status确定statusText
	Integer status = detailProjectVO.getStatus();
	
	switch (status) {
	case 0:
		detailProjectVO.setStatusText("审核中");
		break;
	case 1:
		detailProjectVO.setStatusText("众筹中");
		break;
	case 2:
		detailProjectVO.setStatusText("众筹成功");
		break;
	case 3:
		detailProjectVO.setStatusText("已关闭");
		break;

	default:
		break;
	}
	
	// 3.根据deployeDate计算lastDay
	// 2020-10-15
	String deployDate = detailProjectVO.getDeployDate();
	
	// 获取当前日期
	Date currentDay = new Date();
	
	// 把众筹日期解析成Date类型
	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	try {
		Date deployDay = format.parse(deployDate);
		
		// 获取当前当前日期的时间戳
		long currentTimeStamp = currentDay.getTime();
		
		// 获取众筹日期的时间戳
		long deployTimeStamp = deployDay.getTime();
		
		// 两个时间戳相减计算当前已经过去的时间
		long pastDays = (currentTimeStamp - deployTimeStamp) / 1000 / 60 / 60 / 24;
		
		// 获取总的众筹天数
		Integer totalDays = detailProjectVO.getDay();
		
		// 使用总的众筹天数减去已经过去的天数得到剩余天数
		Integer lastDay = (int) (totalDays - pastDays);
		
		detailProjectVO.setLastDay(lastDay);
		
	} catch (ParseException e) {
		e.printStackTrace();
	}
	
	return detailProjectVO;
	
}
2.4.2、Handler方法
  • 获取项目信息,返回给调用者

image-20200706185937884

@RequestMapping("/get/project/detail/remote/{projectId}")
public ResultEntity<DetailProjectVO> getDetailProjectVORemote(@PathVariable("projectId") Integer projectId) {
	
	try {
		DetailProjectVO detailProjectVO = projectService.getDetailProjectVO(projectId);
		
		return ResultEntity.successWithData(detailProjectVO);
		
	} catch (Exception e) {
		e.printStackTrace();
		
		return ResultEntity.failed(e.getMessage());
	}
	
}

2.5、api远程方法声明

  • api工程中声明远程方法(需与mysql-provider中的声明一致)

image-20200706160517306

@RequestMapping("/get/project/detail/remote/{projectId}")
public ResultEntity<DetailProjectVO> getDetailProjectVORemote(@PathVariable("projectId") Integer projectId);

2.6、project-consumer调用接口

  • project-consumer工程中调用mysql-provider微服务中的远程方法

image-20200706190224574

@RequestMapping("/get/project/detail/{projectId}")
public String getProjectDetail(@PathVariable("projectId") Integer projectId, Model model) {
	
	ResultEntity<DetailProjectVO> resultEntity = mySQLRemoteService.getDetailProjectVORemote(projectId);
	
	if(ResultEntity.SUCCESS.equals(resultEntity.getResult())) {
		DetailProjectVO detailProjectVO = resultEntity.getData();
		
		model.addAttribute("detailProjectVO", detailProjectVO);
	}
	
	return "project-show-detail";
}

2.7、创建项目详情页面

  • 创建project-show-detail.html页面,用于显示项目详情
<!-- 显示项目头图和项目详情图片 -->
<img alt="140x140" width="740" src="img/product_detail_head.jpg" th:src="${detailProjectVO.headerPicturePath}" />
<img alt="140x140" width="740" src="img/product_detail_body.jpg" th:each="detailPicturePath : ${detailProjectVO.detailPicturePathList}" th:src="${detailPicturePath}" />

<!-- 显示项目详情信息 -->
<div th:if="${#strings.isEmpty(detailProjectVO)}">查询项目详情信息失败!</div>
<div th:if="${not #strings.isEmpty(detailProjectVO)}">
	<div class="container">
		<div class="row clearfix">
			<div class="col-md-12 column">
				<div class="jumbotron nofollow" style="padding-top: 10px;">
					<h3 th:text="${detailProjectVO.projectName}">酷驰触控龙头,智享厨房黑科技</h3>
					<div style="float: left; width: 70%;" th:text="${detailProjectVO.projectDesc}">智能时代,酷驰触控厨房龙头,让煮妇解放双手,触发更多烹饪灵感,让美味信手拈来。</div>
					<div style="float: right;">
						<button type="button" class="btn btn-default">
							<i style="color: #f60" class="glyphicon glyphicon-heart"></i>
							关注[[${detailProjectVO.followerCount}]]
						</button>
					</div>
				</div>
			</div>
		</div>
	</div>
	<div class="container">
		<div class="row clearfix">
			<div class="col-md-12 column">
				<div class="row clearfix">
					<div class="col-md-8 column" th:if="${#strings.isEmpty(detailProjectVO.detailPicturePathList)}">加载详情信息失败</div>
					<div class="col-md-8 column" th:if="${not #strings.isEmpty(detailProjectVO.detailPicturePathList)}">
						<img alt="140x140" width="740" src="img/product_detail_head.jpg" th:src="${detailProjectVO.headerPicturePath}" />
						<img alt="140x140" width="740" src="img/product_detail_body.jpg" th:each="detailPicturePath : ${detailProjectVO.detailPicturePathList}" th:src="${detailPicturePath}" />
					</div>
					<div class="col-md-4 column">
						<div class="panel panel-default" style="border-radius: 0px;">
							<div class="panel-heading"
								style="background-color: #fff; border-color: #fff;">
								<span class="label label-success"><i
									class="glyphicon glyphicon-tag"></i> [[${detailProjectVO.statusText}]]</span>
							</div>
							<div class="panel-body">
								<h3>已筹资金:¥[[${detailProjectVO.supportMoney}]]</h3>
								<p>
									<span>目标金额 : [[${detailProjectVO.money}]]</span><span style="float: right;">达成
										: [[${detailProjectVO.percentage}]]%</span>
								</p>
								<div class="progress"
									style="height: 10px; margin-bottom: 5px;">
									<div class="progress-bar progress-bar-success"
										role="progressbar" aria-valuenow="[[${detailProjectVO.percentage}]]" aria-valuemin="0"
										aria-valuemax="100" style="width: 60%;" th:style="'width: '+${detailProjectVO.percentage}+'%;'"></div>
								</div>
								<p>剩余 [[${detailProjectVO.lastDay}]] 天</p>
								<div>
									<p>
                                        	<span>已有[[${detailProjectVO.supporterCount}]]人支持该项目</span>
									</p>
									<button type="button"
										class="btn  btn-warning btn-lg btn-block"
										data-toggle="modal" data-target="#myModal">立即支持</button>
								</div>
							</div>
							<div class="panel-footer"
								style="background-color: #fff; border-top: 1px solid #ddd; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;">
								<div class="container-fluid">
									<div class="row clearfix">
										<div class="col-md-3 column" style="padding: 0;">
											<img alt="140x140" src="img/services-box2.jpg"
												data-holder-rendered="true"
												style="width: 80px; height: 80px;">
										</div>
										<div class="col-md-9 column">
											<div class="">
												<h4>
													<b>福建省南安厨卫</b> <span
														style="float: right; font-size: 12px;"
														class="label label-success">已认证</span>
												</h4>
												<p style="font-size: 12px">
													酷驰是一家年轻的厨卫科技公司,我们有一支朝气蓬勃,有激情、有想法、敢实践的团队。</p>
												<p style="font-size: 12px">客服电话:0595-86218855</p>
											</div>
										</div>
									</div>
								</div>
							</div>
						</div>
						<div th:if="${#strings.isEmpty(detailProjectVO.detailReturnVOList)}">没有加载到项目回报信息</div>
						<div th:if="${not #strings.isEmpty(detailProjectVO.detailReturnVOList)}">
							<div th:each="return : ${detailProjectVO.detailReturnVOList}" class="panel panel-default" style="border-radius: 0px;">
								<div class="panel-heading">
									<h3>
										¥[[${return.supportMoney}]]
										<span th:if="${return.signalPurchase == 0}" style="float: right; font-size: 12px;">无限额,447位支持者</span>
										<span th:if="${return.signalPurchase == 1}" style="float: right; font-size: 12px;">限额[[${return.purchase}]]位,剩余1966位</span>
									</h3>
								</div>
								<div class="panel-body">
									<p th:if="${return.freight==0}">配送费用:包邮</p>
									<p th:if="${return.freight>0}">配送费用:[[${return.freight}]]</p>
									<p>预计发放时间:项目筹款成功后的[[${return.returnDate}]]天内</p>
									<button type="button" class="btn  btn-warning btn-lg"
										onclick="window.location.href='pay-step-1.html'">支持</button>
									<br>
									<br>
									<p th:text="${return.content}">感谢您的支持,在众筹开始后,您将以79元的优惠价格获得“遇见彩虹?”智能插座一件(参考价208元)。</p>
								</div>
							</div>
						</div>
						<div class=" panel panel-default" style="border-radius: 0px;">
							<div class="panel-heading">
								<h3>风险提示</h3>
							</div>
							<div class="panel-body">
								<p>
									1.众筹并非商品交易,存在一定风险。支持者根据自己的判断选择、支持众筹项目,与发起人共同实现梦想并获得发起人承诺的回报。<br>
									2.众筹平台仅提供平台网络空间及技术支持等中介服务,众筹仅存在于发起人和支持者之间,使用众筹平台产生的法律后果由发起人与支持者自行承担。<br>
									3.本项目必须在2017-06-09之前达到¥10000.00
									的目标才算成功,否则已经支持的订单将取消。订单取消或募集失败的,您支持的金额将原支付路径退回。<br>
									4.请在支持项目后15分钟内付款,否则您的支持请求会被自动关闭。<br>
									5.众筹成功后由发起人统一进行发货,售后服务由发起人统一提供;如果发生发起人无法发放回报、延迟发放回报、不提供回报后续服务等情况,您需要直接和发起人协商解决。<br>
									6.如您不同意上述风险提示内容,您有权选择不支持;一旦选择支持,视为您已确认并同意以上提示内容。
								</p>
							</div>
						</div>

						<div>
							<h2>为你推荐</h2>
							<hr>
						</div>
						<div class="prjtip panel panel-default"
							style="border-radius: 0px;">
							<div class="panel-body">
								<img src="img/product-3.png" width="100%" height="100%">
							</div>
						</div>

						<div class="prjtip panel panel-default"
							style="border-radius: 0px;">
							<div class="panel-body">
								<img src="img/product-4.jpg" width="100%" height="100%">
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div>
</div>

2.8、测试

  • 成功啦~~~

image-20200706191631506

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值