jinxia.mo il y a 2 ans
Parent
commit
03dae40eae

+ 374 - 0
public/collectImgNew/index - 副本.html

@@ -0,0 +1,374 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
+  <script type="text/javascript" async
+    src="https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/MathJaxFiles/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
+  <script type="text/javascript" async src="js/globalVariable.js"></script>
+  <script type="text/javascript" async src="js/html2canvas.min.js"></script>
+  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
+  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
+  <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
+  <title></title>
+  <style>
+    html,
+    body {
+      margin: 0;
+      padding: 0
+    }
+
+    .el-radio--medium.is-bordered {
+      height: auto;
+      padding-bottom: 8px;
+    }
+
+    #title::after {
+      display: table;
+      content: "";
+      clear: both;
+    }
+  </style>
+</head>
+
+<body>
+  <div id="app">
+    <div style="min-height:300px;">
+      <div id="title" style="background:#fff;max-width:1024px">
+        <div style="padding-top: 10px; padding-left: 10px;">
+          <div id="qs" style="padding-bottom: 15px" v-html="data.title"></div>
+          <div id="ans" style="background:#fff;width: fit-content;">
+            <template v-for="(itemOpt, idx) in data.options">
+              <div :key="idx">
+                <el-radio style="margin-bottom: 15px" :label="selectOpt[idx]" border size="medium">
+                  {{ selectOpt[idx] + ' 、 ' }}<span style="white-space: normal" v-html="itemOpt"></span>
+                </el-radio>
+              </div>
+            </template>
+          </div>
+          <div style="height:15px"></div>
+        </div>
+      </div>
+    </div>
+    <div style="margin-bottom:20px;padding: 15px;background: rgb(255, 255, 255); max-width: 1024px;">
+      <el-input v-model="questionId" style="width: 150px;" placeholder="请输入题目编号"></el-input>
+      <el-button type="primary" :disabled="isAuto" @click="search">搜索</el-button>
+      <el-button type="primary" :disabled="isAuto" @click="upLoad">手动上传</el-button>
+      <el-button type="primary" @click="auto">{{ isAuto ? '暂停' : '自动运行' }}</el-button>
+    </div>
+    <div v-if="imgUri" style="margin-top:30px;padding: 15px;background: rgb(255, 255, 255);  max-width: 1024px;">
+      <!-- 图片展示: -->
+      <img :src="imgUri" alt="" crossorigin="anonymous">
+    </div>
+  </div>
+
+
+  <script>
+    var exampleData = {
+      selectOpt: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
+      data: {},
+      time: null,
+      domain: '',
+      isAuto: false,
+      questionId: '18342627',
+      imgUri: '',
+      times: 2,
+      qsHeight: null
+    }
+    // window.onload = function(){
+    new Vue({
+      el: '#app',
+      data: exampleData,
+      created() {
+        // if(this.domain == 'localhost:9800'){
+        this.domain = 'https://front.mingxuejinbang.com'
+        // }
+        this.getData()
+      },
+      methods: {
+        convertImgToBase64(img) {
+          return new Promise((resolve, reject) => {
+            let canvas = document.createElement('canvas')
+            const ctx = canvas.getContext('2d')
+            canvas.height = img.height
+            canvas.width = img.width
+            ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
+            let ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
+            const base64 = canvas.toDataURL('image/' + ext)
+            canvas = null
+            const holder = new Image()
+            holder.setAttribute('crossOrigin', 'anonymous')
+            holder.onload = (e) => {
+              resolve(holder)
+            }
+            holder.src = base64
+            // return base64;
+          })
+        },
+        hasImg(dom) {
+          for (let i of dom?.children || []) {
+            if (i.nodeName === 'IMG') {
+              return true
+            }
+          }
+          return false
+        },
+        getCanvasWrap(width, height) {
+          const canvasWrap = document.createElement('canvas')
+          canvasWrap.width = this.times * width
+          canvasWrap.height = this.times * height
+          canvasWrap.style.width = this.times * width + 'px'
+          canvasWrap.style.height = this.times * height + 'px'
+          canvasWrap.getContext('2d').scale(this.times, this.times)
+          return canvasWrap
+        },
+        getUnderline(num) {
+          const underline = document.createElement('div')
+          // 暂定于1个空格5像素
+          underline.setAttribute('style', `width: ${num * 5}px;border-bottom: 1px solid #000000;display: inline-block;vertical-align: baseline;transform: translateY(2px);`)
+          return underline
+        },
+        // 遍历所有子元素
+        findAllEle(promiseArr, parent) {
+          for (let i of parent.childNodes) {
+            if (i.nodeName === 'U') {
+              parent.insertBefore(this.getUnderline(i.innerText.length), i)
+              parent.removeChild(i)
+            } else if (i.nodeName === 'IMG') {
+              const cb = (i, resolve) => {
+                if (i.style.float && i.style.float !== 'none' && i.style.float !== 'unset') {
+                  const qs = document.querySelector('#qs')
+                  this.qsHeight = qs.getBoundingClientRect().height;
+                }
+                const title = document.querySelector('#title')
+                const ans = document.querySelector('#ans')
+                ans.style.display = 'none';
+                this.$nextTick(() => {
+                  const { width, height } = title.getBoundingClientRect();
+                  html2canvas(title, {
+                    canvas: this.getCanvasWrap(width + 20, height),
+                    useCORS: true,
+                    onclone: (e) => {
+                      const ans = e.getElementById('ans');
+                      ans.parentNode.removeChild(ans);
+                    }
+                  }).then((canvas) => {
+                    ans.style.display = 'block';
+                    this.$nextTick(() => {
+                      resolve(canvas);
+                    });
+                  })
+                });
+
+              }
+              const promise = new Promise((resolve, reject) => {
+                i.onload = (e) => {
+                  // 如果图片存在浮动,需要手动设置容器的高度
+                  cb(i, resolve)
+                }
+                if (i.complete) {
+                  cb(i, resolve)
+                }
+              })
+              promiseArr.push(promise)
+            }
+            if (i.hasChildNodes()) {
+              this.findAllEle(promiseArr, i)
+            }
+          }
+        },
+        waitingLoadingImg(cb) {
+          this.qsHeight = null;
+          let doms
+          let parent
+          const title = document.querySelector('#title');
+          const qs = document.querySelector('#qs');
+          this.qsHeight = qs.getBoundingClientRect().height;
+          // 每次重置容器高度
+          title.style.height = 'auto'
+          const promiseArr = []
+          this.findAllEle(promiseArr, title)
+          if (promiseArr.length === 0) {
+            const { width, height } = qs.getBoundingClientRect()
+            html2canvas(title, {
+              canvas: this.getCanvasWrap(width + 20, height),
+              useCORS: true,
+              onclone: (e) => {
+                const ans = e.getElementById('ans');
+                ans.parentNode.removeChild(ans);
+              }
+            }).then((canvas) => {
+              if (cb) {
+                cb(canvas)
+              }
+            })
+          } else {
+            Promise.all(promiseArr).then(res => {
+              // 虽然用了Promise.all,但实际假设只有一张图片
+              console.log(res)
+              if (cb) {
+                cb(res[0])
+              }
+            })
+          }
+        },
+        search() {
+          if (this.questionId) {
+            this.getData(this.questionId)
+          } else {
+            this.$message({
+              message: '请输入题目编号',
+              type: 'warning'
+            })
+          }
+        },
+        auto() {
+          this.isAuto = !this.isAuto
+          if (this.isAuto) {
+            this.getData()
+          }
+        },
+        upLoad() {
+          if (this.questionId && this.imgUri) {
+            this.uploadQuestionImage(this.imgUri, 1)
+          } else {
+            this.$message({
+              message: '请先搜索题目',
+              type: 'warning'
+            })
+          }
+        },
+        getData(questionId) {
+          axios.defaults.withCredentials = true
+          let str = ''
+          if (questionId) {
+            str = '?questionId=' + questionId
+          }
+          axios.get(this.domain + '/prod-api/front/questionCollection/getNextQuestionForImageGenerate' + str).then(response => {
+            if (response.data.code == 200) {
+              this.data = response.data.data
+              this.$nextTick(() => {
+                MathQueue('title', () => {
+                  // this.MathQueueTitle(str)
+                })
+              });
+            } else {
+              this.isAuto = false
+              this.$message({
+                message: '获取题目信息失败',
+                type: 'warning'
+              })
+            }
+          }).catch(function (error) { // 请求失败处理
+            this.isAuto = false
+            this.$message.error('网络请求异常!')
+          })
+        },
+        uploadQuestionImage(src, type) {
+          axios.defaults.withCredentials = true
+          var formData = new FormData()
+          formData.append('questionId', this.data.questionId)
+          formData.append('imageBase64', src)
+          if (this.isAuto == false) {
+            formData.append('manual', true)
+          }
+          axios.post(this.domain + '/prod-api/front/questionCollection/uploadQuestionImage', formData).then(response => {
+            if (response.data.code == 200) {
+              if (this.isAuto) {
+                setTimeout(() => {
+                  this.getData()
+                }, 1500)
+              }
+              if (type) {
+                this.$message({
+                  message: '上传题目信息成功!',
+                  type: 'success'
+                })
+              }
+            } else {
+              this.isAuto = false
+              this.$message({
+                message: '上传题目信息失败!',
+                type: 'warning'
+              })
+            }
+
+          }).catch(function (error) { // 请求失败处理
+            this.isAuto = false
+            this.$message.error('网络请求异常!')
+          })
+        },
+        getCookie(str) {//获取cookie
+          let cookie = document.cookie.split('; ')
+          let cookies = {}
+          cookie.forEach(item => {
+            cookies[item.split('=')[0]] = item.split('=')[1]
+          })
+          return cookies[str]
+        },
+        MathQueueTitle(str) {//初始化公式
+          console.log(isMathjaxConfig)
+          if (isMathjaxConfig) {
+            setTimeout(() => {
+              this.$nextTick(() => {
+                this.waitingLoadingImg((canvas) => {
+                  this.downLoad(str, canvas)
+                })
+              });
+            }, 0)
+          } else {
+            setTimeout(() => {
+              this.MathQueueTitle(str)
+            }, 300)
+          }
+        },
+        downLoad(type, canvas1) {
+          if (!this.data.questionId) {
+            this.$message({
+              message: '请先搜索题目!',
+              type: 'warning'
+            })
+            return
+          }
+          this.questionId = this.data.questionId
+          let _canvas = document.getElementById('ans')
+          const { width, height } = _canvas.getBoundingClientRect()
+          html2canvas(_canvas, {
+            canvas: this.getCanvasWrap(width + 40, height),
+            useCORS: true,
+            onclone: (e) => {
+              const qs = e.getElementById('qs');
+              qs.parentNode.removeChild(qs)
+            }
+          }).then((canvas2) => {
+            var canvas3 = document.createElement('canvas')
+            canvas3.width = Math.max(canvas1?.width ?? 0, canvas2.width)
+            canvas3.height = (canvas1?.height ?? 0) + (canvas2.width && canvas2.height ? canvas2.height : 0)
+            var ctx = canvas3.getContext('2d')
+            // 绘制题目
+            canvas1 && ctx.drawImage(canvas1, 0, 0, canvas1.width, canvas1.height)
+            if (canvas2.width && canvas2.height) {
+              // 绘制答案
+              ctx.drawImage(canvas2, 0, (this.qsHeight * this.times) || (canvas1?.height ?? 0), canvas2.width, canvas2.height)
+            }
+            this.imgUri = canvas3.toDataURL('image/png')
+            canvas1 = null
+            canvas2 = null
+            canvas3 = null
+            if (!type) {
+              this.uploadQuestionImage(this.imgUri)
+            }
+          })
+        }
+
+      }
+    })
+  // }
+
+  </script>
+</body>
+
+</html>

+ 371 - 0
public/collectImgNew/index.html

@@ -0,0 +1,371 @@
+<!DOCTYPE html>
+<html lang="zh">
+
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
+  <script type="text/javascript" async
+    src="https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/MathJaxFiles/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
+  <script type="text/javascript" async src="js/globalVariable.js"></script>
+  <script type="text/javascript" async src="js/html2canvas.min.js"></script>
+  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
+  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
+  <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
+  <title></title>
+  <style>
+    html,
+    body {
+      margin: 0;
+      padding: 0;
+      font-size: 24px;
+    }
+
+    .el-radio--medium.is-bordered {
+      height: auto;
+      padding-bottom: 8px;
+    }
+
+    #title::after {
+      display: table;
+      content: "";
+      clear: both;
+    }
+  </style>
+</head>
+
+<body>
+  <div id="app">
+    <div v-if="show" style="min-height:300px;">
+      <div id="title" style="background:#fff;max-width:1024px">
+        <div style="padding-top: 10px; padding-left: 10px;">
+          <div id="qs" style="padding-bottom: 15px" v-html="data.title"></div>
+          <div id="ans" style="background:#fff;width: fit-content;">
+            <template v-for="(itemOpt, idx) in data.options">
+              <div :key="idx">
+                <el-radio style="margin-bottom: 15px" :label="selectOpt[idx]" border size="medium">
+                  {{ selectOpt[idx] + ' 、 ' }}<span style="white-space: normal" v-html="itemOpt"></span>
+                </el-radio>
+              </div>
+            </template>
+          </div>
+          <div style="height:15px"></div>
+        </div>
+      </div>
+      <el-button id="next" type="primary" size="mini" @click="getData()">下一个</el-button>
+    </div>
+  </div>
+
+
+  <script>
+    var exampleData = {
+      selectOpt: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
+      data: {},
+      time: null,
+      domain: '',
+      isAuto: false,
+      questionId: '18342627',
+      imgUri: '',
+      times: 2,
+      qsHeight: null,
+      show: false
+    }
+    // window.onload = function(){
+    new Vue({
+      el: '#app',
+      data: exampleData,
+      created() {
+        // if(this.domain == 'localhost:9800'){
+        this.domain = 'https://front.mingxuejinbang.com'
+        // }
+        this.getData()
+      },
+      methods: {
+        convertImgToBase64(img) {
+          return new Promise((resolve, reject) => {
+            let canvas = document.createElement('canvas')
+            const ctx = canvas.getContext('2d')
+            canvas.height = img.height
+            canvas.width = img.width
+            ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
+            let ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase()
+            const base64 = canvas.toDataURL('image/' + ext)
+            canvas = null
+            const holder = new Image()
+            holder.setAttribute('crossOrigin', 'anonymous')
+            holder.onload = (e) => {
+              resolve(holder)
+            }
+            holder.src = base64
+            // return base64;
+          })
+        },
+        hasImg(dom) {
+          for (let i of dom?.children || []) {
+            if (i.nodeName === 'IMG') {
+              return true
+            }
+          }
+          return false
+        },
+        getCanvasWrap(width, height) {
+          const canvasWrap = document.createElement('canvas')
+          canvasWrap.width = this.times * width
+          canvasWrap.height = this.times * height
+          canvasWrap.style.width = this.times * width + 'px'
+          canvasWrap.style.height = this.times * height + 'px'
+          canvasWrap.getContext('2d').scale(this.times, this.times)
+          return canvasWrap
+        },
+        getUnderline(num) {
+          const underline = document.createElement('div')
+          // 暂定于1个空格5像素
+          underline.setAttribute('style', `width: ${num * 5}px;border-bottom: 1px solid #000000;display: inline-block;vertical-align: baseline;transform: translateY(2px);`)
+          return underline
+        },
+        // 遍历所有子元素
+        findAllEle(promiseArr, parent) {
+          for (let i of parent.childNodes) {
+            if (i.nodeName === 'U') {
+              parent.insertBefore(this.getUnderline(i.innerText.length), i)
+              parent.removeChild(i)
+            } else if (i.nodeName === 'IMG') {
+              const cb = (i, resolve) => {
+                if (i.style.float && i.style.float !== 'none' && i.style.float !== 'unset') {
+                  const qs = document.querySelector('#qs')
+                  this.qsHeight = qs.getBoundingClientRect().height;
+                }
+                const title = document.querySelector('#title')
+                const ans = document.querySelector('#ans')
+                ans.style.display = 'none';
+                this.$nextTick(() => {
+                  const { width, height } = title.getBoundingClientRect();
+                  html2canvas(title, {
+                    canvas: this.getCanvasWrap(width + 20, height),
+                    useCORS: true,
+                    onclone: (e) => {
+                      const ans = e.getElementById('ans');
+                      ans.parentNode.removeChild(ans);
+                    }
+                  }).then((canvas) => {
+                    ans.style.display = 'block';
+                    this.$nextTick(() => {
+                      resolve(canvas);
+                    });
+                  })
+                });
+
+              }
+              const promise = new Promise((resolve, reject) => {
+                i.onload = (e) => {
+                  // 如果图片存在浮动,需要手动设置容器的高度
+                  cb(i, resolve)
+                }
+                if (i.complete) {
+                  cb(i, resolve)
+                }
+              })
+              promiseArr.push(promise)
+            }
+            if (i.hasChildNodes()) {
+              this.findAllEle(promiseArr, i)
+            }
+          }
+        },
+        waitingLoadingImg(cb) {
+          this.qsHeight = null;
+          let doms
+          let parent
+          const title = document.querySelector('#title');
+          const qs = document.querySelector('#qs');
+          this.qsHeight = qs.getBoundingClientRect().height;
+          // 每次重置容器高度
+          title.style.height = 'auto'
+          const promiseArr = []
+          this.findAllEle(promiseArr, title)
+          if (promiseArr.length === 0) {
+            const { width, height } = qs.getBoundingClientRect()
+            html2canvas(title, {
+              canvas: this.getCanvasWrap(width + 20, height),
+              useCORS: true,
+              onclone: (e) => {
+                const ans = e.getElementById('ans');
+                ans.parentNode.removeChild(ans);
+              }
+            }).then((canvas) => {
+              if (cb) {
+                cb(canvas)
+              }
+            })
+          } else {
+            Promise.all(promiseArr).then(res => {
+              // 虽然用了Promise.all,但实际假设只有一张图片
+              console.log(res)
+              if (cb) {
+                cb(res[0])
+              }
+            })
+          }
+        },
+        search() {
+          if (this.questionId) {
+            this.getData(this.questionId)
+          } else {
+            this.$message({
+              message: '请输入题目编号',
+              type: 'warning'
+            })
+          }
+        },
+        auto() {
+          this.isAuto = !this.isAuto
+          if (this.isAuto) {
+            this.getData()
+          }
+        },
+        upLoad() {
+          if (this.questionId && this.imgUri) {
+            this.uploadQuestionImage(this.imgUri, 1)
+          } else {
+            this.$message({
+              message: '请先搜索题目',
+              type: 'warning'
+            })
+          }
+        },
+        getData(questionId) {
+          this.show = false;
+          axios.defaults.withCredentials = true
+          let str = ''
+          if (questionId) {
+            str = '?questionId=' + questionId
+          }
+          axios.get(this.domain + '/prod-api/front/questionCollection/getNextQuestionForImageGenerate' + str).then(response => {
+            if (response.data.code == 200) {
+              this.data = response.data.data
+              this.questionId = this.data.questionId
+              localStorage.setItem('questionId', this.questionId);
+              this.show = true;
+              this.$nextTick(() => {
+                MathQueue('title', () => {
+                  // this.MathQueueTitle(str)
+                })
+              });
+            } else {
+              this.isAuto = false
+              this.$message({
+                message: '获取题目信息失败',
+                type: 'warning'
+              })
+            }
+          }).catch(function (error) { // 请求失败处理
+            this.isAuto = false
+            this.$message.error('网络请求异常!')
+          })
+        },
+        uploadQuestionImage(src, type) {
+          axios.defaults.withCredentials = true
+          var formData = new FormData()
+          formData.append('questionId', this.data.questionId)
+          formData.append('imageBase64', src)
+          if (this.isAuto == false) {
+            formData.append('manual', true)
+          }
+          axios.post(this.domain + '/prod-api/front/questionCollection/uploadQuestionImage', formData).then(response => {
+            if (response.data.code == 200) {
+              if (this.isAuto) {
+                setTimeout(() => {
+                  this.getData()
+                }, 1500)
+              }
+              if (type) {
+                this.$message({
+                  message: '上传题目信息成功!',
+                  type: 'success'
+                })
+              }
+            } else {
+              this.isAuto = false
+              this.$message({
+                message: '上传题目信息失败!',
+                type: 'warning'
+              })
+            }
+
+          }).catch(function (error) { // 请求失败处理
+            this.isAuto = false
+            this.$message.error('网络请求异常!')
+          })
+        },
+        getCookie(str) {//获取cookie
+          let cookie = document.cookie.split('; ')
+          let cookies = {}
+          cookie.forEach(item => {
+            cookies[item.split('=')[0]] = item.split('=')[1]
+          })
+          return cookies[str]
+        },
+        MathQueueTitle(str) {//初始化公式
+          console.log(isMathjaxConfig)
+          if (isMathjaxConfig) {
+            setTimeout(() => {
+              this.$nextTick(() => {
+                this.waitingLoadingImg((canvas) => {
+                  this.downLoad(str, canvas)
+                })
+              });
+            }, 0)
+          } else {
+            setTimeout(() => {
+              this.MathQueueTitle(str)
+            }, 300)
+          }
+        },
+        downLoad(type, canvas1) {
+          if (!this.data.questionId) {
+            this.$message({
+              message: '请先搜索题目!',
+              type: 'warning'
+            })
+            return
+          }
+          this.questionId = this.data.questionId
+          let _canvas = document.getElementById('ans')
+          const { width, height } = _canvas.getBoundingClientRect()
+          html2canvas(_canvas, {
+            canvas: this.getCanvasWrap(width + 40, height),
+            useCORS: true,
+            onclone: (e) => {
+              const qs = e.getElementById('qs');
+              qs.parentNode.removeChild(qs)
+            }
+          }).then((canvas2) => {
+            var canvas3 = document.createElement('canvas')
+            canvas3.width = Math.max(canvas1?.width ?? 0, canvas2.width)
+            canvas3.height = (canvas1?.height ?? 0) + (canvas2.width && canvas2.height ? canvas2.height : 0)
+            var ctx = canvas3.getContext('2d')
+            // 绘制题目
+            canvas1 && ctx.drawImage(canvas1, 0, 0, canvas1.width, canvas1.height)
+            if (canvas2.width && canvas2.height) {
+              // 绘制答案
+              ctx.drawImage(canvas2, 0, (this.qsHeight * this.times) || (canvas1?.height ?? 0), canvas2.width, canvas2.height)
+            }
+            this.imgUri = canvas3.toDataURL('image/png')
+            canvas1 = null
+            canvas2 = null
+            canvas3 = null
+            if (!type) {
+              this.uploadQuestionImage(this.imgUri)
+            }
+          })
+        }
+
+      }
+    })
+  // }
+
+  </script>
+</body>
+
+</html>

+ 85 - 0
public/collectImgNew/index.js

@@ -0,0 +1,85 @@
+/**
+ * 在无头浏览器中将一个网页截图保存为图片
+ */
+const fs = require('fs')
+const path = require('path')
+const axios = require('axios')
+const FormData = require('form-data')
+
+const puppeteer = require('puppeteer');
+
+const saveScreenshot = async (url) => {
+  // 启动浏览器
+  const browser = await puppeteer.launch({
+    headless: true
+  });
+  // 打开页面
+  const page = await browser.newPage();
+  // 设置浏览器视窗
+  page.setViewport({
+    width: 1920,
+    height: 1080,
+  })
+  // 地址栏输入网页地址
+  await page.goto(url, {
+    // 等界面加载完
+    waitUntil: 'networkidle0'
+  });
+  capchaAndUpload(page);
+  // 关闭浏览器
+  // await browser.close();
+};
+
+saveScreenshot('file:////Users/admin/Documents/D Disk/git/mingxue/testevaluation/code/test/test-ui/public/collectImgNew/index.html');
+
+async function capchaAndUpload(page) {
+  await page.waitForSelector('#title');
+  let store = await page.evaluate(() => JSON.stringify(localStorage));
+  store = JSON.parse(store)
+  console.log('------------------' + store.questionId + '请求成功!-------------------')
+  let clip = await page.evaluate((scope) => {
+    let {
+      x,
+      y,
+      width,
+      height
+    } = document.getElementById('title').getBoundingClientRect();
+    window.scope = scope;
+    return {
+      x,
+      y,
+      width,
+      height
+    };
+  });
+  const filename = `./preview/${store.questionId}.png`;
+  const options = {
+    path: filename,
+    fullPage: false,
+    clip
+  }
+  await page.screenshot(options).then(res => {
+    let base64 = Buffer.from(res).toString('base64');//转为base64编码字符串
+    const formData = new FormData()
+    formData.append('questionId', store.questionId)
+    formData.append('imageBase64', base64)
+    upload(page, formData, store.questionId);
+  });
+}
+
+function upload(page, formData, questionId) {
+  const reqUrl = 'https://front.mingxuejinbang.com/prod-api/front/questionCollection/uploadQuestionImage';
+  axios.post(reqUrl, formData)
+    .then((res) => {
+      if (res.data.code === 200) {
+        console.log(questionId + '上传成功!')
+        // 获取下一个问题
+        page.click('#next');
+        setTimeout(() => {
+          capchaAndUpload(page);
+        }, 100)
+      } else {
+        console.log('出错了')
+      }
+    });
+}

