tree-node-edit.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <hc-dialog v-model="isShow" widths="26rem" title="编辑节点" is-footer-center @close="dialogClose">
  3. <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" label-width="auto">
  4. <el-form-item label="节点名称:" prop="nodeName">
  5. <el-input v-model="formModel.nodeName" clearable class="is-right-btn">
  6. <template #append>
  7. <el-button hc-btn type="primary" @click="aliasShowClick">添加别名</el-button>
  8. </template>
  9. </el-input>
  10. </el-form-item>
  11. <el-form-item label="上级节点:">
  12. <el-input v-model="formModel.parentName" disabled />
  13. </el-form-item>
  14. <el-form-item label="节点类型:" prop="nodeType">
  15. <el-select v-model="formModel.nodeType" placeholder="选择节点类型" filterable block>
  16. <el-option v-for="item in nodeTypelist" :key="item.value" :label="item.label" :value="item.value" />
  17. </el-select>
  18. </el-form-item>
  19. <el-form-item v-if="wbsType !== 2 && wbsType !== 5" label="划分编号:">
  20. <el-input v-model="formModel.partitionCode" clearable />
  21. </el-form-item>
  22. <el-form-item v-if="wbsType !== 5" label="唯一编码:">
  23. <el-input v-model="formModel.uniqueCode" clearable />
  24. </el-form-item>
  25. <el-form-item v-if="wbsType === 6" label="是否有混凝土:">
  26. <div class="form-item-div">
  27. <el-radio-group v-model="formModel.isConcrete">
  28. <el-radio :value="0">否</el-radio>
  29. <el-radio :value="1">有</el-radio>
  30. </el-radio-group>
  31. </div>
  32. </el-form-item>
  33. <el-form-item v-if="wbsType === 6" label="是否试验节点:">
  34. <div class="form-item-div">
  35. <el-radio-group v-model="formModel.isExpernode">
  36. <el-radio :value="0">否</el-radio>
  37. <el-radio :value="1">是</el-radio>
  38. </el-radio-group>
  39. </div>
  40. </el-form-item>
  41. <el-form-item v-if="wbsType !== 2 && wbsType !== 5" label="内业资料类型:" prop="majorDataType">
  42. <el-select v-model="formModel.majorDataType" placeholder="选择内业资料类型" filterable block>
  43. <el-option v-for="item in majorDataType" :key="item.value" :label="item.label" :value="item.value" />
  44. </el-select>
  45. </el-form-item>
  46. <el-form-item v-if="wbsType === 2 && formModel.nodeType === 53" label="勾选相关联试验:" prop="mixRatioTestIds" :f="getTestTreeData()">
  47. <el-tree-select
  48. v-model="mixRatioTestIds" placeholder="选择勾选相关联试验" show-checkbox clearable filterable multiple block
  49. node-key="id" :data="testData" :props="testProps" :render-after-expand="false" @check="testTreeCheckChange"
  50. />
  51. </el-form-item>
  52. </el-form>
  53. <template #footer>
  54. <el-button hc-btn @click="dialogClose">取消</el-button>
  55. <el-button hc-btn type="primary" :loading="submitLoading" @click="dialogSubmit">提交</el-button>
  56. </template>
  57. </hc-dialog>
  58. <!-- 节点别名 -->
  59. <hc-dialog v-model="isAliasShow" widths="26rem" title="节点别名" is-footer-center @close="aliasDialogClose">
  60. <el-form ref="formAliasRef" :model="formAliasModel" :rules="formAliasRules" label-position="top" label-width="auto">
  61. <el-form-item prop="aliasName">
  62. <el-input v-model="formAliasModel.aliasName" placeholder="请输入节点别名" clearable class="is-right-btn">
  63. <template v-if="formModel.pKeyId" #append>
  64. <el-button hc-btn type="primary" @click="addAliasName">添加</el-button>
  65. </template>
  66. </el-input>
  67. </el-form-item>
  68. </el-form>
  69. <div v-if="aliasArr.length > 0" class="hc-tree-node-edit-form-alias-name">
  70. <template v-for="(item, index) in aliasArr" :key="index">
  71. <el-tag closable type="primary" @close="aliasNameClose(index)">{{ item }}</el-tag>
  72. </template>
  73. </div>
  74. <template #footer>
  75. <el-button hc-btn @click="aliasDialogClose">取消</el-button>
  76. <el-button hc-btn type="primary" :loading="submitAliasLoading" @click="aliasSubmit">提交</el-button>
  77. </template>
  78. </hc-dialog>
  79. </template>
  80. <script setup>
  81. import { ref, watch } from 'vue'
  82. import { deepClone, formValidate, getArrValue, isNullES } from 'js-fast-way'
  83. import projectApi from '~api/project/project'
  84. import privateApi from '~api/wbs/private'
  85. const props = defineProps({
  86. node: {
  87. type: Object,
  88. default: () => ({}),
  89. },
  90. type: {
  91. type: Number,
  92. default: 1,
  93. },
  94. wid: {
  95. type: [String, Number],
  96. default: '',
  97. },
  98. pid: {
  99. type: [String, Number],
  100. default: '',
  101. },
  102. treeProps: {
  103. type: Object,
  104. default: () => ({}),
  105. },
  106. nodeType: {
  107. type: Array,
  108. default: () => ([]),
  109. },
  110. majorType: {
  111. type: Array,
  112. default: () => ([]),
  113. },
  114. })
  115. //事件
  116. const emit = defineEmits(['change', 'close'])
  117. //双向绑定
  118. // eslint-disable-next-line no-undef
  119. const isShow = defineModel('modelValue', {
  120. default: false,
  121. })
  122. //数据变量
  123. const formModel = ref(props.node)
  124. const wbsType = ref(props.type)
  125. const wbsId = ref(props.wid)
  126. const projectId = ref(props.pid)
  127. const nodeTypelist = ref(props.nodeType)
  128. const majorDataType = ref(props.majorType)
  129. const testProps = ref(props.treeProps)
  130. //监听数据
  131. watch(() => [
  132. props.node,
  133. props.type,
  134. props.wid,
  135. props.pid,
  136. props.nodeType,
  137. props.majorType,
  138. props.treeProps,
  139. ], ([node, type, wid, pid, nodeType, majorType, treeProps]) => {
  140. formModel.value = node
  141. wbsType.value = type
  142. wbsId.value = wid
  143. projectId.value = pid
  144. nodeTypelist.value = nodeType
  145. majorDataType.value = majorType
  146. testProps.value = treeProps
  147. }, { deep: true })
  148. //监听显示
  149. watch(isShow, (val) => {
  150. if (val) {
  151. getDataInfo()
  152. } else {
  153. emit('close')
  154. }
  155. })
  156. //获取数据
  157. const getDataInfo = () => {
  158. const { nodeType } = formModel.value
  159. if (nodeType === 53) {
  160. getTestTreeData()
  161. }
  162. }
  163. //节点别名
  164. const isAliasShow = ref(false)
  165. //节点别名
  166. const formAliasRef = ref(null)
  167. const formAliasModel = ref({})
  168. const formAliasRules = {
  169. aliasName: {
  170. required: true,
  171. trigger: 'blur',
  172. message: '请输入节点别名',
  173. },
  174. }
  175. //显示节点别名弹窗
  176. const aliasArr = ref([])
  177. const aliasShowClick = () => {
  178. isAliasShow.value = true
  179. aliasArr.value = []
  180. const { fullName } = deepClone(formModel.value)
  181. if (isNullES(fullName)) return
  182. aliasArr.value = fullName.split(',')
  183. }
  184. //添加别名
  185. const addAliasName = async () => {
  186. const formRes = await formValidate(formAliasRef.value)
  187. if (!formRes) return false
  188. const { aliasName } = deepClone(formAliasModel.value)
  189. if (aliasArr.value.indexOf(aliasName) !== -1) {
  190. window.$message.warning('请不要重复别名')
  191. return
  192. }
  193. aliasArr.value.push(aliasName)
  194. formAliasModel.value.aliasName = ''
  195. }
  196. //移除别名
  197. const aliasNameClose = (index) => {
  198. aliasArr.value.splice(index, 1)
  199. }
  200. //提交别名
  201. const submitAliasLoading = ref(false)
  202. const aliasSubmit = async () => {
  203. submitAliasLoading.value = true
  204. const { pKeyId } = formModel.value
  205. const fullName = aliasArr.value.join(',')
  206. const { isRes } = await privateApi.privateSubmitFullName({
  207. pKeyId, fullNames: fullName,
  208. })
  209. submitAliasLoading.value = false
  210. if (!isRes) return
  211. aliasDialogClose()
  212. window?.$message?.success('操作成功')
  213. }
  214. //关闭节点别名弹窗
  215. const aliasDialogClose = () => {
  216. isAliasShow.value = false
  217. formAliasModel.value = {}
  218. }
  219. //获取实验树的数据
  220. const testData = ref([])
  221. const mixRatioTestIds = ref([])
  222. const getTestTreeData = async () => {
  223. testData.value = []
  224. const { primaryKeyId, pKeyId, mixRatioTestIds: testIds } = formModel.value
  225. let pid = primaryKeyId ?? pKeyId
  226. const { data } = await projectApi.findProjectTree({
  227. projectId: projectId.value,
  228. wbsId: wbsId.value,
  229. parentId: pid,
  230. })
  231. testData.value = getArrValue(data)
  232. if (!isNullES(testIds)) {
  233. mixRatioTestIds.value = testIds?.split(',') ?? []
  234. } else {
  235. mixRatioTestIds.value = []
  236. }
  237. }
  238. //监听实验树的勾选, halfCheckedKeys
  239. const testTreeCheckChange = (_, { checkedKeys }) => {
  240. formModel.value.mixRatioTestIds = checkedKeys.join(',')
  241. }
  242. //表单
  243. const formRef = ref(null)
  244. const formRules = {
  245. nodeName: {
  246. required: true,
  247. trigger: 'blur',
  248. message: '请输入节点名称',
  249. },
  250. nodeType: {
  251. required: true,
  252. trigger: 'blur',
  253. message: '请选择节点类型',
  254. },
  255. majorDataType: {
  256. required: true,
  257. trigger: 'blur',
  258. message: '请选择内业资料类型',
  259. },
  260. mixRatioTestIds: {
  261. required: true,
  262. trigger: 'blur',
  263. message: '请勾选相关联试验',
  264. },
  265. }
  266. //提交表单
  267. const submitLoading = ref(false)
  268. const dialogSubmit = async () => {
  269. const formRes = await formValidate(formRef.value)
  270. if (!formRes) return false
  271. submitLoading.value = true
  272. //发起请求
  273. const { isRes } = await privateApi.submit(formModel.value)
  274. submitLoading.value = false
  275. if (!isRes) return
  276. dialogClose()
  277. window?.$message?.success('操作成功')
  278. emit('change')
  279. }
  280. //关闭弹窗
  281. const dialogClose = () => {
  282. isShow.value = false
  283. emit('close')
  284. }
  285. </script>
  286. <style lang="scss">
  287. .hc-tree-node-edit-form-alias-name {
  288. position: relative;
  289. border: 1px dashed #dcdfe6;
  290. border-radius: 4px;
  291. padding: 5px 5px 0;
  292. .el-tag {
  293. margin-right: 5px;
  294. margin-bottom: 5px;
  295. }
  296. }
  297. </style>