loonflow 工單系統


 

該項目是基於django的工作流引擎,工單。項目托管在 Github

 

一、安裝基礎環境

1.1 安裝python 和 pip

yum install -y epel-release
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
yum install -y python36u python36u-devel python36u-pip

# 更新pip pip3.
6 install --upgrade pip pip -V

 

1.2 安裝和新建python3虛擬環境

# 安裝
pip install -U virtualenv
rm -f /usr/bin/python3 && ln -s /usr/bin/python3.6 /usr/bin/python3

# 建立virtualenv目錄
mkdir -p /data/virtualenv

# 新建python3虛擬環境(純凈安裝,名稱為loonflow)
cd /data/virtualenv
virtualenv --no-site-packages -p /usr/bin/python3.6 loonflow

# 激活進入虛擬環境
source /data/virtualenv/loonflow/bin/activate
(loonflow) [root@localhost virtualenv]#

 

1.3 安裝mysql

# 下載yum源
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

# 安裝yum源
yum -y install mysql57-community-release-el7-10.noarch.rpm

# yum安裝MySQL服務
yum -y install mysql-community-server MySQL-python mysql-devel

# 首先啟動MySQL
systemctl start  mysqld.service

# 查看密碼
此時MySQL已經開始正常運行,不過要想進入MySQL還得先找出此時root用戶的密碼,通過如下命令可以在日志文件中找出密碼:
grep "password" /var/log/mysqld.log

# 如下命令進入數據庫:
mysql -uroot -p
# 輸入初始密碼,此時不能做任何事情,因為MySQL默認必須修改密碼之后才能操作數據庫:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Admin@123';

 

1.4 創建數據庫

# 創建庫指定utf8編碼
# 創建后端數據庫
mysql> CREATE DATABASE loonflow DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

# 創建前端數據庫
mysql> CREATE DATABASE shutongflow DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

 

1.5 安裝redis

啟動redis(用於生成唯一的工單流水號+celery異步任務[執行腳本、通知腳本])

# 安裝
yum install -y redis

# 啟動
systemctl start redis
systemctl enable redis

 

二、安裝后端

2.1 下載loonflow代碼

cd /opt
git clone https://github.com/blackholll/loonflow.git

# 切換到 r0.3.19 tag
cd loonflow/
git checkout r0.3.19

 

2.2 安裝loonflow依賴

# 進入虛擬環境
source /data/virtualenv/loonflow/bin/activate

# 安裝requirements依賴
cd /opt/loonflow/requirements

# 添加requests模塊
echo "requests" >> common.txt

# 安裝
(loonflow) # pip install -r pro.txt

 

2.3 配置loonflow

1)配置DB

# 文件:loonflow/settings/pro.py
……
DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'loonflow', # 剛剛新建的數據庫名稱
            'USER': 'root',     # 數據庫用戶 
            'PASSWORD': 'Admin@123',  # 數據庫密碼
            'HOST': '127.0.0.1',       # 數據庫機器IP 
            'PORT': '3306',            # 端口
        }
}
……

2)允許訪問地址

最后設置以域名訪問的時候不會報錯。

# 文件:loonflow/settings/common.py
# ALLOWED_HOSTS 改成如下
…… ALLOWED_HOSTS
= ['*']
……

3)指定配置文件

# 文件:loonflow/tasks.py
# DJANGO_SETTINGS_MODULE 對應配置文件改成為 pro
……
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings.pro')
……

4)初始化db

python manage.py makemigrations
python manage.py migrate

5)創建超級用戶

python manage.py createsuperuser

賬號:root,密碼:Admin123

 

2.4 啟動后端

python manage.py runserver 0.0.0.0:6060

啟動之后,就可以訪問admin后台,然后隨便測試一個接口

# 后端url
http://172.16.34.250:6060

# 后端管理url
http://172.16.34.250:6060/admin

# api
http://172.16.34.250:6060/api/v1.0/workflows

 

