| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566 |
- package com.iscs.bozzys.api
- import android.util.Log
- import com.iscs.bozzys.R
- import com.iscs.bozzys.ui.pages.edit.step.compose.NodeUI
- import com.iscs.bozzys.utils.StringToListSerializer
- import kotlinx.serialization.Serializable
- import kotlinx.serialization.encodeToString
- import kotlinx.serialization.json.Json
- /**
- * 流程节点
- */
- @Serializable
- data class Node(
- val id: Int = 0,
- val workId: Int = 0,
- val uuid: String = "",
- val parentUuid: String = "",
- val childrenUuid: String = "",
- val nodeName: String = "",
- val nodeIcon: String = "",
- val type: String = "",
- val position: String = "",
- val data: String = "",
- val description: String? = null,
- val workerUserId: Int = 0,
- val workerGroupId: Int? = null,
- val formId: Int = 0,
- val formData: String? = null,
- val createTime: Long = 0L,
- val approvalStatus: String = "",
- val approvalOpinion: String = "",
- val isolationType: String? = null, // 隔离类型
- val isolationPoints: String? = null, // 解除隔离的点位
- val isolationNodeUuid: String? = null, // 解除隔离关联的节点uuid
- val nodeUserList: List<User>? = null, // 隔离和解除隔离关联的上锁人和共锁人
- val smsTemplateCode: String? = null, // 短信通知
- val messageTemplateCode: String? = null, // 站内信息
- val emailTemplateCode: String? = null, // 邮件通知
- val appTemplateCode: String? = null, // app消息推送
- val deviceNumber: String? = null, // 设备序列号
- val attachments: String? = null, // 携带的数据
- val points: List<IsolationPoint>? = null, // 隔离点位信息
- val keys: List<Key>? = null, // 隔离点位参与的挂锁
- val locks: List<Lock>? = null, // 隔离点位参与的钥匙
- ) {
- /**
- * 校验是否可以通过手机进行操作
- */
- fun checkCanOptionByPhone(): Boolean {
- return !(listOf("lock", "unlock", "coLock","unlockCoLock").contains(type) && !listOf("0", "2").contains(isolationType))
- }
- /**
- * 校验请求参数
- *
- * @param forms 表单数据
- */
- fun checkCanSubmit(forms: List<FormField>): String {
- forms.forEach {
- Log.d("NodeOption", "checkCanSubmit -> $it")
- if (it.required) {
- if ((it.value.getOrNull(0) ?: "").isEmpty()) {
- return (it.placeholder.getOrNull(0) ?: "").ifEmpty { "请填写${it.label}" }
- }
- }
- }
- return ""
- }
- /**
- * 构建请求参数
- *
- * @param forms 表单数据
- */
- fun buildSubmitParams(forms: List<FormField>, workFormList: List<TaskFormInfo>): MutableMap<String, Any?> {
- val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
- val params = mutableMapOf<String, Any?>("nodeId" to id, "nodeName" to nodeName)
- if (type != "createJob") {
- val workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
- val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "0"
- val findWork = workFormList.find { it.id == formId.toInt() }
- val formData = if (findWork != null) Json.encodeToString(findWork) else null
- val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
- params["workerUserId"] = workerUserId.toInt()
- params["formId"] = formId.toInt()
- params["formData"] = formData
- // 处理隔离点信息表单
- if (listOf("isolation", "releaseIsolation").contains(type)) {
- val isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0) ?: "-1"
- val isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
- if (isolationType == "1") {
- // 移除负责人
- params.remove("workerUserId")
- // 上锁人和共锁人
- val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
- val group = forms.find { it.name == "group" }?.value ?: emptyList()
- val userList = mutableListOf<MutableMap<String, Any>>()
- if (locker.toInt() > 0) userList += mutableMapOf("userId" to locker.toInt(), "type" to "jtlocker")
- group.forEach { userList += mutableMapOf("userId" to it.toInt(), "type" to "jtcolocker") }
- params["nodeUserDOList"] = userList
- }
- params["isolationType"] = isolationType
- params["isolationPoints"] = isolationPoints.joinToString(
- prefix = "[",
- postfix = "]",
- separator = ","
- )
- if (type == "releaseIsolation") {
- val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
- // 解除隔离,这里需要填写关联的节点uuid
- params["isolationNodeUuid"] = isolationNode
- }
- }
- // 通知方式
- // 短信
- params["smsTemplateCode"] = if (noticeType.contains("sms")) "true" else "false"
- // 站内信
- params["messageTemplateCode"] = if (noticeType.contains("message")) "true" else "false"
- // 邮件
- params["emailTemplateCode"] = if (noticeType.contains("email")) "true" else "false"
- // app通知
- params["appTemplateCode"] = if (noticeType.contains("app")) "true" else "false"
- }
- return params
- }
- /**
- * 更新节点信息
- *
- * @param forms
- */
- fun updateNodeInfo(forms: List<FormField>, nodes: List<NodeUI>): Node {
- val nodeName = forms.find { it.name == "nodeName" }?.value?.getOrNull(0) ?: ""
- if (type != "createJob") {
- // 解析关联表单
- val formId = forms.find { it.name == "formId" }?.value?.getOrNull(0) ?: "-1"
- // 解析表单数据
- val formData = forms.find { it.name == "formData" }?.value?.getOrNull(0)
- // 解析负责人
- var workerUserId = forms.find { it.name == "workerUserId" }?.value?.getOrNull(0) ?: "0"
- // 解析隔离方式
- var isolationType = forms.find { it.name == "isolationType" }?.value?.getOrNull(0)
- // 解析点位
- var isolationPoints = forms.find { it.name == "isolationPoints" }?.value ?: emptyList()
- // 解析上锁人
- val locker = forms.find { it.name == "locker" }?.value?.getOrNull(0) ?: "-1"
- // 解析共锁人
- val group = forms.find { it.name == "group" }?.value ?: emptyList()
- // 构建上锁人和共锁人列表
- val userList = mutableListOf<User>()
- if (locker.toInt() > 0) userList += User(userId = locker.toInt(), type = "jtlocker")
- if (group.isNotEmpty()) group.forEach { userList += User(userId = it.toInt(), type = "jtcolocker") }
- // 解析隔离节点
- val isolationNode = forms.find { it.name == "isolationNode" }?.value?.getOrNull(0)
- // 如果是解除隔离操作,隔离方式、隔离点位、负责人(或者上锁人、解锁人)需要从选中的点位中获取
- if (type == "releaseIsolation") {
- nodes.find { it.node?.uuid == isolationNode }?.node?.let {
- // 从节点中将数据copy到当前节点
- workerUserId = "${it.workerUserId}"
- isolationType = it.isolationType
- isolationPoints = if (it.isolationPoints.isNullOrEmpty()) {
- emptyList()
- } else {
- it.isolationPoints.replace("[", "").replace("]", "").split(",")
- }
- userList.addAll(it.nodeUserList ?: emptyList())
- }
- }
- // 通知方式
- val noticeType = forms.find { it.name == "noticeType" }?.value ?: emptyList()
- return Node(
- id = id,
- workId = workId,
- uuid = uuid,
- parentUuid = parentUuid,
- childrenUuid = childrenUuid,
- nodeName = nodeName,
- type = type,
- position = position,
- workerUserId = workerUserId.toInt(),
- formId = formId.toInt(),
- formData = formData,
- isolationType = isolationType,
- isolationPoints = isolationPoints.joinToString(
- prefix = "[",
- postfix = "]",
- separator = ","
- ),
- isolationNodeUuid = isolationNode,
- nodeUserList = if (userList.isEmpty()) null else userList,
- smsTemplateCode = if (noticeType.contains("sms")) "true" else "false",
- messageTemplateCode = if (noticeType.contains("message")) "true" else "false",
- emailTemplateCode = if (noticeType.contains("email")) "true" else "false",
- appTemplateCode = if (noticeType.contains("app")) "true" else "false"
- )
- }
- return Node(
- id = id,
- workId = workId,
- uuid = uuid,
- parentUuid = parentUuid,
- childrenUuid = childrenUuid,
- nodeName = nodeName,
- type = type,
- position = position
- )
- }
- /**
- * 构建表单列表
- *
- * @param workerUserList 负责人列表
- * @param lockerUserList 上锁人列表
- * @param groupUserList 共锁人列表
- * @param workFormList 工作表单列表
- * @param isolationMethodList 获取隔离方式列表
- * @param isolationList 点位列表
- * @param isLocker 是否上锁人
- */
- fun buildFormList(
- workerUserList: List<User>,
- lockerUserList: List<User>,
- groupUserList: List<User>,
- workFormList: List<TaskFormInfo>,
- isolationMethodList: List<Dict>,
- isolationList: List<IsolationPoint>,
- nodes: List<NodeUI> = listOf(),
- isLocker: Boolean = false,
- ): List<FormField> {
- Log.d("NodeOption", "buildFormList -> $this")
- val list = ArrayList<FormField>()
- // 添加节点名称
- list += FormField(
- id.toString(),
- "input",
- "节点名称",
- name = "nodeName",
- true,
- value = listOf(nodeName),
- placeholder = listOf("请输入节点名称")
- )
- if (type == "createJob") return list
- // 添加节点负责人
- list += FormField(
- id.toString(),
- "select",
- "负责人",
- "workerUserId",
- true,
- placeholder = listOf("请选择负责人"),
- options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
- value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf()
- )
- // 添加业务表单
- list += FormField(
- id.toString(),
- "select",
- "业务表单",
- name = "formId",
- true,
- placeholder = listOf("请选择业务表单"),
- options = workFormList.map { FormOption(it.name ?: "", it.id.toString()) },
- value = if (formId > 0) listOf(formId.toString()) else listOf()
- )
- // 隔离配置
- if (listOf("isolation", "releaseIsolation").contains(type)) {
- // 先移除负责人,需要在后面进行添加
- list.removeIf { it.name == "workerUserId" }
- // 而且业务表单非必填
- val formField = list.find { it.name == "formId" }?.copy(required = false)
- list.removeIf { it.name == "formId" }
- formField?.let { list.add(it) }
- val isolations = nodes.map { it.node }.filter { it != null && it.type == "isolation" }
- var enabled = true
- var isLockerTemp = isLocker
- // 如果是解除隔离操作,这里只能选择当前流程中已经存在的隔离点位
- if (type == "releaseIsolation") {
- enabled = false
- // 增加隔离点选择列表
- list += FormField(
- id.toString(),
- type = "select",
- label = "选择隔离节点",
- name = "isolationNode",
- required = true,
- placeholder = listOf("请选择隔离节点"),
- options = isolations.map { FormOption(it?.nodeName ?: "", value = it?.uuid ?: "") },
- value = if (isolationNodeUuid.isNullOrEmpty()) listOf() else listOf(isolationNodeUuid)
- )
- // 如果是解除隔离的操作,这里需要先校验选择的节点是否是拆除
- isLockerTemp = isolationType == "1"
- }
- // 抽取隔离方式value值
- val valueOfIsolationType = if (isolationType.isNullOrEmpty()) {
- listOf()
- // val type = dataMap["isolationMethod"]
- // if (type == null) listOf() else listOf("$type")
- } else listOf(isolationType)
- // 隔离方式
- list += FormField(
- id.toString(),
- "select",
- "隔离方式",
- "isolationType",
- true,
- placeholder = listOf("请选择隔离方式"),
- options = isolationMethodList.map { FormOption(it.label, it.value) },
- value = valueOfIsolationType,
- enabled = enabled
- )
- // 抽取隔离点位value值
- val points = if (isolationPoints.isNullOrEmpty()) "" else isolationPoints.replace("[", "").replace("]", "")
- val valueOfIsolationPoints = if (points.isNotEmpty()) {
- points.split(",")
- } else {
- listOf()
- // when (val value = dataMap["isolationPoints"]) {
- // // 如果是数组
- // is List<*> -> value.map { "$it".toFloat().toInt().toString() }
- // // 如果是String
- // is String -> {
- // value.replace("[", "").replace("]", "").split(",")
- // }
- // // 其他不处理
- // else -> listOf()
- // }
- }
- // 隔离点选择,可多选
- list += FormField(
- id.toString(),
- "select",
- "隔离点选择(可多选)",
- "isolationPoints",
- true,
- listOf("请选择隔离点"),
- multiSelect = true,
- options = isolationList.map { FormOption(it.pointName ?: "", it.id.toString()) },
- value = valueOfIsolationPoints,
- enabled = enabled
- )
- if (isLockerTemp) {
- var locker = nodeUserList?.find { it.type == "jtlocker" }
- var group = nodeUserList?.filter { it.type == "jtcolocker" } ?: emptyList()
- // 如果是解除隔离,且当前解锁和工作人列表为空,需要默认配置
- if (type == "releaseIsolation" && nodeUserList.isNullOrEmpty()) {
- val bindNode = nodes.find { it.node?.uuid == isolationNodeUuid && !isolationNodeUuid.isNullOrEmpty() }
- val nodeUserList = bindNode?.node?.nodeUserList
- locker = nodeUserList?.find { it.type == "jtlocker" }
- group = nodeUserList?.filter { it.type == "jtcolocker" } ?: emptyList()
- }
- // 上锁人
- list += FormField(
- id.toString(),
- "select",
- "上锁人",
- "locker",
- true,
- placeholder = listOf("请选择上锁人"),
- options = lockerUserList.map { FormOption(it.nickname, it.id.toString()) },
- value = if (locker != null) listOf(locker.userId.toString()) else listOf(),
- enabled = enabled
- )
- // 共锁人
- list += FormField(
- id.toString(),
- "select",
- "共锁人(可多选)",
- "group",
- false,
- placeholder = listOf("请选择共锁人"),
- options = groupUserList.map { FormOption(it.nickname, it.id.toString()) },
- value = if (group.isNotEmpty()) group.map { it.userId.toString() } else listOf(),
- multiSelect = true,
- enabled = enabled
- )
- } else {
- // 负责人
- list += FormField(
- id.toString(),
- "select",
- "负责人",
- "workerUserId",
- true,
- placeholder = listOf("请选择负责人"),
- options = workerUserList.map { FormOption(it.nickname, it.id.toString()) },
- value = if (workerUserId > 0) listOf(workerUserId.toString()) else listOf(),
- enabled = enabled
- )
- }
- }
- val notices = arrayListOf<String>()
- if (smsTemplateCode == "true") notices += "sms"
- if (messageTemplateCode == "true") notices += "message"
- if (emailTemplateCode == "true") notices += "email"
- if (appTemplateCode == "true") notices += "app"
- // 通知方式
- list += FormField(
- id.toString(), "checkbox", "通知方式", "noticeType", false, listOf(), notices,
- options = listOf(
- FormOption("短信", "sms"),
- FormOption("站内信", "message"),
- FormOption("邮件", "email"),
- FormOption("App通知", "app"),
- )
- )
- // // 通知人
- // list += FormField(
- // id.toString(), "select", "通知人", nodeName, false, listOf(), options = listOf(
- // FormOption("任务负责人", "p1"),
- // FormOption("任务参与人", "p2"),
- // FormOption("任务负责和参与人", "all"),
- // FormOption("指定人", "custom"),
- // )
- // )
- // // 通知时间
- // list += FormField(
- // id.toString(), "select", "通知时间", nodeName, false, listOf(), options = listOf(
- // FormOption("任务开始前30分钟", "0.5"),
- // FormOption("任务开始前1小时", "1"),
- // FormOption("任务开始前2小时", "2"),
- // FormOption("任务开始前5小时", "5"),
- // )
- // )
- return list
- }
- /**
- * 获取node图标,暂时本地通过type获取
- */
- fun getIcon(): Int {
- return when (type) {
- // 开始/创建
- "createJob" -> R.drawable.node_icon_create_job
- // 审核
- "review" -> R.drawable.node_icon_review
- // 确认
- "confirm" -> R.drawable.node_icon_confirm
- // 录入信息
- "inputInfo" -> R.drawable.node_icon_input_info
- // 隔离
- "isolation" -> R.drawable.node_icon_isolation
- // 解除隔离
- "releaseIsolation" -> R.drawable.node_icon_release_isolation
- // 还锁
- "returnLock" -> R.drawable.node_icon_return_lock
- // 结束
- "complete" -> R.drawable.node_icon_complete
- else -> R.drawable.tips
- }
- }
- /**
- * 将作业票转换为JSON
- */
- fun toKeyTicket(lockList: List<Lock>): String {
- val json = Json {
- // 格式化默认值
- encodeDefaults = true
- // 去除字段为null的字段
- explicitNulls = false
- }
- val target = if (type == "releaseIsolation") 1 else 0
- // 锁具id构成
- var lockId = 0
- val keyTicket = KeyTicket(
- data = listOf(
- TicketTask(
- taskId = id.toString(),
- codeId = id,
- dataList = points?.map { point ->
- TicketPoint(
- dataId = point.id,
- equipName = point.pointName ?: point.pointNfc,
- equipRfidNo = point.pointNfc,
- target = target,
- infoRfidNo = point.lockNfc
- )
- } ?: emptyList())
- ),
- lockList = lockList.map { lock ->
- lockId++
- TicketLock(lockId = lockId, rfid = lock.lockNfc)
- })
- return json.encodeToString(keyTicket)
- }
- }
- /**
- * 表单需要的组件
- *
- * @param id
- * @param type
- * @param label
- * @param name
- * @param required
- * @param placeholder
- * @param options
- * @param cardTitle
- * @param gridColumns
- * @param children
- */
- @Serializable
- data class FormField(
- val id: String = "",
- val type: String = "",
- val label: String = "",
- val name: String = "",
- val required: Boolean = false,
- @Serializable(with = StringToListSerializer::class)
- val placeholder: List<String> = listOf(),
- @Serializable(with = StringToListSerializer::class)
- var value: List<String> = listOf(),
- var options: List<FormOption> = listOf(),
- val cardTitle: String = "",
- val gridColumns: Int = 0,
- val enabled: Boolean = true,
- val multiSelect: Boolean = false,
- val children: List<FormField> = listOf(),
- val maxCount: Int? = null, // 文件上传的最大限制个数
- val uploadType: String? = "file" // 上传文件类型
- )
- /**
- * 表单Option字段
- *
- * @param label 标题
- * @param value 数值
- */
- @Serializable
- data class FormOption(val label: String = "", val value: String = "")
- /**
- * 节点位置信息
- */
- @Serializable
- data class NodePositon(val x: Float, val y: Float)
- /**
- * 节点信息
- */
- @Serializable
- data class NodeInfo(val edgeCount: Int, val edges: List<NodeConnection>)
- /**
- * 节点连接线信息
- */
- @Serializable
- data class NodeConnection(
- val id: String,
- val source: String,
- val target: String,
- val sourceHandle: String,
- val targetHandle: String,
- val type: String
- )
- /**
- * 拆除盲板需要的字段
- */
- @Serializable
- data class Attachment(val name: String = "", val url: String = "")
|