实习总结
新平台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秒,因为服务与服务之间存在相互调用,且不存在心跳机制,当服务未启动完成时另一个服务调用该服务则会出现报错,故更改了又延长了等待时间,确保服务的成功运行
在配置列表中
- 创建配置
填写配置内容## 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 功能代码生成
填写生成配置
下载生成代码
打开代码包
- 将xcloud目录下的src 目录复制到 微服务biz 目录,覆盖原有src目录
- 打开 xcloud-front 打开api,将api下的文件夹 放到 vsn-ui/src/api/vsn 下
- 将views目录下的文件夹复制到vsn-ui/src/views/vsn目录下
- 将const目录下的js复制到上一步views中index.vue的同级目录
- 修改文件引入路径
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个必须字段进行隐藏显示,避免输入和查看的繁琐
由于申请时得不到主管意见,所以将主观意见字段在填写编辑步骤中进行隐藏。效果如图
可以看出简洁了很多
接下来进行按钮的功能测试
新增
添加完成
查看数据库
功能完成编辑
点击编辑
修改完成
数据库也同步更改完成删除
点击删除按钮
点击确定
删除成功
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 <> #{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.总结分析
接触新框架的时间不算很长,但收获颇多
第一次接触到了微服务开发还有远程调用的相关思想,很惊讶接口可以通过远程调用服务进行实现,也了解了在开发中的数据库、业务模块、类名包名、服务名,注解等,都有自己的一套命名规范,也体会到了命名的不一致会导致的麻烦事,需要一行一行的肉眼检查,耗时耗力
在开发中也遇到了很多的错误,举例说明:
- 版本不一致
同是jdk1.8,correct和open jdk两者也会有所差异,导致一个可以正常启动一个不可以正常启动 - 环境变量
环境变量有时候会有缓存,当配置好环境变量后,在命令行查看path的内容,发现还是改变之前的内容,需要重启电脑才能完全更改 - Url错误
在最开始生成微服务包时,一直报url的问题,最后解决方式是在,系统参数里面加上了 –vsn-spring.profiles.active=test 解决了问题 - 命令行过长
在运行程序时,会报命令行太长的错误,解决方式是在编译设置面更改参数 - 前端模板不存在
在flowable下的js中,添加配置中单词字母少写了一个,识别不到文件 - 后端sql错误
也是书写问题,在mapper中少写了一个逗号,导致语句识别错误 - 定时任务执行器识别不到机器地址
当运行后,在控制台中寻找Xxl-job运行的端口号,将执行器的机器地址改为手动,将该地址填入,解决问题
在开发中遇见的错误不止这么点错误,但是大部分错误都是源自不细心导致,命名的不规范、大小写没有检查出来、忘写、漏写、多写导致的,还有一些是函数自动补齐成和自己想要调动的另一个相似的方法,导致功能错误,这都是由于不够细心导致的,因为想要开发快,但却导致纠错时间拉长,反而变得慢,这是后续应该改进的,以后会更加的细心,希望以后可以少犯低级错误,提高自己的学习工作效率