cgft 发表于 2016-11-15 21:02:15

【模块Bug修复】用户自定义公告通知(2015/2016版)

本帖最后由 cgft 于 2017-4-9 08:47 编辑

一、Bug产生环境
系统本身公告通知模块A,自建自定义公告模块B。
用户集{c1}拥有模块A和模块B的权限,用户集{c2}仅有模块A的权限,用户集{c3}仅有模块B的权限。
向用户集{c1}和用户集{c3}同时发布自定义公告,或单独向用户集{c3}发布自定义公告,用户集{c3}都收不到事务提醒。

二、Bug修复
在自定义公告模块的运行目录
MYOA\webroot\general\(自定义公告目录)\manage\
下的add.php和update.php两个文件中,都有如下一段代码://-------排除没有公告通知菜单权限的人-------   
$USER_ID_STR_ARRAY=explode(",",$USER_ID_STR);   
$USER_ID_STR_ARRAY_COUNT=sizeof($USER_ID_STR_ARRAY);   
for($I=0;$I<$USER_ID_STR_ARRAY_COUNT;$I++)   
{      
    if($USER_ID_STR_ARRAY[$I]=="")         
      continue;      
    $FUNC_ID_STR=GetfunmenuByuserID($USER_ID_STR_ARRAY[$I]);      
    if(!find_id($FUNC_ID_STR,4))         
      $USER_ID_STR=str_replace($USER_ID_STR_ARRAY[$I],'',$USER_ID_STR);   
}上面的代码,错在第九句,错用了公告通知的菜单ID(ID=4)进行排除筛选。用如下代码将其覆盖,//-------排除没有公告通知菜单权限的人-------   
$query="SELECT FUNC_ID FROM sys_function WHERE FUNC_NAME='".$dispName."'";   
$cursor=exequery(TD::conn(),$query);   
$ROW=mysql_fetch_array($cursor);
$MY_MENU_ID=$ROW['0'];      // 读取菜单ID   
$USER_ID_STR_ARRAY=explode(",",$USER_ID_STR);   
$USER_ID_STR_ARRAY_COUNT=sizeof($USER_ID_STR_ARRAY);   
for($I=0;$I<$USER_ID_STR_ARRAY_COUNT;$I++)   
{   
    if($USER_ID_STR_ARRAY[$I]=="")         
      continue;      
    $FUNC_ID_STR=GetfunmenuByuserID($USER_ID_STR_ARRAY[$I]);      
    if(!find_id($FUNC_ID_STR,$MY_MENU_ID))         
      $USER_ID_STR=str_replace($USER_ID_STR_ARRAY[$I],'',$USER_ID_STR);   
}即可修复该Bug。

三、适用范围
2013增强版、2015版、2016版。
建议通达予以修复。

cgft 发表于 2016-11-28 09:34:46

大致捋了一遍整个模块的代码,看来问题还真没那么简单。
配置文件config.php,定义了4个变量,后两个变量,基本没用上。不是没有用处,而是程序中把它遗忘了。要想完善地发挥config.php的作用,还需定义菜单代码和APP日志代码两个变量。
例如前帖所述的代码,如果定义了菜单代码,就变成了:

//-------排除没有公告通知菜单权限的人-------   

$USER_ID_STR_ARRAY=explode(",",$USER_ID_STR);   

$USER_ID_STR_ARRAY_COUNT=sizeof($USER_ID_STR_ARRAY);   

for($I=0;$I<$USER_ID_STR_ARRAY_COUNT;$I++)   

{   
   
if($USER_ID_STR_ARRAY[$I]=="")         

      
continue;      
   
$FUNC_ID_STR=GetfunmenuByuserID($USER_ID_STR_ARRAY[$I]);      

   
if(!find_id($FUNC_ID_STR,$ExtNotify_FUNC_ID))         

      
$USER_ID_STR=str_replace($USER_ID_STR_ARRAY[$I],'',$USER_ID_STR);   

}
代码简单了许多,免除了数据库的查询,加快了执行速度。
除了主公告通知和自定义公告通知因授权用户集不同,造成用户收不到新建公告通知的事务提醒外,由于主公告通知和自定义公告通知两个模块混用内部标志,还会造成阅读记录混乱、阅读记录记载的时间错误、不能按要求再次提醒未读人员、删除公告通知时日志提醒等删除不彻底或删错等一系列莫名其妙的错误,如果企业因某种需求,想要用公告通知的阅读人员和阅读时间作为管理凭证甚至作为电子证据,那热闹可就大发了,不知道会产生多少“冤假错案”呢。总得来说,在二十多个程序中,只要涉及到自定义公告通知的内部标志的程序,都存在Bug。
下面,就是我改写后的manage目录下的delete.php代码:


