React UmiJS项目开发日记(一)

最近在开发React UmiJS前端项目,后端是springboot。

简要记录下开发流程。

下方代码的名称有的是框架固定的,有的是自己起的。

 

一、需求

需要在列表页新增2个筛选条件框,以及在列表页新增1列。

要筛选出学员公司(tree,一级是公司,二级是分公司,多选)、学员类型(多选);要在列表页新增"学员类型"列(学员公司列之前就已经展示出来了)。

 

二、开发过程

1.下载Visual Studio Code,打开待开发项目。(推荐用这个工具,搜索文件与代码很快;之前试着用Hbuilder开发,搜索太慢了,实在影响效率)

2.找到列表页所在的js文件,有以下几种方法:

(1)搜索页面中文关键字,可以找到zh-CN.js文件;

'StudentPage.studentName': '学生姓名',

然后再搜索"StudentPage.studentName",就能找到页面所在的js文件了,例如某个目录下的querySimple.js;

<FormItem label={<FormattedMessage id="StudentPage.studentName" />}>
  {getFieldDecorator('studentName_equals',{
    initialValue: queryPara.studentName_equals,
  })(
    <Input
         placeholder={
           formatMessage({id: 'global.input.placeholder' }) +
           formatMessage({id: 'StudentPage.studentName' })
         }
         allowClear
         autoComplete="off"
    />
   )}
</FormItem>

这段代码对应页面上的一个学生姓名input输入框。

(2)可以搜索文件:项目路径/config/router.config.js,其中有前端页面的url。(如果格式规范的话,url中的名称对应页面js的名称)

3.按照上方的方法,找到了筛选条件框的页面,querySimple.js,然后增加2个筛选条件框,一个是包含TreeSelect的复选框,一个是普通Select复选框;代码如下:

<FormItem label={<FormattedMessage id="StudentPage.studentCom" />}>
  {getFieldDecorator('studentCom_in',{
    initialValue: queryPara.studentCom_in,
  })(
     <TreeSelect 
       dropdownStyle={(maxHeight: 400, overflow: 'auto')}
       treeData={codeselect.managecomTreeData}
       treeCheckable
       showCheckedStrategy={SHOW_PARENT}
       allowClear
       treeDefaultExpandedKeys={[
         codeselect.managecomTreeData[0] ? codeselect.managecomTreeData[0].key : null,
       ]}
       placeholder={
           formatMessage({id: 'global.input.placeholder' }) +
           formatMessage({id: 'StudentPage.studentCom' })
       }
     />
   )}
</FormItem>

<FormItem label={<FormattedMessage id="StudentPage.studentType" />}>
  {getFieldDecorator('studentType_in',{
    initialValue: queryPara.studentType_in,
  })(
    <Select
      showSearch
      mode="multiple"  
      optionFilterProp="children"
      filterOption={ (input,option) => 
        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
      }  
      placeholder={
           formatMessage({id: 'global.input.placeholder' }) +
           formatMessage({id: 'StudentPage.studentType' })
      }
      onChange={this.handleChange}
    >
      {codeselect.studentType.map(item => (
        <Select.Option key ={item.codeValue}>{item.codeName}</Select.Option>
      ))}
    </Select>
   )}
</FormItem>

需要注意,其中"_in"是有含义的,多选用;如果是单选框,就用"_equals",也有含义。下方会讲解。

同时,这个文件中还修改了其它内容,记录如下:

//增加TreeSelect
import {Form, Input, DatePicker, Select, TreeSelect, Button, Icon} from 'antd';

//增加const
const {SHOW_PARENT} = TreeSelect;

4.按照上方方法,找到列表页所在的js文件,某个目录下的homeTable.js,增加了内容,记录如下:

{
  title: formatMessage({ id: 'StudentPage.studentType' }),
  dataIndex: 'studentType',
  align: 'center',
  width: 100,
  render: (text) => {
    return this.parseStudentType(text)
  }
}

还增加了方法parseStudentType(),记录如下:

