package com.malk.base;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;
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.util.Date;

/**
 * 实体基类
 *
 * @MappedSuperclass 作为公共属性场景. 类注解, 标注后该类将不是一个完整的实体类，也不会映射到数据库表，但其的属性都将映射到其子类的数据库字段中
 * @Cloumn java为小驼峰命名，数据库为下划线命名，若有差异，通过name指定表字段. 若相同则可不用指定name [直接设置字段值即可，无效额外注解]
 * -
 * 功能使用自带
 * -
 * @JsonFormat(pattern = "yyyy-MM-dd HH:smm:ss", timezone = "GMT+8")，数据库 Date 类型序列化后转到前台的指定格式【jackjson】
 * @DateTimeFormat @DateTimeFormat(pattern = "yyyy-MM-dd")，使用和@jsonFormat差不多，前台传入的按照指定格式自动转为Date储存
 * @JsonIgnoreProperties 类注解，作用是json序列化时将bean中的一些属性忽略掉，序列化和反序列化都受影响。支持多个属性 [也用于双向绑定解决循环序列化]
 * @JsonIgnore 此注解用于属性或者方法上（最好是属性上），作用和上面的@JsonIgnoreProperties一样，屏蔽该字段在序列化和数据发挥会自动忽略
 * @JsonGetter 用于序列化, 还可指定返回属性名，@JsonSetter 用于反序列化。注意@JsonGetter比@JsonProperty的优先级高，同时存在属性忽略会失效
 * @Transient ORM框架将忽略该属性，不入库。如果一个属性并非数据库表的字段映射，就务必将其标示为@Transient，否则ORM框架默认其注解为@Basic
 * @Temporal & @JsonFormat: fixme: 指定时区, new Date 会默认当前系统时区, 不添加 json 时区注解, 会出现序列化后的对象时间不是 GMT 时区 [方法2见BaseDto, jsonFormatDateTime]
 */
@MappedSuperclass
@Data
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public abstract class BasePo extends BaseDto {

    // 若是实体若不直接在 com.malk 下, 可声明继承id, 避免编辑器提示 [不加也不影响编译以及运行] [ppExt: 现有表如u8, 不继承 BaseDto, 避免默认id与时间字段匹配异常]
    @ExcelIgnore
    @Id
    @JsonIgnore
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    @ExcelIgnore
    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    @ExcelIgnore
    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date updateTime;

    public void upsert(BasePo po_old) {

        if (ObjectUtil.isNotNull(po_old)) {
            this.id = po_old.id;
            this.setCreateTime(po_old.getCreateTime());
        }
    }
}
