当前位置:网站首页>22-07-04 西安 尚好房-项目经验总结(01)

22-07-04 西安 尚好房-项目经验总结(01)

2022-07-05 09:10:00 £小羽毛

尚好房是一个二手房管理服务平台,开放优质资源和线上能力,聚合线上线下二手房产资源,打造一个全方位二手房服务生态市场,为消费者提供优质房产服务资源。

根据演示了解项目业务

尚好房后台管理系统:权限管理系统

尚好房前端:找房网


惊讶一:抽取公共的模块

BaseController,里面真的很简单,但是考虑到以后每一个Controller都要用到封装的那俩行代码,

在新增,修改添加成功会用得到。是用来给消费者的Controller继承的。

public class BaseController {
    private final static String PAGE_SUCCESS = "common/successPage";
    public String successPage(Model model, String successMessage){
        model.addAttribute("messagePage",successMessage);
        return PAGE_SUCCESS;
    }
}

 BaseService是用来给中间商“service-api”来继承的,

 它里面的内容是下面这样子的,继承了它就相当于Service里写了五个通用的增删改查方法

public interface BaseService<T> {
    void insert(T t);

    T getById(Long id);

    /**
     * 逻辑删除
     * @param id
     */
    void delete(Long id);

    /**
     * 修改信息
     * @param t
     */
    void update(T t);

    /**
     * 分页查询信息
     * @param filters
     * @return
     */
    PageInfo<T> findPage(Map<String, Object> filters);
}

BaseServiceImpl和BaseMapper就是让服务的提供者去使用继承的。一个写具体的业务逻辑,一个写对数据库的操作。

这里BaseServiceImpl是一个抽象类,它里面有一个抽象方法getEntityMapper(),这个方法就是为了让继承它的子类去重写它,把正真的mapper接口送给他,他好帮你去调用方法呐

public abstract class BaseServiceImpl<T> {

    /**
     * 该抽象方法用来获取真实的mapper接口
     * @return
     */
    protected abstract BaseMapper<T> getEntityMapper();
    