三、安裝前端

使用第三方代碼:https://github.com/youshutong2080/shutongFlow
本系統使用Vue.js + Django開發,前端展示由loonflow配置決定,可以說前端是全動態,只需要配置好loonflow即可。

3.1 下載shutongFlow

cd /opt
git clone https://github.com/youshutong2080/shutongFlow.git

 

3.2 安裝依賴

# 激活進入虛擬環境
source /data/virtualenv/loonflow/bin/activate

cd /opt/shutongFlow/apps
pip install -r requirements.txt

 

3.3 配置shutongFlow

1)初始化db

# 初始化db
python manage.py makemigrations
python manage.py migrate 

2)導入數據

# 導入第三方數據(這里主要是用戶數據)
cd /opt/shutongFlow/
mysql -uroot shutongflow < shutongflow.sql
# 導入loonflow數據(配置數據及用戶數據)
mysql -uroot loonflow < loonflownew.sql

3)監聽主機地址

# 文件:shutongFlow/fronted/config/index.js
# host: 'localhost' 改成如下
……
host: '0.0.0.0'
……

 

3.4 啟動前端

1)啟動shutongFlow后端

# 啟動shutongFlow
cd /opt/shutongFlow/apps
python manage.py runserver 0.0.0.0:6062

2)啟動shutongFlow前端vue

# 啟動vue,會監聽6061端口,前端的訪問端口。
npm install .
npm run dev

 

3.5 啟動通知服務

# 啟動celery任務: 
celery -A tasks worker -l info -Q loonflow

生產環境命令如下:celery multi start -A tasks worker -l info -c 8 -Q loonflow --logfile=xxx.log --pidfile=xxx.pid
參數說明:-c為啟動的celery進程數, logfile為日志文件路徑, pidfile為pid文件路徑,可自行視情況調整。

 

四、前后端用戶同步

前端數據庫:shutongflow.user(username,alias,email)
后端數據庫:loonflow.account_loonuser(username,alias,email)
當前端shutongflow庫中的user表有插入動作,則把(username,alias,email)數據同步到后端loonflow庫的account_loonuser表的(username,alias,email)數據。

4.1 插入的觸發器

use shutongflow
DELIMITER //
CREATE TRIGGER user_trigger AFTER INSERT ON user FOR EACH ROW
BEGIN
INSERT INTO loonflow.account_loonuser(username,alias,email) VALUES(new.username,new.alias,new.email);
END ;
//
DELIMITER ;

注:在命令提示符下輸入delimiter // 這樣是用//替換換行符,這樣可避免點擊換行鍵時執行程序。

4.2 查看數據

當前端集成好了LDAP后,前端采用LDAP賬號登入,會同步賬號信息到后端數據庫,這時候可以查看數據是否已經同步。

select * from shutongflow.user;
select * from loonflow.account_loonuser;

4.3 觸發器操作

# 查詢觸發器
select * from information_schema.triggers\G

# 刪除觸發器
use shutongflow
DROP TRIGGER user_trigger;

 

五、配置LDAP認證

當前端ldap登入后,會在user表中插入用戶信息,然后觸發器會同步數據到后端loonflow.account_loonuser用戶表。

5.1 安裝模塊

# 激活進入虛擬環境
source /data/virtualenv/loonflow/bin/activate

pip install python-ldap django_auth_ldap

5.2 配置文件

修改前端同步ldap文件:shutongFlow/apps/apps/settings.py

import ldap
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion, GroupOfNamesType