<?
include_once("inc/auth.inc.php");
include_once("inc/utility_all.php");
include_once("inc/utility_file.php");
include_once("inc/utility_sms1.php");
include_once("inc/utility_cache.php");
include_once("../config.php");
include_once("inc/header.inc.php");
$HTML_PAGE_TITLE="";
?>
<body class="bodycolor">
<?
$PARA_ARRAY=get_sys_para("NOTIFY_EDIT_PRIV".$dbName);
if($DELETE_STR=="")
$DELETE_STR=0;
elseif(substr($DELETE_STR,-1,1)==",")
$DELETE_STR=substr($DELETE_STR,0,-1);
$query="select BEGIN_DATE,SUBJECT,ATTACHMENT_ID,ATTACHMENT_NAME,NOTIFY_ID
from $dbName where NOTIFY_ID in ($DELETE_STR)";
$cursor=
exequery(TD::conn(),$query);
while($ROW=mysql_fetch_array($cursor))
{
$BEGIN_DATE=$ROW["BEGIN_DATE"];
$SUBJECT1=$ROW["SUBJECT"];
$SUMMARY=$ROW["SUMMARY"];
$ATTACHMENT_ID=$ROW["ATTACHMENT_ID"];
$ATTACHMENT_NAME=$ROW["ATTACHMENT_NAME"];
$BEGIN_DATE=date("Y-m-d",$BEGIN_DATE);
$NOTIFY_ID=$ROW["NOTIFY_ID"];
$REMIND_URL="1:".$dbName."/show/read_notify.php?NOTIFY_ID=".$NOTIFY_ID;
delete_remind_sms($sms_num,'','','',$REMIND_URL);
if($ATTACHMENT_NAME!="")
delete_attach($ATTACHMENT_ID,$ATTACHMENT_NAME);
$query="delete
from APP_LOG where MODULE='$ExtNotify_MODULE_ID' and
OPP_ID='$NOTIFY_ID'";
exequery(TD::conn(),
$query);
add_log($log_num,"删除《".$SUBJECT1."》",$_SESSION["LOGIN_USER_ID"]);
}
$query="delete from $dbName where NOTIFY_ID in
($DELETE_STR)";
exequery(TD::conn(),$query);
if($SEARCH==1) {
header("location:
search.php?start=$start&SEARCH=1&SEND_TIME_MIN=$SEND_TIME_MIN&SEND_TIME_MAX=$SEND_TIME_MAX&SUBJECT=
$SUBJECT&CONTENT= $CONTENT&FORMAT=$FORMAT&TYPE_ID=$TYPE_ID&PUBLISH=$PUBLISH&TOP=$TOP&TO_ID=$TO_ID&STAT=$STAT&IS_MAIN=1");
}
else {
if($FROM!=2)
header("location:
index1.php?start=$start&IS_MAIN=1");
else
header("location:../auditing/audited.php?start=$start&IS_MAIN=1");
}
?></body></html>

cgft 发表于 2016-11-28 09:40:46

本帖最后由 cgft 于 2017-4-9 08:40 编辑

论坛发帖,代码的粘贴,有问题。莫名其妙的多出来多余的换行,不该换行的也加进了换行。这次,因为仅是示例,就不重新编辑了。
______________________    ps:以下为新编辑内容—————————————————————————

因用户自定义的公告通知栏目名称不同,另外用户系统也因已安装的应用不同,所以有关参数值不能固定。为保持原模块的通用性,就不能简单地在程序中修改或添加具体的参数数值,还是应该用变量来带入参数值。
原模块的参数值赋值程序config.php是这样写的:

<?
$dbName='';
$dispName='';
$sms_num='';
$log_num='';
?>
修复后的模块,参数值赋值程序config.php改为:

<?
$dbName='';
$dispName='';
$sms_num='';
$log_num='';
$ExtNotify_FUNC_ID='';
$ExtNotify_MODULE_ID='';
?>
以上各变量:
$dbName是自定义公告通知的栏目名称,一般是中文;
$dispName是自定义公告通知的数据库表名,要求应符合数据库表命名规则;
$sms_num是事务提醒的系统代码;
$log_num是操作日志的系统代码;
$ExtNotify_FUNC_ID,新增,自定义公告通知菜单的系统代码;
$ExtNotify_MODULE_ID,新增,附件模块信息的系统代码。

liao99 发表于 2016-11-28 10:58:55

佩服,OA应用有深度

cgft 发表于 2016-11-29 14:10:32

本帖最后由 cgft 于 2016-11-29 21:22 编辑

改自于公告通知的自定义模块,自然还带着原母版的Bug。但有一些Bug,在后续的版本升级中已经修复了。以manage/delete_all.php为例,我就觉得逻辑有问题,对管理员授权莫名其妙。这是原版2016自定义模块代码:
<?
include_once("inc/auth.inc.php");
include_once("inc/utility_all.php");
include_once("inc/utility_file.php");
include_once("inc/utility_sms1.php");
include_once("inc/utility_cache.php");
include_once("../config.php");
include_once("inc/header.inc.php");
$HTML_PAGE_TITLE="";
?>
<body class="bodycolor"><?
$PARA_ARRAY=get_sys_para("NOTIFY_EDIT_PRIV".$dbName);if($_SESSION["LOGIN_USER_PRIV"]!="1")
   $query="select ATTACHMENT_ID,ATTACHMENT_NAME from $dbName where ATTACHMENT_NAME!=''";
$cursor=exequery(TD::conn(),$query);
while($ROW=mysql_fetch_array($cursor))
{
$ATTACHMENT_ID=$ROW["ATTACHMENT_ID"];
$ATTACHMENT_NAME=$ROW["ATTACHMENT_NAME"];delete_attach($ATTACHMENT_ID,$ATTACHMENT_NAME);
}if($_SESSION["LOGIN_USER_PRIV"]=="1")
   $query="delete from $dbName";
exequery(TD::conn(),$query);if($_SESSION["LOGIN_USER_PRIV"]=="1")
delete_remind_sms(1);
else
delete_remind_sms(1, $_SESSION["LOGIN_USER_ID"]);
add_log(15,_("删除所有".$dispName),$_SESSION["LOGIN_USER_ID"]);
header("location: index1.php?IS_MAIN=1");
?></body>
</html>
这是我改过的:
<?
include_once("inc/auth.inc.php");
include_once("inc/utility_all.php");
include_once("inc/utility_file.php");
include_once("inc/utility_sms1.php");
include_once("inc/utility_cache.php");
include_once("../config.php");
include_once("inc/header.inc.php");
$HTML_PAGE_TITLE="";
?><body class="bodycolor"><?
if($_SESSION["LOGIN_USER_PRIV"]!="1") {
echo '<br /><br />';
Message('','此操作仅授权给系统管理员');
exit();
}$query="select ATTACHMENT_ID,ATTACHMENT_NAME from $dbName where ATTACHMENT_NAME!=''";
$cursor=exequery(TD::conn(),$query);
while($ROW=mysql_fetch_array($cursor)) {
$ATTACHMENT_ID=$ROW["ATTACHMENT_ID"];
$ATTACHMENT_NAME=$ROW["ATTACHMENT_NAME"];
delete_attach($ATTACHMENT_ID,$ATTACHMENT_NAME);
}$query="delete from $dbName";
exequery(TD::conn(),$query);
$query="delete from APP_LOG where MODULE='$ExtNotify_MODULE_ID'";
exequery(TD::conn(), $query);
delete_remind_sms($sms_num);
add_log($log_num,'删除所有'.$dispName,$_SESSION['LOGIN_USER_ID']);
header("location: index1.php?IS_MAIN=1");?>
</body></html>
今天,从网友那里淘到一个2016钻石版的delete_all.php原码,对比一看,我还真改对了,要按照2016自定义模块原版的逻辑去删除全部的内容,真会乱了套。不过嘛,2016钻石版的,删得不如自己改得彻底,阅读记录没删除,日久天长,难免就沉淀成了辣鸡。
<?
include_once("inc/auth.inc.php");
include_once("inc/utility_all.php");
include_once("inc/utility_file.php");
include_once("inc/utility_sms1.php");
include_once("inc/utility_cache.php");include_once("inc/header.inc.php");
?><body class="bodycolor"><?
// $PARA_ARRAY=get_sys_para("NOTIFY_EDIT_PRIV");if($_SESSION["LOGIN_USER_PRIV_TYPE"] == "1")
{
    $query="select ATTACHMENT_ID,ATTACHMENT_NAME from NOTIFY where ATTACHMENT_NAME!=''";
    $cursor=exequery(TD::conn(),$query);
    while($ROW=mysql_fetch_array($cursor))
    {
      $ATTACHMENT_ID=$ROW["ATTACHMENT_ID"];
      $ATTACHMENT_NAME=$ROW["ATTACHMENT_NAME"];      delete_attach($ATTACHMENT_ID,$ATTACHMENT_NAME);
    }    $query="delete from NOTIFY";
    exequery(TD::conn(),$query);    delete_remind_sms(1);
}// delete_remind_sms(1, $_SESSION["LOGIN_USER_ID"]);add_log(15, _("删除所有公告通知"), $_SESSION["LOGIN_USER_ID"]);
header("location: index1.php?IS_MAIN=1");
?></body>
</html>

cgft 发表于 2016-11-29 21:25:57

本帖最后由 cgft 于 2016-11-30 00:11 编辑

实在忍不住吐槽一下,坛子里的代码粘贴功能,实在是难弄。

langos_5 发表于 2017-8-3 16:43:44

太棒了c哥

cgft 发表于 2017-8-4 18:05:13

本帖最后由 cgft 于 2017-8-4 18:08 编辑

dell

cgft 发表于 2017-8-4 18:05:21

本帖最后由 cgft 于 2017-8-4 18:08 编辑

dell
页: [1]
查看完整版本: 【模块Bug修复】用户自定义公告通知(2015/2016版)