parseStudentType = (value) => {
  if( value==null || value== "" || value == undefined || value == "undefined" ){
    return "其它";
  }
  const {codeselect} = this.props
  const arr = value.split(",")
  const strArr = []
  // eslint-disable-next-line no-plusplus
  for(let i = 0; i < arr.length; i++){
    // eslint-disable-next-line no-plusplus
    for(let j = 0; j < codeselect.studentType.length; j++){
      if(arr[i] === codeselect.studentType[j].codeValue){
        strArr.push(
          codeselect.studentType[j].codeName
        )
      }
    }
  }
  return strArr.join(",")
}

5.修改java后台代码,springboot,通过搜索请求url找到后台代码要修改的文件;对应代码记录如下:

@GetMapping("/stu-msg-search")
@Timed
public ResponseEntity<List<StudentDTO>> getAllStudent(StudentCriteria criteria, Pageable pageable){
  log.debug("REST request to get AllStudent by criteria: {}", criteria);
  Page<StudentDTO> page = studentService.findByCriteria(criteria, pageable);
  HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/stu-msg-search");
  return ResponseEntity.ok().headers(headers).body(page.getContent());
}

6.查看第5步中的StudentCriteria.java类,发现其中有两类变量:

public class StudentCriteria implements Serializable {
  private LongFilter id;
  private StringFilter studentName;
  private InstantFilter dueStartTime;
  private InstantFilter dueFinishTime;
  private StringFilter studentType;
}

其中,LongFilter是接收数字的对象;InstantFilter是接收时间的对象;StringFilter是接收字符串的对象;

(1)例如,前端传键值对,参数为:

dueFinishTime.greaterOrEqualThan: 2021-04-08T16:00:00.000Z

dueFinishTime.lessOrEqualThan: 2021-04-09T18:00:00.000Z

studentType.equals: xxx

studentType.in[0]: 1

studentType.in[1]: 3

studentType.in[2]: 9

(2)后台查看StudentCriteria对象,可以发现其中的studentName变量中的equals变量中有内容,为xxx;

其中的dueFinishTime中的变量中的greaterOrEqualThan与lessOrEqualThan变量有内容,为传入的时间(Instant类型)

其中的studentType变量中的in变量中有值,为传入的数组1,3,9.

(3)所以在前端代码中,"_in"的意思就是最后发出".in"的键值对,后台才能正常接收;相应的也可以写"_equals",发出的键值对就为".equals"。

(4)后台后续处理为,将StudentCriteria对象转为Specification对象,然后把Specification对象传入数据库查询jpa方法中;后台数据库查询方法是hibernate,Specification对象在spring-data-jpa-2.0.12.RELEASE.jar包中。

Specification<Student> specification = Specification.where(null);
if(studentCriteria != null){
  if(studentCriteria.getDueFinishTime() != null) {
    //Range,注意这个是buildRangeSpecification,是jhipster-framework-2.0.29.jar中的方法
    specification = specification.and(buildRangeSpecification(studentCriteria.getDueFinishTime(), Student_.dueFinishTime));
  }
  if(studentCriteria.getStudentName() != null) {
    //String,注意这个是buildStringSpecification,是jhipster-framework-2.0.29.jar中的方法
    specification = specification.and(buildStringSpecification(studentCriteria.getStudentName(), Student_.studentName));
  }
}

return studentRepository.findAll(specification, page).map(studentMapper::toDto);

 

三、总结

本项目前端是React UmiJS;

后端是springboot,用到了hibernate、jpa、jhipster等;

有些地方本人也没有看懂,因此以日记形式记录一下,后续有空再完善。

需要记录的几点:

1.UmiJS中的"导出"按钮与"选择展示的列"按钮不需要特殊处理,当本人在代码中增加了显示的列后,这两个按钮也会自动增加相应的列。

2.下拉菜单中展示的内容、展示的tree树,都是在数据库中配置的,没有在前端写死。

3.UmiJS中的"查询"按钮与"重置"按钮也没有特殊修改,当本人在代码中增加了2个筛选条件框后,"查询"可以将增加的值传给后台,"重置"也可以重置新增的筛选框。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想永不停

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值