欢迎您来到 数字平台。 您尚未登录。[登录] [注册新用户]
当前位置: 论坛首页 / 栏目 产品与服务 / 文章 802

点击:29878[回复顶层] [树状] [详细]
[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 1 楼
文章id: 799
请教根据馆藏地判断是否开放借阅的脚本

作者: 阿甲


在dp2circulation中的脚本中,尝试写了下面这一段:

===================

// 根据馆藏地判断可借与否
          if (StringUtil.IsInList("红泥巴/典藏室", strItemLocation) == true)
          {
               strMessageText = "红泥巴典藏室不能外借";
               return false;
          }
         
        strMessageText = "可借";

====================

大概实现了这样的效果,当借的书馆藏点在 红泥巴/典藏室 时,便会弹出窗口显示"红泥巴典藏室不能外借"

不知这么写是否有问题?

现在,有这样的需求:在 红泥巴/ 分馆下有N个馆藏点,但只有其中一个或两个馆藏点是可以外借的,这应该怎么写呢?比如只有 红泥巴/阅览室 和 红泥巴/绘本馆 这两个馆藏点是可以外借的,而在 红泥巴/ 以下的所有馆藏点都不能外借。同时,这样的限定不影响其他分馆。

还有一个问题由于条件所限没有测试过。就是A分馆的管理员在写脚本的时候,是否有可能影响B分馆。比如A分馆在限定自己的馆藏点外借问题的时候,不小心写到了涉及全局的脚本,是否会产生对全局或其他分馆的影响?



发表时间: 2013-03-28 10:49:20
最后修改时间: 2013-03-28 10:50:35



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 2 楼
文章id: 801
回复: 请教根据馆藏地判断是否开放借阅的脚本

作者: xietao

关键词: //


以下是引用 阿甲 于 2013/3/28 10:49:20 发表的文字:

在dp2circulation中的脚本中,尝试写了下面这一段:

===================

// 根据馆藏地判断可借与否
          if (StringUtil.IsInList("红泥巴/典藏室", strItemLocation) == true)
          {
               strMessageText = "红泥巴典藏室不能外借";
               return false;
          }
         
        strMessageText = "可借";

====================

大概实现了这样的效果,当借的书馆藏点在 红泥巴/典藏室 时,便会弹出窗口显示"红泥巴典藏室不能外借"

不知这么写是否有问题?

现在,有这样的需求:在 红泥巴/ 分馆下有N个馆藏点,但只有其中一个或两个馆藏点是可以外借的,这应该怎么写呢?比如只有 红泥巴/阅览室 和 红泥巴/绘本馆 这两个馆藏点是可以外借的,而在 红泥巴/ 以下的所有馆藏点都不能外借。同时,这样的限定不影响其他分馆。

还有一个问题由于条件所限没有测试过。就是A分馆的管理员在写脚本的时候,是否有可能影响B分馆。比如A分馆在限定自己的馆藏点外借问题的时候,不小心写到了涉及全局的脚本,是否会产生对全局或其他分馆的影响?

 
dp2circulation 里面的脚本很多,我猜测您说的是 dp2library 也就是服务器端的 library.xml 中的脚本,其中有这么一个函数:
 
    public bool ItemCanBorrow(
            bool bRenew,
            Account account,
            XmlDocument itemdom,
            out string strMessageText)
 
这个函数一旦起作用,在 dp2circulation 中“系统管理窗”的“馆藏地”属性页的配置就失效了,系统认上述脚本函数的作用。
 
这个函数确实是能起到精确限定各种复杂的允许借阅的组合情况的作用。但缺点也是显而易见的,就是编写复杂,而且当分馆模式下,地点很多的时候,代码更会复杂。地点发生变动,代码也要及时修改,维护起来还是很麻烦的。
 
所以,最近我在琢磨一个类似的功能,就是根据分馆模式下常见的应用,用更简单配置文件或界面来设定这些规则,包括那个操作者不能负责借或者还某个地点的图书,不要用二次开发的脚本来弄。这个新功能能部分取代上述脚本功能。当然,这个新功能还没有出来以前,玩一玩这个服务器端脚本也是不错的。
 
> 在 红泥巴/ 分馆下有N个馆藏点,但只有其中一个或两个馆藏点是可以外借的,这应该怎么写呢?
 
可以在 if 探测到可以外借的地点字符串的时候,返回 true;其他情况简单返回 false 就可以了。
 
例如:
 
 if (StringUtil.IsInList("红泥巴/阅览室", strItemLocation) == true || StringUtil.IsInList("红泥巴/绘本馆", strItemLocation) == true )
{
strMessageText = "可借";
return true;
}

strMessageText = strItemLocation + "不能外借";
return false;
 
当然,这还是针对一个分馆的情况判断语句。
 
> 同时,这样的限定不影响其他分馆。
 
可以把每个分馆的一段语句放在一个更大的 if 里面。这样,每个if 里面的逻辑修改,都不会影响到其他 if 内的逻辑了。
 
那这里就涉及到如何从 strItemLocation 中观察 左边部分,也就是分馆名的问题。系统有一些库函数可以达到这个效果。
 
首先,从册记录的 <location> 元素中获得字符串有一定的要求,因为这个元素内有时候可能是 "#reservation,分馆/阅览室"这样的形态,所以用下面语句得到比较可靠:
 
            // 馆藏地点
            string strLocation = DomUtil.GetElementText(item_dom.DocumentElement, "location");
            // 去掉#reservation部分
            strLocation = StringUtil.GetPureLocationString(strLocation);
 
注意,GetPureLocationString() 函数就是专门用来得到干净的字符串的,去掉了 # 部分。
 
然后,可以用下面的代码,将分馆部分和地点部分分离:
 
 
            string strRoomName = "";  // 阅览室名
            string strLibraryCode = ""; // 馆代码
            // 解析
            LibraryApplication.ParseCalendarName(strLocation,
        out strLibraryCode,
        out strRoomName);
 
 
这样,判断起来就方便了:
 
if (strLibraryCode == "红泥巴")
{
    if (strRoomName == "阅览室")
    {
        ....
    }
    ....
}
 
if (strLibraryCode == "望湖小学")
{
    if (strRoomName == "教师图书馆")
    {
        ....
    }
    ....
 
}
 
 
~~~
 
但是,您举例的应用实在太典型了,还不是真正要用 library.xml 中脚本的理由。
 
因为在 dp2circulation 中“系统管理窗”的“馆藏地”属性页的配置本来是完全可以的!所谓典型的应用,就是这个地点明确可以借,那个地点明确不能借。如果这么明确,用个对照表就可以配置,何必动用脚本。
 
我看了一下红泥巴数字平台服务器上目前的“馆藏地”属性页,应该是能奏效的(当然前提是要删除 ItemCanBorrow() 脚本函数)。
 
那么什么情况才是脚本适合应用的场合呢?比如,有个地点,对某些读者允许外借,对另外的读者不允许外借。比如,有个地点上午允许外借,下午不能外借。类似这种复杂的非常规的情况,才是值得用脚本的。后面如果有兴趣我们可以针对这些假想的情景做一些练习,这样以后一旦遇到复杂的情况,相关的经验就可以派上用场了。


发表时间: 2013-03-28 22:41:41
最后修改时间: 2013-03-28 23:19:04



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 3 楼
文章id: 802
非常感谢,我来克隆整理了一下:

作者: 阿甲


下面这段测试成功了:

        // 馆藏地点
         string strLocation = DomUtil.GetElementText(itemdom.DocumentElement, "location");
         // 去掉#reservation部分
         strLocation = StringUtil.GetPureLocationString(strLocation);
            string strRoomName = "";  // 阅览室名
            string strLibraryCode = ""; // 馆代码
            // 解析
            LibraryApplication.ParseCalendarName(strLocation,
            out strLibraryCode,
            out strRoomName);

            if (strLibraryCode == "红泥巴")
            {
                if (strRoomName == "阅览室" || strRoomName == "典藏室" )
                {
                strMessageText = "可借";
                return true;
                }
                strMessageText = strRoomName + "不能外借";
                return false;
            }


测试中发现上文代码一个小地方:(item_dom.DocumentElement, "location")
改成:(itemdom.DocumentElement, "location") 就好了

关于应用我解释一下。我这里是用红泥巴来做练习,真正的应用主要是在学校方面。比如望湖小学有两个馆藏点是常规开放借阅的,但还需要新设N个临时的馆藏点,可能是在馆内的某个浏览区,可能是某个走廊或楼梯间,数量多而杂,临时性强。只需要在这些馆藏点不能外借(以免与中心馆藏点搞混)就行了。假如为这些馆藏点再一一在系统中设置,反而麻烦了。

不过是否可行,还需要实施一段时间才能判断。

另外,当一个分馆有多个馆藏点是可以外借时,读者还书时,如果还书窗口能立即显示“这本书隶属于哪个馆藏点”,对于管理员上架会方便一些(假如书上没有贴特别的馆藏点标志)。

目前还书时提示的是“还书成功”,如果想在后面加上一句,“该书属于 某分馆/某馆藏点”,这种提示可以在什么地方添加?



发表时间: 2013-03-29 09:28:06



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 4 楼
文章id: 803
回复: 非常感谢,我来克隆整理了一下:

作者: xietao


以下是引用 阿甲 于 2013/3/29 9:28:06 发表的文字:

下面这段测试成功了:

        // 馆藏地点
         string strLocation = DomUtil.GetElementText(itemdom.DocumentElement, "location");
         // 去掉#reservation部分
         strLocation = StringUtil.GetPureLocationString(strLocation);
            string strRoomName = "";  // 阅览室名
            string strLibraryCode = ""; // 馆代码
            // 解析
            LibraryApplication.ParseCalendarName(strLocation,
            out strLibraryCode,
            out strRoomName);

            if (strLibraryCode == "红泥巴")
            {
                if (strRoomName == "阅览室" || strRoomName == "典藏室" )
                {
                strMessageText = "可借";
                return true;
                }
                strMessageText = strRoomName + "不能外借";
                return false;
            }


测试中发现上文代码一个小地方:(item_dom.DocumentElement, "location")
改成:(itemdom.DocumentElement, "location") 就好了

关于应用我解释一下。我这里是用红泥巴来做练习,真正的应用主要是在学校方面。比如望湖小学有两个馆藏点是常规开放借阅的,但还需要新设N个临时的馆藏点,可能是在馆内的某个浏览区,可能是某个走廊或楼梯间,数量多而杂,临时性强。只需要在这些馆藏点不能外借(以免与中心馆藏点搞混)就行了。假如为这些馆藏点再一一在系统中设置,反而麻烦了。

不过是否可行,还需要实施一段时间才能判断。

另外,当一个分馆有多个馆藏点是可以外借时,读者还书时,如果还书窗口能立即显示“这本书隶属于哪个馆藏点”,对于管理员上架会方便一些(假如书上没有贴特别的馆藏点标志)。

目前还书时提示的是“还书成功”,如果想在后面加上一句,“该书属于 某分馆/某馆藏点”,这种提示可以在什么地方添加?

 
关于临时书架的设想,非常好,从软件的角度来说,软件作为一种工作的工具应当尽快适应这种极具价值的应用模式。
 
从流程和概念来说,大抵是两种思路实现这种方式的管理:
 
1) 用一个“集体借阅证”,把若干图书“借”在一起,然后移动到某个小区域,实现管理。这个方法的缺点是,第一,不容易从册记录中看出这个册现在实际在何处;第二,已经处在借阅状态的册,不能再次真正“借”给小读者,除非是展示区只让阅览。
 
