index.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <template>
  2. <div class="go-chart-configurations-data" v-if="targetData">
  3. <setting-item-box name="请求方式" :alone="true">
  4. <n-select
  5. v-model:value="targetData.data.requestDataType"
  6. :options="selectOptions"
  7. @on-update="selectHandle"
  8. />
  9. </setting-item-box>
  10. <n-timeline>
  11. <n-timeline-item type="info" :title="TimelineTitleEnum.MAPPING">
  12. <n-table striped>
  13. <thead>
  14. <tr>
  15. <th v-for="item in tableTitle" :key="item">{{ item }}</th>
  16. </tr>
  17. </thead>
  18. <go-skeleton :repeat="3" :load="tableLoad" style="width: 300px;"></go-skeleton>
  19. <tbody v-show="!tableLoad">
  20. <tr v-for="(item, index) in getDimensionsAndSource" :key="index">
  21. <td>{{ item.field }}</td>
  22. <td>{{ item.mapping }}</td>
  23. <td>
  24. <n-space v-if="item.result === 0">
  25. <n-badge dot type="success"></n-badge>
  26. <n-text>无</n-text>
  27. </n-space>
  28. <n-space v-else>
  29. <n-badge dot :type="item.result === 1 ? 'success' : 'error'"></n-badge>
  30. <n-text>匹配{{ item.result === 1 ? '成功' : '失败' }}</n-text>
  31. </n-space>
  32. </td>
  33. </tr>
  34. </tbody>
  35. </n-table>
  36. </n-timeline-item>
  37. <n-timeline-item type="success" :title="TimelineTitleEnum.CONTENT">
  38. <n-space vertical>
  39. <n-text prefix="bar" depth="3">数据格式需要符合 ECharts-setdata 规范</n-text>
  40. <n-space class="source-btn-box">
  41. <n-upload
  42. v-model:file-list="uploadFileListRef"
  43. :show-file-list="false"
  44. :customRequest="customRequest"
  45. @before-upload="beforeUpload"
  46. >
  47. <n-space>
  48. <n-button class="sourceBtn-item">
  49. <template #icon>
  50. <n-icon>
  51. <document-add-icon />
  52. </n-icon>
  53. </template>
  54. 导入(json / txt)
  55. </n-button>
  56. </n-space>
  57. </n-upload>
  58. <n-button class="sourceBtn-item" @click="download">
  59. <template #icon>
  60. <n-icon>
  61. <document-download-icon />
  62. </n-icon>
  63. </template>
  64. 下载
  65. </n-button>
  66. </n-space>
  67. <n-card>
  68. <n-code :code="getSource" language="json"></n-code>
  69. </n-card>
  70. </n-space>
  71. </n-timeline-item>
  72. </n-timeline>
  73. </div>
  74. </template>
  75. <script setup lang="ts">
  76. import { ref, computed, watch, nextTick } from 'vue'
  77. import { SettingItemBox } from '@/components/ChartItemSetting/index'
  78. import { RequestDataTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
  79. import { useTargetData } from '../hooks/useTargetData.hook'
  80. import { UploadCustomRequestOptions } from 'naive-ui'
  81. import { FileTypeEnum } from '@/enums/fileTypeEnum'
  82. import { readFile, downloadFile } from '@/utils'
  83. import { DataResultEnum, TimelineTitleEnum, SelcetOptionsLableEnum, SelectOptionsType } from './index.d'
  84. import { icon } from '@/plugins'
  85. const { DocumentAddIcon, DocumentDownloadIcon } = icon.carbon
  86. const uploadFileListRef = ref()
  87. const { targetData } = useTargetData()
  88. const source = ref()
  89. const dimensions = ref()
  90. // 表格标题
  91. const tableTitle = ['字段', '映射', '状态']
  92. // 选项
  93. const selectOptions: SelectOptionsType[] = [
  94. {
  95. label: SelcetOptionsLableEnum.STATIC,
  96. value: RequestDataTypeEnum.STATIC
  97. },
  98. {
  99. label: SelcetOptionsLableEnum.AJAX,
  100. value: RequestDataTypeEnum.AJAX,
  101. disabled: true,
  102. }
  103. ]
  104. // 获取数据
  105. const getSource = computed(() => {
  106. return JSON.stringify(source.value)
  107. })
  108. watch(() => targetData.value?.option?.dataset, (newData) => {
  109. if (newData) {
  110. source.value = newData.source
  111. dimensions.value = newData.dimensions
  112. }
  113. }, {
  114. immediate: true
  115. })
  116. // 处理映射列表状态结果
  117. const matchingHandle = (mapping: string) => {
  118. for (let i = 0; i < source.value.length; i++) {
  119. let res = DataResultEnum.FAILURE
  120. if (source.value[i][mapping] !== undefined) {
  121. return DataResultEnum.SUCCESS
  122. }
  123. return res
  124. }
  125. return DataResultEnum.SUCCESS
  126. }
  127. // 处理映射列表
  128. const getDimensionsAndSource = computed(() => {
  129. // 去除首项数据轴标识
  130. return dimensions.value.map((item: string, index: number) => {
  131. return index === 0 ?
  132. {
  133. // 字段
  134. field: '通用标识',
  135. // 映射
  136. mapping: item,
  137. // 结果
  138. result: DataResultEnum.NULL
  139. } : {
  140. field: `数据项-${index}`,
  141. mapping: item,
  142. result: matchingHandle(item)
  143. }
  144. })
  145. })
  146. // 表格数据加载
  147. const tableLoad = computed(() => {
  148. return !getDimensionsAndSource.value || getDimensionsAndSource.value.length === 0
  149. })
  150. // 选择方式
  151. const selectHandle = () => { }
  152. //@ts-ignore
  153. const beforeUpload = ({ file }) => {
  154. uploadFileListRef.value = []
  155. const type = file.file.type
  156. if (type !== FileTypeEnum.JSON && type !== FileTypeEnum.TXT) {
  157. window['$message'].warning('仅支持上传 【JSON】 格式文件,请重新上传!')
  158. return false
  159. }
  160. return true
  161. }
  162. // 自定义上传操作
  163. const customRequest = (options: UploadCustomRequestOptions) => {
  164. const { file } = options
  165. nextTick(() => {
  166. if (file.file) {
  167. readFile(file.file).then((fileData: any) => {
  168. targetData.value.option.dataset = JSON.parse(fileData)
  169. });
  170. } else {
  171. window['$message'].error('导入数据失败,请稍后重试或联系管理员!')
  172. }
  173. })
  174. }
  175. // 下载文件
  176. const download = () => {
  177. window['$message'].success('正在下载文件...')
  178. downloadFile(getSource.value, undefined, 'json')
  179. }
  180. </script>
  181. <style>
  182. </style>
  183. <style lang="scss" scoped>
  184. @include go("chart-configurations-data") {
  185. @include deep() {
  186. pre {
  187. white-space: pre-wrap;
  188. word-wrap: break-word;
  189. }
  190. }
  191. .source-btn-box {
  192. margin-top: 10px !important;
  193. }
  194. }
  195. </style>