+ 235 - 0
public/collectImgNew/index0.html

@@ -0,0 +1,235 @@
+<!DOCTYPE html>
+<html lang="zh">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <meta http-equiv="X-UA-Compatible" content="ie=edge">
+  <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
+  <script type="text/javascript" async
+          src="https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/MathJaxFiles/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
+  <script type="text/javascript" async src="js/globalVariable.js"></script>
+  <script type="text/javascript" async src="js/html2canvas.min.js"></script>
+  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
+  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
+  <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
+  <title></title>
+  <style>
+    html, body {
+      margin: 0;
+      padding: 0
+    }
+
+    .el-radio--medium.is-bordered {
+      height: auto;
+      padding-bottom: 8px;
+    }
+
+    #title::after {
+      display: table;
+      content: "";
+      clear: both;
+    }
+  </style>
+</head>
+<body>
+<div id="app">
+  <div style="min-height:300px;">
+    <div id="title" style="background:#fff; max-width:1024px">
+      <div style=";padding-top:10px;padding-left:10px">
+        <div style="padding-bottom: 15px" v-html="data.title"></div>
+        <div v-for="(itemOpt, idx) in data.options" :key="idx">
+          <el-radio
+            style="margin-bottom: 15px"
+            :label="selectOpt[idx]"
+            border
+            size="medium">
+            {{ selectOpt[idx] + ' 、 ' }}<span style="white-space: normal" v-html="itemOpt"></span>
+          </el-radio>
+        </div>
+        <div style="height:15px"></div>
+      </div>
+    </div>
+  </div>
+  <div style="margin-bottom:20px;padding: 15px;background: rgb(255, 255, 255); max-width: 1024px;">
+    <el-input v-model="questionId" style="width: 150px;" placeholder="请输入题目编号"></el-input>
+    <el-button type="primary" :disabled="isAuto" @click="search">搜索</el-button>
+    <el-button type="primary" :disabled="isAuto" @click="upLoad">手动上传</el-button>
+    <el-button type="primary" @click="auto">{{ isAuto ? '暂停' : '自动运行' }}</el-button>
+  </div>
+  <div v-if="imgUri" style="margin-top:30px;padding: 15px;background: rgb(255, 255, 255);  max-width: 1024px;">
+    图片展示:
+    <img :src="imgUri" alt="" crossorigin="anonymous">
+  </div>
+</div>
+
+
+<script>
+  var exampleData = {
+    selectOpt: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
+    data: {},
+    time: null,
+    domain: '',
+    isAuto: false,
+    questionId: '',
+    imgUri: ''
+  }
+  // window.onload = function(){
+  new Vue({
+    el: '#app',
+    data: exampleData,
+    created() {
+      // if(this.domain == 'localhost:9800'){
+      this.domain = 'https://front.mingxuejinbang.com'
+      window.myVue = this
+      // }
+      // this.getData()
+    },
+    methods: {
+      search() {
+        if (this.questionId) {
+          this.getData(this.questionId)
+        } else {
+          this.$message({
+            message: '请输入题目编号',
+            type: 'warning'
+          })
+        }
+      },
+      auto() {
+        this.isAuto = !this.isAuto
+        if (this.isAuto) {
+          this.getData()
+        }
+      },
+      upLoad() {
+        if (this.questionId && this.imgUri) {
+          this.uploadQuestionImage(this.imgUri, 1)
+        } else {
+          this.$message({
+            message: '请先搜索题目',
+            type: 'warning'
+          })
+        }
+      },
+      getData(questionId) {
+        axios.defaults.withCredentials = true
+        let str = ''
+        if (questionId) {
+          str = '?questionId=' + questionId
+        }
+        axios.get(this.domain + '/prod-api/front/questionCollection/getNextQuestionForImageGenerate' + str).then(response => {
+          if (response.data.code == 200) {
+            this.data = response.data.data
+            this.$nextTick(() => {
+              this.MathQueueTitle(str)
+            })
+          } else {
+            this.isAuto = false
+            this.$message({
+              message: '获取题目信息失败',
+              type: 'warning'
+            })
+          }
+        }).catch(function(error) { // 请求失败处理
+          this.isAuto = false
+          this.$message.error('网络请求异常!')
+        })
+      },
+      uploadQuestionImage(src, type) {
+        axios.defaults.withCredentials = true
+        var formData = new FormData()
+        formData.append('questionId', this.data.questionId)
+        formData.append('imageBase64', src)
+        if (this.isAuto == false) {
+          formData.append('manual', true)
+        }
+        axios.post(this.domain + '/prod-api/front/questionCollection/uploadQuestionImage', formData).then(response => {
+          console.log(response)
+          if (response.data.code == 200) {
+            if (this.isAuto) {
+              this.getData()
+            }
+            if (type) {
+              this.$message({
+                message: '上传题目信息成功!',
+                type: 'success'
+              })
+            }
+          } else {
+            this.isAuto = false
+            this.$message({
+              message: '上传题目信息失败!',
+              type: 'warning'
+            })
+          }
+
+        }).catch(function(error) { // 请求失败处理
+          this.isAuto = false
+          this.$message.error('网络请求异常!')
+        })
+      },
+      getCookie(str) {//获取cookie
+        let cookie = document.cookie.split('; ')
+        let cookies = {}
+        cookie.forEach(item => {
+          cookies[item.split('=')[0]] = item.split('=')[1]
+        })
+        return cookies[str]
+      },
+      MathQueueTitle(str) {//初始化公式
+        if (MathQueue) {
+          clearInterval(this.time)
+          MathQueue('title')
+          setTimeout(() => { //
+            this.$nextTick(() => {
+              this.downLoad(str)
+            })
+          }, 1000)
+        } else {
+          this.time = setInterval(() => {
+            this.MathQueueTitle()
+          }, 5)
+        }
+      },
+      downLoad(type) {
+        if (!this.data.questionId) {
+          this.$message({
+            message: '请先搜索题目!',
+            type: 'warning'
+          })
+          return
+        }
+        this.questionId=this.data.questionId
+        const times = 2 // 图片放大倍数,能提升清晰度
+        let _this = this
+        _this.imgUri = ''
+        let canvas2 = document.createElement('canvas')
+        let _canvas = document.getElementById('title')
+        let w = parseInt(window.getComputedStyle(_canvas).width)
+        let h = parseInt(window.getComputedStyle(_canvas).height)
+        canvas2.width = times * w
+        canvas2.height = times * h
+        canvas2.style.width = times * w + 'px'
+        canvas2.style.height = times * h + 'px'
+        let context = canvas2.getContext('2d')
+        context.scale(times, times) ///缩放等级
+        html2canvas(document.getElementById('title'), {
+          canvas: canvas2,
+          useCORS: true
+          //allowTaint: false,
+        }).then(function(canvas) {
+          let imgUri = canvas.toDataURL('image/jpeg', 2) // 获取生成的图片的url
+          _this.imgUri = imgUri
+          // if (!type) {
+            _this.uploadQuestionImage(imgUri)
+          // }
+        })
+      }
+
+    }
+  })
+  // }
+
+</script>
+</body>
+</html>