2) 用正规的调拨功能。就是把这批书调拨到这个馆藏地点。对于工作人员来说,要做的操作就是把所有相关册扫一遍册条码,也是很简单很基础的图书馆日常业务操作。
 
现在看来您是不反对第二种正规做法的。
 
问题在于,这些地点有临时性,如果需要在增设和撤销的时候,需要中心系统管理员介入,可能预感到有些工作量。我觉得这个担忧不必太大,其实增设的时候是有工作量,但撤销的时候可以滞后撤销,短期不撤销对一般管理工作也基本无害。另外现在,分馆的管理员应该是可以进行增、减馆藏地点(子地点)的配置操作的,如果有些环节暂时没有打通(也就是说现有软件还有点障碍),我们打通它就是。
 
> 如果想在后面加上一句,“该书属于 某分馆/某馆藏点”,这种提示可以在什么地方添加?
 
这个功能现在是有的,就是借助“凭条打印”二次开发方案实现。以前这种方案主要用于配置凭条打印的格式,但因为它的动作触发点正巧在借还动作后,其实也特别适合用于出现窗口提示某个特殊位置需要的后续事宜,很早就给某个用户单位配置了这样的功能。
 
这个功能如果用在红泥巴数字平台中心的参与馆,可能有个缺点就是定义比较繁琐,另外前端用户要安装这个方案,也有些操作步骤需要学习。
 
这样,我后面专门介绍一下这个功能,您先用用,玩玩。
 
后面,我已经计划增加新的功能,能够比较简便地定义还回以后的提示,做成一个通用的功能。上次在中心的 QQ 群中我看到了有关这个功能的需求和设想,我当时就开始动脑筋准备这个功能了。在这里也感谢“高人”用户们的启发啊。


发表时间: 2013-03-29 19:20:37



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 5 楼
文章id: 804
如何利用凭条打印脚本实现还书位置提示

作者: xietao


这里我提供一个特殊的“凭条打印”脚本代码,它实现了根据特定还书位置进行提示的功能。

之所以说“特殊”,是因为凭条打印脚本一般是用于配置凭条打印格式的,但这里用于还书提示。为了示范简洁起见,我提供的这个脚本代码只有还书提示的功能。如果图书馆要同时保有还书提示和凭条打印功能,则需要把负责凭条打印的功能和还书提示的功能混合以后写在同一个脚本文件里,但这里就不示范了。因为任一时刻 dp2circulation 只能有一个凭条打印方案起作用,所以才需要上述混合的做法。

下面是脚本代码:

// 还书提示

using System;
using System.Windows.Forms;
using System.IO;
using System.Text;
using System.Xml;

using DigitalPlatform.Xml;
using DigitalPlatform.IO;
using DigitalPlatform.Text;