AUTHENTICATION_BACKENDS = (
    'django_auth_ldap.backend.LDAPBackend',  #配置為先使用LDAP認證,如通過認證則不再使用后面的認證方式
    'django.contrib.auth.backends.ModelBackend',
)
AUTH_LDAP_SERVER_URI = "ldap://ldap.wmq.com:389"  # ldap服務器地址
AUTH_LDAP_BIND_DN = 'cn=manager,dc=wmq,dc=com'  # 管理員賬號
AUTH_LDAP_BIND_PASSWORD = 'xxxxx'
OUg = 'DC=wmq,DC=com'
AUTH_LDAP_USER_SEARCH = LDAPSearch(OUg, ldap.SCOPE_SUBTREE, "(&(objectClass=inetOrgPerson)(uid=%(user)s))")
AUTH_LDAP_USER_ATTR_MAP = {"first_name": "givenName", "last_name": "sn", "alias": "sn", "email": "mail", "username":"name"}
AUTH_LDAP_ALWAYS_UPDATE_USER = True  # 是否同步LDAP修改
AUTH_USER_MODEL = 'account.Users'

 

六、supervisor守護進程

supervisor 是基於 python 的任務管理工具,用來自動運行各種后台任務,當然你也能直接利用 nohup 命令使任務自動后台運行,但如果要重啟任務,每次都自己手動 kill 掉任務進程,這樣很繁瑣,而且一旦程序錯誤導致進程退出的話,系統也無法自動重載任務。

6.1 安裝supervisor

yum install -y epel-release
yum install -y supervisor

# 開機自啟動
systemctl enable supervisord 

 

6.2 配置supervisor

# 創建配置文件
mkdir /etc/supervisor
echo_supervisord_conf > /etc/supervisor/supervisord.conf
# 修改日志、pid、sock 存放目錄
vim /etc/supervisor/supervisord.conf …… [unix_http_server] file=/var/run/supervisor.sock …… [supervisord] logfile=/var/log/supervisord.log pidfile=/var/run/supervisord.pid …… [supervisorctl] serverurl=unix:///var/run/supervisor.sock …… [include] files = /etc/supervisor.d/*.ini

 

6.3 配置項目啟動文件

# 創建項目配置文件
vim /etc/supervisord.d/loonflow.ini [program:loonflow] directory=/opt/loonflow environment=HOME="/opt/loonflow" command=/data/virtualenv/loonflow/bin/python manage.py runserver 0.0.0.0:6060 ;在python3的虛擬環境運行,需要指定virtualenv的絕對路徑 autostart=true autorestart=true startsecs=3 stdout_logfile = /var/log/loonflow/loonflow_access.log stderr_logfile = /var/log/loonflow/loonflow_error.log stopasgroup=true killasgroup=true
[program:shutongflow] directory=/opt/shutongFlow/apps command=/data/virtualenv/loonflow/bin/python manage.py runserver 0.0.0.0:6062 autostart=true autorestart=true startsecs=3 stdout_logfile = /var/log/loonflow/shutongflow_access.log stderr_logfile = /var/log/loonflow/shutongflow_error.log stopasgroup=true killasgroup=true
[program:vue] directory
=/opt/shutongFlow/fronted command=npm run dev autostart=true autorestart=true startsecs=3 stdout_logfile = /var/log/loonflow/vue_access.log stderr_logfile = /var/log/loonflow/vue_error.log stopasgroup=true killasgroup=true
[program:celery] directory
=/opt/loonflow environment=HOME="/opt/loonflow" command=/data/virtualenv/loonflow/bin/celery -A tasks worker -l info -c 8 -Q loonflow --pidfile=/var/run/loonflow_celery.pid autostart=true autorestart=true startsecs=3 stdout_logfile = /var/log/loonflow/celery.log stderr_logfile = /var/log/loonflow/celery_error.log stopasgroup=true killasgroup=true
# 創建日志存儲目錄
mkdir /var/log/loonflow

參考:https://github.com/jimmy201602/workflowdemo/blob/master/supervisord.conf

參數說明:https://www.restran.net/2015/10/04/supervisord-tutorial/

 

6.4 啟動

# 啟動
systemctl start supervisord 

systemctl status supervisord    //運行狀態
systemctl stop supervisord       //停止
systemctl restart supervisord    //重啟

啟動完成后,可以查看項目對應進程的啟動狀態,如果有錯誤查看日志文件。

supervisorctl status

celery                           RUNNING   pid 31359, uptime 0:00:10
loonflow                         RUNNING   pid 31361, uptime 0:00:10
shutongflow                      RUNNING   pid 31362, uptime 0:00:10
vue                              RUNNING   pid 31360, uptime 0:00:10

 

6.5 訪問

訪問前端:http://172.31.57.1:6061
默認賬號:admin,密碼:yxuqtr
前端數據庫:http://172.31.57.1:6062/admin/

訪問后端(支持ldap):http://172.31.57.1:6060
默認賬號:admin,密碼:123456
后端數據庫:http://172.31.57.1:6060/admin/

去除“所有工單”功能按鈕,找到//注釋即可。
shutongFlow/fronted/src/router/routers.js

 

七、配置域名

vue前端需要采用nginx進行代理才能正常以域名地址訪問;其他端口直接做了域名解析即可訪問,不用設置代理。

7.1 安裝nginx

yum install -y nginx

7.2 配置文件

vim /etc/nginx/conf.d/loonflow.conf

server {
  listen *:80;
  server_name     loonflow.wmq.com;

  location / {
    proxy_pass      http://127.0.0.1:6061;
  }
}

7.3 域名解析

172.31.57.1 loonflow.wmq.com

這樣 6.5 節的訪問url地址全部可以通過域名進行訪問了。

 

八、附:企業微信通知腳本

send_wechat.py
內容如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
通知腳本loonflow會將標題、內容、參與人等信息作為全局變量傳給通知腳本,腳本中直接使用這些參數,通過各自的發送消息邏輯將信息發送出去。
詳情參數參考:loonflow/media/notice_script/demo_notice_script.py 里面有變量名稱。
本腳本引用三個變量:participant:接收人,content_result:內容,title_result:標題。
另外通知腳本內容是exec來執行的,不是直接執行腳本。所以 __name__ !== "__main__",不能用if __name__ == "__main__""""

import json
import requests

class WeChat:
    def __init__(self):
        self.CORPID = 'wxc08*****7d5b2cb'
        self.CORPSECRET = 'pmv*******************QBRv5w'
        self.AGENTID = '1000020'

    def _get_access_token(self):
        url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken'
        values = {'corpid': self.CORPID,
                  'corpsecret': self.CORPSECRET,
                  }
        req = requests.post(url, params=values)
        return req

    def get_access_token(self):
        get_req = self._get_access_token()
        if get_req.status_code != 200:
            print('連接服務器失敗')
        else:
            get_req_json = json.loads(get_req.text)
            if get_req_json['errcode'] != 0:
                print('響應結果不正確')
            else:
                access_token = get_req_json['access_token']
                return access_token

    def send_data(self):
        send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + self.get_access_token()
        send_values = {
            "touser": participant,
            "msgtype": "text",
            "agentid": self.AGENTID,
            "text": {
                "content": '%s <a href=\"http://172.31.57.1:6061/ticket/todo\">%s</a>' % (content_result,title_result)
            },
            "safe": "0"
        }
        send_msges = (bytes(json.dumps(send_values), 'utf-8'))
        respone = requests.post(send_url, send_msges)
        respone = respone.json()
        return respone["errmsg"]


wx = WeChat()
wx.send_data()

 

 

相關鏈接

后端(django):https://github.com/blackholll/loonflow

本文采用的前端demo(vue+django):https://github.com/youshutong2080/shutongFlow

其他前端demo(bootstrap+django):https://hub.docker.com/r/webterminal/workflowdemo

通知腳本:https://github.com/blackholll/loonflow-helper/blob/master/notice_script_demo/notice_script_demo.py

django接入ldap:https://igolang.cn/Python/django%20%E6%8E%A5%E5%85%A5%20ldap/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM