dsy 5 дней назад
Родитель
Сommit
9491aca632

+ 0 - 1
src/styles/mixin.scss

@@ -41,7 +41,6 @@
 @mixin preview-base {
   display: grid;
   gap: 6px;
-  background-repeat: no-repeat;
 
   :deep .rich-text {
     @include rich-text;

+ 7 - 0
src/views/book/courseware/data/common.js

@@ -66,6 +66,13 @@ export const borderStyleList = [
   { value: 'double', label: '双线' },
 ];
 
+// 图片显示模式
+export const imageModeList = [
+  { value: 'free', label: '自由' },
+  { value: 'fill', label: '填充' },
+  { value: 'repeat', label: '平铺' },
+];
+
 // 序号样式
 export const serialNumberStyleList = [
   { value: 'solidBlockStyle' }, // 实心方块

+ 25 - 16
src/views/book/courseware/preview/components/common/PreviewMixin.js

@@ -149,25 +149,34 @@ const mixin = {
      * 得到背景图、背景色及边框样式
      */
     getComponentStyle() {
-      if (!Object.hasOwn(this.data.property, 'background_image_url')) return {};
+      let backgroundData = {};
+      if (Object.hasOwn(this.data.property, 'background_image_url')) {
+        // 保护性读取位置/大小值,避免 undefined 导致字符串 "undefined%"
+        const { background_position: pos } = this.data.property;
+        const widthPct = typeof pos.width === 'undefined' ? '' : pos.width;
+        const heightPct = typeof pos.height === 'undefined' ? '' : pos.height;
+        const leftPct = typeof pos.left === 'undefined' ? '' : pos.left;
+        const topPct = typeof pos.top === 'undefined' ? '' : pos.top;
 
-      // 保护性读取位置/大小值,避免 undefined 导致字符串 "undefined%"
-      const { background_position: pos } = this.data.property;
-      const widthPct = typeof pos.width === 'undefined' ? '' : pos.width;
-      const heightPct = typeof pos.height === 'undefined' ? '' : pos.height;
-      const leftPct = typeof pos.left === 'undefined' ? '' : pos.left;
-      const topPct = typeof pos.top === 'undefined' ? '' : pos.top;
+        backgroundData.backgroundImage = `url(${this.data.property.background_image_url})`;
+        backgroundData.backgroundSize = pos.image_mode === 'fill' ? '100% 100%' : `${widthPct}% ${heightPct}%`;
+        backgroundData.backgroundPosition = pos.image_mode === 'fill' ? '0% 0%' : `${leftPct}% ${topPct}%`;
+        backgroundData.backgroundRepeat = pos.image_mode === 'repeat' ? 'repeat' : 'no-repeat';
+      }
+
+      let borderData = {};
+      if (Object.hasOwn(this.data.property, 'is_border')) {
+        const isBorder = isEnable(this.data.property.is_border);
+        borderData.borderWidth = isBorder ? (this.data.property.border_style === 'double' ? '3px' : '1px') : '0px';
+        borderData.borderStyle = isBorder ? this.data.property.border_style : 'none';
+        borderData.borderColor = isBorder ? this.data.property.border_color : 'transparent';
+      }
 
-      let style = {
-        backgroundColor: this.data.property.background_color,
-        backgroundImage: `url(${this.data.property.background_image_url})`,
-        backgroundSize: `${widthPct}% ${heightPct}%`,
-        backgroundPosition: `${leftPct}% ${topPct}%`,
-        borderWidth: isEnable(this.data.property.is_border) ? '1px' : '0px',
-        borderStyle: isEnable(this.data.property.is_border) ? this.data.property.border_style : 'none',
-        borderColor: isEnable(this.data.property.is_border) ? this.data.property.border_color : 'transparent',
+      return {
+        backgroundColor: this.data.property?.background_color,
+        ...backgroundData,
+        ...borderData,
       };
-      return style;
     },
   },
 };