diff --git a/server/src/interfaces/survey.ts b/server/src/interfaces/survey.ts index 1e68afcc..34f1659f 100644 --- a/server/src/interfaces/survey.ts +++ b/server/src/interfaces/survey.ts @@ -135,6 +135,17 @@ export interface BaseConf { export interface SkinConf { skinColor: string; inputBgColor: string; + backgroundConf: { + color: string; + type: string; + image: string; + }; + contentConf: { + opacity: number; + }; + themeConf: { + color: string; + }; } export interface BottomConf { diff --git a/server/src/modules/file/services/uploadHandlers/local.handler.ts b/server/src/modules/file/services/uploadHandlers/local.handler.ts index 6639bb1b..fb4c0d36 100644 --- a/server/src/modules/file/services/uploadHandlers/local.handler.ts +++ b/server/src/modules/file/services/uploadHandlers/local.handler.ts @@ -1,4 +1,4 @@ -import { join, dirname } from 'path'; +import { join, dirname, sep } from 'path'; import fse from 'fs-extra'; import { createWriteStream } from 'fs'; import { FileUploadHandler } from './uploadHandler.interface'; @@ -23,7 +23,9 @@ export class LocalHandler implements FileUploadHandler { const filePath = join( options?.pathPrefix ? options?.pathPrefix : '', filename, - ); + ) + .split(sep) + .join('/'); const physicalPath = join(this.physicalRootPath, filePath); await fse.mkdir(dirname(physicalPath), { recursive: true }); const writeStream = createWriteStream(physicalPath); diff --git a/server/src/modules/survey/__test/dataStatistic.controller.spec.ts b/server/src/modules/survey/__test/dataStatistic.controller.spec.ts index bdc6ee7f..e6c3bd8f 100644 --- a/server/src/modules/survey/__test/dataStatistic.controller.spec.ts +++ b/server/src/modules/survey/__test/dataStatistic.controller.spec.ts @@ -249,6 +249,8 @@ describe('DataStatisticController', () => { skinConf: { backgroundConf: { color: '#fff', + type: 'color', + image: '', }, themeConf: { color: '#ffa600', diff --git a/server/src/modules/survey/__test/mockResponseSchema.ts b/server/src/modules/survey/__test/mockResponseSchema.ts index c0e44602..7adb3e0c 100644 --- a/server/src/modules/survey/__test/mockResponseSchema.ts +++ b/server/src/modules/survey/__test/mockResponseSchema.ts @@ -44,6 +44,17 @@ export const mockSensitiveResponseSchema: ResponseSchema = { logoImageWidth: '60%', }, skinConf: { + backgroundConf: { + color: '#fff', + type: 'color', + image: '', + }, + themeConf: { + color: '#ffa600', + }, + contentConf: { + opacity: 100, + }, skinColor: '#4a4c5b', inputBgColor: '#ffffff', }, @@ -327,6 +338,17 @@ export const mockResponseSchema: ResponseSchema = { logoImageWidth: '60%', }, skinConf: { + backgroundConf: { + color: '#fff', + type: 'color', + image: '', + }, + themeConf: { + color: '#ffa600', + }, + contentConf: { + opacity: 100, + }, skinColor: '#4a4c5b', inputBgColor: '#ffffff', }, diff --git a/server/src/modules/survey/__test/survey.controller.spec.ts b/server/src/modules/survey/__test/survey.controller.spec.ts index 655212c8..b9906bed 100644 --- a/server/src/modules/survey/__test/survey.controller.spec.ts +++ b/server/src/modules/survey/__test/survey.controller.spec.ts @@ -176,7 +176,21 @@ describe('SurveyController', () => { endTime: '2034-01-23 21:59:05', }, bottomConf: { logoImage: '/imgs/Logo.webp', logoImageWidth: '60%' }, - skinConf: { skinColor: '#4a4c5b', inputBgColor: '#ffffff' }, + skinConf: { + skinColor: '#4a4c5b', + inputBgColor: '#ffffff', + backgroundConf: { + color: '#fff', + type: 'color', + image: '', + }, + themeConf: { + color: '#ffa600', + }, + contentConf: { + opacity: 100, + }, + }, submitConf: {}, dataConf: { dataList: [], diff --git a/server/src/modules/survey/template/surveyTemplate/templateBase.json b/server/src/modules/survey/template/surveyTemplate/templateBase.json index 2af433e7..0194bf75 100644 --- a/server/src/modules/survey/template/surveyTemplate/templateBase.json +++ b/server/src/modules/survey/template/surveyTemplate/templateBase.json @@ -47,7 +47,9 @@ "skinColor": "#4a4c5b", "inputBgColor": "#ffffff", "backgroundConf": { - "color": "#ffffff" + "color": "#ffffff", + "type": "color", + "image": "" }, "themeConf": { "color": "#ffa600" diff --git a/server/src/modules/surveyResponse/__test/mockResponseSchema.ts b/server/src/modules/surveyResponse/__test/mockResponseSchema.ts index bef78ad8..607de2a2 100644 --- a/server/src/modules/surveyResponse/__test/mockResponseSchema.ts +++ b/server/src/modules/surveyResponse/__test/mockResponseSchema.ts @@ -44,6 +44,17 @@ export const mockResponseSchema: ResponseSchema = { logoImageWidth: '60%', }, skinConf: { + backgroundConf: { + color: '#fff', + type: 'color', + image: '', + }, + themeConf: { + color: '#ffa600', + }, + contentConf: { + opacity: 100, + }, skinColor: '#4a4c5b', inputBgColor: '#ffffff', }, diff --git a/web/public/imgs/icons/upload.png b/web/public/imgs/icons/upload.png new file mode 100644 index 00000000..950531ca Binary files /dev/null and b/web/public/imgs/icons/upload.png differ diff --git a/web/src/common/utils/applySkinConfig.ts b/web/src/common/utils/applySkinConfig.ts new file mode 100644 index 00000000..1d489d17 --- /dev/null +++ b/web/src/common/utils/applySkinConfig.ts @@ -0,0 +1,21 @@ +export default function (skinConfig: any) { + const root = document.documentElement + const { themeConf, backgroundConf, contentConf } = skinConfig + + if (themeConf?.color) { + // 设置主题颜色 + root.style.setProperty('--primary-color', themeConf?.color) + } + + // 设置背景 + const { color, type, image } = backgroundConf || {} + root.style.setProperty( + '--primary-background', + type === 'image' ? `url(${image}) no-repeat center / cover` : color + ) + + if (contentConf?.opacity.toString()) { + // 设置全局透明度 + root.style.setProperty('--opacity', `${contentConf.opacity / 100}`) + } +} diff --git a/web/src/management/pages/edit/index.vue b/web/src/management/pages/edit/index.vue index 704e0593..6f5425fa 100644 --- a/web/src/management/pages/edit/index.vue +++ b/web/src/management/pages/edit/index.vue @@ -14,22 +14,34 @@ @@ -103,7 +84,7 @@ export default defineComponent({ display: flex; flex-direction: column; align-items: center; - background-color: #f6f7f9; + background: var(--primary-background); } .pagination-wrapper { @@ -137,7 +118,6 @@ export default defineComponent({ } .box { - background-color: var(--primary-background-color); position: relative; .mask { @@ -150,9 +130,7 @@ export default defineComponent({ } .content { - margin: 0 0.3rem; background: rgba(255, 255, 255, var(--opacity)); - border-radius: 8px 8px 0 0; } } } diff --git a/web/src/management/pages/edit/setterConfig/skinConfig.js b/web/src/management/pages/edit/setterConfig/skinConfig.js index 9177466d..4fbec3c8 100644 --- a/web/src/management/pages/edit/setterConfig/skinConfig.js +++ b/web/src/management/pages/edit/setterConfig/skinConfig.js @@ -11,10 +11,37 @@ export default [ name: '背景', key: 'skinConf.backgroundConf', formConfigList: [ + { + type: 'TabsSetter', + key: 'type', + tabList: [ + { + label: '图片(<5M)', + value: 'image', + }, + { + label: '颜色', + value: 'color', + } + ] + }, + { + label: '背景图片', + type: 'UploadSingleFile', + accept: "image/*", + limitSize: 5,// 单位MB + key: 'image', + relyFunc: (data) => { + return data.type === 'image' + } + }, { label: '背景颜色', type: 'ColorPicker', - key: 'color' + key: 'color', + relyFunc: (data) => { + return data.type === 'color' + } } ] }, diff --git a/web/src/materials/setters/widgets/TabsSetter.vue b/web/src/materials/setters/widgets/TabsSetter.vue new file mode 100644 index 00000000..b50c0d97 --- /dev/null +++ b/web/src/materials/setters/widgets/TabsSetter.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/web/src/materials/setters/widgets/UploadSingleFile.vue b/web/src/materials/setters/widgets/UploadSingleFile.vue new file mode 100644 index 00000000..2cbac721 --- /dev/null +++ b/web/src/materials/setters/widgets/UploadSingleFile.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/web/src/render/App.vue b/web/src/render/App.vue index 28416b75..5108916c 100644 --- a/web/src/render/App.vue +++ b/web/src/render/App.vue @@ -6,31 +6,12 @@ import { watch } from 'vue' import { storeToRefs } from 'pinia' import { useSurveyStore } from './stores/survey' +import applySkinConfig from '@/common/utils/applySkinConfig'; const { skinConf } = storeToRefs(useSurveyStore()) -const updateSkinConfig = (value: any) => { - const root = document.documentElement - const { themeConf, backgroundConf, contentConf } = value - - if (themeConf?.color) { - // 设置主题颜色 - root.style.setProperty('--primary-color', themeConf?.color) - } - - if (backgroundConf?.color) { - // 设置背景颜色 - root.style.setProperty('--primary-background-color', backgroundConf?.color) - } - - if (contentConf?.opacity.toString()) { - // 设置全局透明度 - root.style.setProperty('--opacity', `${parseInt(contentConf.opacity) / 100}`) - } -} - watch(skinConf, (value) => { - updateSkinConfig(value) + applySkinConfig(value) }) diff --git a/web/src/render/pages/RenderPage.vue b/web/src/render/pages/RenderPage.vue index b70f8f9d..a860b79b 100644 --- a/web/src/render/pages/RenderPage.vue +++ b/web/src/render/pages/RenderPage.vue @@ -176,13 +176,11 @@ const handleSubmit = () => { .wrapper { min-height: 100%; - background-color: var(--primary-background-color); display: flex; flex-direction: column; .content { flex: 1; - margin: 0 0.3rem; background: rgba(255, 255, 255, var(--opacity)); border-radius: 8px 8px 0 0; height: 100%;