当前位置:   article > 正文

golang办公流程引擎初体验js-ojus/flow——系列三_go 工作流引擎

go 工作流引擎

golang语言的办公工作流的包介绍——系列一

golang办公工作流workflow利用js-ojus/flow做测试——系列二

golang办公流程引擎初体验js-ojus/flow——系列三

golang办公流程引擎初体验js-ojus/flow——系列四

1.办公流程概念 

流程大致是这样的:

1.管理员定义好流程类型doctype,这个下面再分流程类型workflow1,workflow2,workflow下再具体分为节点node1,node2,

再定义通用的状态state,通用的动作action,以及根据workflow1下的节点来定义流程走向transition,

再定义contex里的用户-组-角色-权限

2.对于一个要走流程的文件document_001数据表的某个文件,先建立一个document,再给它定义多个事件event,根据workflow1下的节点多少来定义,节点数-1个事件,也就是transition的个数。这个事件就是定义将document_001里的某个文件从状态1 state1改为state2的动作action。

3.开始走流程了,用事件event来修改document_001数据表里某个文件的状态,这个状态从state1变为state2,符合node1里的state1到node2里的state2,也符合transition里的state1——action1——state2

2.测试代码 

  1. package controllers
  2. import (
  3. "database/sql"
  4. "github.com/astaxie/beego"
  5. // "strings"
  6. // "testing"
  7. "fmt"
  8. _ "github.com/go-sql-driver/mysql"
  9. "github.com/js-ojus/flow"
  10. // "github.com/3xxx/meritms/models"
  11. // _ "github.com/mattn/go-sqlite3"
  12. // "github.com/astaxie/beego/httplib"
  13. // "github.com/astaxie/beego/logs"
  14. "log"
  15. )
  16. type MainController struct {
  17. beego.Controller
  18. }
  19. func (c *MainController) Get() {
  20. c.Data["Website"] = "beego.me"
  21. c.Data["Email"] = "astaxie@gmail.com"
  22. c.TplName = "index.tpl"
  23. }
  24. // var db *sql.DB
  25. // func init() {
  26. // driver, connStr := "mysql", "root:root@/flow"
  27. // tdb := fatal1(sql.Open(driver, connStr)).(*sql.DB)
  28. // // flow.RegisterDB(tdb)
  29. // if tdb == nil {
  30. // log.Fatal("given database handle is `nil`")
  31. // }
  32. // db = tdb
  33. // }
  34. // @Title show wf list
  35. // @Description show workflow page
  36. // @Success 200 {object} models.GetProductsPage
  37. // @Failure 400 Invalid page supplied
  38. // @Failure 404 articls not found
  39. // @router /workflow [get]
  40. //页面
  41. func (c *MainController) WorkFlow() {
  42. c.TplName = "merit/workflow.tpl"
  43. }
  44. // @Title get wf list
  45. // @Description get workflowlist by page
  46. // @Success 200 {object} models.GetProductsPage
  47. // @Failure 400 Invalid page supplied
  48. // @Failure 404 data not found
  49. // @router /flowtype [get]
  50. //管理员定义流程类型doctype、流程状态state、流程节点node、
  51. //流程动作action、流程流向transition、流程事件event
  52. func (c *MainController) FlowType() {
  53. // func init() {
  54. // orm.RegisterDriver("mysql", orm.DRMySQL)//注册驱动
  55. // orm.RegisterModel(new(Model))//注册 model
  56. // orm.RegisterDataBase("default", "mysql", "test:123456@/test?charset=utf8",30,30)//注册默认数据库
  57. //orm.RegisterDataBase("default", "mysql", "test:@/test?charset=utf8")//密码为空格式
  58. // }
  59. driver, connStr := "mysql", "travis@/flow?charset=utf8&parseTime=true"
  60. tdb := fatal1(sql.Open(driver, connStr)).(*sql.DB)
  61. if tdb == nil {
  62. log.Fatal("given database handle is `nil`")
  63. }
  64. db := tdb
  65. tx, _ := db.Begin()
  66. db.Close()
  67. //定义流程类型
  68. dtID1, err := flow.DocTypes.New(tx, "图纸设计流程")
  69. if err != nil {
  70. fmt.Println(err)
  71. }
  72. dtID2, err := flow.DocTypes.New(tx, "合同评审流程")
  73. if err != nil {
  74. fmt.Println(err)
  75. }
  76. beego.Info(dtID2)
  77. dtID3, err := flow.DocTypes.New(tx, "变更立项流程")
  78. if err != nil {
  79. fmt.Println(err)
  80. }
  81. beego.Info(dtID3)
  82. //定义流程状态
  83. dsID1, err := flow.DocStates.New(tx, "设计中...")
  84. if err != nil {
  85. fmt.Println(err)
  86. }
  87. dsID2, err := flow.DocStates.New(tx, "校核中...")
  88. if err != nil {
  89. fmt.Println(err)
  90. }
  91. dsID3, err := flow.DocStates.New(tx, "审查中...")
  92. if err != nil {
  93. fmt.Println(err)
  94. }
  95. flow.DocStates.New(tx, "批准中...")
  96. flow.DocStates.New(tx, "申报中...")
  97. flow.DocStates.New(tx, "评估中...")
  98. flow.DocStates.New(tx, "审批中...")
  99. //定义流程动作类型
  100. daID1, err := flow.DocActions.New(tx, "设计完成后提交", false) //改变状态设计中...为校核中...
  101. if err != nil {
  102. fmt.Println(err)
  103. }
  104. daID2, err := flow.DocActions.New(tx, "校核完成后提交", false)
  105. if err != nil {
  106. fmt.Println(err)
  107. }
  108. daID3, err := flow.DocActions.New(tx, "审查完成后提交", false)
  109. if err != nil {
  110. fmt.Println(err)
  111. }
  112. daID4, err := flow.DocActions.New(tx, "核定完成后提交", true)
  113. if err != nil {
  114. fmt.Println(err)
  115. }
  116. daID5, err := flow.DocActions.New(tx, "编制完成后提交", true)
  117. if err != nil {
  118. fmt.Println(err)
  119. }
  120. daID6, err := flow.DocActions.New(tx, "审批完成后提交", false)
  121. if err != nil {
  122. fmt.Println(err)
  123. }
  124. daID7, err := flow.DocActions.New(tx, "立项完成后提交", false)
  125. if err != nil {
  126. fmt.Println(err)
  127. }
  128. //添加流程规则1:oldstate1 action1 newstate2
  129. err = flow.DocTypes.AddTransition(tx, dtID1, dsID1, daID1, dsID2)
  130. if err != nil {
  131. beego.Error(err)
  132. }
  133. //添加流程规则2:oldstate2 action2 newstate3
  134. err = flow.DocTypes.AddTransition(tx, dtID1, dsID2, daID2, dsID3)
  135. if err != nil {
  136. beego.Error(err)
  137. }
  138. //定义流程类型doctype下的流程类型workflow
  139. workflowID1, err := flow.Workflows.New(tx, "图纸设计-三级校审流程", dtID1, dsID1) //初始状态是“设计中...”——校核——审查——完成
  140. if err != nil {
  141. fmt.Println(err)
  142. }
  143. beego.Info(workflowID1)
  144. workflowID2, err := flow.Workflows.New(tx, "图纸设计-二级校审流程", dtID1, dsID1) //初始状态是“设计中...”-“校核”——完成
  145. if err != nil {
  146. fmt.Println(err)
  147. }
  148. beego.Info(workflowID2)
  149. //定义合同评审下的流程类型:部门合同流程,总院合同流程
  150. //略
  151. //定义用户、组、角色、权限集合
  152. accessContextID1, err := flow.AccessContexts.New(tx, "Context")
  153. if err != nil {
  154. beego.Error(err)
  155. }
  156. //定义流程类型workflow下的具体每个节点node,用户对文件执行某个动作(event里的action)后,会沿着这些节点走
  157. // AddNode maps the given document state to the specified node. This
  158. // map is consulted by the workflow when performing a state transition
  159. // of the system.nodeID1
  160. _, err = flow.Workflows.AddNode(tx, dtID1, dsID1, accessContextID1, workflowID1, "图纸设计-三级校审流程-设计", flow.NodeTypeBegin)
  161. if err != nil {
  162. fmt.Println(err)
  163. }
  164. _, err = flow.Workflows.AddNode(tx, dtID1, dsID2, accessContextID1, workflowID1, "图纸设计-三级校审流程-校核", flow.NodeTypeLinear)
  165. if err != nil {
  166. fmt.Println(err)
  167. }
  168. _, err = flow.Workflows.AddNode(tx, dtID1, dsID3, accessContextID1, workflowID1, "图纸设计-三级校审流程-审查", flow.NodeTypeEnd)
  169. if err != nil {
  170. fmt.Println(err)
  171. }
  172. //定义用户-组-角色-权限关系
  173. res, err := tx.Exec(`INSERT INTO users_master(first_name, last_name, email, active)
  174. VALUES('秦', '晓川-1', 'email1@example.com', 1)`)
  175. if err != nil {
  176. log.Fatalf("%v\n", err)
  177. }
  178. uid, _ := res.LastInsertId()
  179. uID1 := flow.UserID(uid)
  180. _, err = flow.Groups.NewSingleton(tx, uID1)
  181. res, err = tx.Exec(`INSERT INTO users_master(first_name, last_name, email, active)
  182. VALUES('秦', '晓川-2', 'email2@example.com', 1)`)
  183. if err != nil {
  184. log.Fatalf("%v\n", err)
  185. }
  186. uid, _ = res.LastInsertId()
  187. uID2 := flow.UserID(uid)
  188. _, err = flow.Groups.NewSingleton(tx, uID2)
  189. res, err = tx.Exec(`INSERT INTO users_master(first_name, last_name, email, active)
  190. VALUES('秦', '晓川-3', 'email3@example.com', 1)`)
  191. if err != nil {
  192. log.Fatalf("%v\n", err)
  193. }
  194. uid, _ = res.LastInsertId()
  195. uID3 := flow.UserID(uid)
  196. _, err = flow.Groups.NewSingleton(tx, uID3)
  197. res, err = tx.Exec(`INSERT INTO users_master(first_name, last_name, email, active)
  198. VALUES('秦', '晓川-4', 'email4@example.com', 1)`)
  199. if err != nil {
  200. log.Fatalf("%v\n", err)
  201. }
  202. uid, _ = res.LastInsertId()
  203. uID4 := flow.UserID(uid)
  204. _, err = flow.Groups.NewSingleton(tx, uID4)
  205. gID1 := fatal1(flow.Groups.New(tx, "设计人员组", "G")).(flow.GroupID)
  206. gID2 := fatal1(flow.Groups.New(tx, "校核人员组", "G")).(flow.GroupID)
  207. fatal0(flow.Groups.AddUser(tx, gID1, uID1))
  208. fatal0(flow.Groups.AddUser(tx, gID1, uID2))
  209. fatal0(flow.Groups.AddUser(tx, gID1, uID3))
  210. fatal0(flow.Groups.AddUser(tx, gID2, uID2))
  211. fatal0(flow.Groups.AddUser(tx, gID2, uID3))
  212. fatal0(flow.Groups.AddUser(tx, gID2, uID4))
  213. roleID1 := fatal1(flow.Roles.New(tx, "设计人员角色")).(flow.RoleID)
  214. roleID2 := fatal1(flow.Roles.New(tx, "校核人员角色")).(flow.RoleID)
  215. //给角色role赋予action权限
  216. fatal0(flow.Roles.AddPermissions(tx, roleID1, dtID1, []flow.DocActionID{daID1, daID2, daID3, daID4}))
  217. fatal0(flow.Roles.AddPermissions(tx, roleID2, dtID1, []flow.DocActionID{daID1, daID2, daID3, daID4, daID5, daID6, daID7}))
  218. //给用户组group赋予角色role
  219. err = flow.AccessContexts.AddGroupRole(tx, accessContextID1, gID1, roleID1)
  220. if err != nil {
  221. beego.Error(err)
  222. }
  223. //将group和role加到accesscontext里——暂时不理解
  224. err = flow.AccessContexts.AddGroupRole(tx, accessContextID1, gID2, roleID2)
  225. if err != nil {
  226. beego.Error(err) //UNIQUE constraint failed: wf_ac_group_roles.ac_id已修补
  227. }
  228. tx.Commit() //这个必须要!!!!!!
  229. c.Data["json"] = "ok"
  230. c.ServeJSON()
  231. }
  232. // @Title post wf state
  233. // @Description post workflow state
  234. // @Success 200 {object} models.GetProductsPage
  235. // @Failure 400 Invalid page supplied
  236. // @Failure 404 data not found
  237. // @router /flowdocevent [get]
  238. //对具体文件进行流程初始化,对具体文件进行定义动作事件
  239. func (c *MainController) FlowDocEvent() {
  240. //连接数据库
  241. driver, connStr := "mysql", "travis@/flow?charset=utf8&parseTime=true"
  242. tdb := fatal1(sql.Open(driver, connStr)).(*sql.DB)
  243. if tdb == nil {
  244. log.Fatal("given database handle is `nil`")
  245. }
  246. db := tdb
  247. tx, err := db.Begin()
  248. if err != nil {
  249. beego.Error(err)
  250. }
  251. //查询预先定义的doctype流程类型
  252. dtID1, err := flow.DocTypes.GetByName("图纸设计")
  253. if err != nil {
  254. beego.Error(err)
  255. }
  256. beego.Info(dtID1)
  257. //查询预先定义的docstate状态1
  258. dsID1, err := flow.DocStates.GetByName("设计中...")
  259. if err != nil {
  260. fmt.Println(err)
  261. }
  262. beego.Info(dsID1)
  263. //查询预先定义的docstate状态2
  264. dsID2, err := flow.DocStates.GetByName("校核中...")
  265. if err != nil {
  266. fmt.Println(err)
  267. }
  268. beego.Info(dsID2)
  269. //查询预先定义的docstate状态3
  270. dsID3, err := flow.DocStates.GetByName("审查中...")
  271. if err != nil {
  272. fmt.Println(err)
  273. }
  274. beego.Info(dsID3)
  275. //查询预先定义的action动作1
  276. daID1, err := flow.DocActions.GetByName("提交设计")
  277. if err != nil {
  278. fmt.Println(err)
  279. }
  280. beego.Info(daID1)
  281. //查询预先定义的action动作2
  282. daID2, err := flow.DocActions.GetByName("校核") //应该叫"提交校核"
  283. if err != nil {
  284. fmt.Println(err)
  285. }
  286. beego.Info(daID2)
  287. //查询预先定义的action动作3
  288. daID3, err := flow.DocActions.GetByName("审查") //应该叫"提交审查"
  289. if err != nil {
  290. fmt.Println(err)
  291. }
  292. beego.Info(daID3)
  293. //查询预先定义的流程类型workflow,这个相当于doctype下面再分很多种流程
  294. //比如doctype为图纸设计流程,下面可以分为二级校审流程,三级校审流程,四级校审流程
  295. myWorkflow, err := flow.Workflows.GetByName("图纸设计-三级校审流程")
  296. if err != nil {
  297. beego.Error(err)
  298. }
  299. beego.Info(myWorkflow)
  300. //查询context——这个应该是管理用户-组-权限的
  301. accessContextID1, err := flow.AccessContexts.List("Context", 0, 0)
  302. if err != nil {
  303. beego.Error(err)
  304. }
  305. beego.Info(accessContextID1[0].ID)
  306. beego.Info(flow.GroupID(1))
  307. //开始为具体一个文件设立流程-此处是新建一个文件。对于旧文件应该怎么操作来着?
  308. docNewInput := flow.DocumentsNewInput{
  309. DocTypeID: dtID1.ID, //属于图纸设计类型的流程
  310. AccessContextID: accessContextID1[0].ID, //所有用户权限符合这个contex的要求
  311. GroupID: 11, //groupId,初始状态下的用户组,必须是个人用户组(一个用户也可以成为一个独特的组,因为用户无法赋予角色,所以必须将用户放到组里)
  312. Title: "厂房布置图", //这个文件的名称
  313. Data: "设计、制图: 秦晓川1, 校核: 秦晓川2", //文件的描述
  314. }
  315. // flow.Documents.New(tx, &docNewInput)
  316. DocumentID1, err := flow.Documents.New(tx, &docNewInput)
  317. if err != nil {
  318. beego.Error(err)
  319. }
  320. // tx.Commit() //new后面一定要跟commit
  321. beego.Info(DocumentID1)
  322. beego.Info(daID2)
  323. beego.Info(flow.GroupID(12))
  324. //针对具体一个文件定义动作事件,从"校核中……"状态通过动作"校核"将它修改为"审查中……"
  325. docEventInput := flow.DocEventsNewInput{
  326. DocTypeID: dtID1.ID, //flow.DocTypeID(1),
  327. DocumentID: DocumentID1,
  328. DocStateID: dsID1.ID, //document state must be this state,文档的现状状态
  329. DocActionID: daID2.ID, //flow.DocActionID(2),
  330. GroupID: 12, //必须是个人用户组
  331. Text: "校核",
  332. }
  333. docEventID1, err := flow.DocEvents.New(tx, &docEventInput)
  334. if err != nil {
  335. beego.Error(err)
  336. }
  337. tx.Commit() //一个函数里只能有一个commit,所以,这个是提前定义好的!!!!
  338. beego.Info(docEventID1)
  339. c.Data["json"] = "OK"
  340. c.ServeJSON()
  341. }
  342. // @Title post wf state
  343. // @Description post workflow state
  344. // @Success 200 {object} models.GetProductsPage
  345. // @Failure 400 Invalid page supplied
  346. // @Failure 404 data not found
  347. // @router /flownext [get]
  348. //对具体文件修改状态
  349. func (c *MainController) FlowNext() {
  350. //连接数据库
  351. driver, connStr := "mysql", "travis@/flow?charset=utf8&parseTime=true"
  352. tdb := fatal1(sql.Open(driver, connStr)).(*sql.DB)
  353. if tdb == nil {
  354. log.Fatal("given database handle is `nil`")
  355. }
  356. db := tdb
  357. tx, err := db.Begin()
  358. if err != nil {
  359. beego.Error(err)
  360. }
  361. myDocEvent, err := flow.DocEvents.Get(16)
  362. if err != nil {
  363. beego.Error(err)
  364. }
  365. beego.Info(myDocEvent)
  366. //给出接受的组groupids
  367. groupIds := []flow.GroupID{flow.GroupID(13)}
  368. beego.Info(groupIds)
  369. //查询workflow
  370. myWorkflow, err := flow.Workflows.GetByName("图纸设计-三级校审流程")
  371. if err != nil {
  372. beego.Error(err)
  373. }
  374. beego.Info(myWorkflow)
  375. newDocStateId, err := myWorkflow.ApplyEvent(tx, myDocEvent, groupIds)
  376. if err != nil {
  377. beego.Error(err)
  378. }
  379. tx.Commit() //一个函数里只能有一个commit!!!!
  380. fmt.Println("newDocStateId=", newDocStateId, err)
  381. c.Data["json"] = "OK"
  382. c.ServeJSON()
  383. }
  384. // beego.Info(wflist)
  385. // wflist, err = flow.DocStates.List(0, 0)
  386. // if err != nil {
  387. // beego.Error(err)
  388. // }
  389. // // beego.Info(wflist1)
  390. // wflist, err = DocActions.List(0, 0)
  391. // if err != nil {
  392. // beego.Error(err)
  393. // }
  394. // wflist1, err = flow.Workflows.List(0, 0)
  395. // if err != nil {
  396. // beego.Error(err)
  397. // }
  398. // fatal1 expects a value and an error value as its arguments.
  399. func fatal1(val1 interface{}, err error) interface{} {
  400. if err != nil {
  401. fmt.Println("%v", err)
  402. }
  403. return val1
  404. }
  405. // error0 expects only an error value as its argument.
  406. func error0(err error) error {
  407. if err != nil {
  408. fmt.Println("%v", err)
  409. }
  410. return err
  411. }
  412. // error1 expects a value and an error value as its arguments.
  413. func error1(val1 interface{}, err error) interface{} {
  414. if err != nil {
  415. fmt.Println("%v", err)
  416. return nil
  417. }
  418. return val1
  419. }
  420. // fatal0 expects only an error value as its argument.
  421. func fatal0(err error) {
  422. if err != nil {
  423. fmt.Println("%v", err)
  424. }
  425. }

3.flow自身的测试

安装mysql

建立flow数据库的用户:

CREATE USER 'travis'@'localhost' IDENTIFIED BY '';

在Navicat里新建一个flow数据库,选择utf8mb4——它源码里有个地方交代了。

开始数据库里的表下面是没有内容的,与下图不同。

然后给用户travis赋权。

必须将setup_db.sh文件拷贝到sql文件夹上一级,否则会出现下列错误:

 

将sql文件里的setup_db.sh和setup_blob_dirs.sh拷贝到上一级目录里(flow文件夹里),然后cmd窗口进入这个文件夹,运行

setup_db.sh -t

setup_blob_dirs.sh

go test

4.mysql和sqlite数据库问题

Flow里的sql语句是mysql的,和sqlite差别很大。从数据表初始化的sh文件开始就不同,一直到flow的go文件里的数据表插入数据,查询数据,jion连接表格,unique多列集合的约束,枚举数据类型,生成view数据表视图等等,太多的不同了。

在sqlite里,新建表用sh文件,也可以用改造好的beego自动建表,

  1. package models
  2. import (
  3. "fmt"
  4. "github.com/astaxie/beego/orm"
  5. "time"
  6. )
  7. // CREATE TABLE users_master (
  8. // id INT NOT NULL AUTO_INCREMENT,
  9. // first_name VARCHAR(30) NOT NULL,
  10. // last_name VARCHAR(30) NOT NULL,
  11. // email VARCHAR(100) NOT NULL,
  12. // active TINYINT(1) NOT NULL,
  13. // PRIMARY KEY (id),
  14. // UNIQUE (email)
  15. // );
  16. type users_master struct {
  17. Id int64
  18. First_name string `orm:"size(30)"`
  19. Last_name string `orm:"size(30)"`
  20. Email string `orm:"unique;size(100)"`
  21. Active bool
  22. }
  23. // CREATE TABLE wf_ac_group_hierarchy (
  24. // id INT NOT NULL AUTO_INCREMENT,
  25. // ac_id INT NOT NULL,
  26. // group_id INT NOT NULL,
  27. // reports_to INT NOT NULL,
  28. // PRIMARY KEY (id),
  29. // FOREIGN KEY (ac_id) REFERENCES wf_access_contexts(id),
  30. // FOREIGN KEY (group_id) REFERENCES wf_groups_master(id),
  31. // FOREIGN KEY (reports_to) REFERENCES wf_groups_master(id),
  32. // UNIQUE (ac_id, group_id)
  33. // );
  34. type wf_ac_group_hierarchy struct {
  35. Id int64
  36. Ac *wf_access_contexts `orm:"rel(fk);unique"`
  37. Group *wf_groups_master `orm:"rel(fk);unique"`
  38. Reports_to *wf_groups_master `orm:"rel(fk);column(reports_to)"`
  39. }
  40. // CREATE TABLE wf_ac_group_roles (
  41. // id INT NOT NULL AUTO_INCREMENT,
  42. // ac_id INT NOT NULL,
  43. // group_id INT NOT NULL,
  44. // role_id INT NOT NULL,
  45. // PRIMARY KEY (id),
  46. // FOREIGN KEY (ac_id) REFERENCES wf_access_contexts(id),
  47. // FOREIGN KEY (group_id) REFERENCES wf_groups_master(id),
  48. // FOREIGN KEY (role_id) REFERENCES wf_roles_master(id)
  49. // );
  50. type wf_ac_group_roles struct {
  51. Id int64
  52. Ac *wf_access_contexts `orm:"rel(fk)"`
  53. Group *wf_groups_master `orm:"rel(fk)"`
  54. Role *wf_roles_master `orm:"rel(fk)"`
  55. }
  56. ……
  57. ……
  58. // CREATE TABLE wf_workflows (
  59. // id INT NOT NULL AUTO_INCREMENT,
  60. // name VARCHAR(100) NOT NULL,
  61. // doctype_id INT NOT NULL,
  62. // docstate_id INT NOT NULL,
  63. // active TINYINT(1) NOT NULL,
  64. // PRIMARY KEY (id),
  65. // FOREIGN KEY (doctype_id) REFERENCES wf_doctypes_master(id),
  66. // FOREIGN KEY (docstate_id) REFERENCES wf_docstates_master(id),
  67. // UNIQUE (name),
  68. // UNIQUE (doctype_id)
  69. // );
  70. type wf_workflows struct {
  71. Id int64
  72. Name string `orm:"size(100);unique"`
  73. Doctype *wf_doctypes_master `orm:"rel(fk);unique"`
  74. Docstate *wf_docstates_master `orm:"rel(fk)"`
  75. Active bool
  76. }
  77. func init() {
  78. orm.RegisterModel(new(users_master), new(wf_ac_group_hierarchy), new(wf_ac_group_roles))
  79. orm.RegisterModel(new(wf_access_contexts), new(wf_docactions_master), new(wf_docevent_application))
  80. orm.RegisterModel(new(wf_docevents), new(wf_docstate_transitions), new(wf_docstates_master))
  81. orm.RegisterModel(new(wf_doctypes_master), new(wf_document_blobs), new(wf_document_tags))
  82. orm.RegisterModel(new(wf_group_users), new(wf_groups_master), new(wf_mailboxes))
  83. orm.RegisterModel(new(wf_messages), new(wf_role_docactions), new(wf_roles_master))
  84. orm.RegisterModel(new(wf_workflow_nodes), new(wf_workflows))
  85. }
  86. func InitFlow() {
  87. sql := fmt.Sprintf("CREATE VIEW wf_ac_perms_v AS " +
  88. "SELECT wf_ac_group_roles.ac_id, wf_ac_group_roles.group_id, wf_group_users.user_id, wf_ac_group_roles.role_id, wf_role_docactions.doctype_id, wf_role_docactions.docaction_id " +
  89. "FROM wf_ac_group_roles " +
  90. "JOIN wf_group_users ON wf_ac_group_roles.group_id = wf_group_users.group_id " +
  91. "JOIN wf_role_docactions ON wf_ac_group_roles.role_id = wf_role_docactions.role_id;")
  92. sql2 := fmt.Sprintf("INSERT INTO wf_docstates_master(name) VALUES('__RESERVED_CHILD_STATE__');")
  93. sql3 := fmt.Sprintf("INSERT INTO wf_roles_master(name) VALUES('SUPER_ADMIN');")
  94. sql4 := fmt.Sprintf("INSERT INTO wf_roles_master(name) VALUES('ADMIN');")
  95. sql5 := fmt.Sprintf("CREATE VIEW wf_users_master AS SELECT id, first_name, last_name, email, active FROM users_master;")
  96. o := orm.NewOrm()
  97. res, err := o.Raw(sql).Exec()
  98. if err == nil {
  99. num, _ := res.RowsAffected()
  100. fmt.Println("mysql row affected nums: ", num)
  101. } else {
  102. o.Rollback() // beego.Info("插入t_studentInfo表出错,事务回滚")
  103. }
  104. res, err = o.Raw(sql2).Exec()
  105. if err == nil {
  106. num, _ := res.RowsAffected()
  107. fmt.Println("mysql row affected nums: ", num)
  108. } else {
  109. o.Rollback() // beego.Info("插入t_studentInfo表出错,事务回滚")
  110. }
  111. res, err = o.Raw(sql3).Exec()
  112. if err == nil {
  113. num, _ := res.RowsAffected()
  114. fmt.Println("mysql row affected nums: ", num)
  115. } else {
  116. o.Rollback() // beego.Info("插入t_studentInfo表出错,事务回滚")
  117. }
  118. res, err = o.Raw(sql4).Exec()
  119. if err == nil {
  120. num, _ := res.RowsAffected()
  121. fmt.Println("mysql row affected nums: ", num)
  122. } else {
  123. o.Rollback() // beego.Info("插入t_studentInfo表出错,事务回滚")
  124. }
  125. res, err = o.Raw(sql5).Exec()
  126. if err == nil {
  127. num, _ := res.RowsAffected()
  128. fmt.Println("mysql row affected nums: ", num)
  129. } else {
  130. o.Rollback() // beego.Info("插入t_studentInfo表出错,事务回滚")
  131. }
  132. }

解决golang:unsupported Scan, storing driver.Value type []uint8 into type *time.Time

https://blog.csdn.net/han0373/article/details/81698713

在open连接后拼接参数:parseTime=true 即可
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/746837
推荐阅读
相关标签
  

闽ICP备14008679号