烟草局绩效考核系统打分模块开发笔记
开发一个绩效考核系统,其难度、复杂度不在开发一个功能复杂的权限系统开发难度之下。作者这里把原始设计以及一些技术细节公布出来,希望能和大家一起交流学习。
背景:原始系统设计方案参见《某烟草局绩效考核系统整体设计方案》。
要求:指标树层级排列,以便打分使用。
环境:WindowsXP5.1SP2、IE6.0、JDK(JRE)1.6U0、MyEclipse5.1.0、Tomcat5.5、Oracle9i、PL/SQL Developer7.0。
技术细节:临时表 + 存储过程实现树形结构查询 + 游标 + 递归查询。
技术难点:返回结果集的存储过程的编写以及调用、临时表与 Java 程序的衔接。
部分页面效果及其部分源码如下:
1、指标库界面:
指标库数据结构:
2、岗位指标界面:
岗位指标数据结构:
3、临时表的创建 sql:
-- Create table
create global temporary table JXKH_TEMP_ROLE_GUIDELINE
(
ID NUMBER(15),
FID NUMBER(15),
ROLEID NUMBER(15),
ROLENAME VARCHAR2(50),
GUIDELINEID NUMBER(15),
GUIDELINENAME VARCHAR2(50),
ISATOMIC NUMBER(1),
GUIDEFID NUMBER(15),
GUIDESEQ NUMBER(4),
GUIDELEVEL NUMBER(1),
NOTES VARCHAR2(1000),
MAXIMUM NUMBER(5,2),
MINIMUM NUMBER(5,2),
CHILDNUM NUMBER
)
on commit delete rows;
4、评估打分列表界面:
5、目标:评估打分页面:
评估打分静态页面效果源代码(部分):
<table class="Ntable" cellspacing="1" cellpadding="1" align="Center" border="0" id="gvInfo" style="border-style:None;width:100%;">
<tr class="SkyTDTopLine" align="center">
<th scope="col">指标大类</th><th scope="col">指标小类</th><th scope="col">指标名称</th><th scope="col">说明</th><th scope="col">最小值</th><th scope="col">最大值</th><th scope="col">单项分</th>
</tr><tr class="SkyTDLine" align="center">
<!-- 一级指标 -->
<td rowspan="2">经济指标</td>
<!-- 二级指标 -->
<td rowspan="1">投资管理</td>
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">省局项目</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-50" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1076">
<input name="guideNames" id="guideNames" type="hidden" value="省局项目">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
<!-- 二级指标 -->
<td rowspan="1">会务组织</td>
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">制定会务管理制度</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-2" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1075">
<input name="guideNames" id="guideNames" type="hidden" value="制定会务管理制度">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
<!-- 一级指标 -->
<td rowspan="4">工作质量指标</td>
<!-- 二级指标 -->
<td rowspan="1">会务组织</td>
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">组织及时</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-10" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1140">
<input name="guideNames" id="guideNames" type="hidden" value="组织及时">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
<!-- 二级指标 -->
<td rowspan="3">办公用品管理</td>
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">用品管理</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-4" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1141">
<input name="guideNames" id="guideNames" type="hidden" value="用品管理">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">办公用品</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-5" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1142">
<input name="guideNames" id="guideNames" type="hidden" value="办公用品">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
<!-- 三级指标 -->
<td>
<div style="width:200px;">
<span id="gvInfo_ctl02_Label1">办公管理</span></div>
</td><td><a href="/jxkh/atomicGuideLine.do?method=getNotes" mce_href="jxkh/atomicGuideLine.do?method=getNotes" target="_blank">说明</a></td><td>
<input class='classN1' name="Sky_10351" type="text" style="width:30px;" value="-8" readonly="readonly">
</td><td>
<input class='classN2' name="Sky_10352" type="text" style="width:30px;" value="0" readonly="readonly">
</td><td>
<input name="marks" id="marks" type="text" style="width:80px;" value="0" maxlength="4"> <!-- onblur="skyChange(this,'1035');" -->
<input name="guideIds" id="guideIds" type="hidden" value="1143">
<input name="guideNames" id="guideNames" type="hidden" value="办公管理">
<input type="hidden" name="markIds" id="markIds" value=""/>
</td>
</tr><tr class="SkyTDLine" align="center">
6、编写 JXKH_GUIDELE_CHILD_NUM 存储过程源代码:
CREATE OR REPLACE PROCEDURE JXKH_GUIDELE_CHILD_NUM(
ROLE_ID_ JXKH_ROLE_GUIDELINE.ROLEID%TYPE,
REF_CURSOR OUT SYS_REFCURSOR
)
AS
NUM_ NUMBER;
CURSOR C_ROLE_GUIDE IS SELECT * FROM V_JXKH_ROLE_GUIDELINE;---申明一个游标 这时候ORACLE并不执行SELECT 只是申明
V_EMP V_JXKH_ROLE_GUIDELINE%ROWTYPE;
BEGIN
NUM_:=0;
OPEN C_ROLE_GUIDE;--打开游标ORACLE才执行SELECT
FETCH C_ROLE_GUIDE INTO V_EMP;
WHILE C_ROLE_GUIDE%FOUND LOOP
--EXIT WHEN (C_ROLE_GUIDE%NOTFOUND);
IF V_EMP.GUIDELEVEL = 1 THEN--一级分类
SELECT COUNT(*) INTO NUM_ FROM V_JXKH_ROLE_GUIDELINE WHERE FID IN (SELECT GUIDELINEID FROM V_JXKH_ROLE_GUIDELINE WHERE FID=V_EMP.GUIDELINEID AND ROLEID=ROLE_ID_);
INSERT INTO JXKH_TEMP_ROLE_GUIDELINE VALUES(V_EMP.ID,V_EMP.fid,V_EMP.ROLEID,V_EMP.ROLENAME,V_EMP.GUIDELINEID,V_EMP.GUIDELINENAME,V_EMP.isatomic,V_EMP.guideFid,V_EMP.guideseq,V_EMP.guidelevel,V_EMP.notes,V_EMP.maximum,V_EMP.minimum,NUM_);
ELSIF V_EMP.GUIDELEVEL = 2 THEN--二级分类
SELECT COUNT(*) INTO NUM_ FROM V_JXKH_ROLE_GUIDELINE WHERE FID=V_EMP.GUIDELINEID AND ROLEID=ROLE_ID_;
INSERT INTO JXKH_TEMP_ROLE_GUIDELINE VALUES(V_EMP.ID,V_EMP.fid,V_EMP.ROLEID,V_EMP.ROLENAME,V_EMP.GUIDELINEID,V_EMP.GUIDELINENAME,V_EMP.isatomic,V_EMP.guideFid,V_EMP.guideseq,V_EMP.guidelevel,V_EMP.notes,V_EMP.maximum,V_EMP.minimum,NUM_);
ELSE--三级分类
INSERT INTO JXKH_TEMP_ROLE_GUIDELINE VALUES(V_EMP.ID,V_EMP.fid,V_EMP.ROLEID,V_EMP.ROLENAME,V_EMP.GUIDELINEID,V_EMP.GUIDELINENAME,V_EMP.isatomic,V_EMP.guideFid,V_EMP.guideseq,V_EMP.guidelevel,V_EMP.notes,V_EMP.maximum,V_EMP.minimum,NUM_);
END IF;
NUM_:=0;--计数器清零
FETCH C_ROLE_GUIDE INTO V_EMP;
END LOOP;
CLOSE C_ROLE_GUIDE;
OPEN REF_CURSOR FOR SELECT * FROM (SELECT * FROM JXKH_TEMP_ROLE_GUIDELINE T1 WHERE T1.ROLEID=ROLE_ID_)T2 START WITH T2.FID=0 CONNECT BY PRIOR T2.GUIDELINEID=T2.FID;--存储过程返回结果集
END;
调用 JXKH_GUIDELE_CHILD_NUM 存储过程 Java 源代码:
/**
* 根据传入的角色id,调用存储过程jxkh_guidele_child_num返回该角色分配的所有指标任务
*/
public List<AtomicGuideLine> getRoleGuideline(String roleId){
List<AtomicGuideLine> list = new ArrayList<AtomicGuideLine>();
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
DBConnectionManager dcm = DBConnectionManager.getInstance();
conn = dcm.getConnection("oracle");
conn.setAutoCommit(false);//这里一定要的,不然会报“ORA-08103”错误
stmt = conn.prepareCall("BEGIN JXKH_GUIDELE_CHILD_NUM(?,?); END;");
stmt.setInt(1, Integer.parseInt(roleId));
stmt.registerOutParameter(2, -10 /* OracleTypes.CURSOR = -10 */); //REF CURSOR(OracleTypes.CURSOR==-10)
stmt.execute();
rs = (ResultSet) stmt.getObject(2);
while(rs.next()){
AtomicGuideLine atomicGuideLine = new AtomicGuideLine();
atomicGuideLine.setId(rs.getString("guidelineid"));
atomicGuideLine.setFid(rs.getString("fid"));
atomicGuideLine.setGuideName(rs.getString("guidelinename"));
atomicGuideLine.setGuideSeq(rs.getString("guideSeq"));
atomicGuideLine.setGuideLevel(rs.getString("guideLevel"));
atomicGuideLine.setNotes(rs.getString("notes"));
atomicGuideLine.setMaximum(rs.getString("maximum"));
atomicGuideLine.setMinimum(rs.getString("minimum"));
atomicGuideLine.setChildNum(rs.getString("childNum"));
atomicGuideLine.setGuideMark("0");
list.add(atomicGuideLine);
}
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return list;
}
关于绩效考核系统设计以及存储过程结果集调用方面的任何问题,欢迎读者在线和作者交流,msn:[email protected]。