using dp2Circulation;

public class MyPrint : PrintHost
{
    public override void OnInitial(object sender, EventArgs e)
    {
        this.MainForm.ChargingNeedReturnItemXml = true;
    }

    public override void OnReturned(object sender,
    ReturnedEventArgs e)
    {
        base.OnReturned(sender, e);

        string strError = "";

        if (String.IsNullOrEmpty(e.ItemXml) == true)
        {
            strError = "ItemXml为空";
            goto ERROR1;
        }

        XmlDocument dom = new XmlDocument();
        try
        {
            dom.LoadXml(e.ItemXml);
        }
        catch (Exception ex)
        {
            strError = "XML装载到DOM时出错: " + ex.Message;
            goto ERROR1;
        }

        string strLocation = DomUtil.GetElementText(dom.DocumentElement, "location");
        // 去掉#reservation部分
        strLocation = StringUtil.GetPureLocationString(strLocation);

        if (strLocation == "流通库")
        {
            // MessageBox.Show(this.MainForm, strLocation);
            e.ChargingForm.FastMessageBox(InfoColor.Yellow,
            "注意",
            "请把本册放入特殊书架",
            2);

        }

        return;

    ERROR1:
        MessageBox.Show(this.MainForm, strError);
    }
}

怎么应用上述脚本代码呢?操作步骤如下:

1) 在 dp2circulation 的框架窗口中,用主菜单“帮助/参数配置”打开参数配置对话框。切换到“凭条打印”属性页;

2) 按“方案管理”按钮。在随后出现的方案管理对话框中,用“新增”按钮创建一个新的方案,注意把方案名字修改为“还书提示”。然后把上面的代码 paste 到方案的 main.cs 文件中,然后关闭相关对话框,回到参数配置对话框。

3) 这时候凭条打印方案已经创建好了。在“方案管理”按钮下面的“方案名”输入域中,输入或者选定刚创建的“还书提示”方案。这时候还不能使用这个方案,需要退出 dp2circulation,然后重新进入。

4) 上述代码中设定了馆藏地为“流通库”的册还书时候,会出现一个黄色的提示对话框,显示一句话。可以把代码修改为实际需要的馆藏地点名,然后记得每次修改后,都要退出 dp2circulation 然后重新进入。

~~~

上面代码是假定在全局馆藏地的情况。

如果是总分馆模式,需要进行改造。一个是,利用昨天我介绍的方法,用一段代码把馆藏地字符串解析为两段,然后综合进行判断。当然,也可以直接进行比较,例如:

if (strLocation == "分馆名/走廊书架")

{

    ....

}

另外一个,提示语句可以利用变量构造,例如:

            e.ChargingForm.FastMessageBox(InfoColor.Yellow,
            "注意",
            "请把本册放入"+strLocation+"书架",
            2);

~~~

这里我有个初步的想法,就是还书提示,应该是针对特殊地点的少数提示。如果对每个馆藏地点都提示,那黄色提示框就是失去了稀有性,操作者会视觉疲劳。因为黄色提示框本来就是用来提示少量情况下需要继续动作的。

(比如,还书时遇到来自大库的书是不需要提示的,而只有来自走廊书架的才需要提示,因为这个地点要专门分拨上架,还书的时候顺便分堆放)

