index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <template>
  2. <div class="go-canvas-setting">
  3. <n-form inline :label-width="45" size="small" label-placement="left">
  4. <n-form-item label="宽度">
  5. <!-- 尺寸选择 -->
  6. <n-input-number
  7. size="small"
  8. v-model:value="canvasConfig.width"
  9. :validator="validator"
  10. @update:value="changeSizeHandle"
  11. ></n-input-number>
  12. </n-form-item>
  13. <n-form-item label="高度">
  14. <n-input-number
  15. size="small"
  16. v-model:value="canvasConfig.height"
  17. :validator="validator"
  18. @update:value="changeSizeHandle"
  19. ></n-input-number>
  20. </n-form-item>
  21. </n-form>
  22. <n-card class="upload-box">
  23. <n-upload
  24. v-model:file-list="uploadFileListRef"
  25. :show-file-list="false"
  26. :customRequest="customRequest"
  27. :onBeforeUpload="beforeUploadHandle"
  28. >
  29. <n-upload-dragger>
  30. <img
  31. v-if="canvasConfig.backgroundImage"
  32. class="upload-show"
  33. :src="canvasConfig.backgroundImage"
  34. alt="背景"
  35. />
  36. <div class="upload-img" v-show="!canvasConfig.backgroundImage">
  37. <img src="@/assets/images/canvas/noImage.png" />
  38. <n-text class="upload-desc" depth="3">
  39. 背景图需小于 {{ backgroundImageSize }}M ,格式为 png/jpg/gif
  40. 的文件
  41. </n-text>
  42. </div>
  43. </n-upload-dragger>
  44. </n-upload>
  45. </n-card>
  46. <n-space vertical :size="12">
  47. <n-space>
  48. <n-text>背景色</n-text>
  49. <n-color-picker
  50. style="width: 326px;"
  51. :showPreview="true"
  52. :swatches="swatchesColors"
  53. v-model:value="canvasConfig.background"
  54. ></n-color-picker>
  55. </n-space>
  56. <n-space>
  57. <n-text>使用颜色</n-text>
  58. <n-switch
  59. size="small"
  60. v-model:value="canvasConfig.selectColor"
  61. :loading="switchSelectColorLoading"
  62. :round="false"
  63. :disabled="!canvasConfig.backgroundImage"
  64. :onUpdate="switchSelectColorHandle"
  65. ></n-switch>
  66. </n-space>
  67. <n-space>
  68. <n-text>背景</n-text>
  69. <n-button size="small" :disabled="!canvasConfig.backgroundImage" @click="clearImage">清除背景图</n-button>
  70. <n-button size="small" :disabled="!canvasConfig.background" @click="clearColor">清除颜色</n-button>
  71. </n-space>
  72. </n-space>
  73. <!-- 滤镜 -->
  74. <styles-setting :is-canvas="true" :chartStyles="canvasConfig"></styles-setting>
  75. <n-divider style="margin: 10px 0;"></n-divider>
  76. <!-- 主题选择和全局配置 -->
  77. <n-tabs class="tabs-box" size="small" type="segment">
  78. <n-tab-pane
  79. v-for="item in globalTabList"
  80. :key="item.key"
  81. :name="item.key"
  82. size="small"
  83. display-directive="show:lazy"
  84. >
  85. <template #tab>
  86. <n-space>
  87. <span>{{ item.title }}</span>
  88. <n-icon size="16" class="icon-position">
  89. <component :is="item.icon"></component>
  90. </n-icon>
  91. </n-space>
  92. </template>
  93. <component :is="item.render"></component>
  94. </n-tab-pane>
  95. </n-tabs>
  96. </div>
  97. </template>
  98. <script setup lang="ts">
  99. import { ref, nextTick } from 'vue'
  100. import { backgroundImageSize } from '@/settings/designSetting'
  101. import { FileTypeEnum } from '@/enums/fileTypeEnum'
  102. import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  103. import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
  104. import { StylesSetting } from '@/components/Pages/ChartItemSetting'
  105. import { UploadCustomRequestOptions } from 'naive-ui'
  106. import { fileToUrl, loadAsyncComponent } from '@/utils'
  107. import { icon } from '@/plugins'
  108. const { ColorPaletteIcon } = icon.ionicons5
  109. const { ZAxisIcon } = icon.carbon
  110. const chartEditStore = useChartEditStore()
  111. const canvasConfig = chartEditStore.getEditCanvasConfig
  112. const uploadFileListRef = ref()
  113. const switchSelectColorLoading = ref(false)
  114. const ChartThemeColor = loadAsyncComponent(() =>
  115. import('./components/ChartThemeColor/index.vue')
  116. )
  117. const ChartDataSetting = loadAsyncComponent(() =>
  118. import('./components/ChartDataSetting/index.vue')
  119. )
  120. // 北京默认展示颜色列表
  121. const swatchesColors = [
  122. '#232324',
  123. '#2a2a2b',
  124. '#313132',
  125. '#373739',
  126. '#757575',
  127. '#e0e0e0',
  128. '#eeeeee',
  129. '#fafafa'
  130. ]
  131. const globalTabList = [
  132. {
  133. key: 'ChartTheme',
  134. title: '主题颜色',
  135. icon: ColorPaletteIcon,
  136. render: ChartThemeColor
  137. },
  138. {
  139. key: 'ChartSysSetting',
  140. title: '数据配置',
  141. icon: ZAxisIcon,
  142. render: ChartDataSetting
  143. }
  144. ]
  145. // 规则
  146. const validator = (x: number) => x > 50
  147. // 前置处理
  148. //@ts-ignore
  149. const beforeUploadHandle = async ({ file }) => {
  150. uploadFileListRef.value = []
  151. const type = file.file.type
  152. const size = file.file.size
  153. if (size > 1024 * 1024 * backgroundImageSize) {
  154. window['$message'].warning(
  155. `图片超出 ${backgroundImageSize}M 限制,请重新上传!`
  156. )
  157. return false
  158. }
  159. if (type !== FileTypeEnum.PNG && type !== FileTypeEnum.JPEG && type !== FileTypeEnum.GIF) {
  160. window['$message'].warning('文件格式不符合,请重新上传!')
  161. return false
  162. }
  163. return true
  164. }
  165. // 修改尺寸
  166. const changeSizeHandle = () => {
  167. chartEditStore.computedScale
  168. chartEditStore.setPageSize
  169. }
  170. // 清除背景
  171. const clearImage = () => {
  172. chartEditStore.setEditCanvasConfig(
  173. EditCanvasConfigEnum.BACKGROUND_IAMGE,
  174. undefined
  175. )
  176. chartEditStore.setEditCanvasConfig(
  177. EditCanvasConfigEnum.SELECT_COLOR,
  178. true
  179. )
  180. }
  181. // 清除颜色
  182. const clearColor = () => {
  183. chartEditStore.setEditCanvasConfig(
  184. EditCanvasConfigEnum.BACKGROUND,
  185. undefined
  186. )
  187. if (canvasConfig.backgroundImage) {
  188. chartEditStore.setEditCanvasConfig(
  189. EditCanvasConfigEnum.SELECT_COLOR,
  190. false
  191. )
  192. }
  193. }
  194. // 启用/关闭 颜色
  195. const switchSelectColorHandle = () => {
  196. switchSelectColorLoading.value = true
  197. setTimeout(() => {
  198. switchSelectColorLoading.value = false
  199. }, 1000)
  200. }
  201. // 自定义上传操作
  202. const customRequest = (options: UploadCustomRequestOptions) => {
  203. const { file } = options
  204. nextTick(() => {
  205. if (file.file) {
  206. const ImageUrl = fileToUrl(file.file)
  207. chartEditStore.setEditCanvasConfig(
  208. EditCanvasConfigEnum.BACKGROUND_IAMGE,
  209. ImageUrl
  210. )
  211. chartEditStore.setEditCanvasConfig(
  212. EditCanvasConfigEnum.SELECT_COLOR,
  213. false
  214. )
  215. } else {
  216. window['$message'].error('添加图片失败,请稍后重试!')
  217. }
  218. })
  219. }
  220. </script>
  221. <style lang="scss" scoped>
  222. $updloadWidth: 326px;
  223. $updloadHeight: 193px;
  224. @include go(canvas-setting) {
  225. padding-top: 20px;
  226. .upload-box {
  227. cursor: pointer;
  228. margin-bottom: 20px;
  229. @include deep() {
  230. .n-card__content {
  231. padding: 0;
  232. overflow: hidden;
  233. }
  234. .n-upload-dragger {
  235. padding: 5px;
  236. width: $updloadWidth;
  237. }
  238. }
  239. .upload-show {
  240. width: -webkit-fill-available;
  241. height: $updloadHeight;
  242. border-radius: 5px;
  243. }
  244. .upload-img {
  245. display: flex;
  246. flex-direction: column;
  247. align-items: center;
  248. img {
  249. height: 150px;
  250. }
  251. .upload-desc {
  252. padding: 10px 0;
  253. }
  254. }
  255. }
  256. .icon-position {
  257. padding-top: 2px;
  258. }
  259. .tabs-box {
  260. margin-top: 20px;
  261. }
  262. }
  263. </style>