概述
背景
以前做护士站的时候,维护床位信息有个给床号编号的问题。为了能批量的按指定规则编号维护床位。当时设想实现一个编号解析器,然后按规则维护编号串就行。然后当时就有C#实现了一套按规则走号的逻辑。来到检验之后碰到各种检验流水号、微生物鉴定号的编号规则,为此改了不少特殊代码。之后重启当年思想,再实现一波Caché的规则编号器,由于接触了json,而json的二维数组就可以很好的表示编号维护意图,因而这次使用大众化的json作为编号维护格式。希望借此一统编号逻辑实现的乱象。
规则定义
约定以JS的JSON格式作为编号描述。JS,C#,M各自实现走号方法。约定以二维数组来描述一个流水号例如:[[“1”,”2”,”3”],[“1”,”2”,”3”],[“a”,”b”,”c”]]
内层数组描述每位数组循环走的数字(可以是任意字符串),从开始一直递增往后取。按十进制走的模式满位进一。
对日期表示的约定$y1 $y2 $y3 $y4表示年的1234位, $M1 $M2表示月的12位, $d1 $d2表示日的12位 $h1 $h2表示时的12位, $m1 $m2表示分钟的12位, $s1 $s2表示秒的12位。
M实现
/// 规则编号器支持类,作为走号基础,非bug不可轻易改动,保证该类的接口性
Class LIS.WS.BLL.DHCLISRuleNo Extends %RegisteredObject
{
// 约定以二维数组来描述一个流水号例如:[["1","2","3"],["1","2","3"],["a","b","c"]]。内层数组描述每位数组循环走的数字(可以是任意字符串),从开始一直递增往后取。按十进制走的模式满位进一。对日期表示的约定$y1 $y2 $y3 $y4表示年的1234位,$M1 $M2表示月的12位,$d1 $d2表示日的12位 $h1 $h2表示时的12位,$m1 $m2表示分钟的12位,$s1 $s2表示秒的12位。
// RuleStr:规则串
// CurNo:当前号,当前号传空返回最小号
// IsDateNoReset:是否日期不重置。1:不重置,否则日期没比对上重新开始号
// 测试初始号
// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","")
// 测试下一号
// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","259")
// 测试年效果
// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0""],[""7""],[""$y3""],[""$y4""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0719259")
// 测试日期变化是否重置非日期编号(日期编号走号时非日期位数是否重置)
// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0""],[""7""],[""$d1""],[""$d2""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0731259")
ClassMethod GetNextNoByRule(RuleStr, CurNo, IsDateNoReset)
{
//规则串
s RuleStr=$g(RuleStr)
//当前号
s CurNo=$g(CurNo)
//日期变化是否不重置编号
s IsDateNoReset=$g(IsDateNoReset)
//分割第二位串
s RuleStr=$REPLACE(RuleStr,"],[","^")
//替换双引号
s RuleStr=$tr(RuleStr,"""","")
//去掉中括号
s RuleStr=$tr(RuleStr,"[","")
//去掉中括号
s RuleStr=$tr(RuleStr,"]","")
//存规则的二维数组,方便走位数
s RuleAll=""
f i=1:1:$l(RuleStr,"^") d
.//当前一位数的可走范围
.s OneRangeStr=$p(RuleStr,"^",i)
.//存可走范围数组
.s OneRangeLi=""
.//解析存可走范围数据
.f j=1:1:$l(OneRangeStr,",") d
..s OneRangeLi=OneRangeLi_$lb($p(OneRangeStr,",",j))
.//按位数存可走数的范围
.s RuleAll(i)=OneRangeLi
//返回号码
s RetNo=""
//空串返回开始号
i CurNo="" d
.f i=1:1:$l(RuleStr,"^") d
..s Index=1
..//跳过0
..i (i=$l(RuleStr,"^")),($lg(RuleAll(i),1)="0") d
...s Index=2
..s RetNo=RetNo_$lg(RuleAll(i),Index)
i CurNo="" q ..DealSpecialStr(RetNo)
//检测当前号和规则的长度
i $l(CurNo)'=$l(RuleStr,"^") q "-1^当前号长度和规则不匹配!"
//存当前号每位在可选范围的位数
s IndexList=""
s Err=""
//每个字符检测维护
f i=1:1:$l(CurNo) d
.//当前遍历的字符串
.s CurChar=$e(CurNo,i,i)
.//取出当前位数的可选范围
.s CurRange=RuleAll(i)
.//检测是否有
.s HasChar=0
.//和可选范围比对得到字符的位数
.f j=1:1:$ll(CurRange) d
..//相同就是位置
..i CurChar=$lg(CurRange,j) d
...//位置存数字
...s IndexList=IndexList_$lb(j)
...s HasChar=1
...//退出检测位置循环
.//没有匹配上切规则位数为1,考虑日期的规则
.i (HasChar=0),($ll(CurRange)=1) d
..//处理可能的日期串
..s DateRet=..DealDateStr($lg(CurRange,1))
..//日期匹配
..i CurChar=DateRet d
...s IndexList=IndexList_$lb(1)
...s HasChar=1
..//日期不匹配
..e d
...//日期变化后不重置
...i IsDateNoReset="1" d
....s IndexList=IndexList_$lb(1)
....s HasChar=1
...//日期没匹配上获得规则开始号
...else if ('$l(RetNo)) d
....f i=1:1:$l(RuleStr,"^") d
.....s Index=1
.....//跳过0
.....i (i=$l(RuleStr,"^")),($lg(RuleAll(i),1)="0") d
......s Index=2
.....s RetNo=RetNo_$lg(RuleAll(i),Index)
.i HasChar=0 s Err="-1^第"_j_"位不在规则范围内!" q
//返回日期开始号
i $l(Err),$l(RetNo) q ..DealSpecialStr(RetNo)
//返回错误
i $l(Err) q Err
//增加量
s AddNum=1
//逆序按位置增加
f i=$ll(IndexList):-1:1 d
.//当前索引加偏移量
.s curIndex=$lg(IndexList,i)+AddNum
.//当前可选范围
.s CurRange=RuleAll(i)
.//没满位就把偏移量置0,增加完成
.i curIndex<=$ll(CurRange) d
..s AddNum=0
.e d
..//否则当前位归最开始,前一个数继续增加位数
..s curIndex=1
.//从后往前拼串
.s RetNo=$lg(CurRange,curIndex)_RetNo
//最大号不增加
i AddNum=1 s RetNo=CurNo
q ..DealSpecialStr(RetNo)
}
/// Creator: zhanglianzhu
/// CreatDate: 20190601
/// Description::
/// Table:
/// Input: 得到一个规则指定号以后的指定数量的号,没指定号查所有号,没指定数量就是后面99999个
/// Output:
/// Return:
/// Others:
Query QryAllRuleNo(RuleStr, CurNo, Num, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, Output RowCount As %String) As %Query(ROWSPEC = "No")
{
}
/// Query的执行方法
/// d ##class(%ResultSet).RunQuery("LIS.WS.BLL.DHCLISRuleNo","QryAllRuleNo","[[""0""],[""7""],[""$y3""],[""$y4""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0719259","","","","","","","","","","","","","","")
ClassMethod QryAllRuleNoExecute(ByRef qHandle As %Binary, RuleStr, CurNo, Num, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, Output RowCount As %String) As %Status
{
//规则串
s RuleStr=$g(RuleStr)
//指定号
s CurNo=$g(CurNo)
//数量
s Num=$g(Num)
//没数量限制最大数量
i '$l(Num) s Num=99999
Set repid=$I(^CacheTemp)
If $Get(ind)="" Set ind=1
k ^TMPLIS($zn,repid,$j)
//没有规则串退出
i '$l(RuleStr) q $$$OK
s PreNo=""
f i=1:1:Num d
.s CurNo=..GetNextNoByRule(RuleStr,CurNo)
.d OutputRow
.i $l(PreNo),PreNo=CurNo q
.s PreNo=CurNo
k ^TMPLIS($zn,repid,$j)
Set qHandle=$lb(0,repid,0)
Quit $$$OK
OutputRow
s Data=$lb(CurNo)
Set ColFields="CurNo"
Set ^CacheTemp(repid,ind)=##Class(LIS.Util.Common).TransListNull(Data,ColFields)
Set ind=ind+1
quit
}
ClassMethod QryAllRuleNoClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = QryAllRuleNoExecute ]
{
Set repid=$LIST(qHandle,2)
Kill ^CacheTemp(repid)
Quit $$$OK
}
ClassMethod QryAllRuleNoFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = QryAllRuleNoExecute ]
{
Set AtEnd=$LIST(qHandle,1)
Set repid=$LIST(qHandle,2)
Set ind=$LIST(qHandle,3)
Set ind=$o(^CacheTemp(repid,ind))
If ind="" {
Set AtEnd=1
Set Row=""
}
Else {
Set Row=^CacheTemp(repid,ind)
}
// Save QHandle
s qHandle=$lb(AtEnd,repid,ind)
Quit $$$OK
}
// 处理特殊命令
ClassMethod DealSpecialStr(RuleNo)
{
s RuleNo=$g(RuleNo)
//当前日期
s CurDate=$zd($h,8)
//当前时间
s CurTime=$tr($zt($h),":","")
//日期
s y1=$e(CurDate,1,1)
s y2=$e(CurDate,2,2)
s y3=$e(CurDate,3,3)
s y4=$e(CurDate,4,4)
s M1=$e(CurDate,5,5)
s M2=$e(CurDate,6,6)
s d1=$e(CurDate,7,7)
s d2=$e(CurDate,8,8)
//时间
s h1=$e(CurTime,1,1)
s h2=$e(CurTime,2,2)
s m1=$e(CurTime,3,3)
s m2=$e(CurTime,4,4)
s s1=$e(CurTime,5,5)
s s2=$e(CurTime,6,6)
s RuleNo=$REPLACE(RuleNo,"$y1",y1)
s RuleNo=$REPLACE(RuleNo,"$y2",y2)
s RuleNo=$REPLACE(RuleNo,"$y3",y3)
s RuleNo=$REPLACE(RuleNo,"$y4",y4)
s RuleNo=$REPLACE(RuleNo,"$M1",M1)
s RuleNo=$REPLACE(RuleNo,"$M2",M2)
s RuleNo=$REPLACE(RuleNo,"$d1",d1)
s RuleNo=$REPLACE(RuleNo,"$d2",d2)
s RuleNo=$REPLACE(RuleNo,"$h1",h1)
s RuleNo=$REPLACE(RuleNo,"$h2",h2)
s RuleNo=$REPLACE(RuleNo,"$m1",m1)
s RuleNo=$REPLACE(RuleNo,"$m2",m2)
s RuleNo=$REPLACE(RuleNo,"$s1",s1)
s RuleNo=$REPLACE(RuleNo,"$s2",s2)
q RuleNo
}
// 处理日期字符串
ClassMethod DealDateStr(RuleNo)
{
s RuleNo=$g(RuleNo)
//当前日期
s CurDate=$zd($h,8)
//当前时间
s CurTime=$tr($zt($h),":","")
//日期
s y1=$e(CurDate,1,1)
s y2=$e(CurDate,2,2)
s y3=$e(CurDate,3,3)
s y4=$e(CurDate,4,4)
s M1=$e(CurDate,5,5)
s M2=$e(CurDate,6,6)
s d1=$e(CurDate,7,7)
s d2=$e(CurDate,8,8)
s RuleNo=$REPLACE(RuleNo,"$y1",y1)
s RuleNo=$REPLACE(RuleNo,"$y2",y2)
s RuleNo=$REPLACE(RuleNo,"$y3",y3)
s RuleNo=$REPLACE(RuleNo,"$y4",y4)
s RuleNo=$REPLACE(RuleNo,"$M1",M1)
s RuleNo=$REPLACE(RuleNo,"$M2",M2)
s RuleNo=$REPLACE(RuleNo,"$d1",d1)
s RuleNo=$REPLACE(RuleNo,"$d2",d2)
q RuleNo
}
}
测试效果
最后
以上就是落后荷花为你收集整理的Caché实现规则编号器的全部内容,希望文章能够帮你解决Caché实现规则编号器所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复