很是叼的工單系統,工單結束,工做完成;很是叼的權限管控,精細到頁面按鈕及API

最近在研究工單系統的時候,被我找到一個很是流弊的工單系統,咱們都知道工單系統最麻煩的就是流程和模版的維護,而且,在工單處理過程當中極可能會添加一些操做,這些操做被稱之爲鉤子。就按我目前調研的結果來講,目前其實沒有啥工單系統能實現的這麼好的。html

這個工單系統就把流程設計,模版設計等等作的很是不錯,並且對權限的把控很是詳細,包括API接口、菜單、頁面按鈕權限,均可以靈活的控制,很是的不錯。前端

Demo:http://fdevops.com:8001/#/dashboardvue

Github:https://github.com/lanyulei/ferrynode

若是以爲不錯就給做者一個star,你的star沒準就是做者繼續維護下去的動力呢。python

功能介紹

系統管理linux

  • 用戶管理不單單包括了用戶,還有角色、職位、部門的管理,方便後面的工單處理人擴展。
  • 菜單管理,對菜單,頁面按鈕,甚至是API接口的管理。
  • 登錄日誌,對用戶登錄和退出的日誌記錄。

流程中心nginx

  • 流程申請,對流程進行分類管理,方便維護與可視化。
  • 工單列表,拆分了4個分類,包括:我待辦的工單,我建立的工單,我相關的工單,還有全部工單。
  • 轉交工單,若是你當前有別的事情在處理就能夠把工單轉交給別人去處理。
  • 結束工單,若是一個工單發展申請不對,權限足夠的話,是能夠直接結束工單的。
  • 工單處理人的多樣化,不只能夠我的處理,還能夠是部門、角色、變量。
  • 處理人變量,根據用戶數據來自動得到是該誰處理,好比:建立人,建立人leader,HRBP等等。
  • 會籤,若是是多個選擇人的話,而且勾選了會籤功能,那麼就須要這些負責人都處理完成後纔會經過。
  • 任務管理,能夠給任何階段綁定任務,至關於流程中的鉤子操做,實現的效果就是,工單完成,任務也就執行完成了,減小不少的人力成本。
  • 通知方式的靈活性,能夠經過任務給每一個階段綁定通知方式,也能夠給流程綁定全局通知。
  • 網關,支持排他網關和並行網關,排他網關即經過條件判斷,只要有一個條件經過,則可進入下一個階段;並行網關,即必須全部的階段都完成處理,才能夠進行下一個階段
  • 後面還會有不少的功能擴展,包括:加簽,催辦,子流程等等。

等等還有不少功能待研究。git

數據結構設計

對於一個完整的工做流系統來講,咱們須要有流程、模版、分組、用戶、任務等等,而且這些東西都是能夠靈活定製的,由於若是不能靈活定製的話,對於普通的使用這來講是很是不方便的,因此對於一個好的工做流系統,是必需要實現靈活性的。github

下面直接來展現一下,數據結構的設計圖。web

工做流數據結構設計圖

流程分類

type Classify struct {
    base.Model
    Name    string `gorm:"column:name; type: varchar(128)" json:"name" form:"name"`     // 分類名稱
    Creator int    `gorm:"column:creator; type: int(11)" json:"creator" form:"creator"` // 建立者
}

func (Classify) TableName() string {
    return "process_classify"
}

流程

type Info struct {
    base.Model
    Name      string          `gorm:"column:name; type:varchar(128)" json:"name" form:"name"`        // 流程名稱
    Structure json.RawMessage `gorm:"column:structure; type:json" json:"structure" form:"structure"` // 流程結構
    Classify  int             `gorm:"column:classify; type:int(11)" json:"classify" form:"classify"` // 分類ID
    Tpls      json.RawMessage `gorm:"column:tpls; type:json" json:"tpls" form:"tpls"`                // 模版
    Task      json.RawMessage `gorm:"column:task; type:json" json:"task" form:"task"`                // 任務ID, array, 可執行多個任務,能夠當成通知任務,每一個節點都會去執行
    Creator   int             `gorm:"column:creator; type:int(11)" json:"creator" form:"creator"`    // 建立者
}

func (Info) TableName() string {
    return "process_info"
}

模版

type Info struct {
    base.Model
    Name          string          `gorm:"column:name; type: varchar(128)" json:"name" form:"name" binding:"required"`                       // 模板名稱
    FormStructure json.RawMessage `gorm:"column:form_structure; type: json" json:"form_structure" form:"form_structure" binding:"required"` // 表單結構
    Creator       int             `gorm:"column:creator; type: int(11)" json:"creator" form:"creator"`                                      // 建立者
    Remarks       string          `gorm:"column:remarks; type: longtext" json:"remarks" form:"remarks"`                                     // 備註
}

func (Info) TableName() string {
    return "tpl_info"
}

工單

type Info struct {
    base.Model
    Title         string          `gorm:"column:title; type:varchar(128)" json:"title" form:"title"`                    // 工單標題
    Process       int             `gorm:"column:process; type:int(11)" json:"process" form:"process"`                   // 流程ID
    Classify      int             `gorm:"column:classify; type:int(11)" json:"classify" form:"classify"`                // 分類ID
    IsEnd         int             `gorm:"column:is_end; type:int(11); default:0" json:"is_end" form:"is_end"`           // 是否結束, 0 未結束,1 已結束
    State         json.RawMessage `gorm:"column:state; type:json" json:"state" form:"state"`                            // 狀態信息
    RelatedPerson json.RawMessage `gorm:"column:related_person; type:json" json:"related_person" form:"related_person"` // 工單全部處理人
    Creator       int             `gorm:"column:creator; type:int(11)" json:"creator" form:"creator"`                   // 建立人
}

func (Info) TableName() string {
    return "work_order_info"
}

工單綁定模版

type TplData struct {
    base.Model
    WorkOrder     int             `gorm:"column:work_order; type: int(11)" json:"work_order" form:"work_order"`          // 工單ID
    FormStructure json.RawMessage `gorm:"column:form_structure; type: json" json:"form_structure" form:"form_structure"` // 表單結構
    FormData      json.RawMessage `gorm:"column:form_data; type: json" json:"form_data" form:"form_data"`                // 表單數據
}

func (TplData) TableName() string {
    return "work_order_tpl_data"
}

工單流轉歷史

type CirculationHistory struct {
    base.Model
    Title        string `gorm:"column:title; type: varchar(128)" json:"title" form:"title"`                         // 工單標題
    WorkOrder    int    `gorm:"column:work_order; type: int(11)" json:"work_order" form:"work_order"`               // 工單ID
    State        string `gorm:"column:state; type: varchar(128)" json:"state" form:"state"`                         // 工單狀態
    Source       string `gorm:"column:source; type: varchar(128)" json:"source" form:"source"`                      // 源節點ID
    Target       string `gorm:"column:target; type: varchar(128)" json:"target" form:"target"`                      // 目標節點ID
    Circulation  string `gorm:"column:circulation; type: varchar(128)" json:"circulation" form:"circulation"`       // 流轉ID
    Processor    string `gorm:"column:processor; type: varchar(45)" json:"processor" form:"processor"`              // 處理人
    ProcessorId  int    `gorm:"column:processor_id; type: int(11)" json:"processor_id" form:"processor_id"`         // 處理人ID
    CostDuration string `gorm:"column:cost_duration; type: varchar(128)" json:"cost_duration" form:"cost_duration"` // 處理時長
    Remarks      string `gorm:"column:remarks; type: longtext" json:"remarks" form:"remarks"`                       // 備註
}

func (CirculationHistory) TableName() string {
    return "work_order_circulation_history"
}

任務

type Info struct {
    base.Model
    Name     string `gorm:"column:name; type: varchar(256)" json:"name" form:"name"`               // 任務名稱
    TaskType string `gorm:"column:task_type; type: varchar(45)" json:"task_type" form:"task_type"` // 任務類型
    Content  string `gorm:"column:content; type: longtext" json:"content" form:"content"`          // 任務內容
    Creator  int    `gorm:"column:creator; type: int(11)" json:"creator" form:"creator"`           // 建立者
    Remarks  string `gorm:"column:remarks; type: longtext" json:"remarks" form:"remarks"`          // 備註
}

func (Info) TableName() string {
    return "task_info"
}

任務執行歷史

type History struct {
    base.Model
    Task          int    `gorm:"column:task; type: int(11)" json:"task" form:"task"`                                    // 任務ID
    Name          string `gorm:"column:name; type: varchar(256)" json:"name" form:"name"`                               // 任務名稱
    TaskType      int    `gorm:"column:task_type; type: int(11)" json:"task_type" form:"task_type"`                     // 任務類型, python, shell
    ExecutionTime string `gorm:"column:execution_time; type: varchar(128)" json:"execution_time" form:"execution_time"` // 執行時間
    Result        string `gorm:"column:result; type: longtext" json:"result" form:"result"`                             // 任務返回
}

func (History) TableName() string {
    return "task_history"
}

安裝部署

go >= 1.14
vue >= 2.6
npm >= 6.14

二次開發

後端

# 1. 獲取代碼
git https://github.com/lanyulei/ferry.git

# 2. 進入工做路徑
cd ./ferry

# 3. 修改配置 ferry/config/settings.dev.yml
vi ferry/config/settings.dev.yml

# 配置信息注意事項:
1. 程序的啓動參數
2. 數據庫的相關信息
3. 日誌的路徑

# 4. 初始化數據庫
go run main.go init -c=config/settings.dev.yml

# 5. 啓動程序
go run main.go server -c=config/settings.dev.yml

前端

# 1. 獲取代碼
git https://github.com/lanyulei/ferry_web.git

# 2. 進入工做路徑
cd ./ferry_web

# 3. 安裝依賴
npm install

# 4. 啓動程序
npm run dev

上線部署

後端

# 1. 進入到項目路徑下進行交叉編譯(centos)
env GOOS=linux GOARCH=amd64 go build

更多交叉編譯內容,請訪問 https://www.fdevops.com/2020/03/08/go-locale-configuration

# 2. config目錄上傳到項目根路徑下,並確認配置信息是否正確
vi ferry/config/settings.yml

# 配置信息注意事項:
1. 程序的啓動參數
2. 數據庫的相關信息
3. 日誌的路徑

# 3. 建立日誌路徑及靜態文件經歷
mkdir -p log static/uploadfile

# 4. 初始化數據
./ferry init -c=config/settings.yml

# 5. 啓動程序,推薦經過"進程管理工具"進行啓動維護
nohup ./ferry server -c=config/settings.yml > /dev/null 2>&1 &

前端

# 1. 編譯
npm run build:prod

# 2. 將dist目錄上傳至項目路徑下便可。
mv dist web

# 3. nginx配置,根據業務自行調整便可
  server {
    listen 8001; # 監聽端口
    server_name localhost; # 域名能夠有多個,用空格隔開

    #charset koi8-r;

    #access_log  logs/host.access.log  main;
    location / {
      root /data/ferry/web;
      index index.html index.htm; #目錄內的默認打開文件,若是沒有匹配到index.html,則搜索index.htm,依次類推
    }

    #ssl配置省略
    location /api {
      # rewrite ^.+api/?(.*)$ /$1 break;
      proxy_pass http://127.0.0.1:8002; #node api server 即須要代理的IP地址
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 登錄
    location /login {
      proxy_pass http://127.0.0.1:8002; #node api server 即須要代理的IP地址
    }

    # 刷新token
    location /refresh_token {
      proxy_pass http://127.0.0.1:8002; #node api server 即須要代理的IP地址
    }

    # 接口地址
    location /swagger {
      proxy_pass http://127.0.0.1:8002; #node api server 即須要代理的IP地址
    }

    # 後端靜態文件路徑
    location /static/uploadfile {
      proxy_pass http://127.0.0.1:8002; #node api server 即須要代理的IP地址
    }

    #error_page  404              /404.html;    #對錯誤頁面404.html 作了定向配置

    # redirect server error pages to the static page /50x.html
    #將服務器錯誤頁面重定向到靜態頁面/50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
      root html;
    }
  }

自此項目就介紹完了,反正我以爲仍是很是不錯的,若是你也以爲不錯,就給做者一個star吧。

相關文章
相關標籤/搜索