《OA办公平台》操作手册
在学习本文档之前,要求先熟悉 项目开始配置 的使用。
名称 | 访问地址 | 账号 | 密码 |
---|---|---|---|
项目地址 | http://v-devsuit-train.t.yindangu.com | admin | 8 |
配置中心 | http://v-devsuit-train.t.yindangu.com/system/settings/index.html#/login | sa | 8 |
下面主要结合开发规范,介绍项目中几个重要模块的配置过程。
1. 登录
构件编码 | 构件名称 | 业务分类 | 作用 |
---|---|---|---|
oa_login | 登录 | 业务构件 | ① 实现页面登录功能 ② 忘记密码设置、发送邮件功能等 |
1.1 开发系统配置
添加引用 | 作用 |
---|---|
LoginComp(登录构件) | 用于实现登入和登录身份校验 |
vbase_organization(VBase_组织机构API) | 用于查询账号信息(包含账号人员岗位机构信息) |
`vbase_email(vbase_邮件管理API) | 主要用于实现发送邮件的相关接口 |
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_login | 登录 | 网页窗体-自定义窗体 |
- 1. 界面设计
- 2. 实体定义
- 3. 方法定义
- 4. 方法实现
- template
- script
- theme.less
- var.less
<div style="background: #eff0f4;width: 100%;height: 100%;">
<div class="box_bg">
<div class="box">
<div class="logo">
<img src="./../../../share/login_img/left.jpg" alt="">
</div>
<div class="fgx"></div>
<div class="input">
<h2>用户登录</h2>
<div class="border-top"></div>
<div class="input_item ">
用户名(演示账号test):
<br>
<input v-model="userInfo.current.username" type="text" placeholder="test">
</div>
<div class="input_item">
密 码(演示账号密码8):<br>
<input v-model="userInfo.current.userPassword" type="password">
</div>
<div class="input_item yzm">
验证码:<br>
<div>
<input v-model="inputCodo.current.inputCode" type="text" @keyup.enter="$emit('login')">
<img v-id2url:src="verificationCode.current.imgId" v-on:click="$emit('createCode')" class="code" alt="">
</div>
</div>
<div class="input_item bh">
<div>
<input type="checkbox" class="cbox" v-model="userInfo.current.remPassword">
<div>记住密码</div>
</div>
<a href="#" v-on:click="$emit('findPwds')">找回密码</a>
</div>
<div class="input_item btn">
<button v-on:click="$emit('login')" class="submit">登录OA系统</button>
</div>
</div>
</div>
<div class="nav">
<span style="float: left;">版权所有:珠海银弹谷网络有限公司</span>
<span style="float: right;">| Copyright© 2015—2023 Firdot All Rights Reserved.</span>
</div>
</div>
</div>
import vdk from 'v3-vdk';
import entities from './entities.js';
export default {
props: entities,
data: function () {
return {};
},
methods: {
}
};
@import "../theme.less";
@import "./var.less";
body {
background: #eff0f4;
}
* {
margin: 0;
padding: 0;
font-size: 14px;
}
#oa_login_form1_form1_8a819c3b8720bd8f0187272ec68937b6 {
background: #eff0f4 !important;
}
.box_bg {
height: 510px;
width: 1000px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -270px;
margin-left: -500px;
background: #fff;
padding-top: 66px;
padding-right: 74px;
padding-bottom: 34px;
padding-left: 66px;
}
.box {
width: 955px;
padding-top: 15px;
margin: 0 auto;
}
.logo {
width: 55%;
padding-top: 15px;
padding-right: 15px;
padding-bottom: 0px;
padding-left: 15px;
border-width: 0px;
border-style: solid;
float: left;
}
.logo img {
width: 479px;
height: 325px;
position: absolute;
top: 83px;
left: 65px;
}
.fgx {
width: 2px;
height: 275px;
margin-top: 50px;
margin-left: 15px;
margin-right: 28px;
float: left;
border-left: 2px solid #428bca;
}
.input {
width: 32%;
padding-top: 0px;
padding-right: 15px;
padding-bottom: 0px;
padding-left: 15px;
border-width: 0px;
border-style: solid;
float: left;
}
.input h2 {
color: #428bca;
font-size: 23px;
border-bottom: #428bca 3px solid;
margin-bottom: 8px;
width: 120px;
height: 34px;
text-align: center;
}
.input_item {
width: 100%;
height: 65px;
padding-top: 8px;
color: #000;
font-weight: bold;
justify-content: space-evenly;
flex-direction: column;
align-items: center;
}
.border-top {
border-top: 1px solid #428bca;
position: relative;
top: -9px;
}
.input_item input {
width: 100%;
height: 34px;
border-radius: 5px;
margin-top: 5px;
border: 1px #ccc solid;
text-indent: 10px;
}
.yzm input {
width: 200px;
margin-right: 30px;
}
.yzm div {
display: flex;
}
.bh {
display: flex;
flex-direction: row;
justify-content: space-between;
font-weight: normal;
height: 50px;
width: 90%;
margin-left: 8%;
line-height: 25px;
}
.bh a {
color: #000;
text-decoration: none;
}
.bh input {
width: 17px;
height: 17px;
margin-right: 10px;
}
.btn {
height: 40px;
}
.btn button {
width: 90%;
position: relative;
left: 50%;
transform: translateX(-50%);
}
.bh>div {
display: flex;
}
.code {
height: 30px;
width: auto;
border: 1px solid #000;
margin-top: 7px;
margin-left: -25px;
}
.submit {
width: 300px;
height: 34px;
background: #428bca;
color: #fff;
font-weight: bold;
text-align: center;
border: none;
border-radius: 5px;
}
.nav {
width: 860px;
margin: 35px auto;
height: 80px;
padding-top: 5px;
border-top: 5px solid #428bca;
float: left;
}
.nav span {
font-size: 10px;
}
(1)新增实体记录【用户实体】
(2)新增实体记录【验证码-inputCodo】
(3)执行方法_createCode(生成随机码)
(4)IF:
GetCookie("userName","")<>""
,则给界面实体/控件/变量赋值【userInfo】
1. 方法变量
2. 规则配置
(1)执行方法_ServerFunc__CheckLogin(登录校验)
(2)执行方法API_Login(API登入)
(3)执行方法API_AfterLoginoutJumpStartPage(API登出后跳转启动页面)
(1)IF:
[userInfo].[remPassword]
——若勾选记住密码,则:① 执行函数/表达式【记住密码】
② 执行函数/表达式【记住用户名】
(2)Else ——不勾选记住密码,则:
① 执行函数/表达式【删除密码】
② 执行函数/表达式【删除用户名】
(1)校验验证码
(2)IF:!BR_OUT.BR_CheckCertCode1.isValidateOK ——校验失败
① 显示设置的提示信息【验证码校验失败!】
② 执行方法_createCode(生成随机码)
③ 中断规则【中断所有】
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_forgetPwd | 忘记密码 | 网页窗体-自定义窗体 |
- 1. 界面设计
- 2. 实体定义
- 3. 方法定义
- 4. 方法实现
- template
- script
- theme.less
- var.less
<div>
<header class="header">
<nav class="nav1">
<div>同望科技股份有限公司</div>
<a v-on:click="$emit('retureLogin')">返回登录页面</a>
</nav>
<nav class="nav2 nav1">
<img src="./../../../share/home_img/HRMSLogo.png" alt="">
<div>同望科技股份有限公司</div>
</nav>
</header>
<section>
<div class="conter">
<div class="conter_header">
<div class="title">找回密码</div>
<div class="item">
<button @click="emailClick" :style="enterStyleA">通过邮件找回</button>
<button @click="wechatClick" :style="enterStyleB">通过微信找回</button>
</div>
<hr>
</div>
<div class="conter_main">
<retrive-by-email :codeSrc="verificationCode.current.imgId" @emilSubmit="emilSubmit" @resetCode1="resetCode1" v-if="isShow"></retrive-by-email>
<retrive-by-we-chat :codeSrc="verificationCode.current.imgId" @emilSubmit="emilSubmit" @resetCode1="resetCode1" @vchatSubmint="vchatSubmint" v-if="!isShow"></retrive-by-we-chat>
</div>
</div>
</section>
<footer class="footer">
<div>
Copyright © 2015-2023 版权所有:同望科技股份有限公司
</div>
</footer>
</div>
import vdk from 'v3-vdk';
import entities from './entities.js';
import RetriveByEmail from '../../../share/RetrieveByEmail.vue'
import RetriveByWeChat from '../../../share/RetrieveBYWeChat.vue'
export default {
components: {
RetriveByEmail,
RetriveByWeChat
},
props: entities,
data: function () {
return {
isShow: true,
blurStyle: "",
enterStyle: "",
enterStyleA: "",
enterStyleB: "",
enterStyle1: "font-size: 18px;color: #f60;border-bottom: 3px solid #f60; font-weight: bold;",
isVchatSubmit: "",
email: "",
username: "",
verificationCode: "",
codeSrc: this.verificationCode.current.imgId,
};
},
mounted() {
this.reSetEnterStyleA()
},
methods: {
emailClick() {
if (this.isShow == false) {
this.isShow = !this.isShow
this.enterStyleB = ""
this.enterStyleA = this.enterStyle1
}
},
wechatClick() {
if (this.isShow) {
this.isShow = !this.isShow
this.enterStyleA = ""
this.enterStyleB = this.enterStyle1
}
},
reSetEnterStyleA() {
this.enterStyleA = this.enterStyle1
},
vchatSubmint(vchatVal) {
this.isVchatSubmit = vchatVal;
if (this.isVchatSubmit) {
this.$emit('vchatSubmit')
}
},
emilSubmit(val1, val2, val3) {
// console.log(val1, val2, val3);
this.userInfo.current.emial = val1;
this.userInfo.current.username = val2;
this.inputCodo.current.inputCode = val3;
this.$emit('submit');
},
resetCode1() {
this.$emit('createCode');
},
},
};
@import "../theme.less";
@import "./var.less";
* {
margin: 0;
padding: 0;
}
body html {
height: 100%;
}
input {
padding: 5px
}
a {
text-decoration: none;
color: #fff;
}
/*正常的未被访问过的链接*/
a:link {
text-decoration: none;
}
/*已经访问过的链接*/
a:visited {
text-decoration: none;
}
/*鼠标划过(停留)的链接*/
a:hover {
text-decoration: none;
}
/* 正在点击的链接,鼠标在元素上按下还没有松开*/
a:active {
text-decoration: none;
}
/* 获得焦点的时候 鼠标松开时显示的颜色*/
a:focus {
text-decoration: none;
}
button{
background: none;
}
section {
margin: 30px;
}
.header {
width: 100%;
height: auto;
display: flex;
flex-direction: column;
}
.nav1 {
width: 100vw;
height: 50px;
background: #2c579b;
color: #fff;
font-size: 18px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.nav2 {
height: 70px;
background: #f2f2f2;
font-size: 15px;
color: #2c579b;
padding-right: 30px;
padding-left: 30px;
align-items: center;
}
.footer {
width: 100%;
height: 76px;
text-align: center;
background-color: rgb(48, 53, 72);
color: #fff;
font-size: 15px;
align-items: center;
line-height: 76px;
position: absolute;
top: 100%;
transform: translateY(-100%);
}
.conter {
border: 1px solid #ccc;
margin: 10px auto;
font-size: 15px;
height: 380px;
}
.conter_header {
margin: 15px 15px 0 15px;
}
.col1{
width: 73px;
}
.conter_header hr {
position: relative;
top: -1px;
}
.title {
font-size: 25px;
height: 40px;
width: 130px;
text-align: center;
border-bottom: 3px solid #2c579b;
color: #2c579b;
}
.item {
margin-top: 30px;
display: flex;
}
.item button {
width: 130px;
text-align: center;
padding-bottom: 5px;
border: none;
}
.conter_main {
padding: 10px;
}
@media (min-width:765px) {
.conter {
padding: 10px;
width: 1000px;
margin: 0 auto;
}
}
1. 方法变量
2. 规则配置
① 执行方法_isLoginfront(登录前校验)
② 执行方法_API_Biz_OrgQueryAccounts(查询账号信息(包含账号人员岗位机构信息))
③ IF:
GetEntityRowCount("resultEntity")==0
--账号不存在,提示相关信息,并且中断当前即可④ 执行方法_checkCertCode(校验验证码)
⑤ 执行方法_createKey(生成密钥)
⑥ 执行方法_API_SendMail(发送邮件)
⑦ IF:BR_VAR_PARENT.isSuccess --发送成功,提示相关信息,并且跳转至重置页
⑧ Else --发送失败,提示相关信息
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_resetPwd | 重置密码 | 网页窗体-自定义窗体 |
- 1. 窗体输入
- 2. 界面设计
- 3. 实体定义
- 4. 方法定义
- 5. 方法实现
- template
- script
- theme.less
- var.less
<div>
<header class="header">
<nav class="nav1">
<div>同望科技股份有限公司</div>
<a v-on:click="$emit('retrueLogin')">返回登录页面</a>
</nav>
<nav class="nav2 nav1">
<img src="./../../../share/home_img/HRMSLogo.png" alt="">
<div>同望科技股份有限公司</div>
</nav>
</header>
<section>
<div class="conter">
<div class="conter_header">
<div class="title">重置密码</div>
<div class="item">
</div>
<hr>
</div>
<div class="conter_main">
<div class="conter_input">
<div class="conter_item">
<div class="col">
<div class="red">*</div>
<div class="textR">用户名</div>
</div>
<div><input v-model="resetUserInfo.current.userName" type="text"></div>
</div>
<div class="conter_item">
<div class="col">
<div class="red">*</div>
<div>新密码</div>
</div>
<div><input v-model="resetUserInfo.current.newPassword" type="password"></div>
</div>
<div class="conter_item">
<div class="col">
<div class="red">*</div>
<div>确认密码</div>
</div>
<div><input v-model="resetUserInfo.current.repeatPassword" type="password"></div>
</div>
<div class="conter_item">
<div class="col">
<div class="red">*</div>
<div>重置密码密钥</div>
</div>
<div><input v-model="resetUserInfo.current.keys1" type="password"></div>
</div>
<div class="conter_item">
<div class="col">
<div class="red">*</div>
<div>验证码</div>
</div>
<div><input v-model="inputCode.current.inputCode" type="text"></div>
<div class="col yzm"><img v-id2url:src="verificationCode.current.imgId" class="codeImg" alt="">
<button @click="$emit('createCode')" style="cursor:pointer">换一个?</button>
</div>
</div>
<div style="margin: 0 atuo; text-align: center;">
<button @click="$emit('submit')" class="submit">提交</button>
</div>
</div>
</div>
</div>
</section>
<footer class="footer">
<div>
Copyright © 2015-2023 版权所有:同望科技股份有限公司
</div>
</footer>
</div>
import vdk from 'v3-vdk';
import entities from './entities.js';
export default {
props: entities,
data: function () {
return {};
},
methods: {
}
};
@import "../theme.less";
@import "./var.less";
* {
padding: 0;
margin: 0;
overflow: hidden;
}
button {
margin: 0;
padding: 0;
outline: none;
border-radius: 0;
background-color: transparent;
line-height: inherit;
width: max-content;
border: none;
}
input {
padding-left: 5px;
}
button:after {
border: none;
}
.textR {
text-align: left;
}
.conter_input {
margin-top: 30px;
position: absolute;
left: 50%;
margin-left: -240px;
}
.conter_item {
display: flex;
margin-top: 10px;
}
.conter_item :nth-child(n) {
margin-right: 10px;
}
.col {
width: 120px;
}
.red {
color: red;
font-size: 20px;
}
.col:nth-child(n) {
display: flex;
}
.col button {
width: 120px;
height: 24px;
}
.yzm {
width: 150px;
}
.submit {
border-radius: 5px;
width: 140px;
height: 35px;
border-color: #d9534f;
background-color: #d9534f;
color: #fff;
font-size: 15px;
margin: 15px auto;
}
.codeImg {
height: 24px !important;
width: auto;
border: 1px solid #000;
}
* {
margin: 0;
padding: 0;
}
body html {
height: 100%;
}
a {
text-decoration: none;
color: #fff;
}
/*正常的未被访问过的链接*/
a:link {
text-decoration: none;
}
/*已经访问过的链接*/
a:visited {
text-decoration: none;
}
/*鼠标划过(停留)的链接*/
a:hover {
text-decoration: none;
}
/* 正在点击的链接,鼠标在元素上按下还没有松开*/
a:active {
text-decoration: none;
}
/* 获得焦点的时候 鼠标松开时显示的颜色*/
a:focus {
text-decoration: none;
}
section {
margin: 30px;
}
.header {
width: 100%;
height: auto;
display: flex;
flex-direction: column;
}
.nav1 {
width: 100vw;
height: 50px;
background: #2c579b;
color: #fff;
font-size: 18px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 10px;
}
.nav2 {
height: 70px;
background: #f2f2f2;
font-size: 15px;
color: #2c579b;
padding-right: 30px;
padding-left: 30px;
align-items: center;
}
.footer {
width: 100%;
height: 76px;
text-align: center;
background-color: rgb(48, 53, 72);
color: #fff;
font-size: 15px;
align-items: center;
line-height: 76px;
position: absolute;
top: 100%;
transform: translateY(-100%);
}
.conter {
border: 1px solid #ccc;
font-size: 15px;
height: 380px;
width: 1000px;
position: absolute;
left: 50%;
margin-left: -500px;
}
.conter_header {
margin: 15px 15px 0 15px;
}
.conter_header hr {
position: relative;
top: -1px;
}
.title {
font-size: 25px;
height: 40px;
width: 130px;
text-align: center;
border-bottom: 3px solid #2c579b;
color: #2c579b;
}
.item {
display: flex;
}
.item button {
width: 130px;
text-align: center;
padding-bottom: 5px;
border: none;
}
.conter_main {
padding: 10px;
}
1. 方法变量
2. 规则配置
① 执行方法_isEmptyInfo(判断所填是否为空)
② 执行方法_isUsernameSame(判断用户名是否一致)
③ 执行方法_checkCertCode(校验验证码)
④ 执行方法_checkKeyCode(检验密钥)
⑤ 执行方法_OrgUpdateAccountPwd(修改账号密码)
⑥ IF:BR_VAR_PARENT.isSuccess --修改成功,则提示相关信息,并且跳转到登录页即可
1.2 执行系统配置
访问地址:http://v-devsuit-train.t.yindangu.com
账号:
admin
,密码:8
,登录验证效果即可。
2. 首页
首页模块,主要介绍首页框架搭建,例如:首页+门户+导航布局的结合使用,以及门户管理的应用场景。
2.1 开发系统配置
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_index | 办公平台 | 网页窗体-导航布局 |
- 1. 界面设计
- 2. 实体定义
- 3. 方法定义
- 4. 方法实现
创建一个导航布局类型的网页窗体,并且在属性中,设置布局方式。
1. 方法变量
2. 规则配置
(1)执行方法API_QueryLoginInfo(API查询登录信息)
(2)新增实体记录【登录用户】
(3)执行方法_openPortal(打开门户窗体)
(4)执行方法_getPortals(获取登陆用户的门户)
(1)打开窗体并返回数据【门户窗体】
(2)执行方法_spi_setDefaultPortal(设置默认门户)
info这里执行的是构件方法中定义的客户端方法spi,要求学员先掌握 spi的具体使用。
1. 方法变量
2. 规则配置
(1)清除界面实体中的数据
(2)执行方法_API_GetDefaultPortal(获取登陆用户默认门户)
(3)获取登陆用户的门户
(4)界面实体记录循环处理
①
[v_sys_PortalConfig].[portalCode]==BR_VAR_PARENT.[portalConfig].[portalCode]
,则设置是否默认门户为1
;②
[v_sys_PortalConfig].[portalCode]<>BR_VAR_PARENT.[portalConfig].[portalCode]
,则设置是否默认门户为0
。
1. 方法输入
2. 规则配置
(1)设置用户默认门户
(2)执行方法_openPortal(打开门户窗体)
(3)界面实体记录循环处理
①
[v_sys_PortalConfig].[portalCode]==BR_VAR_PARENT.[portalConfig].[portalCode]
,则设置是否默认门户为1
;②
[v_sys_PortalConfig].[portalCode]<>BR_VAR_PARENT.[portalConfig].[portalCode]
,则设置是否默认门户为0
。
1. 方法输入
2. 规则配置
(1)IF:BR_IN_PARENT.title=="工作桌面"
① 打开窗体并返回数据【门户窗体】——无需传参
② 执行方法_spi_setDefaultPortal(设置默认门户) ——构件方法中定义的客户端方法spi,无需传参
③ 中断规则【当前】
(2)BR_IN_PARENT.title=="通知公告"
① 执行方法API_LoadMenuTree(API加载菜单树)
② 打开窗体并返回数据【导航窗体】——无需传参
③ 执行方法_spi_setMenuData(设置菜单数据) ——构件方法中定义的客户端方法spi,需传参
spi和ep均定义的方法输入:
④ 中断规则【当前】
依次类推,根据菜单定义目录编号,加载菜单树时,传递菜单编码的参数如下:
菜单名称 | 菜单编码 |
---|---|
通知公告 | cd01 |
工作管理 | cd02 |
人事考勤 | cd03 |
行政后勤 | cd04 |
系统管理 | user,并且设置加载具体目录的菜单 |
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_nav | 导航布局 | 网页窗体-门户窗体 |
- 1. 实体定义
- 2. 方法扩展实现
实现构件方法中定义的客户端方法spi的扩展点:ep_setDefaultPortal(设置默认门户)
(1)清除界面实体中的数据
(2)执行方法_API_GetDefaultPortal(获取登陆用户默认门户)
窗体编码 | 窗体名称 | 窗体类型 |
---|---|---|
form_protal | 门户窗体 | 网页窗体-导航布局 |
- 1. 界面设计
- 2. 实体定义
- 3. 方法扩展实现
实现构件方法中定义的客户端方法spi的扩展点:ep_setMenuData(设置菜单数据)
2.2 执行系统配置
info学习本章节前,要求学员先掌握 菜单管理的使用。
info学习本章节前,要求学员先掌握 门户管理的使用。
访问地址:http://v-devsuit-train.t.yindangu.com
账号:
admin
,密码:8
,登录验证效果即可。
3. 员工档案
- 该模块主要实现新增员工档案业务信息,包括:员工基本信息、登录账号信息等;
- 新增或编辑时,将对应的账号和人员信息同步更新到Vbase内置的人员和账号信息表中,默认密码(8);
- 删除员工档案信息时,也同步删除Vbase内置的人员和账号信息表中对应的人员和账号信息;
- 在本项目中,为了保持Vbase人员账号表和员工档案表信息一致,由sa超级管理员维护机构信息后,只需授权 “员工档案” 菜单给用户使用,即可。
3.1 开发系统配置
表字段下载:表employee字段设计.xls
- 1. 窗体输入
- 2. 界面设计
- 3. 实体定义
- 4. 方法定义
- 5. 方法实现
(1)查询面板
绑定数据源,添加查询字段,并以此设置操作符和显示的风格。
“在职状态”下拉选择的值来源:
(2)列表
绑定员工档案实体,按原型需求选择需要显示的实体字段,设置列表只读,并依次调整列宽和属性,添加列表记录切换事件和部门链接事件。
(1)ENT_QueryPanel(查询条件过滤实体)
(2)employee(人员信息)
(3)loginUser(登录用户信息
(4)resultEntity(返回结果)
1. 方法变量
2. 规则配置
(1)给界面实体/控件/变量赋值【当前窗体实例编码】
(2)执行方法API_QueryLoginInfo(API查询登录信息)
(3)新增实体记录【登录用户信息】
(4)执行方法_loadData(加载数据)
1. 方法输入
2. 规则配置
(1)打开窗体并返回数据【员工档案编辑】
(2)IF:@isEditData --表示编辑窗体已更新数据,列表窗体需要刷新数据
① 给界面实体/控件/变量赋值【清除编辑信息】
② 执行方法_loadData(加载数据)
1. 方法变量
2. 规则配置
(1)IF:GetEntitySelectedRowCount("employee") == 0 -- 未选中删除记录,提示相关信息,并且中断当前
(2)显示设置的提示信息【是否删除】 --询问的方式
(3)IF:!BR_OUT.BR_ShowMessage3.confirm --针对(2)的提示取消删除,则中断当前
(4)新增实体记录【userEntity】
(5)执行方法_API_Biz_OrgDeleteUser(删除人员)
(6)IF:!BR_VAR_PARENT.isSuccess --删除人员失败,则提示删除失败信息,中断当前
(7)新增实体记录【accountEntity】
(8)执行方法_API_Biz_OrgDeleteAccount(删除账号)
(9)IF:!BR_VAR_PARENT.isSuccess --删除账号失败,则提示删除失败信息,中断当前
(10)删除实体记录【userEntity】
(11)删除实体记录【accountEntity】
(12)修改数据库中的记录【修改删除状态】--假删
(13)删除实体记录【employee】
(14)执行方法_setComponentState(设置控件状态)
(15)显示设置的提示信息【删除成功】
(1)打开窗体并返回数据【机构树选择】
(2)
IF:GetEntityRowCount("resultEntity")<>0
--选择部门机构返回,则修改字段,并且保存① 给界面实体/控件/变量赋值【所属部门】
② 保存实体到数据库【employee】
(1)打开窗体并返回数据【机构树选择】
(2)
IF:GetEntityRowCount("resultEntity")<>0
--选择部门机构返回,则修改查询实体字段,给界面实体/控件/变量赋值【所属部门】按照开发规范,窗体方法、控件方法通过“执行方法”规则,执行对应的自定义方法,无需传参(窗体方法、控件方法的编码和名称,保留默认即可)。
方法编码 方法名称 规则配置 form_employee_list_FormLoadAction
窗体加载事件
执行方法_loadForm(加载页面)
dtg_employee_OnDoubleClick
列表_双击事件
执行方法_editData(编辑数据)
dtg_employee_OnRecordIndexChanged
列表_记录切换事件
执行方法_setComponentState(设置控件状态)
tbmrevise_OnClick
修改_单击事件
执行方法_editData(编辑数据)
tbmNew_OnClick
新增_单击事件
执行方法_addData(新增数据)
tbmDelete_OnClick
删除_单击事件
执行方法_deleteData(删除数据)
qcp_qry_OnConditionChanged
查询过滤事件
执行方法_loadData(加载数据)
- 1. 窗体输入
- 2. 界面设计
- 3. 实体定义
- 4. 方法定义
- 5. 方法实现
依次将控件与 “员工信息” 实体进行绑定(包括头像):
文件上传控件,绑定对应的文件实体字段:
(1)fileInfo(文件)
(2)employee(人员信息)
(3)loginUser(登录用户信息
(4)resultEntity(返回结果)
1. 方法变量
2. 规则配置
(1)执行方法API_QueryLoginInfo(API查询登录信息)
(2)新增实体记录【登录用户信息】
(3)IF:@openType=="personal" --在 “工作管理→个人信息” 中打开该页面,则加载当前用户个人档案信息
从数据库获取数据到实体【员工信息】:
(4)Else --在“员工手册”页新增或编辑时打开该页面
① IF:
IsEmpty(@mainId)&&(@openType<>"personal")
--新增时打开,则执行新增逻辑新增实体记录【员工档案】:
② Else --在编辑时打开,则执行加载数据逻辑
从数据库获取数据到实体【员工信息】:
(5)执行方法_setComponentState(设置控件状态)
(1)打开窗体并返回数据【机构树选择】
(2)
IF:GetEntityRowCount("resultEntity")<>0
--选择部门机构返回,则修改字段给界面实体/控件/变量赋值【所属部门】:
1. 方法输出
2. 方法变量
3. 规则配置
(1)实体间复制记录【用户数据】
(2)执行方法_API_Biz_OrgSyncUser(同步人员)
(3)IF:!BR_OUT_PARENT.isSuccess --同步人员信息失败,则提示相关信息,并且中断当前
(4)实体间复制记录【账号数据】
(5)执行方法_API_Biz_OrgSyncAccount(同步账号)
1. 方法变量
2. 规则配置
(1)必填项检查
(2)IF:
!BR_OUT.BR_CheckRequired1.isCheckRequiredOK
-- 必填项不通过,则中断当前(3)数据合法性校验【身份证】
(4)IF:
!BR_OUT.BR_DataValidationEditor1.isValidateOK
--合法性校验不通过,则中断当前(5)IF:
!IsEmpty([employee].[phone])
-- 手机号不为空时,才进行合法性校验,同样校验不通过,则中断当前(6)IF:
!IsEmpty([employee].[workEmail])
-- 邮箱不为空时,才进行合法性校验,同样校验不通过,则中断当前(7)前后台唯一性检查【用户名-账号】
(8)IF:
!BR_OUT.BR_CheckUnique1.isUnique
-- 唯一性不同通过,则提示信息并且中断当前(9)执行方法_editVbaseData(同步Vbase人员账号)
(10)IF:
BR_VAR_PARENT.isSuccess==False
-- 同步Vbase人员账号失败,则提示信息并且中断当前(11)保存实体到数据库【employee】
(12)IF:!IsEmpty(@parentWindowInstanceCode) --存在来源窗体实例,保存成功后已更新数据,则执行来源窗体方法刷新数据
(13)显示设置的提示信息【保存成功!】
按照开发规范,窗体方法、控件方法通过“执行方法”规则,执行对应的自定义方法,无需传参(窗体方法、控件方法的编码和名称,保留默认即可)。
方法编码 方法名称 规则配置 form_employee_edit_FormLoadAction
窗体加载事件
执行方法_loadForm(加载页面)
atm_file_OnFileSelected
文件已选择
执行方法_fileSelectAfter(文件选择后)
atm_file_OnUploadCompleted
文件已上传
执行方法_fileUploadAfter(文件上传后)
txt_department_OnLabelClick
所属部门_单击标题
执行方法_department(选择所属部门)
btnSave_OnClick
保存_单击事件
执行方法_saveData(保存数据)
3.2 执行系统配置
访问地址:http://v-devsuit-train.t.yindangu.com
账号:
admin
,密码:8
,登录验证效果即可。
4. 报销管理
4.1 开发系统配置
在本案例中,结合开发规范,按照业务功能分离成三个构件。
构件编码 | 构件名称 | 业务分类 | 作用 |
---|---|---|---|
(1)common_action_lib | 流程公共_业务动作库 | 业务动作库 | ① 定义业务动作 ② 生成业务动作模版 |
(2)ydg_reimburse_db | 报销申请_DB | 数据库构件 | ① 定义数据表 ② 初始化基础数据 ③ 输出数据表保存、删除、修改方法 |
(3)ydg_reimburse_pc | 报销申请_PC | 业务构件 | ① 日常业务表单 |
构件编码 | 构件名称 | 业务分类 | 作用 |
---|---|---|---|
common_action_lib | 流程公共_业务动作库 | 业务动作库 | ① 定义业务动作 ② 生成业务动作模版 |
在本项目中,所有需要使用业务框架的窗体,均共用一个业务动作库构件,因此在创建业务动作库构件时可以需求创建常用的业务动作。
1. 在构件目录中,打开【业务动作】选项,根据需求自定义业务动作。
动作类型有两种,分别是:通用动作、流程动作。
流程动作,主要用于流程框架菜单。在本案例中,选择通用动作,主题是动作的显示颜色,根据需要进行选择。
2. 选择新建的业务动作,右击选择“新建业务动作扩展点”,创建业务动作扩展点 。
3. 在业务动作中,新增执行方法规则,在执行方法中执行对应的EP扩展点。
4. 若是无需回调业务窗体逻辑,无需建立EP扩展,比如“取消”动作,处理退出窗体逻辑即可。
info
- 业务动作编码、名称,及业务动作扩展实现编码、名称,参照开发规范。
- 业务动作定义,可以按实际业务添加,及配置相关逻辑。
右击构件,选中 '生成业务动作模板' 选项,生成业务动作模版。
生成业务动作模版后,在模版样式 -> 业务动作模版库,可以查看自定义模版,以及已安装的模版。
将该模板构件部署到云空间,发布后项目的其他人员更新了云空间,会自动更新或者安装该构件模板。
构件编码 | 构件名称 | 业务分类 | 作用 |
---|---|---|---|
ydg_reimburse_db | 报销申请_DB | 数据库构件 | ① 定义数据表 ② 初始化基础数据 ③ 输出数据表保存、删除、修改方法 |
在
报销申请_DB
构件中,添加 '登录构件' 引用,用于获取当前登录用户信息,赋值给人员相关字段。
添加引用 | 作用 |
---|---|
LoginComp(登录构件) | 主要用于获取当前登录用户信息赋值给表相关系统和业务字段userName:用户名称 userId:用户Id orgName:机构名称 orgId :机构Id |
在当前构件【引用】文件夹下,右键“增加引用”,依次选择LoginComp(登录构件)
、vbase_workflow_facade(VBase_流程管理)
构件添加至引用,确定即可。
引用方法的具体使用:参考流程常用方法-方法信息。
在当前构件【表】文件夹下新建目录【报销申请】,根据原型设计数据库表,1个报销单包含任意多个报销明细,所以在设计数据库为1对多关系(主从表结构)。
命名规范:
表编码 | 表名称 | 导入固定字段 |
---|---|---|
reimburse_main | 报销申请_主表 | 01主表固定字段.xls |
reimburse_detail | 报销申请_从表 | 02从表固定字段.xls |
reimburse_file | 报销申请_附件表 | 02从表固定字段.xls |
业务字段与数据库设计:
根据原型图定义报销申请的业务字段(排除重复的固定字段)并进行数据库设计,如果不能满足需求,再做修改或新增字段。
报销申请_主表(reimburse_main)
报销申请_从表(reimburse_detail)
报销申请_附件表(reimburse_file)
命名规范:
方法编码 | 方法名称 | 添加到构件输出 |
---|---|---|
saveReimburseDetail | 保存报销申请从表 | ✔ |
deleteReimburseDetail | 删除报销申请从表 | ✔ |
配置视频:
详细配置:
1. 保存报销申请从表(saveReimburseDetail
)
- 方法输入
- 方法输出
- 规则配置
编码 | 名称 | 类型 | 描述 |
---|---|---|---|
reimburseDetail | 报销申请从表 | 实体 | 实体字段,引入对应的表字段。 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
根据入参的实体id判断是否进行保存,入参实体id为空则中断并返回错误提示,不为空则保存实体到数据库,并返回成功提示。
(1) IF:IsEmpty(BR_IN_PARENT.[reimburseDetail].[id]) ——入参为空
① 给界面实体/控件/变量赋值:给方法输出赋值(在本示例中,方法输出设置没有直接体现,主要是根据开发规范,在日志查询、调试等可以获取对应的信息)
② 中断规则:中断当前规则链
(2)保存实体到数据库【报销申请从表】
(3)给界面实体/控件/变量赋值:给方法输出赋值
2. 删除报销申请从表(deleteReimburseDetail
)
- 方法输入
- 方法输出
- 方法变量
- 规则配置
编码 | 名称 | 类型 | 初始值 | 必须 | 描述 |
---|---|---|---|---|---|
ids | 数据Ids | 文本 | ✔ | Id 与 MainId 必填一项,同时存在将分开删除,多个Id用英文逗号隔开 | |
mainId | 主表Ids | 文本 | Id 与 MainId 必填一项,同时存在将分开删除,多个Id用英文逗号隔开 | ||
isDelete | 是否删除 | 布尔 | True |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
dateTime | 当前日期时间 | 日期时间 | yyyy-MM-dd HH:mm:ss | |
userId | 用户Id | 文本 | 当前登录人 | |
userName | 用户名称 | 文本 | 当前登录人 |
根据入参的数据ids、主表mainIds判断是否进行删除,入参为空则中断并返回错误提示,不为空则(逻辑删除)修改数据库中的记录,并返回成功提示。
逻辑删除的本质并不是真正的删除,而是在表中将对应的是否删除标识字段(isDelete)进行修改操作。比如false是未删除,true是删除。在逻辑上数据是被删除的,但数据本身依然存在表中。
对应的SQL语句:update 表名 set isDelete = True where id = 1;
语句表示,在该表中将id为1的信息进行逻辑删除,那么客户端进行查询id为1的信息,服务器就不会提供信息。倘若想继续为客户端提供该信息,可将 isDelete 更改为 False 。
(1)IF: IsEmpty(BR_IN_PARENT.ids) && IsEmpty(BR_IN_PARENT.mainIds) ——入参为空
① 给界面实体/控件/变量赋值:给方法输出赋值(在本示例中,方法输出设置没有直接体现,主要是根据开发规范,在日志查询、调试等可以获取对应的信息)
② 中断规则:中断当前规则链
(2)执行方法API_QueryLoginInfo(API查询登录信息)
(3)给界面实体/控件/变量赋值【记录当前日期时间】
(4)IF:! IsEmpty(BR_IN_PARENT.mainIds) ——主表Id不为空,主要是删除主表的场景,调用该方法执行的删除逻辑
① 修改数据库中的记录【报销申请从表_主表Id】
(5)IF:! IsEmpty(BR_IN_PARENT.ids) ——数据表Id不为空,主要是直接删除从表的场景,调用该方法执行的删除逻辑
① 修改数据库中的记录【报销申请从表_数据Id】
(6)给界面实体/控件/变量赋值:给方法输出赋值
命名规范:
方法编码 | 方法名称 | 添加到构件输出 |
---|---|---|
saveReimburseFile | 保存报销申请附件表 | ✔ |
deleteReimburseFile | 删除报销申请附件表 | ✔ |
配置视频:
详细配置:
1. 保存报销申请附件表(saveReimburseDetail
)
- 方法输入
- 方法输出
- 规则配置
编码 | 名称 | 类型 | 描述 |
---|---|---|---|
reimburseFile | 报销申请附件表 | 实体 | 实体字段,引入对应的表字段。 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
根据入参的实体id判断是否进行保存,入参实体id为空则中断并返回错误提示,不为空则保存实体到数据库,并返回成功提示。
配置逻辑与 “ 保存报销申请附件表(saveReimburseDetail
)” 一样。
2. 删除报销申请附件表(deleteReimburseDetail
)
- 方法输入
- 方法输出
- 方法变量
- 规则配置
编码 | 名称 | 类型 | 初始值 | 必须 | 描述 |
---|---|---|---|---|---|
ids | 数据Ids | 文本 | ✔ | Id 与 MainId 必填一项,同时存在将分开删除,多个Id用英文逗号隔开 | |
mainId | 主表Ids | 文本 | Id 与 MainId 必填一项,同时存在将分开删除,多个Id用英文逗号隔开 | ||
isDelete | 是否删除 | 布尔 | True |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
dateTime | 当前日期时间 | 日期时间 | yyyy-MM-dd HH:mm:ss | |
userId | 用户Id | 文本 | 当前登录人 | |
userName | 用户名称 | 文本 | 当前登录人 |
根据入参的数据ids、主表mainIds判断是否进行删除,入参为空则中断并返回错误提示,不为空则(逻辑删除)修改数据库中的记录,并返回成功提示。
配置逻辑与 “ 删除报销申请附件表(deleteReimburseDetail
)” 一样。
命名规范:
方法编码 | 方法名称 | 添加到构件输出 |
---|---|---|
saveReimburseMain | 保存报销申请主表 | ✔ |
deleteReimburseMain | 删除报销申请主表 | ✔ |
updateReimburseMainBizStatus | 修改报销申请主表业务状态 | ✔ |
配置视频:
详细配置:
1. 保存报销申请主表(saveReimburseMain
)
- 方法输入
- 方法输出
- 规则配置
编码 | 名称 | 类型 | 描述 |
---|---|---|---|
reimburseMain | 报销申请主表 | 实体 | 实体字段,引入对应的表字段。 |
reimburseDetail | 报销申请从表 | 实体 | 实体字段,引入对应的表字段。 |
reimburseFile | 报销申请附件表 | 实体 | 实体字段,引入对应的表字段。 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
根据入参的实体id判断是否进行保存,入参实体id为空则中断并返回错误提示,不为空则保存实体到数据库,并返回成功提示。
配置逻辑与 “ 保存报销申请附件表(saveReimburseDetail
)” 类似,只是在保存主表的时候,同时需要执行保存从表、附件表逻辑。
(1) IF:IsEmpty(BR_IN_PARENT.[reimburseMain].[id])——入参为空
① 给界面实体/控件/变量赋值:给方法输出赋值(在本示例中,方法输出设置没有直接体现,主要是根据开发规范,在日志查询、调试等可以获取对应的信息)
② 中断规则:中断当前规则链
(2)保存实体到数据库【报销申请主表】
(3)执行方法_saveReimburseDetail(保存报销申请从表)
(4)执行方法_saveReimburseFile(保存报销申请附件表)
(5)给界面实体/控件/变量赋值:给方法输出赋值
2. 删除报销申请主表(deleteReimburseMain
)
- 方法输入
- 方法输出
- 方法变量
- 规则配置
编码 | 名称 | 类型 | 初始值 | 必须 | 描述 |
---|---|---|---|---|---|
ids | 数据Ids | 文本 | ✔ | ||
isDelete | 是否删除 | 布尔 | True |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | true | 默认为True |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
dateTime | 当前日期时间 | 日期时间 | yyyy-MM-dd HH:mm:ss | |
userId | 用户Id | 文本 | 当前登录人 | |
userName | 用户名称 | 文本 | 当前登录人 |
根据入参的数据ids判断是否进行删除,入参为空则中断并返回错误提示,不为空则(逻辑删除)修改数据库中的记录,并返回成功提示。
配置逻辑与 “ 删除报销申请附件表(deleteReimburseDetail
)” 类似,只是在删除主表的时候,同时需要执行删除从表、附件表逻辑。
(1)IF: IsEmpty(BR_IN_PARENT.ids) ——入参为空
① 给界面实体/控件/变量赋值:给方法输出赋值(在本示例中,方法输出设置没有直接体现,主要是根据开发规范,在日志查询、调试等可以获取对应的信息)
② 中断规则:中断当前规则链
(2)执行方法API_QueryLoginInfo(API查询登录信息)
(3)给界面实体/控件/变量赋值【记录当前日期时间】
(4) 修改数据库中的记录【报销申请主表】
(5)执行方法_deleteReimburseDetail(删除报销申请从表)
(6)执行方法_deleteReimburseFile(删除报销申请附件表)
(7)给界面实体/控件/变量赋值:给方法输出赋值
3. 修改报销申请主表业务状态(updateReimburseMainBizStatus
)
- 方法输入
- 方法输出
- 方法变量
- 规则配置
编码 | 名称 | 类型 | 初始值 | 必须 | 描述 |
---|---|---|---|---|---|
ids | 数据Ids | 文本 | #bizId | ✔ | 多个Id用英文逗号隔开 |
bizStatusCode | 状态编码 | 文本 | "B" | ✔ | T-1\编制;B\1\审批中;E-9\审批不通过;F\9\审批通过;C\0\已作废;A\8\修订中;R\2\退回 |
bizStatus | 状态 | 文本 | "审批中" | ✔ | T-1\编制;B\1\审批中;E-9\审批不通过;F\9\审批通过;C\0\已作废;A\8\修订中;R\2\退回 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | 默认为True | |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
dateTime | 当前日期时间 | 日期时间 | yyyy-MM-dd HH:mm:ss | |
userId | 用户Id | 文本 | 当前登录人 | |
userName | 用户名称 | 文本 | 当前登录人 |
主要结合工作流程,在审批环节,更新业务数据的业务状态。
根据入参的数据Ids、状态编码、状态判断是否进行修改,入参空则中断并返回错误提示,不为空则修改数据库中的记录,并返回成功提示。
(1)IF:IsEmpty(BR_IN_PARENT.ids) || IsEmpty(BR_IN_PARENT.bizStatusCode) || IsEmpty(BR_IN_PARENT.bizStatus) ——入参为空
① 给界面实体/控件/变量赋值:给方法输出赋值(在本示例中,方法输出设置没有直接体现,主要是根据开发规范,在日志查询、调试等可以获取对应的信息)
② 中断规则:中断当前规则链
(2)执行方法API_QueryLoginInfo(API查询登录信息)
(3)给界面实体/控件/变量赋值【记录当前日期时间】
(4) 修改数据库中的记录【报销申请主表】
(5)给界面实体/控件/变量赋值:给方法输出赋值
4. 修改报销申请主表报销金额(updateReimburseMainReimburseAmt
)
- 方法输入
- 方法输出
- 方法变量
- 规则配置
编码 | 名称 | 类型 | 必须 | 描述 |
---|---|---|---|---|
ids | 数据Ids | 文本 | ✔ | 多个Id用英文逗号隔开 |
reimburseAmt | 报销金额(元) | 小数 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
isSuccess | 是否成功 | 布尔 | 默认为True | |
errorCode | 错误代码 | 文本 | 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 | |
errorMessage | 错误信息 | 文本 |
编码 | 名称 | 类型 | 初始值 | 描述 |
---|---|---|---|---|
dateTime | 当前日期时间 | 日期时间 | yyyy-MM-dd HH:mm:ss | |
userId | 用户Id | 文本 | 当前登录人 | |
userName | 用户名称 | 文本 | 当前登录人 |
主要结合工作流程,在审批环节,更新业务数据的业务状态。
根据入参的数据Ids判断是否进行修改,入参空则中断并返回错误提示,不为空则修改数据库中的记录,并返回成功提示。
配置逻辑与 “ 修改报销申请主表业务状态(updateReimburseMainBizStatus
)” 类似,只是在修改规则中,修改的是报销金额字段。
(1)修改数据库中的记录【报销申请主表报销金额】
构件编码 | 构件名称 | 业务分类 | 作用 |
---|---|---|---|
ydg_reimburse_pc | 报销申请_PC | 业务构件 | ① 日常业务表单 |
在
报销申请_pc
构件中,根据需求,添加相关引用。在
报销申请_DB
构件中,添加 '登录构件' 引用,用于获取当前登录用户信息,赋值给人员相关字段。
添加引用 | 作用 |
---|---|
common_action_lib(流程公共_业务动作库) | 主要用于【报销申请】编辑窗体导入业务动作,并且设置业务动作构件服务映射。 |
ydg_reimburse_db(报销申请_DB) | 主要用于业务构件窗体执行主表、从表、附件表的保存和删除方法。 |
LoginComp(登录构件) | 主要用于获取当前登录用户信息赋值给表相关系统和业务字段 (例如:申请人、新增人、修改人相关字段) userName:用户名称 userId:用户Id orgName:机构名称 orgId :机构Id |
vbase_organization_facade(VBase_组织机构) | 主要用于获取人员信息赋值给表对应的领款人字段。 |
vbase_prd_workflow(vbase_产品化流程管理) | 必须添加,配置流程启动时需要使用。 例如:打开 "流程应用" 窗体启动流程,该窗体在 vbase_prd_workflow(vbase_产品化流程管理) 构件中。 |
vbase_prdbizframe(vbase_产品化) | 主要用于触发业务框架动作数据变化(例如:设置业务框架按钮使能、显示等) |
引用方法的具体使用:参考流程常用方法-方法信息。
本地项目:从当前项目选中添加引用构件。
云项目:可以直接添加引用。
如果被引用构件进行了修改并重新部署,那么当前的引用构件需要执行【更新引用】操作。
例如:修改了
ydg_reimburse_db
构件并重新部署,那么在ydg_reimburse_pc
的引用中选中ydg_reimburse_db
构件执行【更新引用】操作。
在业务构件(
报销申请_PC
)创建查询前,需要将数据库构件(报销申请_DB
)先部署到服务,否则创建查询后,预览会失败。
- 1.获取报销申请主表
- 2.获取报销申请从表
- 3.获取报销申请附件表
查询编码 查询名称 查询类型 getReimburseMain
获取报销申请主表
VSql
SELECT *
FROM toone_reimburse_db.reimburse_main
WHERE IsDelete <> 1
ORDER BY bizCode DESC
查询编码 查询名称 查询类型 getReimburseDetail
获取报销申请从表
VSql
SELECT *
FROM toone_reimburse_db.reimburse_detail
WHERE isDelete <> 1
ORDER BY consumeDate,addDateTime,modifyDateTime DESC
查询编码 查询名称 查询类型 getReimburseFile
获取报销申请附件表
VSql
SELECT *
FROM toone_reimburse_db.reimburse_file
WHERE isDelete <> 1
ORDER BY addDateTime,modifyDateTime DESC
在当前构件【窗体】文件夹下新建目录【报销申请】,根据原型新增窗体。
命名规范:
窗体编码 | 窗体名称 |
---|---|
form_reimburse_list | 报销申请列表 |
form_reimburse_edit | 报销申请编辑 |
form_reimburse_report | 报销申请单 |
- 1. 窗体输入
- 2. 实体定义
- 3. 界面设计
- 4. 方法定义
- 5. 方法实现
私有 编码 名称 类型 初始值 描述 ✔ currentWindowInstanceCode
当前窗体实例编码 文本 主要用于主页面编辑、查看数据时打开编辑窗体进行传参 isEditData
编辑数据标识 布尔 false 用于判断编辑窗体是否编辑了数据,主页面根据返回值为true刷新数据 (1) 报销申请_主表实体
(2)查询条件过滤实体:添加查询面板设置查询条件时,自动生成,不允许修改,只有删除查询面板时才允许删除。
主要是加载页面事件、查询过滤事件、新增或编辑场景刷新数据时,执行
loadData(加载数据)
方法。(1)显示进度条
(2)从数据库获取数据到实体【报销申请主表】
(3)执行方法_setComponentState(设置控件状态)
(4)隐藏进度条
主要是新增、编辑事件,执行
openEditMainData(打开编辑主数据窗体)
方法。方法输入:
编码 名称 类型 初始值 枚举值 描述 openType
打开方式 文本 edit
add
:新增打开方式edit
:编辑打开方式view
:查看打开方式用于新增、编辑事件执行该方法时传入的参数。 openTypeName
打开方式名称 文本 编辑 新增: add
打开方式
编辑:edit
打开方式
查看:view
打开方式用于新增、编辑事件执行该方法时传入的参数。 规则:
(1)打开业务框架【报销申请编辑】
由于业务框架通过【报销申请编辑】窗体创建,因此该窗体对应的窗体输入,在【打开业务框架】规则打开时,依然需要传递参数。
请查看业务单据实例的定义。
窗口标题:Format("报销申请{0}", BR_IN_PARENT.openTypeName)
窗体输入(
parentWindowInstanceCode
):来源窗体实例编码,主要用于编辑窗体保存逻辑执行主窗体方法时,需要设置该参数。窗体输入(
mainId
):主表Id,主要针对非新增场景才需要传递,新增场景Null()。(2)IF:@isEditData
窗体输入(
isEditData
编辑数据标识)默认为false,在【报销申请编辑】窗体中保存数据成功时会执行主窗体事件,传递该参数为True,用于判断是否需要刷新数据。判断窗体输入(
isEditData
编辑数据标识)若为True则刷新数据,同时清除窗体输入(isEditData
编辑数据标识)。① 给界面实体/控件/变量赋值【清除编辑信息】
② 执行方法_loadData(加载数据)
主要执行
openEditMainData(打开编辑主数据窗体)
方法,设置参数传递。(1)IF:
[reimburseMain].[bizStatusCode]=="T"
若业务状态为编辑时,打开业务框架传递参数为
edit
(编辑)。(2)Else
否则业务状态为非编辑时,打开业务框架传递参数为
view
(查看)。主要删除事件,执行
deleteData(删除数据)
方法。(1)IF:GetEntitySelectedRowCount("reimburseMain") == 0
若当前报销申请记录数为空,则提示未选中,并且中断当前规则链。
① 显示设置的提示信息【未选中】——提示"请选中需要删除的记录!"
② 中断规则【未选中则中断当前】
(2)
[reimburseMain].[bizStatusCode] <> "T"
若当前报销申请业务状态为非编制,则提示非编辑不允许删除,并且中断当前规则链。
① 显示设置的提示信息【非编制】——提示"非编制状态不可删除!"
② 中断规则【非编制则中断当前】
(3)显示设置的提示信息【是否删除】
采用提示类型:询问(确定/取消),会返回确认结果True/False。
(4)IF:! BR_OUT.BR_ShowMessage3.confirm
显示设置的提示信息【是否删除】,若取消则会返回确认结果False,中断当前所有规则链。
① 中断规则【取消则中断当前】
(5)执行方法_deleteReimburseMain(删除报销申请主表)
方法变量:
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 true 默认为True errorCode
错误代码 文本 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 errorMessage
错误信息 文本 (6)IF:!BR_VAR_PARENT.isSuccess
若方法变量
isSuccess
不等于True,则提示返回错误信息,中断当前规则链。① 显示设置的提示信息【删除失败】
② 中断规则【删除失败则中断当前】
(7)删除实体记录【reimburseMain】
(8)执行方法_setComponentState(设置控件状态)
若删除实体记录后,根据列表中当前行记录的状态变化,重新设置控件使能。
(9)显示设置的提示信息【删除成功】
主要在【报销申请编辑】窗体中,保存逻辑执行
setEditInfo设置修改信息(编辑窗体调用)
方法。方法输入:
编码 名称 类型 初始值 描述 isEditData
是否已编辑 布尔 False
按照开发规范,窗体方法、控件方法通过“执行方法”规则,执行对应的自定义方法,无需传参(窗体方法、控件方法的编码和名称,保留默认即可)。
方法编码 方法名称 规则配置 form_reimburse_list_FormLoadAction
窗体加载事件
执行方法_loadForm(加载页面)
dtg_main_OnDoubleClick
列表_双击事件
执行方法_editData(编辑数据)
dtg_main_OnRecordIndexChanged
列表_记录切换事件
执行方法_setComponentState(设置控件状态)
ent_txt_bizCode_OnValueChanged
申请编号_值改变事件
执行方法_editData(编辑数据)
tbm_add_OnClick
新增_单击事件
执行方法_addData(新增数据)
tbm_delete_OnClick
删除_单击事件
执行方法_deleteData(删除数据)
tbm_print_OnClick
打印_单击事件
执行方法_printData(打印数据)
- 1.导入业务动作
- 2. 窗体输入
- 3. 实体定义
- 4. 界面设计
- 5. 方法定义
- 6. 方法实现
方法一:在新增窗体时,直接添加业务动作:
方法二:新建窗体后,右击选择导入业务动作操作:
导入后,在窗体方法中,会有对应的业务动作扩展实现:
私有 编码 名称 类型 初始值 描述 ✔ parentWindowInstanceCode
来源窗体实例编码 文本 用于执行来源窗体方法时,需要设置方法所在窗体的窗体实例 bizId
流程业务Id 文本 流程字段 mainId
主表Id 文本 主要用于主页面编辑、查看数据时打开编辑窗体进行传参 1. 报销申请_主表
2. 报销申请_从表
3. 报销申请_附件表
4. 文件:用于绑定文件控件,记录附件相关信息,在目标附件实体在新增时,赋值给相关文件字段。
5. 登录用户信息:用于记录当前登录用户信息,方便新增/修改数据时,赋值给相关字段。
第一部分:窗体加载、控件属性设置、框架属性设置自定义事件
主要是窗体加载事件时,执行
loadForm(加载页面)
方法。方法变量:
编码 名称 类型 初始值 描述 dateTime
当前日期时间 日期时间 yyyy-MM-dd HH:mm:ss userId
用户Id 文本 当前登录人 userName
用户名称 文本 当前登录人 (1)进度条显示
(2)执行方法API_QueryLoginInfo(API查询登录信息)
(3)新增实体记录【登录用户信息】
由于当前登录用户信息,在新增逻辑中作为当前申请人的相关信息,在保存逻辑中作为修改人的相关信息,因此定义登录用户信息实体,在不同场景直接获取实体信息即可,无需重复执行API查询登录信息。
(4)IF:IsEmpty(@bizId)&&IsEmpty(@mainId)
若窗体输入bizId和mainId均为空,则【报销申请编辑】窗体是通过【报销申请列表】窗体点击新增打开的场景,执行新增逻辑。
① 新增实体记录【报销申请主表】
(5)Else
若窗体输入bizId和mainId其一不为空,则【报销申请编辑】窗体是通过【报销申请列表】窗体点击编辑打开的场景(mainId不为空),或者在流程任务审批过程中打开表单窗体的场景(bizId不为空),根据参数执行加载数据逻辑。
① 从数据库获取数据到实体【主表】
② 从数据库获取数据到实体【从表】
③ 从数据库获取数据到实体【附件】
(6)执行方法_setComponentState(设置控件属性)
不管新增或加载的场景,均需要执行方法_setComponentState(设置控件属性)。
(7)隐藏进度条
主要是页面加载事件、从表删除、附件表删除时,执行该方法。
(1)控件属性设置【控件属性控制】
根据业务状态不同,设置界面从表工具栏显示、使能等。
- 从表列表工具栏"删除"按钮,根据业务状态和从表数据是否为空,控制使能;
- 附件表选择文件控件所在编组,根据业务状态控制显示;
- 附件表列表控件“删除”列,默认不显示,根据业务状态控制显示。
(2)执行方法_setFrameworkAttribute(设置框架属性)
方法输入:
编码 名称 类型 枚举值 描述 bizCodeTitle
单据编号标题 文本 单据编号;
业务编号;
编号为null则不修改,
为 " " 则不显示单据编号标题bizCode
单据编号 文本 为null则不修改,
为 " " 则不显示单据编号bizStatusTitle
单据状态标题 文本 单据状态;
业务状态;
当前状态;
状态为null则不修改,
为 " " 则不显示单据状态标题bizStatus
单据状态 文本 编制:T;
审批中:B;
审批不通过:E;
审批通过:F;
已作废:C;
修订中:A;
退回:R为null则不修改,
为 " " 则不显示单据状态bizStatusCode
单据状态编号 文本 T:编制;
B:审批中;
E:审批不通过;
F:审批通过;
C:已作废
A:修订中
R:退回为null则不修改,
用于控制表单状态bizStatusColor
单据状态颜色 文本 #000000:黑色;
#FF0000:红色;
#FFFF00:黄色;
#00FF00:绿色;
#0000FF:蓝色为null则不修改,默认为#FF0000
支持常见颜色编码和16进制颜色编码(1)执行方法_setFrameworkBizTitle(设置框架业务状态信息)
(2)执执行方法_setFrameworkBizStatus(设置框架业务状态属性)
方法输入:
编码 名称 类型 枚举值 描述 bizCodeTitle
单据编号标题 文本 单据编号;
业务编号;
编号为null则不修改,
为 " " 则不显示单据编号标题bizCode
单据编号 文本 为null则不修改,
为 " " 则不显示单据编号bizStatusTitle
单据状态标题 文本 单据状态;
业务状态;
当前状态;
状态为null则不修改,
为 " " 则不显示单据状态标题bizStatus
单据状态 文本 编制:T;
审批中:B;
审批不通过:E;
审批通过:F;
已作废:C;
修订中:A;
退回:R;
未发布:T;
已发布:F为null则不修改,
为 " " 则不显示单据状态bizStatusColor
单据状态颜色 文本 #000000:黑色;
#FF0000:红色;
#FFFF00:黄色;
#00FF00:绿色;
#0000FF:蓝色为null则不修改,默认为#FF0000
支持常见颜色编码和16进制颜色编码PrdSetBizFormStateInfo()函数的具体使用,请参考流程产品化函数。
方法输入:
编码 名称 类型 枚举值 描述 bizStatusCode
单据状态编号 文本 T:编制;
B:审批中;
E:审批不通过;
F:审批通过;
C:已作废
A:修订中
R:退回为null则不修改,
用于控制表单状态方法变量:
编码 名称 类型 默认值 描述 isEnable
是否可编辑 布尔 action
业务动作 实体
action(业务动作)
实体字段:)
规则:
(1) IF:IsEmpty(BR_IN_PARENT.bizStatusCode)
中断规则:入参为空,则中断当前规则链。
(2)给界面实体/控件/变量赋值【是否可编辑】
(3)执行函数/表达式【设置框架状态】:
PrdSetFrameWindowEnable(BR_VAR_PARENT.isEnable)
PrdSetFrameWindowEnable()
函数,主要是设置框架窗体全局使能属性控制方式,参数True则框架窗体全局使能,否则False为不使能。主要用于通过【请假申请列表】窗体,打开【请假申请】业务框架时,根据业务状态判断是否允许编辑,则控制框架窗体全局使能。
该函数的具体使用,请参考流程产品化函数。
(4)执行函数/表达式【设置窗体状态】:
PrdSetBizWindowEnable(BR_VAR_PARENT.isEnable)
PrdSetBizWindowEnable()
函数,主要是设置业务单窗体全局使能属性控制方式,参数True则框架窗体全局使能,否则False为不使能。主要用于通过在待办任务、已办任务中,审批流程打开【业务单流程操作】窗体在家对应的业务单窗体时,根据业务状态判断是否允许编辑,则业务单窗体全局使能属性。
该函数的具体使用,请参考流程产品化函数。
(5)新增实体记录【业务动作_打印】
在本案例中,业务状态为审批通过时,才允许打印。由于
PrdSetFrameWindowEnable(false)
函数会控制业务动作不使能,因此需要重新定义action_print(打印)业务动作属性,触发业务框架动作数据变化。其中,动作编码和动作名称,与业务动作库构件中定义的业务动作一致。
(6)执行方法_API_PrdTriggerBizFrameActionChange(触发业务框架动作数据变化)
该方法在引用
vbase_prdbizframe(vbase_产品化)
构件中,因此需要引入该构件。第二部分:实体数据自定义事件
(1)新增实体记录【从表】
(2)执行方法_setComponentState(设置控件属性)
执行setComponentState(设置控件属性)方法,无需设置参数。
方法变量:
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 true 默认为True errorCode
错误代码 文本 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 errorMessage
错误信息 文本 (1)IF:GetEntitySelectedRowCount("reimburseMain") == 0
若当前报销申请记录数为空,则提示未选中,并且中断当前规则链。
① 显示设置的提示信息【未选中】——提示"请选中需要删除的记录!"
② 中断规则【未选中则中断当前】
(2)
[reimburseMain].[bizStatusCode] <> "T"
若当前报销申请业务状态为非编制,则提示非编辑不允许删除,并且中断当前规则链。
① 显示设置的提示信息【非编制】——提示"非编制状态不可删除!"
② 中断规则【非编制则中断当前】
(3)显示设置的提示信息【是否删除】
采用提示类型:询问(确定/取消),会返回确认结果True/False。
(4)IF:! BR_OUT.BR_ShowMessage3.confirm
显示设置的提示信息【是否删除】,若取消则会返回确认结果False,中断当前所有规则链。
① 中断规则【取消则中断当前】。
(5)执行方法_deleteReimburseDetail(删除报销申请从表)
(6)IF:!BR_VAR_PARENT.isSuccess
若方法变量
isSuccess
不等于True,则提示返回错误信息,中断当前规则链。① 显示设置的提示信息【删除失败】
② 中断规则【删除失败则中断当前】
(7)删除实体记录【从表】:删除选中行
(8)执行方法_setComponentState(设置控件属性)
删除实体记录后,根据列表中当前记录的状态变化,重新设置控件使能,执行设置控件属性方法,无需传参。
(9)执行方法_updateReimburseAmt(计算报销金额)
删除实体记录后,需要重新汇总主表报销金额字段,执行计算报销金额方法,无需传参。
(10)执行方法_updateReimburseMainReimburseAmt(修改报销申请主表报销金额)
由于本案例删除从表是直接删除(不通过保存按钮确定),因此删除实体记录后重新汇总的主表报销金额,同样需要直接修改报销主表报销金额。
(11)IF:!IsEmpty(@parentWindowInstanceCode)
执行方法_setEditInfo(设置修改信息(编辑窗体调用))
该方法在【报销申请列表】主窗体中定义,用于编辑窗体修改、保存和提交数据时,执行主窗体该方法传递相关参数,主窗体再根据参数判断进行数据刷新。
由于跨窗体执行方法,因此需要设置方法所在窗体的窗体实例,窗体实例参数在主窗体打开编辑窗体时传入。
(12)显示设置的提示信息【删除成功】
与删除从表数据逻辑类似。
方法变量:
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 true 默认为True errorCode
错误代码 文本 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 errorMessage
错误信息 文本 (1)IF:GetEntitySelectedRowCount("reimburseMain") == 0
若当前报销申请记录数为空,则提示未选中,并且中断当前规则链。
① 显示设置的提示信息【未选中】——提示"请选中需要删除的记录!"
② 中断规则【未选中则中断当前】
(2)
[reimburseMain].[bizStatusCode] <> "T"
若当前报销申请业务状态为非编制,则提示非编辑不允许删除,并且中断当前规则链。
① 显示设置的提示信息【非编制】——提示"非编制状态不可删除!"
② 中断规则【非编制则中断当前】
(3)显示设置的提示信息【是否删除】
采用提示类型:询问(确定/取消),会返回确认结果True/False。
(4)IF:! BR_OUT.BR_ShowMessage3.confirm
显示设置的提示信息【是否删除】,若取消则会返回确认结果False,中断当前所有规则链。
① 中断规则【取消则中断当前】。
(5)执行方法_deleteReimburseFile(删除报销申请附件表)
(6)IF:!BR_VAR_PARENT.isSuccess
若方法变量
isSuccess
不等于True,则提示返回错误信息,中断当前规则链。① 显示设置的提示信息【删除失败】
② 中断规则【删除失败则中断当前】
(7)执行函数/表达式【删除附件】
(8)删除实体记录【附件表】:删除选中行
(9)执行方法_setComponentState(设置控件属性)
删除实体记录后,根据列表中当前记录的状态变化,重新设置控件使能,执行设置控件属性方法,无需传参。
(10)显示设置的提示信息【删除成功】
方法输入:
编码 名称 类型 初始值 描述 isShowMessage
是否提示信息 布尔 true 用于业务动作(保存)扩展实现执行时,传入的参数 方法输出:
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 false 用于自定义流程相关(提交)事件执行时,输出的参数 方法变量:
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 true 默认为True errorCode
错误代码 文本 000000:成功;0040XX:参数错误;0010XX:未登录;0020XX:未授权;0050XX:方法内部错误 errorMessage
错误信息 文本 (1)必填项检查
(2)IF:!BR_OUT.BR_CheckRequired1.isCheckRequiredOK
如果必填不通过,则中断当前规则链
(3)IF:IsEmpty([reimburseMain].[bizCode])
① 单据编号生成:如果业务单号为空,则配置单据编号生成规则。
② 执行方法_setComponentState(设置控件属性):生成单据编号后,需要刷新框架属性
(4)给界面实体/控件/变量赋值【设置修改字段值】
(5)执行方法_saveReimburseMain(保存报销申请主表)
(6)IF:!BR_VAR_PARENT.isSuccess
若方法变量
isSuccess
不等于True,则提示返回错误信息,中断当前规则链。① 显示设置的提示信息【删除失败】
② 中断规则【保存失败则中断当前】
(7)IF:!IsEmpty(@parentWindowInstanceCode)
执行方法_setEditInfo(设置修改信息(编辑窗体调用))
该方法在【报销申请列表】主窗体中定义,用于编辑窗体修改、保存和提交数据时,执行主窗体该方法传递相关参数,主窗体再根据参数判断进行数据刷新。
由于跨窗体执行方法,因此需要设置方法所在窗体的窗体实例,窗体实例参数在主窗体打开编辑窗体时传入。
(8)给界面实体/控件/变量赋值【输出成功】
(9)显示设置的提示信息【保存成功】
注意:自定义流程相关(提交)事件执行时,不用提示【保存成功】,只有业务动作(保存)扩展实现执行时,才提示信息。
第三部分:其他自定义事件
(1)IF:IsEmpty([reimburseMain].[id])
中断规则【主表为空则中断当前】:如果主表id为空,则中断当前规则。
(2)附件操作【上传】
(1)IF:IsEmpty([reimburseMain].[id])
中断规则【主表为空则中断当前】:如果主表id为空,则中断当前规则。
(2)新增实体记录【reimburseFile】
注意:由于文件控件绑定的是文件(fileInfo)实体,当文件上传后,文件(fileInfo)实体会新增对应的数据。
因此,需要将文件(fileInfo)实体对应的字段赋值给报销附件(reimburseFile)实体。
(3)清除界面实体中的数据【文件附件】
方法变量:
编码 名称 类型 默认值 描述 user
用户 实体 (1)打开窗体并返回数据【机构人员选择】
(2)IF:! BR_OUT.BR_OpenComponentReturnData1.isConfirmSelectionOnClose
中断规则【取消则中断当前】:如果取消退出【根据机构选择人员(通用)】窗体,则中断当前规则链。
(3)给界面实体/控件/变量赋值【领款人】
第四部分:流程相关自定义事件
方法变量:
本案例通过执行流程应用方法启动流程,因此需要定义isSuccess参数接收返回值;
同时,由于本案例根据报销金额判断流程执行分支,因此使用流程应用启动流程时,需要传入对应的流程变量信息。
编码 名称 类型 初始值 描述 isSuccess
是否成功 布尔 true 默认为True workFlowVar
流程变量信息 实体 启动流程传入的流程变量信息
workFlowVar(流程变量信息)
实体:规则:
(1)显示设置的提示信息【是否提交】
采用提示类型:询问(确定/取消),会返回确认结果True/False。
(2)IF:! BR_OUT.BR_ShowMessage1.confirm
显示设置的提示信息【是否提交】,若取消则会返回确认结果False,中断当前所有规则链。
① 中断规则:中断当前规则链。
(3)判断指定实体的数据是否发生变化
由于提交流程前,同样需要保存数据,因此需要判断界面数据是否发生变化,才执行保存逻辑。
(4)IF:BR_OUT.BR_ShowMessageWhenChanged1.isChanged
如果数据发生变化,则需要执行保存逻辑,并且设置参数。
① 执行方法_saveData(保存数据)
(5)IF:!BR_VAR_PARENT.isSuccess
中断规则:保存失败则中断当前规则链。
(6)IF:IsNullOrEmpty([reimburseMain].[reimburseAmt], 0) == 0
① 显示设置的提示信息【报销金额不能为0】;
② 中断规则:报销金额不能为0。
(7)新增实体记录【流程变量-报销金额】
注意:定义的流程变量名称,需要和配置中心设置的流程变量一致。
(8)执行方法_API_WorkFlowOpenStartApplicationWindow(打开启动流程应用窗体)
该方法在引用
vbase_prd_workflow(vbase_产品化流程管理)
构件中,因此需要引入该构件。设置入参如下:
BizId(业务记录ID)
:业务表单Id字段,业务的标识字段,通过唯一的业务ID标识业务流程(流程框架启动),必须赋值。topic(待办任务名称)
:格式可以自定义,用于待办任务和已办任务等环节查找流程时,标识流程任务名称。StarUserId(流程发起人ID)
:一般是当前登录用户Id(或启动流程用户Id)。StarUserName(流程发起人名称)
:一般是当前登录用户名称(或启动流程用户名称)。bizComponentCode(业务窗体构件编码)
:GetComponentCode()
,用于指定业务表单窗体所在构件编码。bizWindowCode(业务窗体编码)
:GetWindowCode()
,用于指定业务表单窗体编码。snapshotData(业务快照)
:PrdGetCurrentWindowSnapShow()
——流程产品化函数。variableEntity(流程变量信息)
:映射定义方法变量(流程变量实体)。processCode(流程编号)
:在流程管理中,进行流程定义时,对应的流程编号参数——[查看流程定义](### 4.2 执行系统配置)。注意:若不设置
processCode(流程编号)
参数,当存在多个流程定义匹配同一个业务表单,在启动流程的时候需要手动选择具体的流程定义;若只有一个流程定义匹配一个业务表单,则可以不设置该参数。(9) IF:! BR_VAR_PARENT.isSuccess——未成功启动流程应用
中断规则:中断当前规则链。
(10)IF:!IsEmpty(@parentWindowInstanceCode)
执行方法_setEditInfo(设置修改信息(编辑窗体调用))
该方法在【报销申请列表】主窗体中定义,用于编辑窗体修改、保存和提交数据时,执行主窗体该方法传递相关参数,主窗体再根据参数判断进行数据刷新。
由于跨窗体执行方法,因此需要设置方法所在窗体的窗体实例,窗体实例参数在主窗体打开编辑窗体时传入。
(11)显示设置的提示信息【提交成功】**
(12)退出窗体:确定退出。**
第五部分:业务动作扩展实现、窗体方法和控件方法
按照开发规范,业务动作扩展实现通过“执行方法”规则,执行对应的自定义方法,无需传参(窗体方法、控件方法的编码和名称,保留默认即可)。
方法编码 方法名称 规则配置 ep_action_print_Impl
打印
执行方法_printData(打印数据)
ep_action_save_Impl
保存
执行方法_save(保存)
设置入参:isShowMessage(是否提示信息)=true
ep_action_submit_Impl
提交
执行方法_submit(提交)
按照开发规范,窗体方法、控件方法通过“执行方法”规则,执行对应的自定义方法,无需传参(窗体方法、控件方法的编码和名称,保留默认即可)。
方法编码 方法名称 规则配置 form_reimburse_edit_FormLoadAction
窗体加载事件
执行方法_loadForm(加载页面)
atm_file_OnFileSelected
文件_文件已选择
执行方法_fileSelectAfter(文件选择后)
atm_file_OnUploadCompleted
文件_文件已上传
执行方法_fileUploadAfter(文件上传后)
ent_flo_consumeAmt_OnValueChanged
消费金额_值改变事件
执行方法_updateTotalAmt(计算明细总费用)
ent_flo_otherAmt_OnValueChanged
其他费用_值改变事件
执行方法_updateTotalAmt(计算明细总费用)
ent_flo_totalAmt_OnValueChanged
总费用_值改变事件
执行方法_updateReimburseAmt(计算报销金额)
ent_txt_deleteData_OnClick
删除_链接事件
执行方法_deleteFileData(删除附件数据)
ent_txt_download_OnClick
下载_链接事件
执行方法_downloadFile(下载附件)
ent_txt_preview_OnClick
预览_链接事件
执行方法_previewFile(预览附件)
tbm_addDetail_OnClick
新增_单击事件
执行方法_addDetailData(新增从表数据)
tbm_deleteDetail_OnClick
删除_单击事件
执行方法_deleteDetailData(删除从表数
据)
- 窗体输入
- 界面设计
- 方法定义
- 方法实现
编码 名称 类型 初始值 描述 mainId
主表Id 文本 主要用于主页面编辑、查看数据时打开编辑窗体进行传参 1. loadData(窗体加载数据)
(1)显示进度条
(2)从数据库或实体获取数据到报表【报销申请】
(3)隐藏进度条
2. 窗体加载事件
通过执行方法规则,执行自定义的loadData(窗体加载数据)方法。
命名规范:
业务单据实例编码 | 菜单名称 |
---|---|
form_reimburse_edit | 报销申请编辑 |
在【报销申请编辑】窗体导入了业务动作后,当【报销申请列表】进行新增、编辑、查看操作时 ,配置”打开业务框架“规则,打开【报销申请编辑】业务单据实例,而不是【报销申请编辑】窗体。
在窗体方法配置中,如果添加业务动作、流程方法等扩展实现,需要进行构件服务映射操作。
在本案例中,【报销申请编辑】窗体导入了业务动作,会生成对应业务动作的扩展实现,同时会自动匹配勾选构件服务映射。
若窗体通过拷贝,构件服务映射不会自动勾选,需要自行勾选。
4.2 执行系统配置
在"流程定义"中,选择流程进行活动定义。
info修改流程定义前,需要先停用流程才可保存修改结果(首次定义流程,未启用,流程状态为“编辑中”)。
根据需求,定义流程图,并且设置相关活动节点。
1. 流程图定义
2. 人工节点设置
根据需求,修改活动节点(财务主管、财务经理、部门经理)名称,选中执行人(在本案例中,执行人从机构选择即可)。
3. 判断节点条件设置
在判断节点中,选择分支线,定义名称,设置判断条件。
(1)报销金额(元)<=1000
(2)报销金额(元)>1000
4. 流程事件设置
在流程图定义中,设置流程的相关事件。
在本案例中,流程启动后和流程结束后,调用同一个构件方法,实现修改状态的功能。
(1)流程启动后事件,参数配置:
(2)流程结束后事件,参数配置:
访问地址:http://v-devsuit-train.t.yindangu.com
账号:
admin
,密码:8
,登录验证效果即可。
5. 网页图标
开发完项目之后,可以根据实际需求是否替换项目图标,如下:
(1)项目图标
操作方式:在 ..\V-AppServer\V3Runtime\pages
目录下,直接替换 favicon.ico
文件即可。
(2)配置中心图标
操作方式:在 ..\V-AppServer\V3Runtime\pages\system\settings
目录下,直接替换 favicon.ico
文件即可。
如果服务整体升级后,会重新生成系统自带的默认ico图标,那么替换的ico图标会失效,具体做法:
- 项目自定义的ico图标拷贝到对应的目录下备份,例如:
favicon_1.ico
; - 服务升级后,将系统默认的
favicon.ico
图标删除,将备份的favicon_1.ico
文件替换favicon.ico
文件即可。