新平台XCloud开发学习

1.简单功能的实现

1.1 配置系统host

在虚拟机中配置好了Mysql,Redis的环境,现在需要在本地系统Host文件中加上虚拟机中的ip地址以及相应映射关系,同时也加上vsn-register、vsn-gateway相应的本地映射ip,方便后续调用。

  • 查找虚拟机对应的ip地址

    文件配置使用的是SwitchHost工具进行配置

1.2 生成微服务

cmd环境下运行
生成微服务脚本
运行结果

该cd路径下生成了一个基本项目

项目结构

更改配置文件

server:
  port: 6901

spring:
  application:
    name: @artifactId@
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_HOST:vsn-register}:${NACOS_PORT:8848}
        metadata: { "VERSION": "1.0" }
        namespace: vsn-${spring.profiles.active}
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        file-extension: yml
        shared-configs:
          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
        namespace: vsn-${spring.profiles.active}
      username: ${NACOS_USER:nacos}
      password: ${NACOS_PWD:nacos}
    inetutils:
      preferred-networks:
        - 10.8
  autoconfigure:
    exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration
  profiles:
    active: @profiles.active@
xcloud:
  xsequence:
    db:
      retry-times: 3
      table-name: xcloud_sequence
      step: 1
      step-start: 30

1.3 启动Nacos以及相关服务

更改配置文件,略微缩短了等待时间,之前试过全改成2秒,因为服务与服务之间存在相互调用,且不存在心跳机制,当服务未启动完成时另一个服务调用该服务则会出现报错,故更改了又延长了等待时间,确保服务的成功运行


访问http://localhost:8848/nacos

