ApiBean.kt 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. package com.iscs.bozzys.api
  2. import android.util.Log
  3. import androidx.compose.runtime.snapshots.SnapshotStateMap
  4. import androidx.compose.ui.geometry.Offset
  5. import androidx.compose.ui.graphics.Color
  6. import com.iscs.bozzys.R
  7. import com.iscs.bozzys.ui.pages.edit.step.compose.Anchor
  8. import com.iscs.bozzys.ui.pages.edit.step.compose.Connection
  9. import com.iscs.bozzys.ui.pages.edit.step.compose.NodeUI
  10. import com.iscs.bozzys.utils.StringToListSerializer
  11. import kotlinx.serialization.Serializable
  12. import kotlinx.serialization.encodeToString
  13. import kotlinx.serialization.json.Json
  14. /**
  15. * 请求基础响应对象
  16. *
  17. * @param code
  18. * @param msg
  19. * @param data
  20. */
  21. open class Response<T>(var code: Int = 500, var msg: String = "", var data: T? = null)
  22. /**
  23. * 账号登录接口响应数据
  24. *
  25. * @param userId 用户id
  26. * @param username 用户名
  27. * @param nickname 用户昵称
  28. * @param accessToken 使用token
  29. * @param refreshToken 刷新token
  30. */
  31. class LoginRsp(
  32. val userId: Int,
  33. val username: String,
  34. val nickname: String,
  35. val accessToken: String,
  36. val refreshToken: String
  37. )
  38. /**
  39. * 获取分页数据
  40. *
  41. * @param total 数据总数
  42. * @param list 当前获取到的数据
  43. */
  44. class PageRsp<T>(val total: Int, val list: List<T>)
  45. /**
  46. * 获取用户角色
  47. *
  48. * @param user 用户信息
  49. * @param roles 角色信息
  50. */
  51. class PermissionRsp(val user: User, val roles: List<String>)
  52. /**
  53. * 任务统计
  54. */
  55. data class TaskStatistics(val inProgressCount: Int, val completedCount: Int)
  56. /**
  57. * 点位基类
  58. */
  59. @Serializable
  60. data class IsolationPoint(val id: Int, val pointName: String, val pointNfc: String)
  61. /**
  62. * 用户
  63. */
  64. @Serializable
  65. data class User(
  66. val id: Int = 0,
  67. val userId: Int? = null,
  68. val username: String = "",
  69. val nickname: String = "",
  70. val cardNfc: String? = null,
  71. val remark: String = "",
  72. val deptId: Int = 0,
  73. val deptName: String? = null,
  74. val postIds: List<Int> = listOf(),
  75. val email: String? = null,
  76. val mobile: String? = null,
  77. val sex: Int = 0,
  78. val avatar: String = "",
  79. val status: Int = 0,
  80. val loginIp: String = "",
  81. val loginDate: Long = 0L,
  82. val createTime: Long = 0L,
  83. val workstationIds: List<Int>? = null,
  84. val type: String? = "",
  85. )
  86. /**
  87. * 流程模板
  88. */
  89. @Serializable
  90. data class Sop(
  91. val id: Int,
  92. val name: String,
  93. val content: String,
  94. val nodeCount: Int,
  95. val status: Int,
  96. val description: String,
  97. val createTime: Long,
  98. val updateTime: Long
  99. )
  100. /**
  101. * 字典结构
  102. */
  103. @Serializable
  104. data class Dict(val id: Int, val sort: Int, val label: String, val value: String, val status: Int)
  105. /**
  106. * 任务信息
  107. */
  108. @Serializable
  109. data class Node(
  110. val id: Int = 0,
  111. val workId: Int = 0,
  112. val uuid: String = "",
  113. val parentUuid: String = "",
  114. val childrenUuid: String = "",
  115. val nodeName: String = "",
  116. val nodeIcon: String = "",
  117. val type: String = "",
  118. val position: String = "",
  119. val data: String = "",
  120. val description: String? = null,
  121. val workerUserId: Int = 0,
  122. val workerGroupId: Int? = null,
  123. val formId: Int = 0,
  124. val formData: String? = null,
  125. val createTime: Long = 0L,
  126. val approvalStatus: String = "",
  127. val approvalOpinion: String = "",
  128. val isolationType: String? = null, // 隔离类型
  129. val isolationPoints: String? = null, // 解除隔离的点位
  130. val isolationNodeUuid: String? = null, // 解除隔离关联的节点uuid
  131. val nodeUserList: List<User>? = null, // 隔离和解除隔离关联的上锁人和共锁人
  132. val smsTemplateCode: String? = null, // 短信通知
  133. val messageTemplateCode: String? = null, // 站内信息
  134. val emailTemplateCode: String? = null, // 邮件通知
  135. val appTemplateCode: String? = null, // app消息推送
  136. ) {
  137. /**
  138. * 校验请求参数
  139. *
  140. * @param forms 表单数据
  141. */
  142. fun checkCanSubmit(forms: List<FormField>): String {
  143. forms.forEach {
  144. Log.d("NodeOption", "checkCanSubmit -> $it")
  145. if (it.required) {
  146. if ((it.value.getOrNull(0) ?: "").isEmpty()) {
  147. return (it.placeholder.getOrNull(0) ?: "").ifEmpty { "请填写${it.label}" }
  148. }
  149. }
  150. }
  151. return ""
  152. }
  153. /**
  154. * 构建请求参数
  155. *
  156. * @param forms 表单数据
  157. */
  158. fun buildSubmitParams(forms: List<FormField>, workFormList: List<TaskFormInfo>): MutableMap<String, Any?> {
  159. val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
  160. val params = mutableMapOf<String, Any?>("nodeId" to id, "nodeName" to nodeName)
  161. if (type != "createJob") {
  162. val workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
  163. val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "0"
  164. val findWork = workFormList.find { it.id == formId.toInt() }
  165. val formData = if (findWork != null) Json.encodeToString(findWork) else null
  166. val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
  167. params["workerUserId"] = workerUserId.toInt()
  168. params["formId"] = formId.toInt()
  169. params["formData"] = formData
  170. // 处理隔离点信息表单
  171. if (listOf("isolation", "releaseIsolation").contains(type)) {
  172. val isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0) ?: "-1"
  173. val isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
  174. if (isolationType == "1") {
  175. // 移除负责人
  176. params.remove("workerUserId")
  177. // 上锁人和共锁人
  178. val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
  179. val group = forms.find { it.name == "group" }?.value ?: emptyList()
  180. val userList = mutableListOf<MutableMap<String, Any>>()
  181. if (locker.toInt() > 0) userList += mutableMapOf("userId" to locker.toInt(), "type" to "jtlocker")
  182. group.forEach { userList += mutableMapOf("userId" to it.toInt(), "type" to "jtcolocker") }
  183. params["nodeUserDOList"] = userList
  184. }
  185. params["isolationType"] = isolationType
  186. params["isolationPoints"] = isolationPoints.joinToString(
  187. prefix = "[",
  188. postfix = "]",
  189. separator = ","
  190. )
  191. if (type == "releaseIsolation") {
  192. val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
  193. // 解除隔离,这里需要填写关联的节点uuid
  194. params["isolationNodeUuid"] = isolationNode
  195. }
  196. }
  197. // 通知方式
  198. // 短信
  199. params["smsTemplateCode"] = if (noticeType.contains("sms")) "true" else "false"
  200. // 站内信
  201. params["messageTemplateCode"] = if (noticeType.contains("message")) "true" else "false"
  202. // 邮件
  203. params["emailTemplateCode"] = if (noticeType.contains("email")) "true" else "false"
  204. // app通知
  205. params["appTemplateCode"] = if (noticeType.contains("app")) "true" else "false"
  206. }
  207. return params
  208. }
  209. /**
  210. * 更新节点信息
  211. *
  212. * @param forms
  213. */
  214. fun updateNodeInfo(forms: List<FormField>, nodes: List<NodeUI>): Node {
  215. val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
  216. if (type != "createJob") {
  217. // 解析关联表单
  218. val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "-1"
  219. // 解析表单数据
  220. val formData = forms.find { it.name == "formData" }?.value?.getOrNull(0)
  221. // 解析负责人
  222. var workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
  223. // 解析隔离方式
  224. var isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0)
  225. // 解析点位
  226. var isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
  227. // 解析上锁人
  228. val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
  229. // 解析共锁人
  230. val group = forms.find { it.name == "group" }?.value ?: emptyList()
  231. // 构建上锁人和共锁人列表
  232. val userList = mutableListOf<User>()
  233. if (locker.toInt() > 0) userList += User(userId = locker.toInt(), type = "jtlocker")
  234. if (group.isNotEmpty()) group.forEach { userList += User(userId = it.toInt(), type = "jtcolocker") }
  235. // 解析隔离节点
  236. val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
  237. // 如果是解除隔离操作,隔离方式、隔离点位、负责人(或者上锁人、解锁人)需要从选中的点位中获取
  238. if (type == "releaseIsolation") {
  239. nodes.find { it.node?.uuid == isolationNode }?.node?.let {
  240. // 从节点中将数据copy到当前节点
  241. workerUserId = "${it.workerUserId}"
  242. isolationType = it.isolationType
  243. isolationPoints = if (it.isolationPoints.isNullOrEmpty()) {
  244. emptyList()
  245. } else {
  246. it.isolationPoints.replace("[", "").replace("]", "").split(",")
  247. }
  248. userList.addAll(it.nodeUserList ?: emptyList())
  249. }
  250. }
  251. // 通知方式
  252. val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
  253. return Node(
  254. id = id,
  255. workId = workId,
  256. uuid = uuid,
  257. parentUuid = parentUuid,
  258. childrenUuid = childrenUuid,
  259. nodeName = nodeName,
  260. type = type,
  261. position = position,
  262. workerUserId = workerUserId.toInt(),
  263. formId = formId.toInt(),
  264. formData = formData,
  265. isolationType = isolationType,
  266. isolationPoints = isolationPoints.joinToString(
  267. prefix = "[",
  268. postfix = "]",
  269. separator = ","
  270. ),
  271. isolationNodeUuid = isolationNode,
  272. nodeUserList = if (userList.isEmpty()) null else userList,
  273. smsTemplateCode = if (noticeType.contains("sms")) "true" else "false",
  274. messageTemplateCode = if (noticeType.contains("message")) "true" else "false",
  275. emailTemplateCode = if (noticeType.contains("email")) "true" else "false",
  276. appTemplateCode = if (noticeType.contains("app")) "true" else "false"
  277. )
  278. }
  279. return Node(
  280. id = id,
  281. workId = workId,
  282. uuid = uuid,
  283. parentUuid = parentUuid,
  284. childrenUuid = childrenUuid,
  285. nodeName = nodeName,
  286. type = type,
  287. position = position
  288. )
  289. }
  290. /**
  291. * 构建表单列表
  292. *
  293. * @param workerUserList 负责人列表
  294. * @param lockerUserList 上锁人列表
  295. * @param groupUserList 共锁人列表
  296. * @param workFormList 工作表单列表
  297. * @param isolationMethodList 获取隔离方式列表
  298. * @param isolationList 点位列表
  299. * @param isLocker 是否上锁人
  300. */
  301. fun buildFormList(
  302. workerUserList: List<User>,
  303. lockerUserList: List<User>,
  304. groupUserList: List<User>,
  305. workFormList: List<TaskFormInfo>,
  306. isolationMethodList: List<Dict>,
  307. isolationList: List<IsolationPoint>,
  308. nodes: List<NodeUI> = listOf(),
  309. isLocker: Boolean = false,
  310. ): List<FormField> {
  311. Log.d("NodeOption", "buildFormList -> $this")
  312. val list = ArrayList<FormField>()
  313. // 添加节点名称
  314. list += FormField(
  315. id.toString(),
  316. "input",
  317. "节点名称",
  318. name = "nodeName",
  319. true,
  320. value = listOf(nodeName),
  321. placeholder = listOf("请输入节点名称")
  322. )
  323. if (type == "createJob") return list
  324. // 添加节点负责人
  325. list += FormField(
  326. id.toString(),
  327. "select",
  328. "负责人",
  329. "workerUserId",
  330. true,
  331. placeholder = listOf("请选择负责人"),
  332. options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
  333. value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf()
  334. )
  335. // 添加业务表单
  336. list += FormField(
  337. id.toString(),
  338. "select",
  339. "业务表单",
  340. name = "formId",
  341. true,
  342. placeholder = listOf("请选择业务表单"),
  343. options = workFormList.map { FormOption(it.name ?: "", it.id.toString()) },
  344. value = if (formId > 0) listOf(formId.toString()) else listOf()
  345. )
  346. // 隔离配置
  347. if (listOf("isolation", "releaseIsolation").contains(type)) {
  348. // 先移除负责人,需要在后面进行添加
  349. list.removeIf { it.name == "workerUserId" }
  350. // 而且业务表单非必填
  351. val formField = list.find { it.name == "formId" }?.copy(required = false)
  352. list.removeIf { it.name == "formId" }
  353. formField?.let { list.add(it) }
  354. val isolations = nodes.map { it.node }.filter { it != null && it.type == "isolation" }
  355. var enabled = true
  356. var isLockerTemp = isLocker
  357. // 如果是解除隔离操作,这里只能选择当前流程中已经存在的隔离点位
  358. if (type == "releaseIsolation") {
  359. enabled = false
  360. // 增加隔离点选择列表
  361. list += FormField(
  362. id.toString(),
  363. type = "select",
  364. label = "选择隔离节点",
  365. name = "isolationNode",
  366. required = true,
  367. placeholder = listOf("请选择隔离节点"),
  368. options = isolations.map { FormOption(it?.nodeName ?: "", value = it?.uuid ?: "") },
  369. value = if (isolationNodeUuid.isNullOrEmpty()) listOf() else listOf(isolationNodeUuid)
  370. )
  371. // 如果是解除隔离的操作,这里需要先校验选择的节点是否是拆除
  372. isLockerTemp = isolationType == "1"
  373. }
  374. // 抽取隔离方式value值
  375. val valueOfIsolationType = if (isolationType.isNullOrEmpty()) {
  376. listOf()
  377. // val type = dataMap["isolationMethod"]
  378. // if (type == null) listOf() else listOf("$type")
  379. } else listOf(isolationType)
  380. // 隔离方式
  381. list += FormField(
  382. id.toString(),
  383. "select",
  384. "隔离方式",
  385. "isolationType",
  386. true,
  387. placeholder = listOf("请选择隔离方式"),
  388. options = isolationMethodList.map { FormOption(it.label, it.value) },
  389. value = valueOfIsolationType,
  390. enabled = enabled
  391. )
  392. // 抽取隔离点位value值
  393. val points = if (isolationPoints.isNullOrEmpty()) "" else isolationPoints.replace("[", "").replace("]", "")
  394. val valueOfIsolationPoints = if (points.isNotEmpty()) {
  395. points.split(",")
  396. } else {
  397. listOf()
  398. // when (val value = dataMap["isolationPoints"]) {
  399. // // 如果是数组
  400. // is List<*> -> value.map { "$it".toFloat().toInt().toString() }
  401. // // 如果是String
  402. // is String -> {
  403. // value.replace("[", "").replace("]", "").split(",")
  404. // }
  405. // // 其他不处理
  406. // else -> listOf()
  407. // }
  408. }
  409. // 隔离点选择,可多选
  410. list += FormField(
  411. id.toString(),
  412. "select",
  413. "隔离点选择(可多选)",
  414. "isolationPoints",
  415. true,
  416. listOf("请选择隔离点"),
  417. multiSelect = true,
  418. options = isolationList.map { FormOption(it.pointName, it.id.toString()) },
  419. value = valueOfIsolationPoints,
  420. enabled = enabled
  421. )
  422. if (isLockerTemp) {
  423. val locker = nodeUserList?.find { it.type == "jtlocker" }
  424. val group = nodeUserList?.filter { it.type == "jtcolocker" } ?: emptyList()
  425. // 上锁人
  426. list += FormField(
  427. id.toString(),
  428. "select",
  429. "上锁人",
  430. "locker",
  431. true,
  432. placeholder = listOf("请选择上锁人"),
  433. options = lockerUserList.map { FormOption(it.nickname, it.id.toString()) },
  434. value = if (locker != null) listOf(locker.userId.toString()) else listOf(),
  435. enabled = enabled
  436. )
  437. // 共锁人
  438. list += FormField(
  439. id.toString(),
  440. "select",
  441. "共锁人(可多选)",
  442. "group",
  443. false,
  444. placeholder = listOf("请选择共锁人"),
  445. options = groupUserList.map { FormOption(it.nickname, it.id.toString()) },
  446. value = if (group.isNotEmpty()) group.map { it.userId.toString() } else listOf(),
  447. multiSelect = true,
  448. enabled = enabled
  449. )
  450. } else {
  451. // 负责人
  452. list += FormField(
  453. id.toString(),
  454. "select",
  455. "负责人",
  456. "workerUserId",
  457. true,
  458. placeholder = listOf("请选择负责人"),
  459. options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
  460. value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf(),
  461. enabled = enabled
  462. )
  463. }
  464. }
  465. val notices = arrayListOf<String>()
  466. if (smsTemplateCode == "true") notices += "sms"
  467. if (messageTemplateCode == "true") notices += "message"
  468. if (emailTemplateCode == "true") notices += "email"
  469. if (appTemplateCode == "true") notices += "app"
  470. // 通知方式
  471. list += FormField(
  472. id.toString(), "checkbox", "通知方式", "noticeType", false, listOf(), notices,
  473. options = listOf(
  474. FormOption("短信", "sms"),
  475. FormOption("站内信", "message"),
  476. FormOption("邮件", "email"),
  477. FormOption("App通知", "app"),
  478. )
  479. )
  480. // // 通知人
  481. // list += FormField(
  482. // id.toString(), "select", "通知人", nodeName, false, listOf(), options = listOf(
  483. // FormOption("任务负责人", "p1"),
  484. // FormOption("任务参与人", "p2"),
  485. // FormOption("任务负责和参与人", "all"),
  486. // FormOption("指定人", "custom"),
  487. // )
  488. // )
  489. // // 通知时间
  490. // list += FormField(
  491. // id.toString(), "select", "通知时间", nodeName, false, listOf(), options = listOf(
  492. // FormOption("任务开始前30分钟", "0.5"),
  493. // FormOption("任务开始前1小时", "1"),
  494. // FormOption("任务开始前2小时", "2"),
  495. // FormOption("任务开始前5小时", "5"),
  496. // )
  497. // )
  498. return list
  499. }
  500. /**
  501. * 获取node图标,暂时本地通过type获取
  502. */
  503. fun getIcon(): Int {
  504. // Log.d("xiaoming", "节点类型:$type")
  505. return when (type) {
  506. // 开始/创建
  507. "createJob" -> R.drawable.node_icon_create_job
  508. // 审核
  509. "review" -> R.drawable.node_icon_review
  510. // 确认
  511. "confirm" -> R.drawable.node_icon_confirm
  512. // 录入信息
  513. "inputInfo" -> R.drawable.node_icon_input_info
  514. // 隔离
  515. "isolation" -> R.drawable.node_icon_isolation
  516. // 解除隔离
  517. "releaseIsolation" -> R.drawable.node_icon_release_isolation
  518. // 还锁
  519. "returnLock" -> R.drawable.node_icon_return_lock
  520. // 结束
  521. "complete" -> R.drawable.node_icon_complete
  522. else -> R.drawable.tips
  523. }
  524. }
  525. }
  526. /**
  527. * 任务表单信息
  528. */
  529. @Serializable
  530. data class TaskFormInfo(
  531. val id: Int = 0,
  532. val name: String? = null,
  533. val conf: String? = null,
  534. val fields: List<String>? = null,
  535. val status: Int? = null,
  536. val remark: String? = null,
  537. val createTime: Long? = null
  538. )
  539. /**
  540. * 作业基类信息
  541. */
  542. @Serializable
  543. data class Job(
  544. val id: Int = -1, // 作业Id
  545. val orderNo: String = "", // 作业编号
  546. val name: String = "", // 作业名称
  547. val type: String = "", // 作业类型
  548. val typeName: String = "", // 作业类型名称,服务端不返回,本地使用
  549. val urgencyLevel: String = "", // 紧急等级
  550. val designId: Int = -1, // sopId
  551. val designName: String = "", // 设计模板
  552. val designContent: String? = null, // sopInfo
  553. val description: String = "", // 描述
  554. val initiatorId: Int = -1, // 创建者id
  555. val initiatorName: String = "", // 创建者名称
  556. val initiatorTime: Long = -1L, // 创建者创建时间
  557. val status: String = "", // 作业状态
  558. val createTime: Long = -1L, // 创建时间
  559. val currentNodeId: String? = null,
  560. val currentNodeName: String? = null,
  561. val completionTime: Long? = null,
  562. val cancellationTime: Long? = null,
  563. val cancellationReason: String? = null,
  564. val workflowWorkNodeDOList: List<Node>? = null
  565. ) : java.io.Serializable {
  566. /**
  567. * 将接口返回的node转换为可显示的Node
  568. */
  569. fun toUINodeMap(): SnapshotStateMap<String, NodeUI> {
  570. val json = Json { ignoreUnknownKeys = true }
  571. val map = SnapshotStateMap<String, NodeUI>()
  572. workflowWorkNodeDOList?.forEach {
  573. val pos = json.decodeFromString<NodePositon>(it.position)
  574. map[it.id.toString()] = NodeUI(it.id.toString(), Offset(pos.x, pos.y), node = it)
  575. }
  576. return map
  577. }
  578. fun String.toAnchor(): Anchor {
  579. return when (this) {
  580. "left-source" -> Anchor.LEFT
  581. "right-source" -> Anchor.RIGHT
  582. "top-source" -> Anchor.TOP
  583. "bottom-source" -> Anchor.BOTTOM
  584. "left-target" -> Anchor.LEFT
  585. "right-target" -> Anchor.RIGHT
  586. "top-target" -> Anchor.TOP
  587. "bottom-target" -> Anchor.BOTTOM
  588. else -> if (this.contains("source")) Anchor.LEFT else Anchor.RIGHT
  589. }
  590. }
  591. /**
  592. * 将api连线数据转化为UI层连线数据
  593. */
  594. fun toUIConnectList(): List<Connection> {
  595. val connections = ArrayList<Connection>()
  596. val json = Json { ignoreUnknownKeys = true }
  597. val nodeInfo: NodeInfo = json.decodeFromString(designContent?.ifEmpty { "{}" } ?: "{}")
  598. nodeInfo.edges.forEach {
  599. val fromUuid = it.target
  600. val toUuid = it.source
  601. val fromId = workflowWorkNodeDOList?.find { node -> node.uuid == fromUuid }?.id ?: 0
  602. val fromAnchor = it.targetHandle.toAnchor()
  603. val toId = workflowWorkNodeDOList?.find { node -> node.uuid == toUuid }?.id ?: 0
  604. val toAnchor = it.sourceHandle.toAnchor()
  605. connections.add(Connection(fromId.toString(), toId.toString(), fromAnchor, toAnchor))
  606. }
  607. return connections
  608. }
  609. /**
  610. * 获取等级名称和背景色
  611. */
  612. fun getLevelNameAndColor(): Pair<String, Color> {
  613. return when (urgencyLevel) {
  614. "1" -> "紧急" to Color(0xFFFF9800)
  615. "2" -> "非常紧急" to Color(0xFFFF4500)
  616. else -> "正常" to Color(0xFF1E90FF)
  617. }
  618. }
  619. /**
  620. * 获取任务状态名称
  621. */
  622. fun getJobStatusName(): String {
  623. return when (status) {
  624. "unreleased" -> "待发布"
  625. "approved" -> "已审核"
  626. "running" -> "进行中"
  627. "completed" -> "已完成"
  628. else -> status
  629. }
  630. }
  631. }
  632. /**
  633. * Task任务
  634. */
  635. @Serializable
  636. data class Task(
  637. val workId: Int,
  638. val nodeId: Int,
  639. val orderNo: String,
  640. val name: String,
  641. val urgencyLevel: String,
  642. val completionTime: Long?,
  643. val cancellationTime: Long?,
  644. val cancellationReason: String?,
  645. val initiatorName: String?, // 发起人
  646. val workerUserName: String?, // 当前执行人
  647. val workTime: Long?,
  648. val currentNodeId: String?,
  649. val currentNodeName: String?,
  650. val approvalStatus: String
  651. ) : java.io.Serializable
  652. /**
  653. * 消息结构体
  654. */
  655. @Serializable
  656. data class Message(
  657. val id: Int = 0,
  658. val userId: Int = 0,
  659. val userType: Int = 0,
  660. val readStatus: Boolean = false,
  661. val createTime: Long = -1L,
  662. val title: String? = null,
  663. val templateContent: String = "",
  664. val isTitle: Boolean = false,
  665. )
  666. /**
  667. * 表单需要的组件
  668. *
  669. * @param id
  670. * @param type
  671. * @param label
  672. * @param name
  673. * @param required
  674. * @param placeholder
  675. * @param options
  676. * @param cardTitle
  677. * @param gridColumns
  678. * @param children
  679. */
  680. @Serializable
  681. data class FormField(
  682. val id: String = "",
  683. val type: String = "",
  684. val label: String = "",
  685. val name: String = "",
  686. val required: Boolean = false,
  687. @Serializable(with = StringToListSerializer::class)
  688. val placeholder: List<String> = listOf(),
  689. @Serializable(with = StringToListSerializer::class)
  690. var value: List<String> = listOf(),
  691. var options: List<FormOption> = listOf(),
  692. val cardTitle: String = "",
  693. val gridColumns: Int = 0,
  694. val enabled: Boolean = true,
  695. val multiSelect: Boolean = false,
  696. val children: List<FormField> = listOf()
  697. )
  698. /**
  699. * 表单Option字段
  700. *
  701. * @param label 标题
  702. * @param value 数值
  703. */
  704. @Serializable
  705. data class FormOption(val label: String = "", val value: String = "")
  706. /**
  707. * 节点位置信息
  708. */
  709. @Serializable
  710. data class NodePositon(val x: Float, val y: Float)
  711. /**
  712. * 节点信息
  713. */
  714. @Serializable
  715. data class NodeInfo(val edgeCount: Int, val edges: List<NodeConnection>)
  716. /**
  717. * 节点连接线信息
  718. */
  719. @Serializable
  720. data class NodeConnection(
  721. val id: String,
  722. val source: String,
  723. val target: String,
  724. val sourceHandle: String,
  725. val targetHandle: String,
  726. val type: String
  727. )