index.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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="chartEditStoreStore.computedScale"
  11. />
  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="chartEditStoreStore.computedScale"
  19. />
  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. />
  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. />
  66. </n-space>
  67. <n-space>
  68. <n-text>背景</n-text>
  69. <n-button
  70. size="small"
  71. :disabled="!canvasConfig.backgroundImage"
  72. @click="clearImage"
  73. >
  74. 清除背景图
  75. </n-button>
  76. <n-button
  77. size="small"
  78. :disabled="!canvasConfig.background"
  79. @click="clearColor"
  80. >
  81. 清除颜色
  82. </n-button>
  83. </n-space>
  84. </n-space>
  85. <!-- 主题选择和全局配置 -->
  86. <n-tabs class="tabs-box" size="small" type="segment">
  87. <n-tab-pane
  88. v-for="item in globalTabList"
  89. :key="item.key"
  90. :name="item.key"
  91. size="small"
  92. display-directive="show:lazy"
  93. >
  94. <template #tab>
  95. <n-space>
  96. <span>{{ item.title }}</span>
  97. <n-icon size="16" class="icon-position">
  98. <component :is="item.icon"></component>
  99. </n-icon>
  100. </n-space>
  101. </template>
  102. <component :is="item.render"></component>
  103. </n-tab-pane>
  104. </n-tabs>
  105. </div>
  106. </template>
  107. <script setup lang="ts">
  108. import { ref, nextTick } from 'vue'
  109. import { backgroundImageSize } from '@/settings/designSetting'
  110. import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
  111. import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
  112. import { UploadCustomRequestOptions } from 'naive-ui'
  113. import { fileToUrl, loadAsyncComponent } from '@/utils'
  114. import { icon } from '@/plugins'
  115. const { ColorPaletteIcon } = icon.ionicons5
  116. const { ZAxisIcon } = icon.carbon
  117. const chartEditStoreStore = useChartEditStoreStore()
  118. const canvasConfig = chartEditStoreStore.getEditCanvasConfig
  119. const uploadFileListRef = ref()
  120. const switchSelectColorLoading = ref(false)
  121. const ChartThemeColor = loadAsyncComponent(() =>
  122. import('./components/ChartThemeColor/index.vue')
  123. )
  124. const ChartDataSetting = loadAsyncComponent(() =>
  125. import('./components/ChartDataSetting/index.vue')
  126. )
  127. // 页面设置
  128. const swatchesColors = [
  129. '#232324',
  130. '#2a2a2b',
  131. '#313132',
  132. '#373739',
  133. '#757575',
  134. '#e0e0e0',
  135. '#eeeeee',
  136. '#fafafa'
  137. ]
  138. const globalTabList = [
  139. {
  140. key: 'ChartTheme',
  141. title: '主题颜色',
  142. icon: ColorPaletteIcon,
  143. render: ChartThemeColor
  144. },
  145. {
  146. key: 'ChartSysSetting',
  147. title: '数据配置',
  148. icon: ZAxisIcon,
  149. render: ChartDataSetting
  150. }
  151. ]
  152. // 规则
  153. const validator = (x: number) => x > 50
  154. // 前置处理
  155. //@ts-ignore
  156. const beforeUploadHandle = async ({ file }) => {
  157. uploadFileListRef.value = []
  158. const type = file.file.type
  159. const size = file.file.size
  160. if (size > 1024 * 1024 * backgroundImageSize) {
  161. window['$message'].warning(
  162. `图片超出 ${backgroundImageSize}M 限制,请重新上传!`
  163. )
  164. return false
  165. }
  166. if (type !== 'image/png' && type !== 'image/jpeg' && type !== 'image/gif') {
  167. window['$message'].warning('文件格式不符合,请重新上传!')
  168. return false
  169. }
  170. return true
  171. }
  172. // 清除背景
  173. const clearImage = () => {
  174. chartEditStoreStore.setEditCanvasConfig(
  175. EditCanvasConfigEnum.BACKGROUND_IAMGE,
  176. undefined
  177. )
  178. chartEditStoreStore.setEditCanvasConfig(
  179. EditCanvasConfigEnum.SELECT_COLOR,
  180. true
  181. )
  182. }
  183. // 清除颜色
  184. const clearColor = () => {
  185. chartEditStoreStore.setEditCanvasConfig(
  186. EditCanvasConfigEnum.BACKGROUND,
  187. undefined
  188. )
  189. if (canvasConfig.backgroundImage) {
  190. chartEditStoreStore.setEditCanvasConfig(
  191. EditCanvasConfigEnum.SELECT_COLOR,
  192. false
  193. )
  194. }
  195. }
  196. // 启用/关闭 颜色
  197. const switchSelectColorHandle = () => {
  198. switchSelectColorLoading.value = true
  199. setTimeout(() => {
  200. switchSelectColorLoading.value = false
  201. }, 1000)
  202. }
  203. // 自定义上传操作
  204. const customRequest = (options: UploadCustomRequestOptions) => {
  205. const {
  206. file,
  207. data,
  208. headers,
  209. withCredentials,
  210. action,
  211. onFinish,
  212. onError,
  213. onProgress
  214. } = options
  215. nextTick(() => {
  216. if (file.file) {
  217. const ImageUrl = fileToUrl(file.file)
  218. chartEditStoreStore.setEditCanvasConfig(
  219. EditCanvasConfigEnum.BACKGROUND_IAMGE,
  220. ImageUrl
  221. )
  222. chartEditStoreStore.setEditCanvasConfig(
  223. EditCanvasConfigEnum.SELECT_COLOR,
  224. false
  225. )
  226. } else {
  227. window['$message'].error('添加图片失败,请稍后重试!')
  228. }
  229. })
  230. }
  231. </script>
  232. <style lang="scss" scoped>
  233. $updloadWidth: 326px;
  234. $updloadHeight: 193px;
  235. @include go(canvas-setting) {
  236. padding-top: 20px;
  237. .upload-box {
  238. cursor: pointer;
  239. margin-bottom: 20px;
  240. @include deep() {
  241. .n-card__content {
  242. padding: 0;
  243. overflow: hidden;
  244. }
  245. .n-upload-dragger {
  246. padding: 5px;
  247. width: $updloadWidth;
  248. }
  249. }
  250. .upload-show {
  251. width: -webkit-fill-available;
  252. height: $updloadHeight;
  253. border-radius: 5px;
  254. }
  255. .upload-img {
  256. display: flex;
  257. flex-direction: column;
  258. align-items: center;
  259. img {
  260. height: 150px;
  261. }
  262. .upload-desc {
  263. padding: 10px 0;
  264. }
  265. }
  266. }
  267. .icon-position {
  268. padding-top: 2px;
  269. }
  270. .tabs-box {
  271. margin-top: 30px;
  272. }
  273. }
  274. </style>