钉钉python实现审批数据库设计

为了实现工单系统,又不想自己去结合钉钉的组织架构实现一套审批流,所以采用钉钉的审批结合自己的系统去实现工单。

由钉钉实现审批流,软件实现查询,记录工单等。

在上一篇中已经实现了审批流程以及回调函数的实现和整个工单的逻辑,下面描述一下数据库的设计。

主要分为两个表去实现:

1. 工单的种类表,主要用于存储钉钉的工单种类或者想要用于操作的工单种类,即不是所有的工单都需要做记录操作。

表名:ticket_type

字段

字段类型

描述

id

int(11)

自增id,主键

process_code

varchar(64)

钉钉工单code码

name

varchar(64)

工单名称

url

varchar(256)

工单钉钉的申请页面地址

icon_url

tinyint(1)

图标地址

create_time

datetime

创建时间

update_time

datetime

修改时间

 

上述这些字段是钉钉的工单类型api会提供的,下面方法获取数据:

def getTicketType():
    Client = SecretClient(CORPID, SECRET) #dingtalk连接
    #用一个userid去获取这个userid的所有工单,如果工单很多,可以遍历执行,这里只有获取100个
    req = Client.bpms.process_listbyuserid(USERID, 0, 100) 
    process_top_vo = req['process_list']['process_top_vo']
    for p in process_top_vo:
        icon_url = p.get('icon_url', '')
        name = p.get('name', '')
        process_code = p.get('process_code', '')
        url = p.get('url', '')
        ticketType = TicketType.objects.filter(process_code=process_code)
        if ticketType:
            ticketType.update(icon_url=icon_url, name=name, url=url, update_time=datetime.datetime.now())
        else:
            TicketType.objects.create(process_code=process_code, icon_url=icon_url, name=name, url=url,
                                      type='', update_time=datetime.datetime.now())

 

2. 工单记录表,主要用于存储工单记录,通过钉钉回调过来的数据,然后记录在ticket_type里面的工单。

表名:ticket_record

字段

字段类型

描述

id

int(11)

自增id,主键

process_code

varchar(64)

钉钉工单code码(ticket_type)

process_instance_id

varchar(64)

工单的唯一编号

business_id

varchar(32)

审批实例业务编号

title

varchar(64)

审批实例标题

operation_records

longtext

操作记录列表

originator_dept_id

varchar(32)

发起的部门(钉钉部门)

originator_userid

varchar(64)

发起人(userid)

form_component_values

longtext

表单详情列表

status

varchar(32)

审批状态

result

varchar(32)

审批结果,分为 agree 和 refuse

cc_userids

varchar(1000)

抄送人

participant

varchar(64)

当前处理人(userid)

relation

varchar(1000)

关联人(记录哪些人操作过)

tasks

longtext

已审批任务列表,可以通过此列表获取已审批人

is_operation

tinyint

是否操作(用于后续自动化操作的记录)

create_time

datetime

创建时间

update_time

datetime

修改时间

 

这个通过钉钉回调过来的信息,然后通过钉钉的api去获取钉钉的工单实例详情:

请求方式:POST(HTTPS)
请求地址https://oapi.dingtalk.com/topapi/processinstance/get?access_token=ACCESS_TOKEN
参数说明

名称类型是否必须示例值描述
process_instance_idString必须1a2b-3e4d审批实例id

 

def getTicketRecord(process_instance_id):#此参数可以用钉钉的回调中获取
    '''
    获取工单详情
    :param process_instance_id: 工单的id
    :return:
    '''
    url = 'https://oapi.dingtalk.com/topapi/processinstance/get?access_token=' + getToken()
    data = {
        'process_instance_id': process_instance_id
    }
    #获取工单的详情
    req = requests.post(url, data=json.dumps(data))
    content = json.loads(req.text)['process_instance']
    originator_userid = content.get('originator_userid')
    business_id = content.get('business_id')
    title = content.get('title')
    operation_records = content.get('operation_records')
    originator_dept_id = content.get('originator_dept_id')
    form_component_values = content.get('form_component_values')
    tasks = content.get('tasks')
    status = content.get('status')
    result = content.get('result')
    cc_userids = content.get('cc_userids')
    relation = []
    participant = ''
    for task in tasks:
        userid = str(task.get('userid', ''))
        if task.get('task_result') == 'NONE' and task.get('task_status') == 'RUNNING':  #如果是这个状态的值,那么就是当前需要操作的
            if not participant:
                participant += userid
            else:
                participant = participant + ',' + userid
        if userid:
            if userid not in relation:
                relation.append(userid)  #所有做过操作的人,用于展示界面上相关的工单列表
    if originator_userid not in relation:
        relation.append(originator_userid)
    relation = ','.join(relation)
    participant = participant

将上述的值存到数据库中即可。

综合,完成一个所有的钉钉流程:

1. 钉钉填写工单:回调到工单系统,工单系统记录下操作。

2. 工单状态的改变:回调到工单系统,工单系统记录下操作。

3. 判断工单是否结束,结束了之后,是否要进行自动化处理,自动化处理要根据具体的项目来实现,达到一个完整的工单,人工只需要进行审批,所有的操作都是自动化。

目前只做了简单的几个自动化,在回调的时候判断函数:

#满足条件进行自动的操作
if  status == 'COMPLETED' and result == 'agree':#判断是否结束,且是同意的
    t = TicketRecord.objects.filter(process_instance_id=processInstanceId) 获取工单详情
    typeTicket = ''
    try:
        ticket = TicketType.objects.get(process_code=process_code)
        process_code = ticket.process_code #此处加了
    except Exception as e:
        print(e)

    if t and not t[0].is_operation:#判断没有进行操作过则进行自动化操作
        if process_code == '12345698765432876543': #判断要进行哪种自动化
            res, msg = attach(processInstanceId)#自动化函数,此处可以用celery异步操作。

 

回调的时候说一下一个容易出错的地方:

'bpms_task_change', 'bpms_instance_change'这两个回调在创建等操作的时候会同时回调回来,这个时候就要注意数据库的操作,避免写入相同的数,避免进行多次操作,需要自己去把控。

 

 

 

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值