useSync.hook.ts 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import { onUnmounted } from 'vue';
  2. import html2canvas from 'html2canvas'
  3. import { getUUID, httpErrorHandle, fetchRouteParamsLocation, base64toFile } from '@/utils'
  4. import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  5. import { EditCanvasTypeEnum, ChartEditStoreEnum, ProjectInfoEnum, ChartEditStorage } from '@/store/modules/chartEditStore/chartEditStore.d'
  6. import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
  7. import { useSystemStore } from '@/store/modules/systemStore/systemStore'
  8. import { fetchChartComponent, fetchConfigComponent, createComponent } from '@/packages/index'
  9. import { saveInterval } from '@/settings/designSetting'
  10. import throttle from 'lodash/throttle'
  11. // 接口状态
  12. import { ResultEnum } from '@/enums/httpEnum'
  13. // 接口
  14. import { saveProjectApi, fetchProjectApi, uploadFile, updateProjectApi } from '@/api/path'
  15. // 画布枚举
  16. import { SyncEnum } from '@/enums/editPageEnum'
  17. import { CreateComponentType, CreateComponentGroupType, ConfigType } from '@/packages/index.d'
  18. import { PublicGroupConfigClass } from '@/packages/public/publicConfig'
  19. // 请求处理
  20. export const useSync = () => {
  21. const chartEditStore = useChartEditStore()
  22. const chartHistoryStore = useChartHistoryStore()
  23. const systemStore = useSystemStore()
  24. /**
  25. * * 组件动态注册
  26. * @param projectData 项目数据
  27. * @param isReplace 是否替换数据
  28. * @returns
  29. */
  30. const updateComponent = async (projectData: ChartEditStorage, isReplace = false, changeId = false) => {
  31. if (isReplace) {
  32. // 清除列表
  33. chartEditStore.componentList = []
  34. // 清除历史记录
  35. chartHistoryStore.clearBackStack()
  36. chartHistoryStore.clearForwardStack()
  37. }
  38. // 列表组件注册
  39. projectData.componentList.forEach(async (e: CreateComponentType | CreateComponentGroupType) => {
  40. const intComponent = (target: CreateComponentType) => {
  41. if (!window['$vue'].component(target.chartConfig.chartKey)) {
  42. window['$vue'].component(target.chartConfig.chartKey, fetchChartComponent(target.chartConfig))
  43. window['$vue'].component(target.chartConfig.conKey, fetchConfigComponent(target.chartConfig))
  44. }
  45. }
  46. if (e.isGroup) {
  47. ;(e as CreateComponentGroupType).groupList.forEach(groupItem => {
  48. intComponent(groupItem)
  49. })
  50. } else {
  51. intComponent(e as CreateComponentType)
  52. }
  53. })
  54. // 数据赋值
  55. for (const key in projectData) {
  56. // 组件
  57. if (key === ChartEditStoreEnum.COMPONENT_LIST) {
  58. for (const comItem of projectData[key]) {
  59. // 重新创建是为了处理类种方法消失的问题
  60. const create = async (
  61. _componentInstance: CreateComponentType,
  62. callBack?: (componentInstance: CreateComponentType) => void
  63. ) => {
  64. // 补充 class 上的方法
  65. let newComponent: CreateComponentType = await createComponent(_componentInstance.chartConfig)
  66. if (callBack) {
  67. if (changeId) {
  68. callBack(Object.assign(newComponent, { ..._componentInstance, id: getUUID() }))
  69. } else {
  70. callBack(Object.assign(newComponent, _componentInstance))
  71. }
  72. } else {
  73. if (changeId) {
  74. chartEditStore.addComponentList(
  75. Object.assign(newComponent, { ..._componentInstance, id: getUUID() }),
  76. false,
  77. true
  78. )
  79. } else {
  80. chartEditStore.addComponentList(Object.assign(newComponent, _componentInstance), false, true)
  81. }
  82. }
  83. }
  84. if (comItem.isGroup) {
  85. // 创建分组
  86. let groupClass = new PublicGroupConfigClass()
  87. if (changeId) {
  88. groupClass = Object.assign(groupClass, { ...comItem, id: getUUID() })
  89. } else {
  90. groupClass = Object.assign(groupClass, comItem)
  91. }
  92. // 注册子应用
  93. const targetList: CreateComponentType[] = []
  94. ;(comItem as CreateComponentGroupType).groupList.forEach(groupItem => {
  95. create(groupItem, e => {
  96. targetList.push(e)
  97. })
  98. })
  99. groupClass.groupList = targetList
  100. // 分组插入到列表
  101. chartEditStore.addComponentList(groupClass, false, true)
  102. } else {
  103. create(comItem as CreateComponentType)
  104. }
  105. }
  106. } else {
  107. // 非组件(顺便排除脏数据)
  108. if (key !== 'editCanvasConfig' && key !== 'requestGlobalConfig') return
  109. Object.assign(chartEditStore[key], projectData[key])
  110. }
  111. }
  112. }
  113. /**
  114. * * 赋值全局数据
  115. * @param projectData 项目数据
  116. * @returns
  117. */
  118. const updateStoreInfo = (projectData: {
  119. id: string,
  120. projectName: string,
  121. indexImage: string,
  122. remarks: string,
  123. state: number
  124. }) => {
  125. const { id, projectName, remarks, indexImage, state } = projectData
  126. // ID
  127. chartEditStore.setProjectInfo(ProjectInfoEnum.PROJECT_ID, id)
  128. // 名称
  129. chartEditStore.setProjectInfo(ProjectInfoEnum.PROJECT_NAME, projectName)
  130. // 描述
  131. chartEditStore.setProjectInfo(ProjectInfoEnum.REMARKS, remarks)
  132. // 缩略图
  133. chartEditStore.setProjectInfo(ProjectInfoEnum.THUMBNAIL, indexImage)
  134. // 发布
  135. chartEditStore.setProjectInfo(ProjectInfoEnum.RELEASE, state === 1)
  136. }
  137. // * 数据获取
  138. const dataSyncFetch = async () => {
  139. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.START)
  140. try {
  141. const res = await fetchProjectApi({ projectId: fetchRouteParamsLocation() }) as unknown as MyResponseType
  142. if (res.code === ResultEnum.SUCCESS) {
  143. if (res.data) {
  144. updateStoreInfo(res.data)
  145. // 更新全局数据
  146. await updateComponent(JSON.parse(res.data.content))
  147. return
  148. }else {
  149. chartEditStore.setProjectInfo(ProjectInfoEnum.PROJECT_ID, fetchRouteParamsLocation())
  150. }
  151. setTimeout(() => {
  152. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.SUCCESS)
  153. }, 1000)
  154. return
  155. }
  156. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
  157. } catch (error) {
  158. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
  159. httpErrorHandle()
  160. }
  161. }
  162. // * 数据保存
  163. const dataSyncUpdate = throttle(async () => {
  164. if(!fetchRouteParamsLocation()) return
  165. if(!systemStore.getFetchInfo.OSSUrl) {
  166. window['$message'].error('数据保存失败,请刷新页面重试!')
  167. return
  168. }
  169. let projectId = chartEditStore.getProjectInfo[ProjectInfoEnum.PROJECT_ID];
  170. if(projectId === null || projectId === ''){
  171. window['$message'].error('数据初未始化成功,请刷新页面!')
  172. return
  173. }
  174. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.START)
  175. // 获取缩略图片
  176. const range = document.querySelector('.go-edit-range') as HTMLElement
  177. // 生成图片
  178. const canvasImage: HTMLCanvasElement = await html2canvas(range, {
  179. backgroundColor: null,
  180. allowTaint: true,
  181. useCORS: true
  182. })
  183. // 上传预览图
  184. let uploadParams = new FormData()
  185. uploadParams.append('object', base64toFile(canvasImage.toDataURL(), `${fetchRouteParamsLocation()}_index_preview.png`))
  186. const uploadRes = await uploadFile(systemStore.getFetchInfo.OSSUrl, uploadParams) as unknown as MyResponseType
  187. // 保存预览图
  188. if(uploadRes.code === ResultEnum.SUCCESS) {
  189. await updateProjectApi({
  190. id: fetchRouteParamsLocation(),
  191. indexImage: uploadRes.data.objectContent.httpRequest.uri
  192. })
  193. }
  194. // 保存数据
  195. let params = new FormData()
  196. params.append('projectId', projectId)
  197. params.append('content', JSON.stringify(chartEditStore.getStorageInfo || {}))
  198. const res= await saveProjectApi(params) as unknown as MyResponseType
  199. if (res.code === ResultEnum.SUCCESS) {
  200. // 成功状态
  201. setTimeout(() => {
  202. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.SUCCESS)
  203. }, 1000)
  204. return
  205. }
  206. // 失败状态
  207. chartEditStore.setEditCanvas(EditCanvasTypeEnum.SAVE_STATUS, SyncEnum.FAILURE)
  208. }, 3000)
  209. // * 定时处理
  210. const intervalDataSyncUpdate = () => {
  211. // 定时获取数据
  212. const syncTiming = setInterval(() => {
  213. dataSyncUpdate()
  214. }, saveInterval * 1000)
  215. // 销毁
  216. onUnmounted(() => {
  217. clearInterval(syncTiming)
  218. })
  219. }
  220. return {
  221. updateComponent,
  222. updateStoreInfo,
  223. dataSyncFetch,
  224. dataSyncUpdate,
  225. intervalDataSyncUpdate
  226. }
  227. }