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%;