请求日账单接口

本文档详细记录了一个实现连表查询并进行分页的API接口过程。涉及内容包括接口文档编写、DAO层实现、Entity与Mapper设计、时间转换、响应参数类、Service与ServiceImpl、拦截器以及Controller的编写。最后通过Postman测试接口,确保其正常工作。
摘要由CSDN通过智能技术生成

记录一个连表查询加分页的接口

table: api-request-daily  产品日统计表  

          product  产品表

项目结构:

matedata-app :service controller..

matedata-comon:entity,mapper..

1.写接口文档 ,确定需求 (GET   只有请求参数 ,无请求体 )

- 请求方式及地址

`GET` - `/product/{productCode}/daily-bill`

- 请求头

| 参数名 | 类型 | 说明 |
| :---: | :---: | :---: |
| token | string | 登录凭证 |

- 请求参数

| 参数名 | 类型 | 是否必传 | 说明 |
| :---: | :---: | :---: | :---: |
| startDate| string | 是 | 起始日,如“2019-03-01” |
| endDate| string | 是 | 截止日,如“2019-03-31” |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 分页量 |
- 响应体

| 参数名 | 类型 | 说明 |
| :---: | :---: | :---: |
| code | int | 状态码 |
| message | string | 状态信息 |
| total | long | 总数 |
| list  | JsonArray | 数据列表 |


    list集合

| 参数名 | 类型 | 说明 |
| :---: | :---: | :---: |
| statsDay| string| 统计日 |
| apiName| string | 接口名称 |
| requestQty | long | 请求次数 |
| chargeQty | long | 计费次数 |
| chargeAmt| string | 计费金额 |


- 响应体示例:
```
{
    "code": 0,
    "message": "ok",
    "total": 12,
    "list": [
        {
            "code": "P100001",
            "statsDay": "2019-01-28",
            "requestQty": 1,
            "chargeQty": 1,
            "chargeAmt": 100000
        },
        {
            "code": "P100001",
            "statsDay": "2019-01-30",
            "requestQty": 71517,
            "chargeQty": 66991,
            "chargeAmt": 6699100
        },
        {
            "code": "P100001",
            "statsDay": "2019-01-31",
            "requestQty": 538,
            "chargeQty": 329,
            "chargeAmt": 32900
        }
    ]
}
```

 

2.dao层的实现 在atedata-comon 完成

 2.1新建一个entity保存 查询出来的列段 (前面加 V  eg.VApiRequestDaily)

package net.matedata.common.domain.entity;

public class VApiRequestDaily
{
    private Integer statsDay;
    private String apiName;
    private Long requestQty;
    private Long chargeQty;
    private Long chargeAmt;

    public Integer getStatsDay()
    {
        return statsDay;
    }

    public void setStatsDay(Integer statsDay)
    {
        this.statsDay = statsDay;
    }

    public String getApiName()
    {
        return apiName;
    }

    public void setApiName(String apiName)
    {
        this.apiName = apiName;
    }

    public Long getRequestQty()
    {
        return requestQty;
    }

    public void setRequestQty(Long requestQty)
    {
        this.requestQty = requestQty;
    }

    public Long getChargeQty()
    {
        return chargeQty;
    }

    public void setChargeQty(Long chargeQty)
    {
        this.chargeQty = chargeQty;
    }

    public Long getChargeAmt()
    {
        return chargeAmt;
    }

    public void setChargeAmt(Long chargeAmt)
    {
        this.chargeAmt = chargeAmt;
    }

}

新建 mapper

package net.matedata.common.domain.mapper;

import net.matedata.common.domain.entity.VApiRequestDaily;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface VApiRequestDailyMapper
{
    List<VApiRequestDaily> getListByParam(@Param("merchantId") Long merchantId,
            @Param("productCode") String productCOde, @Param("startDate") Integer startDate,
            @Param("endDate") Integer endDate);
}

mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="net.matedata.common.domain.mapper.VApiRequestDailyMapper">
    <resultMap id="BaseResultMap" type="VApiRequestDaily">
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="stats_day" property="statsDay" jdbcType="INTEGER" />
        <result column="api_name" property="apiName" jdbcType="VARCHAR" />
        <result column="request_qty" property="requestQty" jdbcType="BIGINT" />
        <result column="charge_qty" property="chargeQty" jdbcType="BIGINT" />
        <result column="charge_amt" property="chargeAmt" jdbcType="BIGINT" />
    </resultMap>

    <!-- @formatter:off -->
    <select id="getListByParam" resultMap="BaseResultMap">
        select
            a.`stats_day`   as stats_day,
            b.`code`        as api_code,
            b.`name`        as api_name,
            a.`request_qty` as request_qty,
            a.`charge_qty`  as charge_qty,
            a.`charge_amt`  as charge_amt
        from `api_request_daily` a
            left join `product_api` b
                on a.`product_api_code` = b.`code`
        <where>
            <if test="merchantId != null">and a.`merchant_id` = #{merchantId}</if>
            <if test="productCode != null">and a.`product_code` = #{productCode}</if>
            <if test="startDay != null">and `stats_day` >= #{startDay}</if>
            <if test="endDay != null">and `stats_day` &lt; #{endDay}</if>
        </where>
        order by a.`create_time` desc
    </select>
    <!-- @formatter:on -->
</mapper>

 

3.matedata-app

get  没有请求体,只有请求参数

 

 创建响应参数类  DailyRes

package net.matedata.app.model.response;

public class DailyRes
{
    private String statsDay;
    private String apiName;
    private Long requestQty;
    private Long chargeQty;
    private String chargeAmt;

    public String getStatsDay()
    {
        return statsDay;
    }

    public void setStatsDay(String statsDay)
    {
        this.statsDay = statsDay;
    }

    public String getApiName()
    {
        return apiName;
    }

    public void setApiName(String apiName)
    {
        this.apiName = apiName;
    }

    public Long getRequestQty()
    {
        return requestQty;
    }

    public void setRequestQty(Long requestQty)
    {
        this.requestQty = requestQty;
    }

    public Long getChargeQty()
    {
        return chargeQty;
    }

    public void setChargeQty(Long chargeQty)
    {
        this.chargeQty = chargeQty;
    }

    public String getChargeAmt()
    {
        return chargeAmt;
    }

    public void setChargeAmt(String chargeAmt)
    {
        this.chargeAmt = chargeAmt;
    }
}

service

package net.matedata.app.service;

import net.matedata.app.model.request.DailyReq;
import net.matedata.app.model.response.DailyRes;
import net.matedata.app.model.response.MerProductRes;
import net.matedata.app.model.response.MyProductRes;
import net.matedata.common.model.PageResp;
import net.matedata.common.model.QueryPage;

public interface ProductService
{
   

    void getListByParam(String productCode, Date startDate, Date endDate, QueryPage queryPage, PageResp<DailyRes> res);
}

serviceImpl   (时间 :date  转 int a="20190322"  再转 string a="2019-03-22" )

package net.matedata.app.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import net.matedata.app.model.AppReqThread;
import net.matedata.app.model.request.DailyReq;
import net.matedata.app.model.response.DailyRes;
import net.matedata.app.model.response.MerProductRes;
import net.matedata.app.model.response.MyProductRes;
import net.matedata.app.service.ProductService;
import net.matedata.common.constant.TrueFalse;
import net.matedata.common.domain.entity.VApiRequestDaily;
import net.matedata.common.domain.entity.VMerchantProduct;
import net.matedata.common.domain.mapper.VApiRequestDailyMapper;
import net.matedata.common.model.PageResp;
import net.matedata.common.model.QueryPage;
import net.matedata.common.util.AmountUtils;
import net.matedata.common.util.MdDateUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService
{
    @Resource
    private VApiRequestDailyMapper vApiRequestDailyMapper;

      @Override
    public void getListByParam(String productCode, Date startDate, Date endDate, QueryPage queryPage,
            PageResp<DailyRes> res)
    {
        Page page = PageHelper.startPage(queryPage.getPageNum(), queryPage.getPageSize());
        List<VApiRequestDaily> dailyList =
                vApiRequestDailyMapper.getListByParam(AppReqThread.getMerchantId(), productCode,
                                                      MdDateUtils.intValueOfDay(startDate),
                                                      MdDateUtils.intValueOfDay(endDate));  //date 转 int 
        res.setTotal(page.getTotal());
        List<DailyRes> list = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(dailyList))
        {
            DailyRes dailyRes;
            for(VApiRequestDaily daily : dailyList)
            {
                dailyRes = new DailyRes();
                dailyRes.setApiName(daily.getApiName());
                dailyRes.setStatsDay(formatIntDateVal(daily.getStatsDay())); int 转 string
                dailyRes.setRequestQty(daily.getRequestQty());
                dailyRes.setChargeQty(daily.getChargeQty());
                dailyRes.setChargeAmt(AmountUtils.centToString(daily.getChargeAmt()));
                list.add(dailyRes);
            }
        }
        res.setList(list);
    }

    private String formatIntDateVal(int intDate)
    {
        String strDate = String.valueOf(intDate);
        return strDate.substring(0, 4) + "-" + strDate.substring(4, 6) + "-" + strDate.substring(6, 8);
    }
}

