index.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. if (mapData?.selectNodes.length > 10) {
  102. globalPopup?.showWarning('最多只能选择10个业务对象')
  103. return
  104. }
  105. sessionStorage.setItem('reportJson', JSON.stringify({
  106. addFormVal: {
  107. ...formVal.value,
  108. visibleRangeData: visibleRangeData.value
  109. },
  110. mindMapJSON: mapData
  111. }))
  112. router.push({
  113. path: '/biReport/dragEdit',
  114. })
  115. }
  116. // 回显数据
  117. function initializedData() {
  118. const reportJson = JSON.parse(sessionStorage.getItem('reportJson') || '{}')
  119. if(!Object.keys(reportJson).length) {
  120. return
  121. }
  122. console.log('reportJson', reportJson)
  123. const { addFormVal = {}, mindMapJSON = {} } = reportJson
  124. visibleRangeData.value = addFormVal.visibleRangeData || []
  125. formVal.value = addFormVal || {}
  126. setTimeout(() => {
  127. flowChartRef.value?.displayBackData(mindMapJSON)
  128. }, 500)
  129. }
  130. onMounted(() => {
  131. if(route?.query?.allParentStoreId) {
  132. formVal.value.parentStoreId = Number(route.query.allParentStoreId)
  133. }
  134. getTreeClassification()
  135. getAllBusTable()
  136. initializedData()
  137. })
  138. </script>
  139. <template>
  140. <div class="w-full h-full flex flex-col bg-white rounded-md">
  141. <div class="p-5 text-[18px] border-b-2">
  142. {{ formVal.id ? '编辑报表' : '新建报表' }}
  143. </div>
  144. <div class="flex-1 py-5 px-16 flex-col flex h-[90%]">
  145. <div class="flex-1 h-full overflow-auto mb-8 scroll-bar">
  146. <el-form style="max-width: 600px" :model="formVal" label-width="80px">
  147. <el-form-item class="relative">
  148. <template #label>
  149. <div class="relative">
  150. 名称
  151. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  152. </div>
  153. </template>
  154. <el-input v-model="formVal.reportFormName" placeholder="请输入" />
  155. </el-form-item>
  156. <el-form-item label="分类">
  157. <el-tree-select v-model="formVal.parentStoreId" :data="treeSelectData" check-strictly
  158. :render-after-expand="false" style="width: 100%" :props="{
  159. label: 'storeName', value: 'id', children: 'childStoreList'
  160. }" clearable />
  161. </el-form-item>
  162. <el-form-item label="描述">
  163. <el-input v-model="formVal.description" :rows="2" type="textarea" placeholder="请输入" />
  164. </el-form-item>
  165. <el-form-item label="可见范围">
  166. <template #label>
  167. <div class="relative">
  168. 可见范围
  169. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  170. </div>
  171. </template>
  172. <div class="flex items-center w-full">
  173. <el-input placeholder="+选择可见部门和人员" readonly :disabled="formVal.privilege"
  174. @click="showTreeDeptUserVis()" />
  175. <el-checkbox v-model="formVal.privilege" label="公开" size="large" class="ml-4" @change="openReport" />
  176. </div>
  177. </el-form-item>
  178. <el-form-item label=" " v-if="visibleRangeData.length">
  179. <div class="flex flex-wrap w-full">
  180. <template v-for="(item, index) in visibleRangeData">
  181. <el-tag :type="`${item.isUser ? 'warning' : 'primary'}`" closable class="mr-2 mb-2"
  182. @close="visibilityClose(index)">
  183. <TextTranslation :translationTypes="`${item.isUser ? 'userName' : 'departmentName'}`"
  184. :translationValue="item.label"></TextTranslation>
  185. </el-tag>
  186. </template>
  187. </div>
  188. </el-form-item>
  189. <el-form-item label="业务对象">
  190. <template #label>
  191. <div class="relative">
  192. 业务对象
  193. <div class="absolute left-[-10px] top-[2px] text-[red]">*</div>
  194. </div>
  195. </template>
  196. <div class="flex w-full items-center">
  197. <el-select v-model="formVal.businessObject" placeholder="请选择" @change="businessObjectSelectChange">
  198. <el-option v-for="item in businessTableList" :key="item.value" :label="item.label" :value="item.value" />
  199. </el-select>
  200. <div class="ml-4">
  201. <el-tooltip class="box-item" effect="dark" content="最多只能选择10个业务对象" placement="top">
  202. <el-icon><QuestionFilled /></el-icon>
  203. </el-tooltip>
  204. </div>
  205. </div>
  206. </el-form-item>
  207. </el-form>
  208. <div class="h-[500px] border mr-6" v-if="formVal.businessObject">
  209. <flowChart ref="flowChartRef"></flowChart>
  210. </div>
  211. </div>
  212. <div class="justify-end flex">
  213. <el-button type="primary" @click="dragAndDropEditing()">下一步</el-button>
  214. </div>
  215. </div>
  216. <!-- 全屏对话框 -->
  217. <!-- <el-dialog v-model="allVisable.mindMapVoisable" fullscreen draggable class="fullScreen" :show-close="false">
  218. <div class="w-full h-full relative">
  219. <flowChart ref="flowChartRef"></flowChart>
  220. <div class="absolute flex justify-end right-2 bottom-2">
  221. <el-button @click="allVisable.mindMapVoisable = false">关闭</el-button>
  222. <el-button type="primary" @click="allVisable.mindMapVoisable = false">
  223. 确定
  224. </el-button>
  225. </div>
  226. </div>
  227. </el-dialog> -->
  228. <!-- 选择部门人员 -->
  229. <el-dialog v-model="allVisable.treeSelectUserVisable" width="600" :show-close="false" top="10vh">
  230. <template #header="{ close, titleId, titleClass }">
  231. <div class="flex justify-between items-center border-b pb-3 dialog-header">
  232. <h4 :id="titleId">选择可见范围</h4>
  233. <div>
  234. <el-button type="primary" @click="visibleRangeDetermination()">确定</el-button>
  235. <el-button @click="allVisable.treeSelectUserVisable = false">取消</el-button>
  236. </div>
  237. </div>
  238. </template>
  239. <div class="scroll-bar m-6">
  240. <selectDeptUser ref="selectDeptUserRef" />
  241. </div>
  242. </el-dialog>
  243. </div>
  244. </template>
  245. <style lang='scss' scoped>
  246. /* 样式代码 */
  247. .fullScreen :deep(.el-dialog__body) {
  248. width: 100%;
  249. height: 100%;
  250. }
  251. </style>