Ver Fonte

背景设置

dsy há 2 semanas atrás
pai
commit
fc1dcce0b3

+ 1 - 1
.env

@@ -11,4 +11,4 @@ VUE_APP_BookWebSI = '/GCLSBookWebSI/ServiceInterface'
 VUE_APP_EepServer = '/EEPServer/SI'
 
 #version
-VUE_APP_VERSION = '2026.03.21'
+VUE_APP_VERSION = '2026.03.25'

+ 707 - 5
package-lock.json

@@ -1,12 +1,12 @@
 {
   "name": "eep_page",
-  "version": "2025.12.07",
+  "version": "2026.03.21",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "eep_page",
-      "version": "2025.12.07",
+      "version": "2026.03.21",
       "hasInstallScript": true,
       "dependencies": {
         "@tinymce/tinymce-vue": "^3.2.8",
@@ -27,6 +27,8 @@
         "three": "^0.181.2",
         "tinymce": "^5.10.9",
         "v-fit-columns": "^0.2.0",
+        "video.js": "^8.23.7",
+        "videojs-markers": "^1.0.1",
         "vis-data": "^8.0.3",
         "vis-network": "^10.0.2",
         "vue": "^2.6.14",
@@ -34,7 +36,8 @@
         "vue-router": "^3.6.5",
         "vue-signature-pad": "^2.0.5",
         "vuedraggable": "^2.24.3",
-        "vuex": "^3.6.2"
+        "vuex": "^3.6.2",
+        "web-highlighter": "^0.7.4"
       },
       "devDependencies": {
         "@babel/core": "^7.28.5",
@@ -1683,7 +1686,6 @@
       "version": "7.28.4",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
       "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -2765,6 +2767,258 @@
         "@parcel/watcher-win32-x64": "2.5.1"
       }
     },
+    "node_modules/@parcel/watcher-android-arm64": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
+      "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-arm64": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
+      "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-darwin-x64": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
+      "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-freebsd-x64": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
+      "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-glibc": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
+      "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm-musl": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
+      "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
+      "cpu": [
+        "arm"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-glibc": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
+      "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-arm64-musl": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
+      "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-glibc": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
+      "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-linux-x64-musl": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
+      "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
+      "cpu": [
+        "x64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-arm64": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
+      "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/@parcel/watcher-win32-ia32": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
+      "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
     "node_modules/@parcel/watcher-win32-x64": {
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
@@ -3271,6 +3525,18 @@
       "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
       "dev": true
     },
+    "node_modules/@types/plist": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz",
+      "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@types/node": "*",
+        "xmlbuilder": ">=11.0.1"
+      }
+    },
     "node_modules/@types/qs": {
       "version": "6.9.15",
       "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.15.tgz",
@@ -3342,6 +3608,14 @@
       "resolved": "https://registry.npmmirror.com/@types/unist/-/unist-2.0.11.tgz",
       "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="
     },
+    "node_modules/@types/verror": {
+      "version": "1.10.11",
+      "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
+      "integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
     "node_modules/@types/ws": {
       "version": "8.5.10",
       "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.10.tgz",
@@ -3382,6 +3656,54 @@
       "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
       "dev": true
     },
+    "node_modules/@videojs/http-streaming": {
+      "version": "3.17.4",
+      "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.17.4.tgz",
+      "integrity": "sha512-XAvdG2dolBuV2Fx8bu1kjmQ2D4TonGzZH68Pgv/O9xMSFWdZtITSMFismeQLEAtMmGwze8qNJp3RgV+jStrJqg==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "@videojs/vhs-utils": "^4.1.1",
+        "aes-decrypter": "^4.0.2",
+        "global": "^4.4.0",
+        "m3u8-parser": "^7.2.0",
+        "mpd-parser": "^1.3.1",
+        "mux.js": "7.1.0",
+        "video.js": "^7 || ^8"
+      },
+      "engines": {
+        "node": ">=8",
+        "npm": ">=5"
+      },
+      "peerDependencies": {
+        "video.js": "^8.19.0"
+      }
+    },
+    "node_modules/@videojs/vhs-utils": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz",
+      "integrity": "sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "global": "^4.4.0"
+      },
+      "engines": {
+        "node": ">=8",
+        "npm": ">=5"
+      }
+    },
+    "node_modules/@videojs/xhr": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.7.0.tgz",
+      "integrity": "sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "global": "~4.4.0",
+        "is-function": "^1.0.1"
+      }
+    },
     "node_modules/@vue/babel-helper-vue-jsx-merge-props": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
