最近我们馆升级的DP2管理系统,升级后OPAC具有了书评、荐书等功能。这些功能没有问题一直很稳定,不过我总是感觉有些隐忧,因为很多读者证没有设定密码,如果别有用心的人利用这一点登陆系统在书评中乱加评论,就算我们可以追究读者密码保管不利的问题。但是,学校恐怕也会追究我们馆,监管不严的责任。为了杜绝这一点点的隐忧,我想对所有没有密码的读者证添加一个密码。这样,出了问题也好有个交代。
为了解决这个问题,我想到了“添加或删除读者证”这个方案,这个方案原本是修改读者证状态或者是删除读者数据用的。我开始考虑的比较简单,我想这个方案既然可以删除读者证数据,或者修改读者证状态那么也应该可以修改读者证的密码。打开方案后,仔细看了一下,修改了里面的“string strState = DomUtil.GetElementText(this.ReaderDom.DocumentElement, "state");”语句,另外注掉了里面的一个判断,结果一测试没有效果,跟踪了里面的返回值返现返回值正常。后来,我又仔细看了一下系统的参考手册,发现里面还有一个“ChangeReaderPassword”函数专门用来修改密码的,我自己试着使用了一下,感觉还是不行。最后,实在没有办法,只好求助江老师,下面是江老师给我发回来的他与谢老师的聊天记录片段。
API SetReaderInfo()是不能修改读者的密码的。道理很简单,工作人员不应随意修改读者的密码,而API SetReaderInfo()正好是拿给读者窗使用的。如果要修改密码,可以使用API ChangeReaderPassword()。
long lRet = this.ReaderStatisForm.Channel.ChangeReaderPassword(
null, // stop,
this.textBox_reader_barcode.Text, // 读者证条码号
this.textBox_reader_oldPassword.Text, // 旧密码
this.textBox_reader_newPassword.Text, // 新密码
out strError);
函数返回1为成功。0和-1都是失败。
如果是工作人员身份调用这个API,则旧密码参数无意义,也就是说,工作人员可以强制修改读者密码(需要changereaderpassword权限)。如果是读者身份调用这个API,则需要提供旧密码。
下面是谢老师编写的关于修改读者密码的一个统计窗的统计方案main.cs中的内容:
// 测试修改读者密码
// 创建日期:2011/11/1
using System;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Xml;
using System.Drawing; // Size
using DigitalPlatform;
using DigitalPlatform.Xml;
using DigitalPlatform.Text;
using DigitalPlatform.dp2.Statis;
using DigitalPlatform.CirculationClient;
using DigitalPlatform.CirculationClient.localhost;
using dp2Circulation;
public class MyStatis : ReaderStatis
{
Table table = new Table(4);
string strOutputErrorFilename = ""; // 输出的错误信息文件名
StreamWriter sw_error = null;
int nErrorCount = 0; // 发生错误的读者记录数
public override void OnBegin(object sender, StatisEventArgs e)
{
this.ClearConsoleForPureTextOutputing();
strOutputErrorFilename = this.ProjectDir + "\\error.txt";
sw_error = new StreamWriter(strOutputErrorFilename,
false, // append
Encoding.GetEncoding(936)); // gb2312
sw_error.Write("<pre>\r\n");
}
public override void OnRecord(object sender, StatisEventArgs e)
{
string strError = "";
int nRet = 0;
// 读者条码
string strReaderBarcode = DomUtil.GetElementText(this.ReaderDom.DocumentElement, "barcode");
this.WriteTextToConsole(this.CurrentRecordIndex.ToString() + " : " + strReaderBarcode + "\r\n");
long lRet = this.ReaderStatisForm.Channel.ChangeReaderPassword(
null, // stop,
strReaderBarcode, // 读者证条码号
null, // 旧密码
"test1", // 新密码
out strError);
if (lRet != 1)
{
nErrorCount++;
sw_error.Write("读者记录 " + this.CurrentRecPath + " 修改密码时发生错误: " + strError + "\r\n");
}
return;
ERROR1:
MessageBox.Show(this.ReaderStatisForm, strError);
e.Continue = ContinueType.SkipAll;
}
public override void FreeResources()
{
if (sw_error != null)
{
sw_error.Close();
sw_error = null;
}
}
public override void OnEnd(object sender, StatisEventArgs e)
{
if (sw_error != null)
{
sw_error.Close();
sw_error = null;
}
string strText = "";
if (nErrorCount > 0)
{
strText += "\r\n\r\n错误信息 " + nErrorCount.ToString() + " 条,请看文件 " + strOutputErrorFilename + " (在读者统计窗的打印结果里面可以看到)";
// 写入打印输出文件
string strPrintFile = this.NewOutputFileName();
File.Copy(this.strOutputErrorFilename, strPrintFile, true);
}
MessageBox.Show(this.ReaderStatisForm, strText);
}
}
下面是我参考谢老师编写的方案后,自己修改出来的
// 测试修改读者密码
// 创建日期:2011/11/3
using System;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Xml;
using System.Drawing; // Size
using DigitalPlatform;
using DigitalPlatform.Xml;
using DigitalPlatform.Text;
using DigitalPlatform.dp2.Statis;
using DigitalPlatform.CirculationClient;
using DigitalPlatform.CirculationClient.localhost;
using dp2Circulation;
public class MyStatis : ReaderStatis
{
Table table = new Table(4);
string strOutputErrorFilename = ""; // 输出的错误信息文件名
StreamWriter sw_error = null;
int nErrorCount = 0; // 发生错误的读者记录数
public override void OnBegin(object sender, StatisEventArgs e)
{
this.ClearConsoleForPureTextOutputing();
strOutputErrorFilename = this.ProjectDir + "\\error.txt";
sw_error = new StreamWriter(strOutputErrorFilename,
false, // append
Encoding.GetEncoding(936)); // gb2312
sw_error.Write("<pre>\r\n");
}
public override void OnRecord(object sender, StatisEventArgs e)
{
if (DomUtil.GetElementText(this.ReaderDom.DocumentElement, "password") == "")
{
string strError = "";
int nRet = 0;
// 读者条码
string strReaderBarcode = DomUtil.GetElementText(this.ReaderDom.DocumentElement, "barcode");
// 读者证号
string strcardNumber = DomUtil.GetElementText(this.ReaderDom.DocumentElement, "cardNumber");
// 读者类型
string strreaderType = DomUtil.GetElementText(this.ReaderDom.DocumentElement, "readerType");
if (strreaderType == "中文专业" || strreaderType == "本科" || strreaderType == "专科")
{
if (strcardNumber == "")
{
strcardNumber = Guid.NewGuid().ToString();
}
}
else if (strreaderType == "教参借阅" || strreaderType == "教师" || strreaderType == "工人" || strreaderType == "特殊借阅")
{
strcardNumber = strReaderBarcode;
}
this.WriteTextToConsole(this.CurrentRecordIndex.ToString() + " : " + strReaderBarcode + "\r\n");
//if (strcardNumber == "") { strcardNumber = "4fd56s4fs65f46s"; }
long lRet = this.ReaderStatisForm.Channel.ChangeReaderPassword(
null, // stop,
strReaderBarcode, // 读者证条码号
null, // 旧密码
strcardNumber, // 新密码
out strError);
if (lRet != 1)
{
nErrorCount++;
sw_error.Write("读者记录 " + this.CurrentRecPath + " 修改密码时发生错误: " + strError + "\r\n");
}
return;
ERROR1:
MessageBox.Show(this.ReaderStatisForm, strError);
e.Continue = ContinueType.SkipAll;
}
}
public override void FreeResources()
{
if (sw_error != null)
{
sw_error.Close();
sw_error = null;
}
}
public override void OnEnd(object sender, StatisEventArgs e)
{
if (sw_error != null)
{
sw_error.Close();
sw_error = null;
}
string strText = "";
if (nErrorCount > 0)
{
strText += "\r\n\r\n错误信息 " + nErrorCount.ToString() + " 条,请看文件 " + strOutputErrorFilename + " (在读者统计窗的打印结果里面可以看到)";
// 写入打印输出文件
string strPrintFile = this.NewOutputFileName();
File.Copy(this.strOutputErrorFilename, strPrintFile, true);
}
MessageBox.Show(this.ReaderStatisForm, strText);
}
}
我上面的方案是在谢老师写的方案的基础上,首先判断此读者是否有密码,如果,这个读者已经设置密码则跳过,如果没有设置密码,则想根据读者类型区分出老师与学生这两类读者,对于学生这类没有设置密码的读者首先判断这个读者是否有证号(证号这个字段中存放的是学生的学号),如果有证号这个字段,就用证号作为这个读者的密码。因为我们馆不是所有的学生数据在入库时都填写了证号,所以,对于没有证号的这类读者,我就采取了一个比较极端的处理方式,用GUID函数直接生成一个不可重复的字符串作为密码写入库中,这样,可以强制这类读者来馆修改密码。对于老师这类读者,因为人数少,所以就用他自己的借阅证号作为密码写入库中。
以上就是这件事情的经过,以及我自己参考谢老师的方案写出的处理方法。在这里首先对谢老师以及江老师的指导表示感谢。呵呵。。谢谢二位的指导,另外,也想请二位老师,以及其他馆的老师,一起讨论一下,看看我这么做是否得当。。。是不是我把这个问题想的太严重了。同时,如果有跟我需求相同的同行们,也可以参考一下谢老师写的方案。方便大家处理这类问题。