+ 80 - 0
public/collectImgNew/index0.js

@@ -0,0 +1,80 @@
+/**
+ * 在无头浏览器中将一个网页截图保存为图片
+ */
+const fs = require('fs')
+const path = require('path')
+const axios = require('axios')
+const FormData = require('form-data')
+
+const puppeteer = require('puppeteer');
+
+const saveScreenshot = async (url) => {
+  // 启动浏览器
+  const browser = await puppeteer.launch({
+    headless: true
+  });
+  // 打开页面
+  const page = await browser.newPage();
+  // 设置浏览器视窗
+  page.setViewport({
+    width: 1920,
+    height: 1080,
+  })
+  // 地址栏输入网页地址
+  await page.goto(url, {
+    // 等界面加载完
+    waitUntil: 'networkidle0'
+  });
+  capchaAndUpload(page);
+  // 关闭浏览器
+  // await browser.close();
+};
+
+saveScreenshot('file:///Users/admin/Desktop/headless/index.html');
+
+async function capchaAndUpload(page) {
+  await page.waitForSelector('#title');
+  let store = await page.evaluate(() => JSON.stringify(localStorage));
+  store = JSON.parse(store)
+  let clip = await page.evaluate((scope) => {
+    let {
+      x,
+      y,
+      width,
+      height
+    } = document.getElementById('title').getBoundingClientRect();
+    window.scope = scope;
+    return {
+      x,
+      y,
+      width,
+      height
+    };
+  });
+  const filename = `./preview/${store.questionId}.png`;
+  const options = {
+    path: filename,
+    fullPage: false,
+    clip
+  }
+  await page.screenshot(options);
+  let buffers = fs.readFileSync(path.resolve(filename));//同步读取文件
+  let base64 = Buffer.from(buffers).toString('base64');//转为base64编码字符串
+  const formData = new FormData()
+  formData.append('questionId', store.questionId)
+  formData.append('imageBase64', base64)
+  const reqUrl = 'https://front.mingxuejinbang.com/prod-api/front/questionCollection/uploadQuestionImage';
+  axios.post(reqUrl, formData)
+    .then((res) => {
+      if (res.data.code === 200) {
+        console.log(store.questionId + '上传成功!')
+        // 获取下一个问题
+        page.click('#next');
+        setTimeout(() => {
+          capchaAndUpload(page);
+        }, 1000)
+      } else {
+        console.log('出错了')
+      }
+    });
+}

Fichier diff supprimé car celui-ci est trop grand
+ 6 - 0
public/collectImgNew/js/html2canvas.min.js


+ 17 - 0
public/collectImgNew/package.json

@@ -0,0 +1,17 @@
+{
+  "name": "headless",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "axios": "^0.27.2",
+    "form-data": "^4.0.0",
+    "formdata-node": "^4.3.3",
+    "puppeteer": "^15.1.1"
+  }
+}

BIN
public/usign2/yfe2.woff


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff