Q框架 - Lua函数

LIMS暴露函数整理

此篇文档主要适用于有简单Lua基础的人阅读。读此文章前务必先通读Lua 基础

1.基础

现阶段LIMS中常用到的Lua脚本有2类,预约自定义脚本和计费自定义脚本

所谓基础函数是指,任何LIMS中的Lua脚本都可直接调用下列变量、函数。

※符号标记了重点函数,务必熟练使用。


now

功能:

变量,直接使用即可


dateT(time)

功能:

返回传入时间的月、日、时、分、秒等信息

os 存在安全问题, 并且 os.date(“*t”, time) 获取时间会存在时区问题,此函数相当于重写原有的os.date()

参数:

  • time时间戳,如果没有传入则为当前时间

返回值:

  • 数组形式
  • 数组key
    • ‘year’ 年
    • ‘month’ 月份(01-12)
    • ‘nmonth’ 月份,不带前导0(1-12)
    • ‘day’ 日期
    • ‘hour’ 24小时制时间
    • ‘ghour’ 12小时制时间
    • ‘min’ 分钟
    • ‘sec’ 秒
    • ‘wday’ 星期(1-7,其中1代表周日,2代表周一……)
    • ‘week’ 一年中第几周
    • ‘yday’ 一年第几天

例子:

  • dateT()[‘hour’]为当前时间的小时
  • dateT(0)[‘year’] == 1970
  • 实例
1
2
3
4
5
6
7
--预约开始时间,只能是每天八点后
can_resrv = false
err_msg = "预约开始时间,只能是每天八点后";

if (dateT(start_time)['hour'] >= 8) then
can_reserv = true
end

week_day(time)

功能:

等同于dateT(time)['wday'],但是从0开始(周日是0,周一是1)

参数:

  • time时间戳,如果没有传入则为当前时间

返回值:

  • [0-6]

month(time)

功能:

完全等同于dateT(time)['nmonth']

参数:

  • time时间戳,如果没有传入则为当前时间

返回值:

  • 1~12

month_day(time)

功能:

一个月中第几天,不带前导0

参数:

  • time时间戳,如果没有传入则为当前时间

返回值:

  • 1~31

today(time)

功能:

返回一个将formart解析后的时间戳,实际上是PHP中的strtotime,详见PHP strtotime() 函数PHP: strtotime - Manual

参数:

  • format规定日期/时间字符串。

返回值:

  • 计算后时间戳

例子:

  • today(“now”) 当前时间戳
  • today(“15 October 1980”)1980年10月15日的时间戳
  • today(“+5 hours”)当前时间的5小时后
  • today(“+1 week”)当前时间1周后
  • today(“+1 week 3 days 7 hours 5 seconds”)。。你猜
  • today(“next Monday”)当前时间的下一个周一,0点
  • today(“last Sunday”))当前时间上一个周日,0点

month_start(time)

month_end(time)

week_start(time)

week_end(time)

day_start(time)

day_end(time)

功能:

获得传入时间的月(周、日)开始(结束时间)

参数:

  • time时间戳,如果没有传入则为当前时间

返回值:

  • 时间戳(start为当天00:00:00,结束时间为当天23:59:59)

days(number)

功能:

再也不用写86400…将天数换算成秒

参数:

  • number 天数

返回值:

  • number * 86400(单位:秒)

second_to_hour(time, n)

功能:

再也不用写/3600,将秒数换算小时数

参数:

  • time 秒数
  • n 小数点后位数,默认为4

返回值:

  • time/3600,小数点后四舍五入到第n位

sprintf(str, arg1, arg2 ....)

功能:

  • 把百分号(%)符号替换成一个作为参数进行传递的变量:

参数:

  • str 必需。规定字符串以及如何格式化其中的变量。
  • arg1 必需。规定插到 format 字符串中第一个 % 符号处的参数。
  • arg2… 可选。规定插到 format 字符串中第二个 % 符号处的参数。

返回值:

  • 替换后的字符串

例子:

  • 描述收费备注时常用
1
2
3
4
5
6
dtemplate ='<span>%s%.2f/小时 * %.2f</span> '
..'<span>共计 %s%.2f 元</span>'

description = sprintf('<p>'..dtemplate..'</p>',
currency, 6, 10 , currency, 60)
--收费备注一栏此时为如下字样:¥6.00/小时 * 10.00 共计 ¥60.00 元

round(float, n)

功能:

round() 函数对浮点数进行四舍五入。

参数:

  • float需要被四舍五入的浮点数
  • n小数点后的位数,默认为0

返回值:

  • 浮点数进行四舍五入后的结果

date(format,timestamp)

功能:

按照格式返回日期字符串

参数:

  • format 规定输出日期字符串的格式。
  • timestamp 当前时间戳,默认当前时间

返回值:

  • 按照format格式规定的字符串

例子:

1
date('Y-m-d H:i:s', 0) --1970-01-01 08:00:00

mktime(hour,minute,second,month,day,year);

功能:

根据传入参数获得时间戳

参数:

  • hour 小时
  • minute 分
  • second 秒
  • month 月
  • day 日
  • year 年

均是整数

返回值:

  • 时间戳

例子:

1
2
time1 = mktime(8, 30 , 00, 2017, 4, 1)
date('Y年m月d日 H:i:s', time1) -- 2017年4月1日 08:30:00

strong(string)

功能:

返回被<strong>标签包裹的string

参数:

  • string 希望被包裹的字符串

返回值:

  • <strong>string</strong>

2.预约相关

现阶段LIMS中常用到的Lua脚本有2类,预约自定义脚本和计费自定义脚本

下列变量及函数只能预约自定义脚本中使用!

※符号标记了重点函数,务必熟练使用。


###※old_start_time

###※old_end_time

###※start_time

###※end_time

功能:

变量,从上至下代表,旧预约结束实际、旧预约开始时间(用于修改),开始时间、结束时间

例子:

  • 当天只能预约10天后一整天的时间
1
2
3
4
5
--核心逻辑
start_time < day_start(now) + days(10)
and start_time > day_end(now) + days(10)
and end_time < day_end(now) + days(10)
and end_time > day_end(now) + days(10)
  • 进阶:每人每周最多预约8小时(old_.*_time是必要的,不然会在用户修改预约时出现bug)
1
2
3
--核心逻辑
month_reserv_time = user_reserv_time(weekstart(now), week_end(now)) - (old_end_time - old_start_time) + (start_time - end_time)
moth_reserv_time < 8 * 3600

is_incharge()

功能:

判断当前用户是否是仪器负责人

参数:

返回值:

  • (boolen)推荐放在if中直接使用

is_contact()

功能:

判断当前用户是否是仪器联系人

参数:

返回值:

  • (boolen)推荐放在if中直接使用

user_tag(name)

功能:

判断当前用户是否属于某用户标签

参数:

  • name用户标签名称

返回值:

  • (boolen)推荐放在if中直接使用

例子:

1
2
3
--首先设置校内用户标签
user_tag("校内")--判断当前用户属于校内
not(user_tag("校内"))--判断当前用户属于校外

user_time(dtstart, dtend)

功能:

判断当前用户从dtstart到dtend之间,当前仪器已关联预约记录的使用时长

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number)总时长,单位秒

例子:

1
2
--用户每月只能最多[使用]当前仪器8小时
user_time(month_start(now), month_end(now)) < 8 * 3600

user_reserv_time(dtstart, dtend)

功能:

当前用户从dtstart到dtend之间,当前仪器的预约时长

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number)总时长,单位秒

例子:

1
2
--用户每月只能最多[预约]当前仪器8小时
user_reserv_time(month_start(now), month_end(now)) < 8 * 3600

lab_time(dtstart, dtend)

功能:

判断当前用户所在课题组从dtstart到dtend之间,当前仪器已关联预约记录的使用时长

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number)总时长,单位秒

lab_reserv_time(dtstart, dtend)

功能:

当前用户所在课题组从dtstart到dtend之间,当前仪器的预约时长

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number)总时长,单位秒

user_reserv_relative_time(dtstart, dtend, dtfrom, dto)

功能:

获取用户某天的某个时段内预约时间, 当用户修改某预约时, 该预约不能在统计之内

不推荐使用,应用范围实在太窄

参数:

  • dtstart 预约的开始时间
  • dtend 预约的结束时间
  • dtfrom 统计时段的开始时间
  • dto 统计时段的结束时间

返回值:

  • (number)总时长,单位秒

例子:

1
2
3
4
5
6
--每天每用户在12点-17点,仅能预约1小时
user_reserv_relative_time(
day_start(now), day_end(now),
today("12:00"), today("17:00"))
- (old_end_time - old_start_time)
+ (end_time - start_time) < 3600

caculate_reserv_duration_time(dtstart, dtend, dtfrom, dto)

功能:

计算dtstart-dtend范围的,在dtfrom-dto时段内的时间长度

参数:

  • dtstart 范围的开始时间
  • dtend 范围的结束时间
  • dtfrom 统计时段的开始时间
  • dto 统计时段的结束时间

返回值:

  • (number)总时长,单位秒

例子:

1
2
3
4
--今日7点-19点范围内,落在今日12点-17点的时长
caculate_reserv_duration_time(
today("12:00"), today("19:00"),
today("12:00"), today("17:00")) --5h

cut_to_days(dtstart, dtend)

功能:

将跨天时间截为数组

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (array)截取后的时间数组

    • [0] => Array
    • (
    • [dtstart] => 第一天的开始时间
    • [dtend] => 第一天的结束时间
    • )

    • [1] => Array

    • (
    • [dtstart] => 第二天的开始时间
    • [dtend] => 第二天开始时间
    • )
      ……

例子:

1
2
3
4
5
6
7
--今日12点-后天17点截为3段
days = cut_to_days(today("12:00:00"), today(" + 2 day 17:00:00"))

#days == 2
days[0]['dtstart'] == today("12:00:00")
days[1]['dtend'] == today("+ 1 day 00:00:00")
days[2]['dtstart'] == today(" + 2 day 00:00:00")

components(dtstart, dtend)※仅2.16.1及之后可用※

功能:

时间段内的此人的预约记录信息

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (array)截取后的时间数组
    • [1] => Array
    • (
    • [dtstart] => 第一次预约的开始时间
    • [dtend] => 第一次预约的结束时间
    • )
    • [2] => Array
    • (
    • [dtstart] => 第二次预约的开始时间
    • [dtend] => 第二次预约的开始时间
    • )
    • ……
    • [total_time] 范围内总时长

例子:

  • 新增时,记录并不在计算范围内,需手动矫正