在配置列表中

  • 创建配置

    填写配置内容
    ## spring security config
    security:
      oauth2:
        client:
          client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)
          client-secret: OS0sVWcU12RxLMaa
          scope: server
          ignore-urls:
            - /druid/**
            - /actuator/**
            - /api/**
            - /v2/api-docs
    
    # datasource config
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://vsn-mysql:3306/xcloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
          username: root
          password: Pccw1234.
          max-active: 32
          stat-view-servlet:
            enabled: true
            allow: ""
            url-pattern: /druid/*
            login-username: admin
            login-password: admin
          filter:
            stat:
              enabled: true
              log-slow-sql: true
              slow-sql-millis: 10000
              merge-sql: false
            wall:
              config:
                multi-statement-allow: true
        dynamic:
          druid:
            connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
            filters: stat,slf4j
            initial-size: 5
            maxActive: 32
            maxWait: 60000
            min-idle: 0
            minEvictableIdleTimeMillis: 300000
            stat-view-servlet:
              allow: ''
              reset-enable: false
              url-pattern: /druid/*
              login-username: admin
              login-password: admin
            testOnBorrow: false
            testOnReturn: false
            testWhileIdle: true
            removeAbandoned: false
            timeBetweenEvictionRunsMillis: 60000
            #validationQuery: SELECT 'x'
            web-stat-filter:
              enabled: true
              exclusions: '*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*'
              url-pattern: /*
    
    # Logger Config
    logging:
      level:
        com.pccw.vsn.hello.mapper: debug
        org.apache.ibatis.session: debug
    
    xcloud:
      sql:
        use-camel-case-mapping: true
        res-upper-case: true
        api-has-pre: true
    
    xxl:
      job:
        executor:
          appName: vsn-job-executors-hello

1.5 导入完整项目包


导入完整项目包并将新生成的微服务模块导入项目中

1.4 启动前端项目

在终端 cd 到 vsn-ui 目录下
执行

npm run dev

访问 http://localhost:8081/ 进入前端界面

1.5 设置动态路由

1.6 建立业务表

建立表必须包含以下字段

设计表

1.7 功能代码生成


填写生成配置

下载生成代码

打开代码包

  1. 将xcloud目录下的src 目录复制到 微服务biz 目录,覆盖原有src目录
  2. 打开 xcloud-front 打开api,将api下的文件夹 放到 vsn-ui/src/api/vsn 下
  3. 将views目录下的文件夹复制到vsn-ui/src/views/vsn目录下
  4. 将const目录下的js复制到上一步views中index.vue的同级目录
  5. 修改文件引入路径

1.8 配置菜单及按钮

权限管理->菜单管理中,点击新增配置相关信息

再添加相应功能的按钮
其中按钮的权限标示,与前端index.vue中的内容一致

computed: {
            ...mapGetters(['permissions']),
            permissionList() {
                return {
                    addBtn: this.vaildData(this.permissions.homan_homanovertime_add, false),
                    delBtn: this.vaildData(this.permissions.homan_homanovertime_del, false),
                    editBtn: this.vaildData(this.permissions.homan_homanovertime_edit, false)
                };
            }
        },

权限标识不一致时,前端将无法访问到后端程序



下一步在角色管理->超级用户->权限,中为菜单按钮分配权限

重新登录页面,由于数据库中还没有填写信息所以表为空,菜单显示如图


在显示和填写中可以看出字段数量比较多不方便观察填写
为了简介方便,因为数据库中的7个必须字段是自动创建的,所以先将数据库中的7个必须字段进行隐藏显示,避免输入和查看的繁琐
由于申请时得不到主管意见,所以将主观意见字段在填写编辑步骤中进行隐藏。

效果如图


可以看出简洁了很多

接下来进行按钮的功能测试

  1. 新增

    添加完成

    查看数据库

    功能完成

  2. 编辑
    点击编辑

    修改完成

    数据库也同步更改完成

  3. 删除
    点击删除按钮

    点击确定

    删除成功

2.流程控制

2.1 设计流程图

在开发平台中选择流程定义新增流程,设计流程图

将两个任务框图分配给用户完成
用户分为管理员和申请人

2.2 添加按钮分配权限

添加申请按钮

为按钮分配权限

在前端也加上权限标识,确保二者一一对应

为首页的js文件添加三个字段,方便观察以及操作流程的进程

{
      "type": "select",
      "label": "工单状态",
      "prop": "workFlowStatus",
      filterable:true,
    }, {
      "type": "input",
      "label": "流程id",
      "prop": "workFlowDataId",
      hide: true,
      display: false
    }, {
      "type": "input",
      "label": "流程KEY",
      "prop": "procDefKey",
      hide: true,
      display: false
    }

2.3 编写界面

在index.vue界面添加申请按钮

<template slot="menuLeft">
  <el-button type="primary" size="small" icon="el-icon-plus" @click="handleStartProcess({},true)"
             v-if="permissionList.overtimeApplyBtn">申请
  </el-button>
</template>

同时添加查询组件,方便检索信息

<!--搜索查询组件 -->
<template slot="searchbox">
  <query-box
    class="query-box-layout"
    :option="tableOption"
    @search-change="searchChange"
  >
  </query-box>
</template>

为操作栏添加查看和编辑的功能

<el-button
        type="text"
        icon="el-icon-edit"
        v-if="getStates(scope.row) && permissionList.editBtn"
        @click="handleStartProcess(scope.row,true)"
      >编辑
      </el-button>

      <el-button
        type="text"
        icon="el-icon-view"
        v-if="!getStates(scope.row)"
        @click="handleStartProcess(scope.row,false)"
      >查看
      </el-button>

在api/vsn-homan/下的js中添加查询函数

export function homanOvertimeWorkFlowPage(query) {
  return request({
    url: '/vsn-homan/homanovertime/homanovertimeWorkFlowPage',
    method: 'get',
    params: query
  })
}

在vus scirpe中引入自定义函数

import {fetchList, addObj, putObj, delObj,homanOvertimeWorkFlowPage} from '@/api/vsn/vsn-homan/homanovertime'
 ......
  getList(page, params) {
            this.tableLoading = true
            homanOvertimeWorkFlowPage(Object.assign({
                current: page.currentPage,
                size: page.pageSize
            }, params, this.searchForm )).then(response => {
                this.tableData = response.data.records
                this.page.total = response.data.total
                this.tableLoading = false
            }).catch(() => {
                this.tableLoading=false
            })
        },

为了方便查阅,为工单状态更改了显示内容格式,将显示的部分字段进行隐藏显示,调整查询的排序规则

setColumn(tableOption,'workFlowStatus',{dicUrl: '/admin/dict/type/WorkflowStatus'})

setSearch(tableOption,true,['workFlowStatus'])
setSearchSort(tableOption,['createTime','workFlowStatus'])
setHide(tableOption, true, ['id', 'createId', 'createName', 'createTime',
  'updateId', 'updateName', 'updateTime'])
setDisplay(tableOption, false, ['id', 'createId', 'createName', 'createTime',
  'updateId', 'updateName', 'updateTime','opinion'])

显示如图

大体界面配置完成

当点击申请后,还需要跳转到一个界面,所以还需要新建一个前端vue和js文件
js文件的字段和菜单首页类似,字段为数据库实际字段

import {setDisplay, setHide} from '@/utils/pccw/avueUtil'

const context={}

const tableOption = {
  "border": true,
  "index": true,
  "indexLabel": "序号",
  "stripe": true,
  "menuAlign": "center",
  "align": "center",
  "searchMenuSpan": 6,
  queryBox: false,
  "addBtn": false,
  "editBtn": false,
  "delBtn": false,
  "submitBtn":false,
  "column": [
    {
      "type": "input",
      "label": "ID",
      "prop": "id"
    },	  {
      "type": "input",
      "label": "员工ID",
      "prop": "staffId"
    },	  {
      "type": "input",
      "label": "员工名称",
      "prop": "staffName"
    },	  {
      "type": "datetimerange",
      "label": "加班日期",
      "prop": "overtimeDate",
      span:24,
      startPlaceholder: "开始时间",
      endPlaceholder: "结束时间",
      format: 'yyyy-MM-dd HH:mm:ss',
      valueFormat: 'yyyy-MM-dd HH:mm:ss'
    },	  {
      "type": "input",
      "label": "加班原因",
      "prop": "cause",
      span:24,
      minRows: 3,
      maxlength:250,
      showWordLimit: true
    },	  {
      "type": "input",
      "label": "主管意见",
      "prop": "opinion",
      span:24,
      minRows: 3,
      maxlength:250,
      showWordLimit: true
    },	  {
      "type": "input",
      "label": "创建人ID",
      "prop": "createId"
    },	  {
      "type": "input",
      "label": "创建人名称",
      "prop": "createName"
    },	  {
      "type": "input",
      "label": "创建时间",
      "prop": "createTime"
    },	  {
      "type": "input",
      "label": "更新人ID",
      "prop": "updateId"
    },	  {
      "type": "input",
      "label": "更新人名称",
      "prop": "updateName"
    },	  {
      "type": "input",
      "label": "更新时间",
      "prop": "updateTime"
    }  ]
}

setHide(tableOption, true, ['id', 'createId', 'createName', 'createTime',
  'updateId', 'updateName', 'updateTime'])

setDisplay(tableOption, false, ['id', 'createId', 'createName', 'createTime',
  'updateId', 'updateName', 'updateTime','opinion'])

export {tableOption}

export function setContext(that,form,columns){
  context.that = that
  context.form = form
  context.columns = columns
}

编写vue界面
在初始化阶段会根据路由参数设置表单数据
主要对于主管意见做了相应的变化,当表单传递到管理员(主管那边),主观意见则会变成显示,同时禁用加班日期以及加班原因框图,主管只需要做出决策
当表单被主管退回给用户,则用户不能修改主管意见

<script>
import {tableOption,setContext} from './addOvertime_avue'
import {changeColmnProp, deepClone} from "@/utils/util";
import {setDisabled} from "@/utils/pccw/avueUtil";
export default {
  name: "addOvertime",
  props: {
  },
  data() {
    return {
      oldFieldCode:'',
      confirmFlag:0,
      formFlag:true,
      taskForm: {},
      taskFormOpen: false,
      tableOption: deepClone(tableOption),
      haveNoFlow:false,//根据业务自己控制,
      taskDefKey:null,
      isEditable:true,
    }
  },
  computed: {
  },
  watch:{},
  created() {
    this.initParams()
    setContext(this,this.taskForm,this.tableOption.column)
    /*if(this.isVsnAdmin() || this.isAuditor()){
      changeColmnProp(this.tableOption, ['belong'], 'display', true)
    }*/
  },
  mounted(){
  },
  methods: {
    initParams() {
      //初始化获取的参数
      this.taskForm.taskId = this.$route.query && this.$route.query.taskId;
      this.taskForm.businessId = this.$route.query && this.$route.query.businessId;
      this.taskForm.businessKey = this.$route.query && this.$route.query.businessKey;
      this.taskForm.procDefKey = this.$route.query && this.$route.query.procDefKey;
      this.taskForm.deployId = this.$route.query && this.$route.query.deployId;
      this.taskForm.workflowDataId = this.$route.query && this.$route.query.workflowDataId;
      this.isEditable = (this.$route.query && ((this.$route.query.editable + "") == "true")) ? true : false;
      this.$set(this.tableOption,"disabled",!this.isEditable);
      this.taskFormOpen = truea
    },
    handleSubmit(form) {
      this.$message.success(JSON.stringify(this.form))
    },
    handleTabClick(event) {
      this.$message.success(event);
    },
    afterInit(data) {
      this.formFlag=false
      this.$nextTick(()=>{
        if(data.taskDefKey === "TASK_VSN_ADMIN"){
          setDisabled(this.tableOption,true,['overtimeDate','cause'])
          changeColmnProp(this.tableOption, ['opinion'], 'display', true)
        }else if(data.status === "RETURNED"){
          changeColmnProp(this.tableOption, ['opinion'], 'display', true)
          changeColmnProp(this.tableOption, ['opinion'], 'disabled', true)
        }

        this.taskDefKey = data.taskDefKey
        this.$emit("afterInit", data)
        this.$set(this, "taskForm", data)
        this.formFlag=true
      })
    },
    beforeSave(data, callback) {


      callback(true)
    },
    async beforeSubmit(data, callback) {
      //用的是avue-form,所以应该是里面的validate
      this.$refs["form"].$refs['form'].validate(valid => {
        if (valid) {
          callback(true)
        } else {
          callback(false)
        }
      })
    }
  }
}
</script>

