index.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <script lang="ts" setup>
  2. import { ref, reactive, onMounted, inject, nextTick } from "vue";
  3. import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
  4. import { useRouter, useRoute } from 'vue-router'
  5. import { post, get } from "@/utils/request";
  6. import { GET_ALL_STORES_TREE, GET_ALL_BUS_TABLE } from "../api"
  7. import flowChart from './flowChart.vue'
  8. import selectDeptUser from "./selectDeptUser.vue";
  9. import { number } from "echarts";
  10. const router = useRouter()
  11. const route = useRoute()
  12. const globalPopup = inject<GlobalPopup>('globalPopup')
  13. const formVal = ref<addEditReportFormVal>({
  14. reportFormName: '',
  15. privilege: false,
  16. parentStoreId: '',
  17. description: '',
  18. deptAccessList: [],
  19. userAccessList: [],
  20. businessObject: []
  21. })
  22. const allVisable = reactive({
  23. mindMapVoisable: false,
  24. treeSelectUserVisable: false
  25. })
  26. const businessTableList = ref<optionType[]>([])
  27. const treeSelectData = ref([])
  28. const selectDeptUserRef = ref<InstanceType<typeof selectDeptUser> | null>(null);
  29. const flowChartRef = ref<InstanceType<typeof flowChart> | null>()
  30. const visibleRangeData = ref<any>([])
  31. function openReport(val: string | number | boolean) {
  32. if (val) {
  33. visibleRangeData.value = []
  34. }
  35. }
  36. function visibleRangeDetermination() {
  37. const val = (selectDeptUserRef.value && selectDeptUserRef.value.getSelectData()) || []
  38. if (val.length == 0) {
  39. globalPopup?.showWarning('请先选择可见范围')
  40. return
  41. }
  42. val.sort((a, b) => {
  43. const isUserA = a.isUser === undefined ? -1 : a.isUser;
  44. const isUserB = b.isUser === undefined ? -1 : b.isUser;
  45. if (isUserA === isUserB) {
  46. return 0;
  47. }
  48. return isUserA < isUserB ? -1 : 1;
  49. });
  50. visibleRangeData.value = val
  51. allVisable.treeSelectUserVisable = false
  52. }
  53. function visibilityClose(index: number) {
  54. visibleRangeData.value.splice(index, 1)
  55. }
  56. function businessObjectSelectChange(val: any) {
  57. const row = businessTableList.value.find((item: any) => item.id === val)
  58. allVisable.mindMapVoisable = true
  59. nextTick(() => {
  60. flowChartRef.value?.initData(row)
  61. })
  62. }
  63. function showTreeDeptUserVis() {
  64. const list = (visibleRangeData.value || []).map((item: any) => item.id)
  65. allVisable.treeSelectUserVisable = true
  66. setTimeout(() => {
  67. selectDeptUserRef.value?.setTreeData(list)
  68. }, 200)
  69. }
  70. function getTreeClassification() {
  71. post(GET_ALL_STORES_TREE, {}).then((res) => {
  72. treeSelectData.value = res.data || []
  73. })
  74. }
  75. function getAllBusTable() {
  76. post(GET_ALL_BUS_TABLE, {}).then(res => {
  77. businessTableList.value = (res.data || []).map((item: any) => {
  78. return {
  79. label: item.name,
  80. value: item.id,
  81. ...item
  82. }
  83. })
  84. })
  85. }
  86. function dragAndDropEditing() {
  87. const mapData = flowChartRef.value?.exportGetData()
  88. const { reportFormName = '', privilege } = formVal.value
  89. if(!reportFormName) {
  90. globalPopup?.showWarning('请输入名称')
  91. return
  92. }
  93. if (!visibleRangeData.value.length && !privilege) {
  94. globalPopup?.showWarning('请选择可见范围')
  95. return
  96. }
  97. if (!mapData?.selectNodes.length) {
  98. globalPopup?.showWarning('请先选择业务对象')
  99. return
  100. }
  101. sessionStorage.setItem('reportJson', JSON.stringify({
  102. addFormVal: {
  103. ...formVal.value,
  104. visibleRangeData: visibleRangeData.value
  105. },
  106. mindMapJSON: mapData
  107. }))
  108. router.push({
  109. path: '/biReport/dragEdit',
  110. })
  111. }
  112. // 回显数据
  113. function initializedData() {
  114. const reportJson = JSON.parse(sessionStorage.getItem('reportJson') || '{}')
  115. if(!Object.keys(reportJson).length) {
  116. return
  117. }
  118. console.log('reportJson', reportJson)
  119. const { addFormVal = {}, mindMapJSON = {} } = reportJson
  120. visibleRangeData.value = addFormVal.visibleRangeData || []
  121. formVal.value = addFormVal || {}
  122. setTimeout(() => {
  123. flowChartRef.value?.displayBackData(mindMapJSON)
  124. }, 500)
  125. }
  126. onMounted(() => {
  127. if(route?.query?.allParentStoreId) {
  128. formVal.value.parentStoreId = Number(route.query.allParentStoreId)
  129. }
  130. getTreeClassification()
  131. getAllBusTable()
  132. initializedData()
  133. })
  134. </script>
  135. <template>
  136. <div class="w-full h-full flex flex-col bg-white rounded-md">
  137. <div class="p-5 text-[18px] border-b-2">
  138. {{ formVal.id ? '编辑报表' : '新建报表' }}
  139. </div>
  140. <div class="flex-1 py-5 px-16 flex-col flex h-[90%]">
  141. <div class="flex-1 h-full overflow-auto mb-8 scroll-bar">
  142. <el-form style="max-width: 600px" :model="formVal" label-width="80px">
  143. <el-form-item class="relative">
  144. <template #label>
  145. <div class="relative">
  146. 名称
  147. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  148. </div>
  149. </template>
  150. <el-input v-model="formVal.reportFormName" placeholder="请输入" />
  151. </el-form-item>
  152. <el-form-item label="分类">
  153. <el-tree-select v-model="formVal.parentStoreId" :data="treeSelectData" check-strictly
  154. :render-after-expand="false" style="width: 100%" :props="{
  155. label: 'storeName', value: 'id', children: 'childStoreList'
  156. }" clearable />
  157. </el-form-item>
  158. <el-form-item label="描述">
  159. <el-input v-model="formVal.description" :rows="2" type="textarea" placeholder="请输入" />
  160. </el-form-item>
  161. <el-form-item label="可见范围">
  162. <template #label>
  163. <div class="relative">
  164. 可见范围
  165. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  166. </div>
  167. </template>
  168. <div class="flex items-center w-full">
  169. <el-input placeholder="+选择可见部门和人员" readonly :disabled="formVal.privilege"
  170. @click="showTreeDeptUserVis()" />
  171. <el-checkbox v-model="formVal.privilege" label="公开" size="large" class="ml-4" @change="openReport" />
  172. </div>
  173. </el-form-item>
  174. <el-form-item label=" " v-if="visibleRangeData.length">
  175. <div class="flex flex-wrap w-full">
  176. <template v-for="(item, index) in visibleRangeData">
  177. <el-tag :type="`${item.isUser ? 'warning' : 'primary'}`" closable class="mr-2 mb-2"
  178. @close="visibilityClose(index)">
  179. <TextTranslation :translationTypes="`${item.isUser ? 'userName' : 'departmentName'}`"
  180. :translationValue="item.label"></TextTranslation>
  181. </el-tag>
  182. </template>
  183. </div>
  184. </el-form-item>
  185. <el-form-item label="业务对象">
  186. <template #label>
  187. <div class="relative">
  188. 业务对象
  189. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  190. </div>
  191. </template>
  192. <el-select v-model="formVal.businessObject" placeholder="请选择" @change="businessObjectSelectChange">
  193. <el-option v-for="item in businessTableList" :key="item.value" :label="item.label" :value="item.value" />
  194. </el-select>
  195. </el-form-item>
  196. </el-form>
  197. <div class="h-[500px] border mr-6" v-if="formVal.businessObject">
  198. <flowChart ref="flowChartRef"></flowChart>
  199. </div>
  200. </div>
  201. <div class="justify-end flex">
  202. <el-button type="primary" @click="dragAndDropEditing()">下一步</el-button>
  203. </div>
  204. </div>
  205. <!-- 全屏对话框 -->
  206. <!-- <el-dialog v-model="allVisable.mindMapVoisable" fullscreen draggable class="fullScreen" :show-close="false">
  207. <div class="w-full h-full relative">
  208. <flowChart ref="flowChartRef"></flowChart>
  209. <div class="absolute flex justify-end right-2 bottom-2">
  210. <el-button @click="allVisable.mindMapVoisable = false">关闭</el-button>
  211. <el-button type="primary" @click="allVisable.mindMapVoisable = false">
  212. 确定
  213. </el-button>
  214. </div>
  215. </div>
  216. </el-dialog> -->
  217. <!-- 选择部门人员 -->
  218. <el-dialog v-model="allVisable.treeSelectUserVisable" width="600" :show-close="false" top="10vh">
  219. <template #header="{ close, titleId, titleClass }">
  220. <div class="flex justify-between items-center border-b pb-3 dialog-header">
  221. <h4 :id="titleId">选择可见范围</h4>
  222. <div>
  223. <el-button type="primary" @click="visibleRangeDetermination()">确定</el-button>
  224. <el-button @click="allVisable.treeSelectUserVisable = false">取消</el-button>
  225. </div>
  226. </div>
  227. </template>
  228. <div class="scroll-bar m-6">
  229. <selectDeptUser ref="selectDeptUserRef" />
  230. </div>
  231. </el-dialog>
  232. </div>
  233. </template>
  234. <style lang='scss' scoped>
  235. /* 样式代码 */
  236. .fullScreen :deep(.el-dialog__body) {
  237. width: 100%;
  238. height: 100%;
  239. }
  240. </style>