@@ -4356,7 +4678,6 @@
       "version": "0.8.10",
       "resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
       "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
-      "dev": true,
       "engines": {
         "node": ">=10.0.0"
       }
@@ -4468,6 +4789,18 @@
         "node": ">= 10.0.0"
       }
     },
+    "node_modules/aes-decrypter": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz",
+      "integrity": "sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "@videojs/vhs-utils": "^4.1.1",
+        "global": "^4.4.0",
+        "pkcs7": "^1.0.4"
+      }
+    },
     "node_modules/agent-base": {
       "version": "6.0.2",
       "resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
@@ -4897,6 +5230,17 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/assign-symbols": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/assign-symbols/-/assign-symbols-1.0.0.tgz",
@@ -6114,6 +6458,24 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/cli-truncate": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+      "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "slice-ansi": "^3.0.0",
+        "string-width": "^4.2.0"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/clipboardy": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/clipboardy/-/clipboardy-2.3.0.tgz",
@@ -6623,6 +6985,17 @@
         "node": ">=10"
       }
     },
+    "node_modules/crc": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
+      "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "buffer": "^5.1.0"
+      }
+    },
     "node_modules/cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -7518,6 +7891,33 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/dmg-license": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz",
+      "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "dependencies": {
+        "@types/plist": "^3.0.1",
+        "@types/verror": "^1.10.3",
+        "ajv": "^6.10.0",
+        "crc": "^3.8.0",
+        "iconv-corefoundation": "^1.1.7",
+        "plist": "^3.0.4",
+        "smart-buffer": "^4.0.2",
+        "verror": "^1.10.0"
+      },
+      "bin": {
+        "dmg-license": "bin/dmg-license.js"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/dns-packet": {
       "version": "5.6.1",
       "resolved": "https://registry.npmmirror.com/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -7574,6 +7974,11 @@
         "url": "https://github.com/fb55/entities?sponsor=1"
       }
     },
+    "node_modules/dom-walk": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
+      "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
+    },
     "node_modules/domelementtype": {
       "version": "2.3.0",
       "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-2.3.0.tgz",
@@ -9181,6 +9586,17 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/extsprintf": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz",
+      "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
+      "dev": true,
+      "engines": [
+        "node >=0.6.0"
+      ],
+      "license": "MIT",
+      "optional": true
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -9644,6 +10060,21 @@
       "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
     },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
     "node_modules/function-bind": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
@@ -9798,6 +10229,16 @@
       "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
       "dev": true
     },
+    "node_modules/global": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
+      "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
+      "license": "MIT",
+      "dependencies": {
+        "min-document": "^2.19.0",
+        "process": "^0.11.10"
+      }
+    },
     "node_modules/global-agent": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/global-agent/-/global-agent-3.0.0.tgz",
@@ -10461,6 +10902,24 @@
         "node": ">=10.17.0"
       }
     },
+    "node_modules/iconv-corefoundation": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
+      "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "dependencies": {
+        "cli-truncate": "^2.1.0",
+        "node-addon-api": "^1.6.3"
+      },
+      "engines": {
+        "node": "^8.11.2 || >=10"
+      }
+    },
     "node_modules/iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -10861,6 +11320,12 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-function": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
+      "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==",
+      "license": "MIT"
+    },
     "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
@@ -12083,6 +12548,17 @@
         "yallist": "^3.0.2"
       }
     },
+    "node_modules/m3u8-parser": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz",
+      "integrity": "sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "@videojs/vhs-utils": "^4.1.1",
+        "global": "^4.4.0"
+      }
+    },
     "node_modules/magic-string": {
       "version": "0.30.21",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -13032,6 +13508,15 @@
         "node": ">=4"
       }
     },
+    "node_modules/min-document": {
+      "version": "2.19.2",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.2.tgz",
+      "integrity": "sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==",
+      "license": "MIT",
+      "dependencies": {
+        "dom-walk": "^0.1.0"
+      }
+    },
     "node_modules/min-indent": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/min-indent/-/min-indent-1.0.1.tgz",
@@ -13285,6 +13770,21 @@
       "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
       "dev": true
     },
+    "node_modules/mpd-parser": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-1.3.1.tgz",
+      "integrity": "sha512-1FuyEWI5k2HcmhS1HkKnUAQV7yFPfXPht2DnRRGtoiiAAW+ESTbtEXIDpRkwdU+XyrQuwrIym7UkoPKsZ0SyFw==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "@videojs/vhs-utils": "^4.0.0",
+        "@xmldom/xmldom": "^0.8.3",
+        "global": "^4.4.0"
+      },
+      "bin": {
+        "mpd-to-m3u8-json": "bin/parse.js"
+      }
+    },
     "node_modules/mri": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/mri/-/mri-1.2.0.tgz",
@@ -13321,6 +13821,23 @@
         "multicast-dns": "cli.js"
       }
     },
+    "node_modules/mux.js": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-7.1.0.tgz",
+      "integrity": "sha512-NTxawK/BBELJrYsZThEulyUMDVlLizKdxyAsMuzoCD1eFj97BVaA8D/CvKsKu6FOLYkFojN5CbM9h++ZTZtknA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.11.2",
+        "global": "^4.4.0"
+      },
+      "bin": {
+        "muxjs-transmux": "bin/transmux.js"
+      },
+      "engines": {
+        "node": ">=8",
+        "npm": ">=5"
+      }
+    },
     "node_modules/mz": {
       "version": "2.7.0",
       "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz",
@@ -13460,6 +13977,14 @@
         "tslib": "^2.0.3"
       }
     },
+    "node_modules/node-addon-api": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
+      "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
     "node_modules/node-fetch": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
@@ -14488,6 +15013,18 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/pkcs7": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.4.tgz",
+      "integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5"
+      },
+      "bin": {
+        "pkcs7": "bin/cli.js"
+      }
+    },
     "node_modules/pkg-dir": {
       "version": "4.2.0",
       "resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
@@ -15495,6 +16032,15 @@
         "renderkid": "^3.0.0"
       }
     },
+    "node_modules/process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -16927,6 +17473,73 @@
         "node": ">=8"
       }
     },
