|
|
@@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.offset
|
|
|
import androidx.compose.foundation.layout.padding
|
|
|
import androidx.compose.foundation.layout.size
|
|
|
import androidx.compose.foundation.lazy.LazyColumn
|
|
|
-import androidx.compose.foundation.lazy.items
|
|
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
|
import androidx.compose.material3.Button
|
|
|
import androidx.compose.material3.Icon
|
|
|
@@ -34,17 +33,13 @@ import androidx.compose.material3.Text
|
|
|
import androidx.compose.runtime.Composable
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
|
|
import androidx.compose.runtime.SideEffect
|
|
|
+import androidx.compose.runtime.collectAsState
|
|
|
import androidx.compose.runtime.getValue
|
|
|
-import androidx.compose.runtime.mutableStateListOf
|
|
|
-import androidx.compose.runtime.mutableStateMapOf
|
|
|
-import androidx.compose.runtime.mutableStateOf
|
|
|
import androidx.compose.runtime.remember
|
|
|
import androidx.compose.runtime.rememberCoroutineScope
|
|
|
-import androidx.compose.runtime.setValue
|
|
|
import androidx.compose.ui.Alignment
|
|
|
import androidx.compose.ui.Modifier
|
|
|
import androidx.compose.ui.draw.clip
|
|
|
-import androidx.compose.ui.geometry.Offset
|
|
|
import androidx.compose.ui.graphics.Color
|
|
|
import androidx.compose.ui.graphics.graphicsLayer
|
|
|
import androidx.compose.ui.platform.LocalContext
|
|
|
@@ -58,23 +53,15 @@ import androidx.compose.ui.window.Dialog
|
|
|
import androidx.compose.ui.window.DialogProperties
|
|
|
import androidx.compose.ui.zIndex
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
+import androidx.lifecycle.viewmodel.compose.viewModel
|
|
|
import com.iscs.bozzys.R
|
|
|
-import com.iscs.bozzys.api.FormField
|
|
|
import com.iscs.bozzys.ui.base.PageBase
|
|
|
import com.iscs.bozzys.ui.base.Title
|
|
|
import com.iscs.bozzys.ui.pages.compose.CardContainer
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormDateRangeSelect
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormDateSelect
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormInput
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormRadio
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormSelect
|
|
|
-import com.iscs.bozzys.ui.pages.compose.FormTextarea
|
|
|
-import com.iscs.bozzys.ui.pages.compose.getFormListByJsonList
|
|
|
-import com.iscs.bozzys.ui.pages.edit.step.compose.Anchor
|
|
|
-import com.iscs.bozzys.ui.pages.edit.step.compose.Connection
|
|
|
-import com.iscs.bozzys.ui.pages.edit.step.compose.Node
|
|
|
+import com.iscs.bozzys.ui.pages.compose.FormContainer
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.NodeItem
|
|
|
import com.iscs.bozzys.ui.pages.edit.step.compose.ZoomPanContainer
|
|
|
+import com.iscs.bozzys.ui.pages.vm.VMEditStep
|
|
|
import com.iscs.bozzys.ui.theme.Text
|
|
|
import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.launch
|
|
|
@@ -82,140 +69,124 @@ import kotlinx.coroutines.launch
|
|
|
/**
|
|
|
* 跳转到编辑流程页面
|
|
|
*/
|
|
|
-fun Context.openPageEditStep() {
|
|
|
- startActivity(Intent(this, PageEditStep::class.java))
|
|
|
+fun Context.openPageEditStep(jobId: Int) {
|
|
|
+ // 传递作业票id进入页面
|
|
|
+ startActivity(Intent(this, PageEditStep::class.java).apply {
|
|
|
+ putExtra("job_id", jobId)
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
class PageEditStep : PageBase() {
|
|
|
@Composable
|
|
|
override fun GetViews(pv: PaddingValues) {
|
|
|
- val nodes = remember { mutableStateMapOf<String, Node>() }
|
|
|
- val selectNode = remember { mutableStateOf(Node("-1", Offset(0f, 0f))) }
|
|
|
- val lines = listOf(
|
|
|
- Connection("A", "B", fromAnchor = Anchor.BOTTOM, toAnchor = Anchor.TOP),
|
|
|
- Connection("A", "D", fromAnchor = Anchor.BOTTOM, toAnchor = Anchor.TOP),
|
|
|
- Connection("B", "C", fromAnchor = Anchor.BOTTOM, toAnchor = Anchor.TOP)
|
|
|
- )
|
|
|
- var showFormDialog by remember { mutableStateOf(false) }
|
|
|
- // 处理显示的表单
|
|
|
- val json =
|
|
|
- "[{\"id\":\"field_1766037799194\",\"type\":\"card\",\"label\":\"卡片容器\",\"name\":\"field1766037799194\",\"required\":false,\"placeholder\":\"\",\"options\":[],\"cardTitle\":\"卡片容器\",\"children\":[{\"id\":\"field_1766037802805\",\"type\":\"grid\",\"label\":\"双栏布局\",\"name\":\"field1766037802805\",\"required\":false,\"placeholder\":\"\",\"options\":[],\"gridColumns\":2,\"children\":[{\"id\":\"field_1766037804595\",\"type\":\"textarea\",\"label\":\"字段2\",\"name\":\"field1766037804595\",\"required\":false,\"placeholder\":\"请输入内容\",\"options\":[]},{\"id\":\"field_1766037807731\",\"type\":\"input\",\"label\":\"字段2\",\"name\":\"field1766037807731\",\"required\":false,\"placeholder\":\"请输入\",\"options\":[]}]}]},{\"id\":\"field_1766038059114\",\"type\":\"select\",\"label\":\"字段2\",\"name\":\"field1766038059114\",\"required\":false,\"placeholder\":\"请选择\",\"options\":[{\"label\":\"选项1\",\"value\":\"option1\"},{\"label\":\"选项2\",\"value\":\"option2\"}]},{\"id\":\"field_1766038062137\",\"type\":\"date\",\"label\":\"字段3\",\"name\":\"field1766038062137\",\"required\":false,\"placeholder\":\"请选择日期\",\"options\":[]},{\"id\":\"field_1766473806339\",\"type\":\"radio\",\"label\":\"字段4\",\"name\":\"field1766473806339\",\"required\":false,\"options\":[{\"label\":\"选项1\",\"value\":\"option1\"},{\"label\":\"选项2\",\"value\":\"option2\"}]}]"
|
|
|
- val fields = remember { mutableStateListOf<FormField>() }
|
|
|
- fields.addAll(json.getFormListByJsonList())
|
|
|
+ val vm: VMEditStep = viewModel()
|
|
|
+ val state by vm.state.collectAsState()
|
|
|
LaunchedEffect(Unit) {
|
|
|
- nodes["A"] = Node("A", Offset(125f, -100f))
|
|
|
- nodes["B"] = Node("B", Offset(50f, 0f))
|
|
|
- nodes["D"] = Node("D", Offset(200f, 0f))
|
|
|
- nodes["C"] = Node("C", Offset(50f, 100f))
|
|
|
- // 默认选中第一个节点
|
|
|
- nodes["A"]?.let { selectNode.value = it }
|
|
|
+ vm.toast.showToast()
|
|
|
+ vm.loading.showLoading()
|
|
|
+ vm.init(intent.getIntExtra("job_id", 0))
|
|
|
}
|
|
|
Column(Modifier.fillMaxSize()) {
|
|
|
Title(pv, "作业流程管理")
|
|
|
- ZoomPanContainer(nodes, lines, modifier = Modifier.fillMaxSize()) { scale, toTopCenter, toCenter, toLast ->
|
|
|
- // 控件显示
|
|
|
- Box(
|
|
|
- modifier = Modifier
|
|
|
- .fillMaxSize()
|
|
|
- .zIndex(3f),
|
|
|
- contentAlignment = Alignment.CenterStart
|
|
|
- ) {
|
|
|
- nodes.forEach {
|
|
|
- NodeItem(it.key, nodes, selectNode, { node ->
|
|
|
- selectNode.value = node
|
|
|
- // 将当前Node平移到屏幕中间
|
|
|
- toTopCenter(node)
|
|
|
- lifecycleScope.launch {
|
|
|
- // 给移动位置增加点动画效果
|
|
|
- delay(280)
|
|
|
- // 弹出Dialog
|
|
|
- showFormDialog = true
|
|
|
- }
|
|
|
- })
|
|
|
+ Box(Modifier.weight(1f)) {
|
|
|
+ ZoomPanContainer(state.nodes, state.connections, modifier = Modifier.fillMaxSize()) { scale, toTopCenter, toCenter, toLast ->
|
|
|
+ // 控件显示
|
|
|
+ Box(
|
|
|
+ modifier = Modifier
|
|
|
+ .fillMaxSize()
|
|
|
+ .zIndex(3f),
|
|
|
+ contentAlignment = Alignment.CenterStart
|
|
|
+ ) {
|
|
|
+ state.nodes.forEach {
|
|
|
+ NodeItem(it.key, state.nodes, state.node, { node ->
|
|
|
+ vm.updateNode(node)
|
|
|
+ // 将当前Node平移到屏幕中间
|
|
|
+ toTopCenter(node)
|
|
|
+ lifecycleScope.launch {
|
|
|
+ // 给移动位置增加点动画效果
|
|
|
+ delay(280)
|
|
|
+ // 弹出Dialog
|
|
|
+ vm.formDialogShow(true)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- // 底部弹出式的Dialog
|
|
|
- FormDialog(showFormDialog, {
|
|
|
- // 回到移动中心位置前的位置,默认不添加 等反馈
|
|
|
- toLast()
|
|
|
- showFormDialog = false
|
|
|
- }, pv) {
|
|
|
-
|
|
|
- // 监听键盘弹出事件
|
|
|
+ // 底部弹出式的Dialog
|
|
|
+ FormDialog(state.showFormDialog, {
|
|
|
+ // 回到移动中心位置前的位置,默认不添加 等反馈
|
|
|
+ toLast()
|
|
|
+ vm.formDialogShow(false)
|
|
|
+ }, pv) {
|
|
|
|
|
|
- val density = LocalDensity.current
|
|
|
- val imeInsets = WindowInsets.ime
|
|
|
- val imeBottom = imeInsets.getBottom(density)
|
|
|
+ // 监听键盘弹出事件
|
|
|
+ val density = LocalDensity.current
|
|
|
+ val imeInsets = WindowInsets.ime
|
|
|
+ val imeBottom = imeInsets.getBottom(density)
|
|
|
|
|
|
- Column(
|
|
|
- Modifier
|
|
|
- .fillMaxHeight(4 / 7f)
|
|
|
- .padding(horizontal = 16.dp)
|
|
|
- ) {
|
|
|
- Box(
|
|
|
+ Column(
|
|
|
Modifier
|
|
|
- .fillMaxSize()
|
|
|
- .weight(1f)
|
|
|
+ .fillMaxHeight(4 / 7f)
|
|
|
+ .padding(horizontal = 16.dp)
|
|
|
) {
|
|
|
- LazyColumn(
|
|
|
+ Box(
|
|
|
Modifier
|
|
|
- .imePadding()
|
|
|
- .padding(vertical = 5.dp)
|
|
|
+ .fillMaxSize()
|
|
|
+ .weight(1f)
|
|
|
) {
|
|
|
- items(fields) {
|
|
|
- when (it.type) {
|
|
|
- "input" -> FormInput(it.label, it.value, { sel -> it.value = sel }, it.placeholder, required = it.required)
|
|
|
- "textarea" -> FormTextarea(
|
|
|
- it.label,
|
|
|
- it.value,
|
|
|
- { sel -> it.value = sel },
|
|
|
- it.placeholder,
|
|
|
- required = it.required
|
|
|
- )
|
|
|
-
|
|
|
- "select" -> FormSelect(
|
|
|
- it.label,
|
|
|
- it.value,
|
|
|
- it.options,
|
|
|
- { sel -> it.value = sel }, required = it.required
|
|
|
- )
|
|
|
-
|
|
|
- "date" -> FormDateSelect(it.label, it.value, { sel -> it.value = sel }, required = it.required)
|
|
|
- // 起止日期选择
|
|
|
- "daterange" -> FormDateRangeSelect(
|
|
|
- it.label,
|
|
|
- it.value,
|
|
|
- { sel -> it.value = sel },
|
|
|
- placeholder = it.placeholder
|
|
|
- )
|
|
|
- // 单选框
|
|
|
- "radio" -> FormRadio(
|
|
|
- it.label,
|
|
|
- it.value,
|
|
|
- it.options,
|
|
|
- { sel -> it.value = sel }, required = it.required
|
|
|
- )
|
|
|
- }
|
|
|
+ LazyColumn(
|
|
|
+ Modifier
|
|
|
+ .imePadding()
|
|
|
+ .padding(vertical = 5.dp)
|
|
|
+ ) {
|
|
|
+ item { FormContainer(state.nodeForms) }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- if (imeBottom <= 0) {
|
|
|
- Spacer(Modifier.height(10.dp))
|
|
|
- Button(
|
|
|
- {},
|
|
|
- modifier = Modifier
|
|
|
- .fillMaxWidth()
|
|
|
- .height(50.dp)
|
|
|
- .clip(RoundedCornerShape(12.dp))
|
|
|
- .background(MaterialTheme.colorScheme.primary),
|
|
|
- shape = RoundedCornerShape(12.dp)
|
|
|
- ) {
|
|
|
- Text("保存", fontSize = 16.sp, fontWeight = FontWeight.Bold)
|
|
|
+ if (imeBottom <= 0) {
|
|
|
+ Spacer(Modifier.height(10.dp))
|
|
|
+ Button(
|
|
|
+ {},
|
|
|
+ modifier = Modifier
|
|
|
+ .fillMaxWidth()
|
|
|
+ .height(50.dp)
|
|
|
+ .clip(RoundedCornerShape(12.dp))
|
|
|
+ .background(MaterialTheme.colorScheme.primary),
|
|
|
+ shape = RoundedCornerShape(12.dp)
|
|
|
+ ) {
|
|
|
+ Text("保存", fontSize = 16.sp, fontWeight = FontWeight.Bold)
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ // 底部下一步按钮
|
|
|
+ Column(
|
|
|
+ Modifier
|
|
|
+ .fillMaxWidth()
|
|
|
+ .background(MaterialTheme.colorScheme.background)
|
|
|
+ .padding(top = 15.dp, bottom = (15f + pv.calculateBottomPadding().value).dp)
|
|
|
+ ) {
|
|
|
+ Button(
|
|
|
+ onClick = { }, modifier = Modifier
|
|
|
+ .padding(horizontal = 16.dp)
|
|
|
+ .fillMaxWidth()
|
|
|
+ .height(50.dp)
|
|
|
+ .clip(RoundedCornerShape(12.dp))
|
|
|
+ .background(MaterialTheme.colorScheme.primary),
|
|
|
+ shape = RoundedCornerShape(12.dp)
|
|
|
+ ) {
|
|
|
+ Row(verticalAlignment = Alignment.CenterVertically) {
|
|
|
+ Text("下一步", fontSize = 16.sp, fontWeight = FontWeight.Bold)
|
|
|
+ Icon(
|
|
|
+ painter = painterResource(R.drawable.next),
|
|
|
+ contentDescription = "",
|
|
|
+ modifier = Modifier
|
|
|
+ .padding(start = 5.dp)
|
|
|
+ .size(16.dp)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|