类型转换工具类

package net.matedata.common.util;

import org.apache.commons.lang3.time.DateUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class MdDateUtils
{
    private MdDateUtils()
    {
    }

    public static String format(Date date, String pattern)
    {
        return new SimpleDateFormat(pattern).format(date);
    }

    public static boolean inDayRange(Date date, Date from, Date to)
    {
        if(date != null && from != null && to != null)
        {
            int dateInt = Integer.parseInt(format(date, "yyyyMMdd"));
            int fromInt = Integer.parseInt(format(from, "yyyyMMdd"));
            int toInt = Integer.parseInt(format(to, "yyyyMMdd"));
            return dateInt >= fromInt && dateInt <= toInt;
        }
        return false;
    }

    /**
     * 获取当前月份
     */
    public static Integer getMonth(Date date)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.MONTH) + 1;
    }

    public static Integer intValueOfDay(Date date)
    {
        return Integer.valueOf(format(date, "yyyyMMdd"));
    }

    public static List<Integer> getIntRange(Date date, int days)
    {
        List<Integer> list = new ArrayList<>();
        Date startDate = DateUtils.addDays(date, -days);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        while(!calendar.getTime().after(date))
        {
            list.add(intValueOfDay(calendar.getTime()));
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        return list;
    }
}

biz就不上代码了

 

拦截器

package net.matedata.app.componet;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class StringToDateConverter implements Converter<String, Date>
{
    @Override
    public Date convert(@Nullable String source)
    {
        if(StringUtils.isBlank(source))
        {
            return null;
        }
        if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2}$"))
        {
            return parseToDate(source, "yyyy-MM-dd");
        }
        else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2}$"))
        {
            return parseToDate(source, "yyyy/MM/dd");
        }
        else if(source.matches("^\\d{4}-\\d{1,2}-\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$"))
        {
            return parseToDate(source, "yyyy-MM-dd HH:mm:ss");
        }
        else if(source.matches("^\\d{4}/\\d{1,2}/\\d{1,2} {1}\\d{1,2}:\\d{1,2}:\\d{1,2}$"))
        {
            return parseToDate(source, "yyyy/MM/dd HH:mm:ss");
        }
        else if(source.matches("^\\d{4}-\\d{1,2}$"))
        {
            return parseToDate(source, "yyyy-MM");
        }
        else
        {
            throw new IllegalArgumentException("Invalid date value '" + source + "'");
        }
    }

    private Date parseToDate(String str, String format)
    {
        try
        {
            return new SimpleDateFormat(format).parse(str);
        }
        catch(ParseException e)
        {
            return null;
        }
    }
}

controller  

package net.matedata.app.controller;

import net.matedata.app.biz.ProductBiz;
import net.matedata.app.model.request.DailyReq;
import net.matedata.app.model.response.DailyRes;
import net.matedata.common.model.PageResp;
import net.matedata.common.model.QueryPage;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class ProductController
{
    @Resource
    private ProductBiz productBiz;

   

 /**
     * 产品请求日账单
     */
    @LoginRequired
    @GetMapping(value = "/product/{productCode}/daily-bill")
    public PageResp<DailyRes> getListByParam(@PathVariable(value = "productCode") String productCode,
            @RequestParam(value = "startDate") Date startDate, @RequestParam(value = "endDate") Date endDate,
            @RequestParam(value = "pageNum") Integer pageNum, @RequestParam(value = "pageSize") Integer pageSize)
    {
        PageResp<DailyRes> res = new PageResp<>();
        productBiz.getListByParam(productCode.toUpperCase(), startDate, endDate, new QueryPage(pageNum, pageSize), res);
        return res;
    }

 

代码到这里就完成了,用Postman测一下这个接口

 

请求头 :登录后拿到token

 

 

请求参数  以及结果的展示:

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值