前端界面申请界面展示

将新建的两个文件,在workflowFormMapping中进行声明

然后再实现申请按钮中的handleStartProcess(row, edit)函数

handleStartProcess(row, edit) {
          // alert(row.workFlowDataId)
          this.$router.push({
            path: '/flowable/task/record/index/homan_overtime/'+this.getListRowIdForTab('homan_overtime'),
            query: {
              procDefKey: "homan_overtime",
              businessId: row.businessId,
              businessKey: row.businessKey,
              workflowDataId: row.workFlowDataId,
              editable: edit
            }
          })
        }

函数用于处理开始流程的操作。它接受两个参数 row 和 edit。根据给定的 row 数据和 edit 参数,生成一个包含路径、查询参数等信息的对象,并通过 $router.push 实现页面跳转

2.4 后端实现

后端部分

因为引入了流程控制,所以在后端方面添加一个事件类用于管理业务流程

@Component(WorkFLowConstants.PREFIX + "homan_overtime")
public class OvertimeApplyWorkflowEvent implements IWorkflowEvent<HomanOvertime> {
	@Autowired
	private HomanOvertimeService homanOvertimeService;
	@Override
	public Class getBussinessData() {
		//获取业务类型
		return HomanOvertime.class;
	}
                ......
	@Override
	public R<?> afterEnd(WorkflowData flowData, HomanOvertime bussinessData, Map<String, Object> proVariables) {
		//流程结束后执行
		log.info("homan加班流程流程结束后执行");
		bussinessData.setId(flowData.getBusinessId());
		homanOvertimeService.save(bussinessData);
		return IWorkflowEvent.super.afterEnd(flowData,bussinessData,proVariables);
	}
}