+    "node_modules/slice-ansi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+      "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/slice-ansi/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/smart-buffer": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "engines": {
+        "node": ">= 6.0.0",
+        "npm": ">= 3.0.0"
+      }
+    },
     "node_modules/snapdragon": {
       "version": "0.8.2",
       "resolved": "https://registry.npmmirror.com/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -19530,6 +20143,89 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/verror": {
+      "version": "1.10.1",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
+      "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      },
+      "engines": {
+        "node": ">=0.6.0"
+      }
+    },
+    "node_modules/verror/node_modules/core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+      "dev": true,
+      "license": "MIT",
+      "optional": true
+    },
+    "node_modules/video.js": {
+      "version": "8.23.7",
+      "resolved": "https://registry.npmjs.org/video.js/-/video.js-8.23.7.tgz",
+      "integrity": "sha512-cG4HOygYt+Z8j6Sf5DuK6OgEOoM+g9oGP6vpqoZRaD13aHE4PMITbyjJUXZcIQbgB0wJEadBRaVm5lJIzo2jAA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@babel/runtime": "^7.28.4",
+        "@videojs/http-streaming": "^3.17.3",
+        "@videojs/vhs-utils": "^4.1.1",
+        "@videojs/xhr": "2.7.0",
+        "aes-decrypter": "^4.0.2",
+        "global": "4.4.0",
+        "m3u8-parser": "^7.2.0",
+        "mpd-parser": "^1.3.1",
+        "mux.js": "^7.0.1",
+        "videojs-contrib-quality-levels": "4.1.0",
+        "videojs-font": "4.2.0",
+        "videojs-vtt.js": "0.15.5"
+      }
+    },
+    "node_modules/videojs-contrib-quality-levels": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz",
+      "integrity": "sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "global": "^4.4.0"
+      },
+      "engines": {
+        "node": ">=16",
+        "npm": ">=8"
+      },
+      "peerDependencies": {
+        "video.js": "^8"
+      }
+    },
+    "node_modules/videojs-font": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-4.2.0.tgz",
+      "integrity": "sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/videojs-markers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/videojs-markers/-/videojs-markers-1.0.1.tgz",
+      "integrity": "sha512-jw3jRhanwno0YgdRR9+z6cbdmMs/jeXcrgkMr6mlEP+XfZN+isWNYp0GnPvdXrBcnb6AANdDHlnXSmIvecEzWA==",
+      "peerDependencies": {
+        "video.js": ">=4"
+      }
+    },
+    "node_modules/videojs-vtt.js": {
+      "version": "0.15.5",
+      "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz",
+      "integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==",
+      "license": "Apache-2.0",
+      "dependencies": {
+        "global": "^4.3.1"
+      }
+    },
     "node_modules/vis-data": {
       "version": "8.0.3",
       "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-8.0.3.tgz",
@@ -19875,6 +20571,12 @@
         "defaults": "^1.0.3"
       }
     },
+    "node_modules/web-highlighter": {
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/web-highlighter/-/web-highlighter-0.7.4.tgz",
+      "integrity": "sha512-07mWw6ib+Abcr/fuKEWYPy1Y0MsCOz6yUUVw9xMpyt5UzyXWtSlcwzy2YqnccCP/LjtM9MZHQSo3dbGJII8h6w==",
+      "license": "MIT"
+    },
     "node_modules/webidl-conversions": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "eep_page",
-  "version": "2026.03.21",
+  "version": "2026.03.25",
   "private": true,
   "main": "main.js",
   "description": "智慧梧桐数字教材编辑器",

+ 18 - 0
src/api/book.js

@@ -457,3 +457,21 @@ export function CheckChapterIsExistChildNode(data) {
     data,
   );
 }
+
+/**
+ * @description 保存课件背景设置
+ * @param {object} data
+ * @param {string} data.id - 章节ID
+ */
+export function SaveCoursewareBackground(data) {
+  return http.post(`${process.env.VUE_APP_EepServer}?MethodName=book_content_manager-SaveCoursewareBackground`, data);
+}
+
+/**
+ * @description 得到课件背景设置
+ * @param {object} data
+ * @param {string} data.id - 章节ID
+ */
+export function GetCoursewareBackground(data) {
+  return http.post(`${process.env.VUE_APP_EepServer}?MethodName=book_content_manager-GetCoursewareBackground`, data);
+}

+ 13 - 8
src/components/CommonPreview.vue

@@ -660,7 +660,7 @@ export default {
         this.getCollect();
       }
     },