另外,假如针对每个地点都需要提示,那么可以在出纳窗显示三个区域的情况下进行,把显示册信息的区域的格式修改一下,把馆藏地点名称用大字体显示,或者每个地点对应一个特殊的文字底色之类。这样就不用出现黄色提示框了,对不对?

或者,利用操作历史面板提供突出馆藏地点的显示?

关于分拨堆放的功能,我还计划另外开发一个专门的功能,一边扫册条码屏幕上就会提示,这个功能是单独的,和借还无关,可以用于上架前的筛选。或者用于读者或者工作人员不清楚一册书该如何归架的时候快速查询用。其实,册窗本来就有这个功能,可能仅仅是馆藏地没有突出显示而已。



发表时间: 2013-03-29 22:11:43



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 6 楼
文章id: 805
预约到书提示和馆藏地提示同时出现?

作者: xietao


上面的还书提示代码编好了以后,我想到一个有意思的场景,就是假如一册书因为有人预约,还书结束的时候出纳窗本来就会弹出黄色提示框提示放入保留架,如果这时候碰巧这册书来自需要提示的馆藏地点,则上述脚本会促使再弹出一个黄色提示框,也许工作人员会看了迷糊 --- 到底要我怎么办?可能会造成短暂的困惑。

此时如果能仅仅提示放入保留架,而不再进行馆藏地提示,怎么办呢?

我这里设想一下。

因为还书完成后,为了表示需要放入保留架这种情况,dp2library已经自动在册记录的 <location> 元素中写入了类似这样的内容:

#reservation,望湖小学/走廊书架

这个做法曾经给我们编程带来一定麻烦,因为平时我们只关注馆藏地的时候,需要用

        // 去掉#reservation部分
        strLocation = StringUtil.GetPureLocationString(strLocation);

这样的语句来取得“干净”的内容。

但是在上述的复杂情况下,其中的"#reservation"部分终于能派上用场了。

可以这样判断:

if (StringUtil.IsInList("#reservation", strLocation) == true)

就知道字符串里面是否有这个 #reservation 部分了。但注意,这个 if 语句必须放在上面的 去掉 #reservation 的语句之前。或者预先保留一个没有去掉的原始字符串,后面单独用来判断。

 

比如,写出来后面一段修改为这样:

        string strLocation = DomUtil.GetElementText(dom.DocumentElement, "location");
        if (StringUtil.IsInList("#reservation", strLocation) == true)
            return; // 直接返回,不做提示了

        // 去掉#reservation部分
        strLocation = StringUtil.GetPureLocationString(strLocation);

        if (strLocation == "流通库")
        {
            // MessageBox.Show(this.MainForm, strLocation);
            e.ChargingForm.FastMessageBox(InfoColor.Yellow,
            "注意",
            "请把本册放入特殊书架",
            2);

        }

        return;

 

~~~

上面的情况和代码纯属我的臆断,我尚未验证过(因为害怕制造预约后到书的场景)。如果你们验证发现问题,请及时告诉我。



发表时间: 2013-03-29 22:27:28
最后修改时间: 2013-03-30 10:55:08



[回复留言] [回复(需要先登录)] [引用(需要先登录)]普通文章第 7 楼
文章id: 806
多谢细心的设计,还需要慢慢消化:)

作者: 阿甲


先找合适的场合测试一下,方能继续讨论。

上面提到的“视觉疲劳”确实是个问题,如果特别用一个黄色框提示,有的分馆需要,涉及到有些馆藏点的提示需要,而另一些却不需要,需要判断分馆,再区分馆藏点,终归是对管理者要求较高的事情。

假如换一个思路,这种提示只是一种例行公事的常规性提示,对于所有人都有效(也可以考虑设个开关“还书时是否提示馆藏地”的选项)。假想一下,可能是下图所示的样子:

 

 这里不需要提示任何别的东西,想关注的人就关注,至于关注了该干什么由其自便;不需要关注的人,就像懒得看“还书成功”四个字一样,也不需要去看是哪个馆藏点的(或者有选项关闭)。

我想如此显示对于一般性的使用已经够用了。如果真要考虑具体到哪个馆藏点该提示什么的时候,才需要特别的脚本来辅助吧。



发表时间: 2013-04-01 21:39:41



页 1 / 1
 

在线用户
(无) 
当前栏目在线用户数 0, 总在线用户数 0