在流程完成后,将加班申请信息储存到数据库中,将数据持久化存储

在Controller层中实现添加的流程工单查询业务

由于接受业务多了三个字段,所以需要新建三个多余字段的VO类,使其继承自实体类,用于接收工单信息

@Data
public class HomanOvertimeWorkFlowVO extends HomanOvertime {
    // 流程状态
    private String workFlowStatus;

    // 流程id
    private String workFlowDataId;

    // 流程定义KEY
    private String procDefKey;
}

先在service层中新建分页查询业务

public interface HomanOvertimeService extends IService<HomanOvertime> {

    IPage<HomanOvertimeWorkFlowVO> getHomanOvertimeWorkFlowPage(Page page, HomanOvertimeWorkFlowVO homanOvertimeWorkFlowVO);
}

实现该方法

在Mapper xml中编写sql语句

<mapper namespace="com.pccw.vsn.homan.mapper.HomanOvertimeMapper">
    ......
    <select id="homanOvertimeWorkFlowPage" resultType="com.pccw.vsn.homan.vo.HomanOvertimeWorkFlowVO">
        SELECT
        id workFlowDataId,
        PROC_DEF_KEY procDefKey,
        STATUS workFlowStatus,
        INSTANCE_ID instanceId,
        UPDATE_TIME updateTime,
        replace(FORM_JSON -> '$.staffId','"','') staffId,
        replace(FORM_JSON -> '$.staffName','"','') staffName,
        replace(FORM_JSON -> '$.overtimeDate','"','') overtimeDate,
        replace(FORM_JSON -> '$.cause','"','') cause,
        replace(FORM_JSON -> '$.opinion','"','') opinion
        FROM
        (select wd.WORKFLOW_DATA_ID id, FORM_JSON,PROC_DEF_KEY,STATUS,INSTANCE_ID,UPDATE_TIME from xcd_workflow_data wd join (
        SELECT max(WORKFLOW_DATA_ID) WORKFLOW_DATA_ID FROM xcd_workflow_data  where DELETE_FLAG='0' and INSTANCE_ID is not null group by INSTANCE_ID
        union all
        SELECT WORKFLOW_DATA_ID FROM xcd_workflow_data  where DELETE_FLAG='0' and INSTANCE_ID is null
        ) wd1 on wd.WORKFLOW_DATA_ID = wd1.WORKFLOW_DATA_ID ) a
        <where>
            PROC_DEF_KEY = 'homan_overtime'
            <if test="query.staffId!=null and query.staffId!='' ">
                and FORM_JSON -> '$.staffId' LIKE concat('%', #{query.staffId}, '%')
            </if>
            <if test="query.staffName!=null and query.staffName!='' ">
                and FORM_JSON -> '$.staffName' LIKE concat('%', #{query.staffName}, '%')
            </if>
            <if test="query.overtimeDate!=null and query.overtimeDate!='' ">
                and FORM_JSON -> '$.overtimeDate' LIKE concat('%', #{query.overtimeDate}, '%')
            </if>
            <if test="query.cause!=null and query.cause!='' ">
                and FORM_JSON -> '$.cause' LIKE concat('%', #{query.cause}, '%')
            </if>
            <if test="query.opinion!=null and query.opinion!='' ">
                and FORM_JSON -> '$.opinion' LIKE concat('%', #{query.opinion}, '%')
            </if>
            <if test="query.workFlowStatus!=null and query.workFlowStatus!='' ">
                and STATUS = #{query.workFlowStatus}
            </if>
            <if test="query.workFlowDataId!=null and query.workFlowDataId!='' ">
                and id &lt;&gt; #{query.workFlowDataId}
            </if>
        </where>
        order by UPDATE_TIME desc
    </select>
    ......
</mapper>

实现类中进行调用

@Service
public class HomanOvertimeServiceImpl extends ServiceImpl<HomanOvertimeMapper, HomanOvertime> implements HomanOvertimeService {

    @Override
    public IPage<HomanOvertimeWorkFlowVO> getHomanOvertimeWorkFlowPage(Page page, HomanOvertimeWorkFlowVO homanOvertimeWorkFlowVO) {
        return getBaseMapper().homanOvertimeWorkFlowPage(page,homanOvertimeWorkFlowVO);
    }
}

在Controller中用该服务调用方法

@ApiOperation(value = "加班申请流程工单查询", notes = "加班申请流程工单查询")
   @GetMapping("/homanovertimeWorkFlowPage" )
   @PreAuthorize("@pms.hasPermission('homan_homanovertime_apply')")
   @SysLog("请假申请工单查询")
   public R getHomanOvertimeWorkFlowPage(Page page, HomanOvertimeWorkFlowVO homanOvertimeWorkFlowVO){
       IPage<HomanOvertimeWorkFlowVO> homanOvertimeWorkFlowPage = homanOvertimeService.getHomanOvertimeWorkFlowPage(page, homanOvertimeWorkFlowVO);
       return R.ok(homanOvertimeWorkFlowPage);
   }

功能实现完成

3.定时任务

3.1 启动Xxl-job服务

3.2 登录Xxl服务界面

添加任务

添加执行器

3.3 后端代码

在Java主类中添加Xxljob的注解,内容为Appname

@EnableXcloudSwagger2
@SpringCloudApplication
@EnableXcloudFeignClients
@EnableXcloudResourceServer
@EnableXcloudNacosXxlJob(appName = "vsn-job-executors-homan")
public class VsnHoman {
    public static void main(String[] args) {
        SpringApplication.run(VsnHoman.class, args);
    }
}

创建定时任务类,同样添加注解,内容为任务分组名

@Slf4j
@Component
public class HomanJobHandler {

	/**
	 * 定时任务演示
	 */
	@XxlJob("overtimeHomanJobHandler")
	public ReturnT<String> demoHomanJobHandler(String param) throws Exception {
		XxlJobLogger.log("XXL-JOB, Hello World.");
		log.info("overtimeHomanJobHandler定时任务开始执行<<<<<<<<<<<<<");
		return ReturnT.SUCCESS;
	}
}

启动Java程序,可以看出定时任务执行在本地的端口号为10000上

执行器的机器地址和该地址对应

3.4 执行任务

在界面任务管理中,点击启动任务

运行成功

4.远程调用

使用远程调用实现让数据库表在前端界面显示

4.1 新建远程调用模块

使用Xcloud生成代码包vsn-feign

4.2 编写代码

在vsn-homan中编写服务
在vsn-homan-api的feign包下创建接口

@FeignClient(contextId = "remoteHomanService", value = "vsn-homan-biz")
public interface RemoteHomanService {

    /**
     * 分页查询
     * @param mapParam 参数map
     * @return
     */
    @PostMapping("/homanovertime/remote/page")
    R getHomanOvertimePage(@RequestBody Map<String,String> mapParam, @RequestHeader(SecurityConstants.FROM) String from);
}

PostMapping路径指向biz的Controller下该方法实现的对应路径


@RestController
@AllArgsConstructor
@RequestMapping("/homanovertime" )
@Api(value = "homanovertime", tags = "加班管理")
public class HomanOvertimeController {

    private final  HomanOvertimeService homanOvertimeService;
    ......
    @Inner
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @PostMapping("/remote/page" )
    public R getHomanOvertimePage(@RequestBody Map<String,String> mapParam) {
        Page page = JSON.parseObject(mapParam.get("page"),Page.class);
        HomanOvertime homanOvertime = JSON.parseObject(mapParam.get("homanOvertime"),HomanOvertime.class);
        return R.ok(homanOvertimeService.page(page, Wrappers.query(homanOvertime)));
    }

    ......
}

4.3 引入依赖配置

@Inner注解对应Service中的请求头参数@RequestHeader(SecurityConstants.FROM) String from

完毕后则实现了该功能,接下来在vsn-feign-biz中的Controller层中调用该服务
需要在vsn-feign-biz下的pom文件中引入vsn-homan-api的依赖

<dependency>
    <groupId>com.pccw</groupId>
    <artifactId>vsn-homan-api</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>

还需要在vsn-homan-api中的resource目录下添加

com.pccw.xcloud.common.feign.XcloudFeignAutoConfiguration=\
  com.pccw.vsn.homan.api.feign.RemoteHomanService

4.4 前端显示

index.vue界面

<script>
import {fetchList} from '@/api/vsn/vsn-feign/homanovertime'
import {tableOption} from './homanovertime'

export default {
  name: 'homanovertime-vsn-feign',
  data() {
    return {
      searchForm: {},
      tableData: [],
      page: {
        total: 0, // 总页数
        currentPage: 1, // 当前页数
        pageSize: 20 // 每页显示多少条
      },
      tableLoading: false,
      tableOption: tableOption
    }
  },
  computed: {

  },
  methods: {
    getList(page, params) {
      this.tableLoading = true
      fetchList(Object.assign({
        current: page.currentPage,
        size: page.pageSize
      }, params, this.searchForm )).then(response => {
        this.tableData = response.data.records
        this.page.total = response.data.total
        this.tableLoading = false
      }).catch(() => {
        this.tableLoading=false
      })
    },
    sizeChange(pageSize){
      this.page.pageSize = pageSize
    },
    currentChange(current){
      this.page.currentPage = current
    },
    searchChange(form, done) {
      this.searchForm = form
      this.getList(this.page, form)
      done()
    },
    refreshChange() {
      this.getList(this.page)
    }
  }
}
</script>

配置数据库显示字段

export const tableOption = {
  "border": true,
  "index": true,
  "indexLabel": "序号",
  "stripe": true,
  "menuAlign": "center",
  "align": "center",
  "searchMenuSpan": 6,
  "addBtn": false,
  "editBtn": false,
  "delBtn": false,
  menu:false,
  "column": [
	  {
      "type": "input",
      "label": "ID",
      "prop": "id"
    },	  {
      "type": "input",
      "label": "员工ID",
      "prop": "staffId"
    },	  {
      "type": "input",
      "label": "员工名称",
      "prop": "staffName"
    },	  {
      "type": "input",
      "label": "加班日期",
      "prop": "overtimeDate"
    },	  {
      "type": "input",
      "label": "加班原因",
      "prop": "cause"
    },	  {
      "type": "input",
      "label": "主管意见",
      "prop": "opinion"
    },	  {
      "type": "input",
      "label": "创建人ID",
      "prop": "createId"
    },	  {
      "type": "input",
      "label": "创建人名称",
      "prop": "createName"
    },	  {
      "type": "input",
      "label": "创建时间",
      "prop": "createTime"
    },	  {
      "type": "input",
      "label": "更新人ID",
      "prop": "updateId"
    },	  {
      "type": "input",
      "label": "更新人名称",
      "prop": "updateName"
    },	  {
      "type": "input",
      "label": "更新时间",
      "prop": "updateTime"
    }  ]
}

在api中编写请求路径

import request from '@/utils/request'

export function fetchList(query) {
  return request({
    url: '/vsn-feign/homanovertime/page',
    method: 'get',
    params: query
  })
}


显示成功

5.总结分析

接触新框架的时间不算很长,但收获颇多
第一次接触到了微服务开发还有远程调用的相关思想,很惊讶接口可以通过远程调用服务进行实现,也了解了在开发中的数据库、业务模块、类名包名、服务名,注解等,都有自己的一套命名规范,也体会到了命名的不一致会导致的麻烦事,需要一行一行的肉眼检查,耗时耗力
在开发中也遇到了很多的错误,举例说明:

  1. 版本不一致
    同是jdk1.8,correct和open jdk两者也会有所差异,导致一个可以正常启动一个不可以正常启动
  2. 环境变量
    环境变量有时候会有缓存,当配置好环境变量后,在命令行查看path的内容,发现还是改变之前的内容,需要重启电脑才能完全更改
  3. Url错误
    在最开始生成微服务包时,一直报url的问题,最后解决方式是在,系统参数里面加上了 –vsn-spring.profiles.active=test 解决了问题
  4. 命令行过长
    在运行程序时,会报命令行太长的错误,解决方式是在编译设置面更改参数
  5. 前端模板不存在
    在flowable下的js中,添加配置中单词字母少写了一个,识别不到文件
  6. 后端sql错误
    也是书写问题,在mapper中少写了一个逗号,导致语句识别错误
  7. 定时任务执行器识别不到机器地址
    当运行后,在控制台中寻找Xxl-job运行的端口号,将执行器的机器地址改为手动,将该地址填入,解决问题

在开发中遇见的错误不止这么点错误,但是大部分错误都是源自不细心导致,命名的不规范、大小写没有检查出来、忘写、漏写、多写导致的,还有一些是函数自动补齐成和自己想要调动的另一个相似的方法,导致功能错误,这都是由于不够细心导致的,因为想要开发快,但却导致纠错时间拉长,反而变得慢,这是后续应该改进的,以后会更加的细心,希望以后可以少犯低级错误,提高自己的学习工作效率