-    multimediaIsAllShow(newVal) {
+    multimediaIsAllShow() {
       // 切换显示全部,需清空所有数据,全部重新加载
       this.bookChapterList.forEach((x) => {
         this.$set(x, 'data', null);
@@ -719,7 +719,13 @@ export default {
         }
       });
     },
-
+    /**
+     * 更新背景信息
+     * @param {Object} background - 背景信息对象
+     */
+    updateBackground(background) {
+      this.background = background;
+    },
     /**
      * 得到教材课件信息
      * @param {string} id - 课件ID
@@ -738,16 +744,15 @@ export default {
      */
     getCoursewareComponentContent_View(id) {
       ContentGetCoursewareContent_View({ id }).then(
-        ({ content, component_list, content_group_row_list, title_list }) => {
+        ({ content, component_list, content_group_row_list, title_list, background }) => {
           if (title_list) this.title_list = title_list || [];
+          if (background) {
+            this.background = JSON.parse(background);
+          }
+
           if (content) {
             const _content = JSON.parse(content);
             this.data = _content;
-            this.background = {
-              background_image_url: _content.background_image_url,
-              background_position: _content.background_position,
-              background: _content.background,
-            };
           } else {
             this.data = { row_list: [] };
           }

+ 1 - 87
src/views/book/courseware/create/components/CreateCanvas.vue

@@ -1,5 +1,5 @@
 <template>
-  <main ref="canvas" class="canvas" :style="computedCanvasStyle()">
+  <main ref="canvas" class="canvas">
     <div v-if="isEdit" class="edit">
       <div v-for="item in lineList" :key="item[0]" class="group-line" :style="computedGroupLine(item)"></div>
       <span class="drag-line" data-row="-1"></span>
@@ -157,14 +157,6 @@ export default {
       courseware_id: this.$route.params.courseware_id,
       project_id,
       data: {
-        background_image_url: '',
-        background_position: {
-          width: 100,
-          height: 100,
-          top: 0,
-          left: 0,
-        },
-        background: {},
         // 组件列表
         row_list: [],
         // 样式调整
@@ -529,13 +521,6 @@ export default {
         loading.close();
       }
     },
-    setBackground(url, position, background) {
-      this.data.background_image_url = url;
-      this.data.background_position = position;
-      this.data.background = background;
-
-      this.$message.success('设置背景图成功');
-    },
     /**
      * 显示设置
      * @param {object} setting 组件设置数据
@@ -1648,56 +1633,6 @@ export default {
       this.data.row_list = [];
       this.content_group_row_list = [];
     },
-    computedCanvasStyle() {
-      const { background_image_url, background_position, background } = this.data;
-
-      let canvasStyle = {
-        '--bg-size': background_image_url ? `${background_position.width}% ${background_position.height}%` : '',
-        '--bg-position': background_image_url ? `${background_position.left}% ${background_position.top}%` : '',
-        '--bg-image': background_image_url ? `url(${background_image_url})` : '',
-        '--bg-opacity': background_image_url && background.mode === 'image' ? background.image_opacity / 100 : 1,
-      };
-
-      if (background) {
-        if (background.imageMode === 'fill') {
-          canvasStyle['--bg-repeat'] = 'repeat';
-        } else {
-          canvasStyle['--bg-repeat'] = 'no-repeat';
-        }
-
-        if (background.imageMode === 'stretch') {
-          canvasStyle['--bg-size'] = '100% 100%';
-        }
-
-        if (background.imageMode === 'adapt') {
-          canvasStyle['--bg-size'] = 'contain';
-        }
-
-        if (background.mode === 'color') {
-          canvasStyle['--bg-color'] = background.color;
-          canvasStyle['--bg-image'] = '';
-          canvasStyle['--bg-repeat'] = '';
-          canvasStyle['--bg-position'] = '';
-          canvasStyle['--bg-size'] = '';
-        }
-
-        if (background.enable_border) {
-          canvasStyle['--bg-border'] =
-            `${background.border_width}px ${background.border_style} ${background.border_color}`;
-        } else {
-          canvasStyle['--bg-border'] = 'none';
-        }
-
-        if (background.enable_radius) {
-          canvasStyle['--bg-border-radius-top-left'] = `${background.top_left_radius}px`;
-          canvasStyle['--bg-border-radius-top-right'] = `${background.top_right_radius}px`;
-          canvasStyle['--bg-border-radius-bottom-left'] = `${background.bottom_left_radius}px`;
-          canvasStyle['--bg-border-radius-bottom-right'] = `${background.bottom_right_radius}px`;
-        }
-      }
-
-      return canvasStyle;
-    },
   },
 };
 </script>
@@ -1706,7 +1641,6 @@ export default {
 .canvas {
   .edit {
     position: relative;
-    z-index: 0;
     display: flex;
     flex-direction: column;
     row-gap: 8px;
@@ -1716,26 +1650,6 @@ export default {
     margin: 0 auto;
     background-color: #fff;
 
-    &::before {
-      position: absolute;
-      top: 0;
-      left: 0;
-      z-index: -1; // 背景在最底层
-      width: 100%;
-      height: 100%;
-      pointer-events: none; // 背景不接受鼠标事件
-      content: '';
-      background-color: #fff;
-      background-image: var(--bg-image);
-      background-repeat: var(--bg-repeat);
-      background-position: var(--bg-position);
-      background-size: var(--bg-size);
-      border: var(--bg-border);
-      border-radius: var(--bg-border-radius-top-left) var(--bg-border-radius-top-right)
-        var(--bg-border-radius-bottom-right) var(--bg-border-radius-bottom-left);
-      opacity: var(--bg-opacity);
-    }
-
     .group-line {
       position: absolute;
       left: 11px;

+ 23 - 6
src/views/book/courseware/create/components/SetBackground.vue

@@ -1,7 +1,7 @@
 <template>
   <el-dialog
     custom-class="background"
-    width="720px"
+    :width="dialogWidth"
     :close-on-click-modal="false"
     :visible="visible"
     :before-close="handleClose"
@@ -11,6 +11,7 @@
       <div
         ref="backgroundImg"
         class="background-img"
+        :style="{ width: `${maxWidth}px`, height: `${maxHeight}px` }"
         :class="{ 'is-crop-mode': cropMode }"
         @mousedown="onBackgroundMouseDown"
       >
@@ -161,8 +162,8 @@ export default {
   },
   data() {
     return {
-      maxWidth: 480,
-      maxHeight: 410,
+      maxWidth: 500,
+      maxHeight: 450,
 
       imgData: {
         width: 0,
@@ -209,7 +210,7 @@ export default {
         bottom_right_radius: 4, // 右下圆角
       },
       imageModeList: [
-        { label: '填充', value: 'fill' },
+        { label: '平铺', value: 'fill' },
         { label: '拉伸', value: 'stretch' },
         { label: '适应', value: 'adapt' },
         { label: '自定', value: 'auto' },
@@ -240,10 +241,25 @@ export default {
         height: `${this.crop.height}px`,
       };
     },
+    dialogWidth() {
+      return `${this.maxWidth + 250}px`;
+    },
   },
   watch: {
     visible(newVal) {
       if (newVal) {
+        const courseware = document.querySelector('div.courserware');
+        if (courseware) {
+          const rect = courseware.getBoundingClientRect();
+          const coursewareRatio = rect.width / rect.height;
+          const imgRatio = this.maxWidth / this.maxHeight;
+          if (coursewareRatio > imgRatio) {
+            this.maxHeight = this.maxWidth / coursewareRatio;
+          } else {
+            this.maxWidth = this.maxHeight * coursewareRatio;
+          }
+        }
+
         this.file_url = this.url;
         this.imgData = {
           width: (this.position.width * this.maxWidth) / 100,
@@ -415,6 +431,9 @@ export default {
         y: Math.min(this.imageDisplay.height, Math.max(0, rawY)),
       };
     },
+    /**
+     * 同步图片显示区域位置和尺寸信息
+     */
     syncImageDisplayRect() {
       this.$nextTick(() => {
         const bg = this.$refs.backgroundImg;
@@ -692,8 +711,6 @@ export default {
 
   .background-img {
     position: relative;
-    flex: 1;
-    height: 410px;
     border: 1px dashed rgba(0, 0, 0, 8%);
 
     &.is-crop-mode {

+ 1 - 0
src/views/book/courseware/create/components/common/ModuleBase.vue

@@ -15,6 +15,7 @@
         <span class="title" @mousedown="dragComponentStart($event)">{{ componentNameList[type] }}</span>
         <div class="module-icon">
           <el-checkbox v-model="checked" />
+          <i class="el-icon-rank" style="cursor: pointer" @mousedown="dragComponentStart($event)"></i>
           <span><SvgIcon icon-class="copy" size="10" @click="copyComponent" /></span>
           <span :class="[{ active: getCurSettingId() === id }]" @click="showSetting">
             <SvgIcon icon-class="setup" size="10" />

+ 1 - 1
src/views/book/courseware/data/common.js

@@ -44,7 +44,7 @@ export let commonSetProperty = {
 
 // 公用组件设置
 export let commonComponentProperty = {
-  background_color: 'rgba(255, 255, 255, 1)', // 背景颜色
+  background_color: 'rgba(255, 255, 255, 0)', // 背景颜色
   background_image_url: '',
   background_position: {
     width: 100,

+ 1 - 0
src/views/book/courseware/preview/CoursewarePreview.vue

@@ -558,6 +558,7 @@ export default {
 
         if (back.imageMode === 'fill') {
           canvasStyle['backgroundRepeat'] = 'repeat';
+          canvasStyle['backgroundSize'] = '';
         } else {
           canvasStyle['backgroundRepeat'] = 'no-repeat';
         }

+ 3 - 2
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -37,9 +37,10 @@
           </div>
         </li>
       </ul>
+
+      <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
     </div>
 
-    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
     <AnswerCorrect
       :answer-correct="data?.answer_correct"
       :visible.sync="visibleAnswerCorrect"
@@ -170,7 +171,7 @@ export default {
       }
 
       // 判断是否是正确答案
-      if (isHas && this.isJudgingRightWrong) {
+      if (isHas && this.isJudgingRightWrong && type !== 'answer-analysis') {
         answerClass = isRight ? ['answer-right'] : ['wrong'];
       }
       return answerClass;

+ 0 - 26
src/views/personal_workbench/edit_task/edit/index.vue

@@ -48,7 +48,6 @@
             <span class="link" @click="useTemplate()">使用模板</span>
             <span class="link" @click="switchComponent()">交换组件</span>
           </template>
-          <span class="link" @click="showSetBackground">背景设置</span>
           <span class="link" @click="saveCoursewareContent('quit')">退出编辑</span>
           <span class="link" @click="saveCoursewareContent()">保存</span>
           <span v-if="isEdit && !type" class="link" @click="showFullTextSettings">样式调整</span>
@@ -73,14 +72,6 @@
       @fullTextSettings="fullTextSettings"
       @applyToSelectedComponents="applyToSelectedComponents"
     />
-
-    <SetBackground
-      :visible.sync="visibleBackground"
-      :url="data.background_image_url"
-      :position="data.background_position"
-      :background-data="data.background"
-      @setBackground="setBackground"
-    />
   </div>
 </template>
 
@@ -89,7 +80,6 @@ import CreatePage from '@/views/book/courseware/create/index.vue';
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import UseTemplate from './UseTemplate.vue';
 import FullTextSettings from '@/views/book/courseware/create/components/FullTextSettings.vue';
-import SetBackground from '@/views/book/courseware/create/components/SetBackground.vue';
 
 import tinymce from 'tinymce';
 import * as OpenCC from 'opencc-js';
@@ -103,7 +93,6 @@ export default {
     MenuPage,
     UseTemplate,
     FullTextSettings,
-    SetBackground,
   },
   provide() {
     return {
@@ -141,12 +130,8 @@ export default {
       // 用于复制 create 组件data数据
       data: {
         unified_attrib: {},
-        background_image_url: '',
-        background_position: {},
-        background: {},
       },
       visibleFullTextSettings: false, // 是否显示样式调整弹窗
-      visibleBackground: false, // 是否显示背景设置弹窗
     };
   },
   created() {
@@ -244,17 +229,6 @@ export default {
     goBackBookList() {
       this.$router.push({ path: '/personal_workbench/edit_task', query: { book_id: this.courseware_info.book_id } });
     },
-    showSetBackground() {
-      const createData = this.$refs.create.$refs.createCanvas.data;
-
-      this.data.background_image_url = createData.background_image_url;
-      this.data.background_position = createData.background_position;
-      this.data.background = createData.background;
-      this.visibleBackground = true;
-    },
-    setBackground(url, position, background) {
-      this.$refs.create.$refs.createCanvas.setBackground(url, position, background);
-    },
     toggleEditMode(isEdit) {
       if (this.isEdit !== isEdit) {
         this.saveCoursewareContent('edit');

+ 51 - 0
src/views/personal_workbench/edit_task/preview/index.vue

@@ -12,6 +12,7 @@
           <span slot="reference" class="link save-template">保存为个人模板</span>
         </el-popover>
         <span class="link"></span>
+        <span v-if="isTrue(courseware.is_can_start_edit)" class="link" @click="showSetBackground">背景设置</span>
         <span v-if="isTrue(courseware.is_can_start_edit)" class="link" @click="editTask()">开始编辑</span>
         <span v-if="isTrue(courseware.is_can_submit_audit)" class="link" @click="submitCoursewareToAuditFlow()">
           提交审核
@@ -25,6 +26,14 @@
       :scope="templateScope"
       @confirm="saveCoursewareAsTemplate"
     />
+
+    <SetBackground
+      :visible.sync="visibleBackground"
+      :url="background.background_image_url"
+      :position="background.background_position"
+      :background-data="background.background"
+      @setBackground="setBackground"
+    />
   </div>
 </template>
 
@@ -32,10 +41,12 @@
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 import CreateCoursewareAsTemplateVue from '@/views/personal_workbench/edit_task/preview/CreateCoursewareAsTemplate.vue';
+import SetBackground from '@/views/book/courseware/create/components/SetBackground.vue';
 
 import { SubmitBookCoursewareToAuditFlow } from '@/api/project';
 import { isTrue } from '@/utils/validate';
 import { SaveCoursewareAsTemplatePersonal } from '@/api/template';
+import { SaveCoursewareBackground, GetCoursewareBackground } from '@/api/book';
 
 export default {
   name: 'TaskPreviewPage',
@@ -43,6 +54,7 @@ export default {
     MenuPage,
     CommonPreview,
     CreateCoursewareAsTemplateVue,
+    SetBackground,
   },
   data() {
     return {
@@ -52,8 +64,19 @@ export default {
       visibleTemplate: false,
       templateScope: 0,
       is_select_part_courseware_mode: 'false',
+      background: {
+        background_image_url: '',
+        background_position: {},
+        background: {},
+      },
+      visibleBackground: false,
     };
   },
+  created() {
+    GetCoursewareBackground({ id: this.id }).then(({ background }) => {
+      this.background = JSON.parse(background);
+    });
+  },
   methods: {
     goBackBookList() {
       this.$router.push({ path: '/personal_workbench/edit_task' });
@@ -118,6 +141,34 @@ export default {
         })
         .catch(() => {});
     },
+    /**
+     * 显示背景设置弹窗
+     */
+    showSetBackground() {
+      // const createData = this.$refs.create.$refs.createCanvas.data;
+
+      // this.data.background_image_url = createData.background_image_url;
+      // this.data.background_position = createData.background_position;
+      // this.data.background = createData.background;
+      this.visibleBackground = true;
+    },
+    /**
+     * 设置背景
+     * @param {string} url 背景图片地址
+     * @param {string} position 背景图片位置
+     * @param {string} background
+     */
+    setBackground(url, position, background) {
+      this.background = {
+        background_image_url: url,
+        background_position: position,
+        background,
+      };
+      SaveCoursewareBackground({ id: this.id, background: JSON.stringify(this.background) }).then(() => {
+        this.$message.success('背景设置成功');
+        this.$refs.preview.updateBackground(this.background);
+      });
+    },
   },
 };
 </script>