    public void insert(T t) {
        getEntityMapper().insert(t);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public T getById(Long id) {
        return getEntityMapper().getById(id);
    }


    public void delete(Long id) {
        getEntityMapper().delete(id);
    }


    public void update(T t) {
        getEntityMapper().update(t);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public PageInfo<T> findPage(Map<String, Object> filters) {
        //将pageSize和pageNum强转成int类型
        //第二个参数表示如果强转失败给默认值
        int pageNum = CastUtil.castInt(filters.get("pageNum"),1);
        int pageSize = CastUtil.castInt(filters.get("pageSize"),10);
        //开启分页
        PageHelper.startPage(pageNum,pageSize);
        //调用持久层的方法查询数据集
        //封装返回结果,老师这里没有传第二个参数
        return new PageInfo<>(getEntityMapper().findPage(filters),10);
    }
}

最后就是这BaseMapper了,我们创建的每一个mapper接口都要去继承这个接口,这样我们的mapper接口就可以省略掉这五个最常用的方法不写了

public interface BaseMapper<T> {

    /**
     * 保存一个实体
     * @param t
     */
    void insert(T t);

    /**
     * 通过一个标识ID 获取一个唯一实体
     * @param id
     * @return
     */
    T getById(Long id);

    /**
     *修改
     * @param t
     */
    void update(T t);

    /**
     * 删除
     * @param id
     */
    void delete(Long id);

    /**
     * 分页查询
     * @param filters
     * @return
     */
    Page<T> findPage(Map<String, Object> filters);
}

惊讶2、字典

这个字典表本身就设计的巧妙

这个页面的视觉效果也很nice:这种树形的目录看着很高级,实际上后端返给前端的也只是一个json数组。

java后端代码:

后端逻辑就很简单,根据父节点的id去查询所有的子节点,把查出来的数据用Stream流做整理。

2021/11/12 北京 stream流,内部类,lambda表达式_£小羽毛的博客-CSDN博客

    public List<Map<String, Object>> findZnodes(Long id) {
        //1. 调用持久层方法,根据父节点id查询List<Dict>
        List<Dict> dictList = dictMapper.findListByParentId(id);
        //使用Stream流
        List<Map<String, Object>> znodes = dictList.stream()
                .map(dict -> {
                    Map<String, Object> znode = new HashMap<>();
                    //往znode中存放id
                    znode.put("id", dict.getId());
                    //往znode中存放name
                    znode.put("name", dict.getName());
                    //往znode中存放isParent
                    znode.put("isParent", dictMapper.countIsParent(dict.getId()) > 0);
                    return znode;
                })
                .collect(Collectors.toList());
        return znodes;
    }

 在SQlyog中执行如下sql:

-- 根据父节点的id去查询所有的子节点
SELECT * FROM hse_dict WHERE parent_id =1


点击全部分类

观察network,发送了这样一个请求,那不就是咱上面分析的那种情况嘛 

http://139.198.152.148:8001/dict/findZnodes?id=1

返给前端的json数据:实际上返回的还是json数组。

{
    "code": 200,
    "data": [
        {
            "isParent": true,
            "name": "户型",
            "id": 10000
        },
        {
            "isParent": true,
            "name": "楼层",
            "id": 20000
        },
        {
            "isParent": true,
            "name": "建筑结构",
            "id": 30000
        },
        {
            "isParent": true,
            "name": "装修情况",
            "id": 40000
        },
        {
            "isParent": true,
            "name": "朝向",
            "id": 50000
        },
        {
            "isParent": true,
            "name": "房屋用途",
            "id": 60000
        },
        {
            "isParent": true,
            "name": "省",
            "id": 100000
        }
    ],
    "message": "成功",
    "ok": true
}

我们再点击户型,此时再发送请求去查询

http://139.198.152.148:8001/dict/findZnodes?id=10000

 返给前端的json数组如下:

{
    "code": 200,
    "data": [
        {
            "isParent": false,
            "name": "一室",
            "id": 10001
        },
        {
            "isParent": false,
            "name": "两室",
            "id": 10002
        },
        {
            "isParent": false,
            "name": "三室",
            "id": 10003
        },
        {
            "isParent": false,
            "name": "四室",
            "id": 10004
        },
        {
            "isParent": false,
            "name": "四室以上",
            "id": 10005
        }
    ],
    "message": "成功",
    "ok": true
}

枚举的俩种用法:

用法1:房源的发布状态HouseStatus

public enum HouseStatus {
    //未发布表示用户看不到,但是后台管理系统可以看得到
    PUBLISHED(1,"已发布"), UNPUBLISHED(0,"未发布");
    public int code;
    public String message;

    HouseStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }
}

在添加房源信息的时候使用:

    @PostMapping("/save")
    public String save(House house,Model model){
        //未发布
        house.setStatus(HouseStatus.UNPUBLISHED.code);
        houseService.insert(house);
        return successPage(model,"添加房源信息成功");
    }

枚举用法2:定义为私有变量。

public enum DictCode {
    HOUSETYPE("houseType"),FLOOR("floor"),BUILDSTRUCTURE("buildStructure"),
    DECORATION("decoration"),DIRECTION("direction"),HOUSEUSE("houseUse");
    private String message;

    DictCode(String message) {
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
}

使用:

//3. 查询各种初始化列表:户型列表、楼层列表、装修情况列表....
List<Dict> houseTypeList =
dictService.findDictListByParentDictCode(DictCode.HOUSETYPE.getMessage());

getListingDateString() House类

在show.html中

<dt>挂牌时间:</dt><dd th:text="${house.listingDateString}"></dd>
<dt>上次交易:</dt><dd th:text="${house.lastTradeDateString}"></dd>

可实际上House这个类中并没有这俩属性,只有如下俩个Date属性,那么是怎么把数据展示到页面中的呢

  • 挂牌日期 private Date listingDate;
  • 上次交易日期 private Date lastTradeDate;

 一个重要知识点,在thymeleaf语法中,在请求域中是用get方法拿到值的。所以实际上是House这个类多了俩个方法。妙啊,美琪妙妙屋

	/**
	 * 以字符串类型获取挂牌日期
	 * @return
	 */
	public String getListingDateString() {
		Date date = this.getListingDate();
		if(null == date) {
			return "";
		}
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = df.format(date);
		return dateString;
	}


	/**
	 * 以字符串方式获取上次交易日期
	 * @return
	 */
	public String getLastTradeDateString() {
		Date date = this.getLastTradeDate();
		if(null == date) {
			return "";
		}
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = df.format(date);
		return dateString;
	}

原网站

版权声明
本文为[£小羽毛]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_56799642/article/details/125602536