1
2
3
4
5
6
--每周不管时长,每人只能预约3次
edit = old_start_time > 1 or false
if ((edit and #components(week_start(start_time), week_end(start_time)) <= 3)
or(not(edit) and #components(week_start(start_time), week_end(start_time)) <= 2)) then
can_reserv = true
end

3.计费

现阶段LIMS中常用到的Lua脚本有2类,预约自定义脚本和计费自定义脚本

以下变量及函数只能在计费自定义脚本中使用

※符号标记了重点函数,务必熟练使用。


start_time

end_time

功能:

变量,直接使用即可,其中送样为测样开始和结束时间

###user_id

功能:

变量,直接使用即可,当前对象的相关用户id,eq_reserv对象为预约者id,eq_sample为送样人id,eq_record为使用者id

###id

功能:

变量,直接使用即可,当前计费关联的使用、预约、送样记录对应ID

currency

功能:

变量,直接使用即可,价格单位,经常用于description,一般为


lab_group(name)※现阶段有bug,不推荐使用※

功能:

判断用户所在课题组,是否在name组织机构下

参数:

  • name,组织机构名

返回值:

  • (boolean),推荐放在if中使用

例子:

1
if (lab_group("化工学院")) then

lab_tag(name)

功能:

判断用户,是否在name用户标签下

参数:

  • name,用户标签名

返回值:

  • (boolean),推荐放在if中使用

例子:

1
if (lab_tag("授权用户")) then

user_tag(name)

功能:

判断用户,是否在name用户标签下。相比lab_tag,唯一的区别是,会涉及中心管理员,在系统设置中的用户标签,推荐使用user_tag

参数:

  • name,用户标签名

返回值:

  • (boolean),推荐放在if中使用

例子:

1
if (user_tag("授权用户")) then

charge_tag(name)

功能:

先设置计费标签,再通过此函数判断计费标签是否被选中(即使计费标签值为0,只要选中,charge_tag就为true)

参数:

  • name,计费标签名

返回值:

  • (boolean),推荐放在if中使用

charge_tag_value(name)

功能:

判断name是否属于该计费相关的计费标签,如果存在则返回标签值,不存在则返回0

参数:

  • name 计费标签名

返回值:

  • (number),计费标签值

例子:

1
2
3
4
--每个试剂瓶额外收费10元
if (charge_tag("试剂瓶")) then
fee = fee + 10 * charge_tag_value("试剂瓶")
end

extra_field_value(category, name, key, prop)※prop参数2.19.1及之后可用※

功能:

返回自定义表单的category类别下name字段,用户填写的具体值

现阶段只支持送样和使用

参数:

  • category 自定义表单,类别
  • name 自定义表单,字段
  • key 自定义表单字段为多选、数值范围时必填
  • prop 自定义表单,类型 (目前仅支持eq_reserv)

返回值:

  • (string),用户填写的具体值,自定义表单类别下字段不存在则为0

例子:

1
2
--使用自定义表单中,"样品信息"类别,"耗材"字段(文本类型),用户送样记录填入的值(汉字)
extra_field_value("样品信息", "耗材")
1
2
--使用自定义表单中,"使用类型"类别,"结果"字段(数值范围类型),用户使用记录填入的第一个值
extra_field_value("使用记录", "结果", "0")
1
2
--预约自定义表单中,"样品信息"类别,"耗材"字段(文本类型),用户预约记录填入的值(汉字)
extra_field_value("样品信息", "耗材", null, "eq_reserv")
1
2
3
4
--使用自定义表单中,"使用类型"类别,"值班老师"字段(多选类型),用户使用记录是否勾选"A老师"选项
extra_field_value("使用记录", "值班老师", "A老师") == 'on'
--等价于:
extra_field_value("使用记录", "值班老师", "A老师") ~= 'null'

records(dtstart, dtend)

功能:

查找到所有对应仪器中dtstart到dtend之间有交错的所有使用记录,包括当前

参数:

  • dtstart 开始时间
  • dtend 结束时间
  • 当开始结束时间都为0时,返回当前使用记录

返回值:

  • (array),所有使用记录详情
    • (
    • [1] => Array
    • (
    • [id] => 使用记录ID
    • [user_id] => 使用者ID
    • [start_time] => 开始时间
    • [end_time] => 结束时间
    • [samples] => 样品数
    • [reserv_id] => 关联送样记录ID,不存在时为0
    • )
    • [2] => Array
    • (
    • [id] =>
    • [user_id] =>
    • [start_time] =>
    • [end_time] =>
    • [samples] =>
    • [reserv_id] =>
    • )
    • ……

例子:

1
2
--当前使用记录的样品数
records()[1]['samples']
1
2
--昨日0点至今日12点,当前使用者一共有count条使用记录
count = #records(today("yesterday 00:00:00"), today("12:00:00"))

reservs(dtstart, dtend)

功能:

查找到所有对应仪器中dtstart到dtend之间有交错的所有预约记录,包括当前

参数:

  • dtstart 开始时间
  • dtend 结束时间
  • 当开始结束时间都为0时,返回当前预约记录

返回值:

  • (array),所有预约记录详情
    • (
    • [1] => Array
    • (
    • [id] => 预约记录ID
    • [start_time] => 开始时间
    • [end_time] => 结束时间
    • [status] => 预约状态[0-正常预约,1-正常使用,2-爽约,4-超时,5-迟到,6-迟到超时]
    • )
    • [2] => Array
    • (
    • [id] =>
    • [start_time] =>
    • [end_time] =>
    • [status] =>
    • )
    • ……

例子:

1
2
--当前预约记录的状态
reservs()[1]['status']
1
2
--昨日0点至今日12点,当前预约者一共有count条预约记录
count = #reservs(today("yesterday 00:00:00"), today("12:00:00"))

###※sample()

功能:

当前送样记录信息

参数:

返回值:

  • (array),当前送样记录详情
    • [id] => 送样记录ID
    • [start_time] => 测样开始时间
    • [end_time] => 测样结束时间
    • [count] => 样品数
    • [status] => 送样状态[1-申请中,2-已批准,3-申请培训被拒绝,4-因故取消,5-已测试]
    • [submit_time] => 送样时间
    • [pickup_time] => 取样时间

例子:

1
2
--当前测样样品数
sample()['count']

record()

功能:

当前使用记录信息

参数:

返回值:

  • (array),当前使用记录详情
    • [id] => 使用记录ID
    • [start_time] => 开始时间
    • [end_time] => 结束时间
    • [samples] => 样品数
    • [reserv_id] => 关联预约ID
    • [reserv_start_time] => 关联预约开始时间
    • [reserv_end_time] => 关联预约结束时间

例子:

1
2
--当前使用记录样品数
record()['count']

connect_record(sid)

功能:

根据当前送样记录,获得关联的使用记录信息

参数:

  • sid 送样记录ID,如果不传则取当前送样记录关联的使用记录

返回值:

  • [id] => 使用记录ID
  • [start_time] => 开始时间
  • [end_time] => 结束时间
  • [samples] => 样品数

connect_samples(rid)

功能:

根据当前使用记录,获得关联的送样记录信息

参数:

  • rid使用记录ID,如果不传则取当前送样记录关联的送样记录

返回值:

  • (array),所有送样记录详情
    • (
    • [1] => Array
    • (
    • [id] => 使用记录ID
    • [start_time] => 测样开始时间
    • [end_time] => 测样结束时间
    • [count] => 样品数
    • [status] => 送样状态[1-申请中,2-已批准,3-申请培训被拒绝,4-因故取消,5-已测试]
    • [submit_time] => 送样时间
    • [pickup_time] => 取样时间
    • )
    • [2] => Array
    • (
    • [id] =>
    • [start_time] =>
    • [end_time] =>
    • [count] =>
    • [status] =>
    • [submit_time] =>
    • [pickup_time] =>
    • )
    • ……

user_tags(uid)

功能:

返回当前用户或者uid用户的用户标签,包含中心管理员在系统设置中设置的

参数:

  • uid人员ID,如果不传则取当前用户

返回值:

  • (array),用户的所有标签
    • (
    • [1] => 校内
    • [2] => 已授权
    • )
    • ……

lab_reserv_time(dtstart, dtend)

功能:

返回当前用户所在课题组累计预约时长,包含此次

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number),课题组累计预约时长

lab_record_time(dtstart, dtend)

功能:

返回当前用户所在课题组累计使用时长,包含此次

参数:

  • dtstart 开始时间
  • dtend 结束时间

返回值:

  • (number),课题组累计预约时长

###※T(string, params)

功能:

sprintf的升级版,在params中以数组形式传入参数,还带翻译特效

推荐description中使用

参数:

  • string 规定字符串
  • params 参数数组

返回值:

  • 替换后的字符串

例子:

  • 描述收费备注时常用
1
2
3
4
5
6
7
8
9
10
11
params= {}
params['%currency'] = currency
params['%price'] = 6
params['%time'] = 10
params['%fee'] = 10 *6

dtemplate ='<span>%currency%price/小时 * %time</span> '
..'<span>共计 %currency%fee 元</span>'

description = T('<p>'..dtemplate..'</p>',params)
--收费备注一栏此时为如下字样:¥6/小时 * 10 共计 ¥60 元