文章目录
1、query-record-list.vue
从你提供的 Vue 组件代码来看,“查询时间” 对应的字段是后端返回的 lastModifiedDate
。
分析:
-
el-table-column
组件:<el-table-column prop="lastModifiedDate" label="查询时间" align="center" width="170"> <template slot-scope="{row}"> <div>{{ row.lastModifiedDate ? row.lastModifiedDate.split(' ')[0] : '' }}</div> <div>{{ row.lastModifiedDate ? row.lastModifiedDate.split(' ')[1] : '' }}</div> </template> </el-table-column>
prop="lastModifiedDate"
: 这表示el-table
组件会从list
数组的每个对象中读取lastModifiedDate
属性作为这一列的数据。label="查询时间"
: 这只是列的标题,用于显示给用户,与后端字段无关。template slot-scope="{row}"
: 这是一个自定义渲染模板,用于格式化lastModifiedDate
的显示。
-
getList()
方法:private async getList() { this.loading = true const { brandId }: any = (await qfcs({}) as any)?.data this.listQuery = { ...this.listQuery, brandId } const res: any = await qcheckList(this.listQuery) if (res?.code === 0) { this.list = res?.data?.content this.listResponse = { ...this.listResponse, total: res?.data?.totalElements } } this.loading = false }
const res: any = await qcheckList(this.listQuery);
: 这里调用了qcheckList
API 获取数据。this.list = res?.data?.content;
: 将 API 返回数据中的content
属性赋值给this.list
。- 这意味着,
this.list
中的每个对象都是从res?.data?.content
中获得的。 - 组件在
el-table
中循环渲染的数据来源是this.list
-
数据结构假设:
基于以上分析,我们可以假设
res?.data?.content
返回的每一项数据结构可能类似这样:[ { "id": 1, "code": "123456", "checkNumber": 3, "result": "success", "longitude": 112.123, "latitude": 34.234, "address": "[北京市, 北京市, 东城区]", "lastModifiedDate": "2024-02-29 10:30:00" // ... 其他属性 }, { "id": 2, "code": "654321", "checkNumber": 1, "result": "fail", "longitude": 110.222, "latitude": 32.111, "address": "[上海市, 上海市, 浦东新区]", "lastModifiedDate": "2024-03-01 14:15:00" // ... 其他属性 } ]
- 从
el-table
的 column 中我们可以看到,后端返回的字段名是lastModifiedDate
。
- 从
结论:
“查询时间” 对应的后端字段是 lastModifiedDate
。
补充说明:
lastModifiedDate
通常表示记录的最后修改时间或者最后更新时间。- 在
el-table-column
组件中,你使用了split(' ')[0]
和split(' ')[1]
将lastModifiedDate
的值按空格拆分为日期和时间两部分进行展示。 qcheckList
应该是一个封装了调用后端的API的方法。
如果你想确认后端返回的具体字段名,你可以查看 qcheckList
API 的响应数据结构。
2、对应的后端接口
URL: http://127.0.0.1:8087/antiFake/checkRecord?page=0&size=15&brandId=61
3、响应数据结构
{
"code": 0,
"msg": "成功",
"data": {
"content": [
{
"id": 3004,
"createdDate": "2022-11-10 22:03:06",
"lastModifiedDate": "2022-11-10 22:03:06",
"antiFakeId": 104760798,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "ubCDTWREdvkCkmFW"
},
{
"id": 3009,
"createdDate": "2022-11-15 11:46:44",
"lastModifiedDate": "2022-11-15 11:46:44",
"antiFakeId": 104746088,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "22SAoyzym573flea"
},
{
"id": 3006,
"createdDate": "2022-11-12 02:49:54",
"lastModifiedDate": "2022-11-12 02:49:54",
"antiFakeId": 104723890,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "Y4ZitVpOiegWOuhf"
},
{
"id": 3005,
"createdDate": "2022-11-11 01:36:38",
"lastModifiedDate": "2022-11-11 01:36:38",
"antiFakeId": 103345972,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "k38e0TmfxYCVKrkH"
},
{
"id": 3007,
"createdDate": "2022-11-14 21:59:34",
"lastModifiedDate": "2022-11-14 21:59:34",
"antiFakeId": 102844696,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "QxtBo3RxRVKrjR6g"
},
{
"id": 3008,
"createdDate": "2022-11-14 22:27:23",
"lastModifiedDate": "2022-11-14 22:27:23",
"antiFakeId": 102109237,
"latitude": "0",
"longitude": "0",
"address": "[]",
"unionId": "",
"result": "成功",
"checkNumber": 1,
"code": "DFVkRlH0Cjt2SCnW"
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"offset": 0,
"pageNumber": 0,
"pageSize": 15,
"paged": true,
"unpaged": false
},
"last": true,
"totalPages": 1,
"totalElements": 6,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"size": 15,
"number": 0,
"first": true,
"numberOfElements": 6,
"empty": false
}
}
4、findCheckRecord
@ApiOperation(value = "查询防伪码校验记录列表")
@GetMapping("checkRecord")
public BaseResult findCheckRecord(@RequestParam(value = "brandId", required = false) Integer brandId,
BasePage basePage,
@ApiIgnore @SessionAttribute(Constants.ADMIN_ID) Integer adminId) {
Page<AntiFakeCheckRecord> list = antiFakeCheckRecordService.find(brandId, basePage.toPageable());
List<AntiFakeCheckRecordDTO> antiFakeCheckRecordDTOS = new ArrayList<>();
list.getContent().forEach(antiFakeCheckRecord -> {
AntiFakeCheckRecordDTO antiFakeCheckRecordDTO = JSON.parseObject(JSON.toJSONString(antiFakeCheckRecord), AntiFakeCheckRecordDTO.class);
AntiFake antiFake = antiFakeService.findById(antiFakeCheckRecord.getAntiFakeId()).orElseThrow(() -> new RuntimeException("未找到防伪码信息"));
antiFakeCheckRecordDTO.setCode(antiFake.getCode());
antiFakeCheckRecordDTOS.add(antiFakeCheckRecordDTO);
});
return BaseResult.success(new PageImpl<>(antiFakeCheckRecordDTOS, PageRequest.of(list.getNumber(), list.getSize()), list.getTotalElements()));
}
从你提供的 Java 代码片段来看,后端返回给前端的对象是 PageImpl<AntiFakeCheckRecordDTO>
。 让我们详细分析一下:
1. 返回类型:BaseResult
BaseResult
是一个自定义的返回类型,通常用于封装后端 API 的响应结果。它可能包含code
(状态码)、message
(消息) 和data
(数据) 等属性。BaseResult.success(...)
表示返回成功,并将数据部分设置为后面的对象。
2. AntiFakeCheckRecordDTO
:
AntiFakeCheckRecordDTO
是一个数据传输对象 (DTO)。 它通常用于在后端和前端之间传输数据。JSON.parseObject(JSON.toJSONString(antiFakeCheckRecord), AntiFakeCheckRecordDTO.class);
将AntiFakeCheckRecord
对象转换为AntiFakeCheckRecordDTO
对象。AntiFakeCheckRecordDTO
的目的通常是,选择性地包含你需要返回给前端的数据字段,可以避免将所有后端实体类的信息都传递给前端,提高效率和安全性。- 代码中又添加了
code
属性 - 我们猜测
AntiFakeCheckRecordDTO
包含的字段有id
,checkNumber
,result
,longitude
,latitude
,address
,lastModifiedDate
,code
等。
3. PageImpl
:
PageImpl
是 Spring Data JPA 中Page
接口的一个实现类,它用于封装分页数据。new PageImpl<>(antiFakeCheckRecordDTOS, PageRequest.of(list.getNumber(), list.getSize()), list.getTotalElements())
创建了一个PageImpl
对象。
*antiFakeCheckRecordDTOS
是包含 DTO 对象的列表,用于封装分页内容。
*PageRequest.of(list.getNumber(), list.getSize())
创建了一个分页请求对象,包含了页码和每页数据量等信息。
*list.getTotalElements()
是总记录数。
4. 返回过程:
antiFakeCheckRecordService.find(brandId, basePage.toPageable())
:首先,从数据库查询AntiFakeCheckRecord
实体列表。 这里使用了basePage
对象来控制分页。- 循环遍历实体列表,将每个
AntiFakeCheckRecord
实体转换为AntiFakeCheckRecordDTO
,并添加code
属性。 - 创建
PageImpl<AntiFakeCheckRecordDTO>
对象,包装转换后的 DTO 列表以及分页信息。 - 最后,将
PageImpl<AntiFakeCheckRecordDTO>
对象作为data
属性值,封装到BaseResult
对象中返回。
5. 前端接收:
- 前端通常会接收
BaseResult
对象,并从中提取data
属性。 data
属性的值是一个PageImpl
对象,它包含两个主要部分:content
: 是AntiFakeCheckRecordDTO
对象的列表。totalElements
: 表示总记录数。
总结:
后端返回给前端的是一个 BaseResult
对象,其中 data
属性的值是一个 PageImpl<AntiFakeCheckRecordDTO>
对象。这个对象包含了分页信息和转换后的数据列表。
前端代码中的对应:
在你的 Vue 组件代码中,你可以看到以下部分:
const res: any = await qcheckList(this.listQuery)
if (res?.code === 0) {
this.list = res?.data?.content
this.listResponse = { ...this.listResponse, total: res?.data?.totalElements }
}
res?.data?.content
: 对应PageImpl
对象中的content
,即AntiFakeCheckRecordDTO
对象的列表。res?.data?.totalElements
: 对应PageImpl
对象中的总记录数。- 这与我们上面分析的完全一致。
因此,前端接收到的数据列表 (this.list
) 是一个 AntiFakeCheckRecordDTO
对象数组。
5、AntiFakeCheckRecordDTO
package com.productQualification.api.service.DTO.antiFake;
import com.productQualification.resource.domain.AntiFakeCheckRecord;
public class AntiFakeCheckRecordDTO extends AntiFakeCheckRecord {
private String code;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
6、AntiFakeCheckRecord
package com.productQualification.resource.domain;
import com.productQualification.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import javax.persistence.Column;
import javax.persistence.Entity;
@ApiModel(description = "防伪码查询记录")
@Entity
@DynamicUpdate
@DynamicInsert
public class AntiFakeCheckRecord extends BaseEntity {
@ApiModelProperty("防伪码")
private Integer antiFakeId;
@ApiModelProperty("纬度")
@Column(length = 20)
private String latitude;
@ApiModelProperty("经度")
@Column(length = 20)
private String longitude;
@ApiModelProperty("所在地")
@Column(length = 100)
private String address;
@ApiModelProperty("微信用户ID")
@Column(length = 50)
private String unionId;
@ApiModelProperty("返回信息")
@Column(length = 50)
private String result;
@ApiModelProperty("校验次数")
private Integer checkNumber;
public Integer getAntiFakeId() {
return antiFakeId;
}
public void setAntiFakeId(Integer antiFakeId) {
this.antiFakeId = antiFakeId;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public Integer getCheckNumber() {
return checkNumber;
}
public void setCheckNumber(Integer checkNumber) {
this.checkNumber = checkNumber;
}
}
7、BaseEntity
package com.productQualification.common.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* 关系型数据库基本实体类
*/
@ApiModel()
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
public abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Integer id;
@ApiModelProperty(value = "创建时间", hidden = true)
@CreatedDate
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdDate;
@ApiModelProperty(value = "修改时间", hidden = true)
@LastModifiedDate
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastModifiedDate;
public BaseEntity() {
}
public BaseEntity(Object[] objects) {
this.id = (Integer) objects[0];
this.createdDate = null == objects[1] ? null : (Date) objects[1];
this.lastModifiedDate = null == objects[2] ? null : (Date) objects[2];
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
8、AntiFakeCheckRecordRepository
package com.productQualification.resource.repository;
import com.productQualification.resource.domain.AntiFakeCheckRecord;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface AntiFakeCheckRecordRepository extends JpaRepository<AntiFakeCheckRecord, Integer> {
@Query(value = "select afcr from AntiFake af join AntiFakeCheckRecord afcr on af.brandId = ?1 and af.id = afcr.antiFakeId")
Page<AntiFakeCheckRecord> findByBrandId(Integer brandId, Pageable pageable);
}
9、anti_fake_check_record 表
-- auto-generated definition
create table anti_fake_check_record
(
id int auto_increment
primary key,
created_date datetime null,
last_modified_date datetime null,
address varchar(100) null,
anti_fake_id int null,
check_number int null,
latitude varchar(20) null,
longitude varchar(20) null,
result varchar(50) null,
union_id varchar(50) null
)
engine = MyISAM;