|
@@ -0,0 +1,891 @@
|
|
|
+<template>
|
|
|
+ <section>
|
|
|
+ <div class="breadcrumb" style="background-color: #fff;padding: 20px 10px 10px;">
|
|
|
+ <el-breadcrumb separator="/">
|
|
|
+ <el-breadcrumb-item>阅卷管理</el-breadcrumb-item>
|
|
|
+ <el-breadcrumb-item><a href="javascript:history.back(-1)">阅卷任务</a></el-breadcrumb-item>
|
|
|
+ <el-breadcrumb-item>{{title}}</el-breadcrumb-item>
|
|
|
+ </el-breadcrumb>
|
|
|
+ </div>
|
|
|
+ <div class="tab">
|
|
|
+ <!-- <el-button type="primary">确认提交</el-button> -->
|
|
|
+
|
|
|
+ <el-tabs v-model="tab_index" @tab-click="handleClick">
|
|
|
+ <el-tab-pane label="按试题批阅" name="1"></el-tab-pane>
|
|
|
+ <el-tab-pane label="按学生批阅" name="2"></el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ <div class="yj_area">
|
|
|
+ <div class="left" v-if="list1.length>0">
|
|
|
+ <template v-if='tab_index == "1"'>
|
|
|
+ <p>第 <b>{{list1[qno_index].qno}}</b> 题 <span><b>{{stu_index+1}}</b>/{{list1[qno_index].total}}人</span></p>
|
|
|
+ <ul>
|
|
|
+ <li v-for="(item,index) in list2" :key='index' :class="stu_index==index?'act':''" @click="changeStu(index)">
|
|
|
+ <p>{{index+1}}.{{item.student_name}} <span>{{item.mark_score}}分</span></p>
|
|
|
+ <img :src="item.imgs" alt="">
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <ul>
|
|
|
+ <li v-for="(item,index) in list1" :key='index' :class="stu_index==index?'act':''" @click="changeStu(index)">
|
|
|
+ <p>{{index+1}}.{{item.student_name}}</p>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <!-- 批阅区 -->
|
|
|
+ <div class="mark_area">
|
|
|
+ <div class="canvas-wraper">
|
|
|
+ <canvas id="canvas" ref="canvas"></canvas>
|
|
|
+ </div>
|
|
|
+ <div class="tool_bar">
|
|
|
+ <!-- <i class="iconfont icondaikuanjisuanqi1"></i> -->
|
|
|
+ <i
|
|
|
+ class="iconfont iconyoushang"
|
|
|
+ @click="handleTools(toolsArr[2], 2)"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class="iconfont icontuoyuan"
|
|
|
+ @click="handleTools(toolsArr[7], 7)"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class="iconfont iconhuabi"
|
|
|
+ @click="handleTools(toolsArr[4], 4)"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class="iconfont iconziti"
|
|
|
+ @click="handleTools(toolsArr[4], 4)"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class="iconfont iconchehui"
|
|
|
+ @click="handleTools(toolsArr[10], 10)"
|
|
|
+ ></i>
|
|
|
+ <i
|
|
|
+ class="iconfont iconqianjin-"
|
|
|
+ @click="handleTools(toolsArr[11], 11)"
|
|
|
+ ></i>
|
|
|
+ <span v-if="list2.length>0">{{list2[stu_index].student_name}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 进度 -->
|
|
|
+ <div class="progress">
|
|
|
+ <div class="mark_df">
|
|
|
+ <div class="df_title">
|
|
|
+ <b>智能阅卷打分板</b><br>
|
|
|
+ <span v-if="list2.length>0">
|
|
|
+ 第{{tab_index==1 ? list1[qno_index].qno : list2[qno_index].qno}}题
|
|
|
+ 满分:{{tab_index==1 ? list2[stu_index].std_score : list2[qno_index].std_score}}分
|
|
|
+ </span>
|
|
|
+ <input type="text" v-model="score">
|
|
|
+ </div>
|
|
|
+ <div class="df_pane">
|
|
|
+ <div class="df_num">
|
|
|
+ <div v-for="item in number" @click="markScore(item)">{{item}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="df_score">
|
|
|
+ <div @click="prev">{{tab_index=='1'?'上一位':'上一题'}}</div>
|
|
|
+ <div @click="next">{{tab_index=='1'?'下一位':'下一题'}}</div>
|
|
|
+ <div class="button" @click="submit">提交</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <template v-if='tab_index == 1'>
|
|
|
+ <p>批阅进度</p>
|
|
|
+ <ul>
|
|
|
+ <li v-for="(item,index) in list1" :key='index' :class="qno_index==index?'act':''" @click="changeQno(index)">
|
|
|
+ <span>第{{item.qno}}题</span>
|
|
|
+ <el-progress :show-text='false' :percentage="item.mark_num/item.total*100"></el-progress>
|
|
|
+ <span>{{item.mark_num}}/{{item.total}}人</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <p>试题</p>
|
|
|
+ <ul class="papers">
|
|
|
+ <li v-for="(item,index) in list2" :key='index' :class="qno_index==index?'act':''" @click="changeQno(index)">
|
|
|
+ <img width="100%" :src="item.imgs" alt=""><br>
|
|
|
+ <span style="margin: 10px auto;">第{{item.qno}}题({{item.mark_score}}分)</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </section>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import { fabric } from 'fabric'
|
|
|
+ // var fabricObj=null
|
|
|
+ export default{
|
|
|
+ data(){
|
|
|
+ return{
|
|
|
+ tab_index:'2',
|
|
|
+ title:'',
|
|
|
+ parm:{
|
|
|
+ mark_type:2, //批阅方式
|
|
|
+ task_id:''
|
|
|
+ },
|
|
|
+ list1:[],
|
|
|
+ list2:[],
|
|
|
+ qno_index:0, //题号索引
|
|
|
+ stu_index:0, //学生索引(左侧列表)
|
|
|
+ number:[1,2,3,4,5,6,7,8,9,'满分',0,'X'],
|
|
|
+ score:'',
|
|
|
+ first:1,
|
|
|
+ lock: true,
|
|
|
+ drawColor: "#E34F51",
|
|
|
+ fabricObj: null,
|
|
|
+ initIdx: 0,
|
|
|
+ currentTool: '',
|
|
|
+ mouseFrom:{},
|
|
|
+ mouseTo:{},
|
|
|
+ moveCount: 1,
|
|
|
+ doDrawing: false,
|
|
|
+ fabricHistoryJson: [],
|
|
|
+ mods: 0,
|
|
|
+ drawingObject: null, //绘制对象
|
|
|
+ drawColor: '#E34F51',
|
|
|
+ drawWidth: 2,
|
|
|
+ toolsArr: [
|
|
|
+ {
|
|
|
+ name: 'pencil',
|
|
|
+ icon: ' icon-pencil'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'line',
|
|
|
+ icon: ' icon-line'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'arrow',
|
|
|
+ icon: ' icon-arrow'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'dashedline',
|
|
|
+ icon: ' icon-xuxian'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'text',
|
|
|
+ icon: ' icon-ziti'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'rectangle',
|
|
|
+ icon: ' icon-juxing'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'circle',
|
|
|
+ icon: ' icon-yuanxing'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'ellipse',
|
|
|
+ icon: ' icon-tuoyuanxing'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'equilateral', //三角形
|
|
|
+ icon: ' icon-sanjiaoxing'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'remove',
|
|
|
+ icon: ' icon-remove'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'undo',
|
|
|
+ icon: ' icon-huitui'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'redo',
|
|
|
+ icon: ' icon-xiangqian'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'reset',
|
|
|
+ icon: ' icon-reset'
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods:{
|
|
|
+ // 切换阅卷方式
|
|
|
+ handleClick(tab){
|
|
|
+ this.parm.mark_type=this.tab_index
|
|
|
+ this.stu_index=0
|
|
|
+ this.qno_index=0
|
|
|
+ this.list1=[]
|
|
|
+ this.list2=[]
|
|
|
+ this.getData()
|
|
|
+ },
|
|
|
+ // 获取进度
|
|
|
+ getData(){
|
|
|
+ let parm=this.parm
|
|
|
+ this.$api.progress(parm).then(res=>{
|
|
|
+ if(res.data.code == 0){
|
|
|
+ this.list1=res.data.data
|
|
|
+ this.getDataDetail()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 获取详情
|
|
|
+ getDataDetail(){
|
|
|
+ let parm=this.parm
|
|
|
+ if(this.tab_index == 1){
|
|
|
+ parm.qno=this.list1[this.qno_index].qno
|
|
|
+ }else{
|
|
|
+ parm.student_id=this.list1[this.stu_index].student_id
|
|
|
+ }
|
|
|
+ this.$api.progressDetail(parm).then(res=>{
|
|
|
+ if(res.data.code == 0){
|
|
|
+ this.list2=res.data.data
|
|
|
+ this.score=res.data.data[0].mark_score?res.data.data[0].mark_score:''
|
|
|
+
|
|
|
+ setTimeout(()=>{
|
|
|
+ // init(res.data.data[0].imgs)
|
|
|
+ this.init(res.data.data[0].imgs)
|
|
|
+ },100)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ //切换题目
|
|
|
+ changeQno(index){
|
|
|
+ this.qno_index=index
|
|
|
+ this.first=1
|
|
|
+ if(this.tab_index == 1){
|
|
|
+ this.list2=[]
|
|
|
+ this.stu_index=0
|
|
|
+ this.getDataDetail()
|
|
|
+ }else{
|
|
|
+
|
|
|
+ init(this.list2[index].imgs)
|
|
|
+ this.score=this.list2[index].mark_score?this.list2[index].mark_score:''
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ //切换学生
|
|
|
+ changeStu(index){
|
|
|
+ this.stu_index=index
|
|
|
+ this.first=1
|
|
|
+ if(this.tab_index == 1){
|
|
|
+ this.score=this.list2[index].mark_score?this.list2[index].mark_score:''
|
|
|
+ init(this.list2[index].imgs)
|
|
|
+ }else{
|
|
|
+ this.list2=[]
|
|
|
+ this.qno_index=0
|
|
|
+ this.getDataDetail()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //下一位
|
|
|
+ next(){
|
|
|
+ if(this.parm.mark_type == 1){
|
|
|
+ this.submit()
|
|
|
+ if(this.stu_index >= this.list2.length-1){
|
|
|
+ setTimeout(() => {
|
|
|
+ this.$message(
|
|
|
+ {
|
|
|
+ message: "已经是最后一位了哦,请选择下一题",
|
|
|
+ type: "warning",
|
|
|
+ },1000);
|
|
|
+ },1000);
|
|
|
+ }else{
|
|
|
+ let index=this.stu_index+1
|
|
|
+ this.changeStu(index)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ prev(){
|
|
|
+ if(this.parm.mark_type == 1){
|
|
|
+ if(this.stu_index == 0){
|
|
|
+ this.$message({
|
|
|
+ message: "已经是第一位了哦",
|
|
|
+ type: "warning",
|
|
|
+ },1000);
|
|
|
+ }else{
|
|
|
+ let index=this.stu_index-1
|
|
|
+ this.changeStu(index)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //打分
|
|
|
+ markScore(item){
|
|
|
+ var score=String(this.score)
|
|
|
+ var full=this.list2[this.stu_index].std_score
|
|
|
+ if(this.tab_index == 2){
|
|
|
+ full=this.list2[this.qno_index].std_score
|
|
|
+ }
|
|
|
+ if(item == '满分'){
|
|
|
+ item=full
|
|
|
+ }else if(item == 'X'){
|
|
|
+ item=''
|
|
|
+ }else{
|
|
|
+ if(this.first){
|
|
|
+ this.first=0
|
|
|
+ }else if(score.length<2){
|
|
|
+ item=score+item
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.score=item
|
|
|
+ },
|
|
|
+ submit(){
|
|
|
+ var score=this.score
|
|
|
+ var full=this.list2[this.stu_index].std_score
|
|
|
+ if(this.tab_index == 2){
|
|
|
+ full=this.list2[this.qno_index].std_score
|
|
|
+ }
|
|
|
+ if (!this.lock) {
|
|
|
+ this.$message.warning("正在打分中~");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.lock = false;
|
|
|
+ setTimeout(() => {
|
|
|
+ this.lock = true;
|
|
|
+ }, 2000);
|
|
|
+ var pattern = /^([1-9]\d*|0)$/;
|
|
|
+ if (!score) {
|
|
|
+ this.$message.warning("还没打分哦~");
|
|
|
+ return;
|
|
|
+ } else if (!pattern.test(score)) {
|
|
|
+ this.$message.warning("分数输入不正确");
|
|
|
+ return;
|
|
|
+ } else if (Number(score) > full) {
|
|
|
+ this.$message.warning(
|
|
|
+ "批阅得分大于试题满分,本题满分为:" +
|
|
|
+ full + "分"
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.downLoadImage()
|
|
|
+ this.reviewSucc()
|
|
|
+ },
|
|
|
+ //提交
|
|
|
+ reviewSucc() {
|
|
|
+ var img_url='',score=this.score
|
|
|
+ var data=this.list2[this.stu_index];
|
|
|
+ if(this.tab_index == 2){
|
|
|
+ data=this.list2[this.qno_index]
|
|
|
+ }
|
|
|
+ let obj={
|
|
|
+ mark_imgs:img_url,
|
|
|
+ task_id:data.task_id,
|
|
|
+ student_id:data.student_id,
|
|
|
+ qno:data.qno,
|
|
|
+ score:score
|
|
|
+ }
|
|
|
+ this.$api.mark(obj).then(res=>{
|
|
|
+ if (res.data.code == 0) {
|
|
|
+ this.score=''
|
|
|
+ this.$message.success("批阅成功");
|
|
|
+ this.getDataDetail()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ init(url){
|
|
|
+ var width=document.querySelector('.mark_area').clientWidth
|
|
|
+ this.fabricObj = new fabric.Canvas("canvas", {
|
|
|
+ isDrawingMode: true,
|
|
|
+ selectable: false,
|
|
|
+ selection: false,
|
|
|
+ devicePixelRatio: true, //Retina 高清屏 屏幕支持
|
|
|
+ });
|
|
|
+ this.fabricObj.freeDrawingBrush.color = "#E34F51";
|
|
|
+ this.fabricObj.freeDrawingBrush.width = 2;
|
|
|
+ this.fabricObj.setWidth(width);
|
|
|
+ this.fabricObj.setHeight(600);
|
|
|
+ var imgElement = new Image();
|
|
|
+ imgElement.src = url;
|
|
|
+ var that=this
|
|
|
+ imgElement.onload=function(){
|
|
|
+ var legimg = new fabric.Image(imgElement,{ //设置图片位置和样子
|
|
|
+ left:10,
|
|
|
+ top:50,
|
|
|
+ width:imgElement.width,
|
|
|
+ height:imgElement.height,
|
|
|
+ angle:0,//设置图形顺时针旋转角度
|
|
|
+ });
|
|
|
+ that.fabricObj.add(legimg);
|
|
|
+ }
|
|
|
+ this.fabricObjAddEvent()
|
|
|
+ },
|
|
|
+ downLoadImage(){
|
|
|
+ var width=document.querySelector('.mark_area').clientWidth
|
|
|
+ var text = new fabric.Textbox(this.score + "分", {
|
|
|
+ left: width-100,
|
|
|
+ top: 30,
|
|
|
+ width: 20,
|
|
|
+ fontSize: 32,
|
|
|
+ fill: this.drawColor,
|
|
|
+ hasControls: true,
|
|
|
+ });
|
|
|
+ this.fabricObj.add(text);
|
|
|
+ //生成双倍像素比的图片
|
|
|
+ let base64URl = this.fabricObj.toDataURL({
|
|
|
+ formart: "jpg",
|
|
|
+ });
|
|
|
+ console.log(base64URl)
|
|
|
+ },
|
|
|
+ fabricObjAddEvent() {
|
|
|
+ this.fabricObj.on({
|
|
|
+ 'mouse:down': (o)=> {
|
|
|
+ this.mouseFrom.x = o.pointer.x;
|
|
|
+ this.mouseFrom.y = o.pointer.y;
|
|
|
+ this.doDrawing = true;
|
|
|
+ if(this.currentTool=='text') {
|
|
|
+ this.drawText()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ 'mouse:up': (o)=> {
|
|
|
+ this.mouseTo.x = o.pointer.x;
|
|
|
+ this.mouseTo.y = o.pointer.y;
|
|
|
+ this.drawingObject = null;
|
|
|
+ this.moveCount = 1;
|
|
|
+ this.doDrawing = false;
|
|
|
+ this.updateModifications(true);
|
|
|
+ },
|
|
|
+ 'mouse:move': (o)=> {
|
|
|
+ if (this.moveCount % 2 && !this.doDrawing) {
|
|
|
+ //减少绘制频率
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.moveCount++;
|
|
|
+ this.mouseTo.x = o.pointer.x;
|
|
|
+ this.mouseTo.y = o.pointer.y;
|
|
|
+ this.drawing();
|
|
|
+ },
|
|
|
+ //对象移动时间
|
|
|
+ 'object:moving': (e)=> {
|
|
|
+ e.target.opacity = 0.5;
|
|
|
+ },
|
|
|
+ //增加对象
|
|
|
+ 'object:added': ()=>{
|
|
|
+ // debugger
|
|
|
+ },
|
|
|
+ 'object:modified':(e)=> {
|
|
|
+ e.target.opacity = 1;
|
|
|
+ // let object = e.target;
|
|
|
+ this.updateModifications(true)
|
|
|
+ },
|
|
|
+ 'selection:created': (e)=>{
|
|
|
+ if (e.target._objects) {
|
|
|
+ //多选删除
|
|
|
+ var etCount = e.target._objects.length;
|
|
|
+ for (var etindex = 0; etindex < etCount; etindex++) {
|
|
|
+ this.fabricObj.remove(e.target._objects[etindex]);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //单选删除
|
|
|
+ this.fabricObj.remove(e.target);
|
|
|
+ }
|
|
|
+ this.fabricObj.discardActiveObject(); //清楚选中框
|
|
|
+ this.updateModifications(true)
|
|
|
+ },
|
|
|
+ });
|
|
|
+ },
|
|
|
+ //储存历史记录
|
|
|
+ updateModifications(savehistory) {
|
|
|
+ if(savehistory==true) {
|
|
|
+ this.fabricHistoryJson.push(JSON.stringify(this.fabricObj))
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //canvas 历史后退
|
|
|
+ undo() {
|
|
|
+ let state = this.fabricHistoryJson
|
|
|
+ if(this.mods < state.length) {
|
|
|
+ this.fabricObj.clear().renderAll();
|
|
|
+ this.fabricObj.loadFromJSON(state[state.length - 1 - this.mods - 1]);
|
|
|
+ this.fabricObj.renderAll();
|
|
|
+ this.mods += 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //前进
|
|
|
+ redo() {
|
|
|
+ let state = this.fabricHistoryJson
|
|
|
+ if (this.mods > 0) {
|
|
|
+ this.fabricObj.clear().renderAll();
|
|
|
+ this.fabricObj.loadFromJSON(state[state.length - 1 - this.mods + 1]);
|
|
|
+ this.fabricObj.renderAll();
|
|
|
+ this.mods -= 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ transformMouse(mouseX, mouseY) {
|
|
|
+ return { x: mouseX / this.zoom, y: mouseY / this.zoom };
|
|
|
+ },
|
|
|
+ resetObj() {
|
|
|
+ this.fabricObj.selectable = false
|
|
|
+ this.fabricObj.selection = false
|
|
|
+ this.fabricObj.skipTargetFind = true
|
|
|
+ //清除文字对象
|
|
|
+ if(this.textboxObj) {
|
|
|
+ this.textboxObj.exitEditing();
|
|
|
+ this.textboxObj = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ handleTools(tools, idx) {
|
|
|
+ this.initIdx = idx;
|
|
|
+ this.currentTool = tools.name;
|
|
|
+ this.fabricObj.isDrawingMode = false;
|
|
|
+ this.resetObj()
|
|
|
+ switch(tools.name) {
|
|
|
+ case 'pencil':
|
|
|
+ this.fabricObj.isDrawingMode = true;
|
|
|
+ break;
|
|
|
+ case 'remove':
|
|
|
+ this.fabricObj.selection = true
|
|
|
+ this.fabricObj.skipTargetFind = false
|
|
|
+ this.fabricObj.selectable = true
|
|
|
+ break;
|
|
|
+ case 'reset':
|
|
|
+ this.fabricObj.clear();
|
|
|
+ break;
|
|
|
+ case 'redo':
|
|
|
+ this.redo();
|
|
|
+ break;
|
|
|
+ case 'undo':
|
|
|
+ this.undo();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //绘制文字对象
|
|
|
+ drawText() {
|
|
|
+ this.textboxObj = new fabric.Textbox(" ", {
|
|
|
+ left: this.mouseFrom.x,
|
|
|
+ top: this.mouseFrom.y,
|
|
|
+ width: 220,
|
|
|
+ fontSize: 18,
|
|
|
+ fill: this.drawColor,
|
|
|
+ hasControls: true
|
|
|
+ });
|
|
|
+ this.fabricObj.add(this.textboxObj);
|
|
|
+ this.textboxObj.enterEditing();
|
|
|
+ this.textboxObj.hiddenTextarea.focus();
|
|
|
+ this.updateModifications(true)
|
|
|
+ },
|
|
|
+ drawing() {
|
|
|
+ if(this.drawingObject) {
|
|
|
+ this.fabricObj.remove(this.drawingObject)
|
|
|
+ }
|
|
|
+ let fabricObject = null
|
|
|
+ switch (this.currentTool) {
|
|
|
+ case 'pencil':
|
|
|
+ this.fabricObj.isDrawingMode = true
|
|
|
+ break;
|
|
|
+ case 'line':
|
|
|
+ fabricObject = new fabric.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y],{
|
|
|
+ stroke: this.drawColor,
|
|
|
+ strokeWidth: this.drawWidth
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ case 'arrow':
|
|
|
+ fabricObject = new fabric.Path(this.drawArrow(this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y, 15.5, 15.5), {
|
|
|
+ stroke: this.drawColor,
|
|
|
+ fill: "rgba(255,255,255,0)",
|
|
|
+ strokeWidth: this.drawWidth
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ case 'dashedline':
|
|
|
+ // doshed line
|
|
|
+ fabricObject = this.drawDoshedLine()
|
|
|
+ break;
|
|
|
+ case 'rectangle':
|
|
|
+ // 矩形
|
|
|
+ fabricObject = this.drawRectangle()
|
|
|
+ break;
|
|
|
+ case "circle": //正圆
|
|
|
+ fabricObject = this.drawCircle()
|
|
|
+ break;
|
|
|
+ case "ellipse":
|
|
|
+ // 椭圆
|
|
|
+ fabricObject = this.drawEllipse()
|
|
|
+ break;
|
|
|
+ case "equilateral": //等边三角形
|
|
|
+ fabricObject = this.drawTriangle()
|
|
|
+ break;
|
|
|
+ case 'remove':
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ // statements_def'
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ if(fabricObject) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.fabricObj.add(fabricObject)
|
|
|
+ this.drawingObject = fabricObject
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // dashed line
|
|
|
+ drawDoshedLine() {
|
|
|
+ return new fabric.Line([this.mouseFrom.x, this.mouseFrom.y, this.mouseTo.x, this.mouseTo.y],{
|
|
|
+ strokeDashArray: [10, 3],
|
|
|
+ stroke: this.drawColor,
|
|
|
+ strokeWidth: this.drawWidth
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // circle
|
|
|
+ drawCircle() {
|
|
|
+ let radius = Math.sqrt((this.mouseTo.x - this.mouseFrom.x) * (this.mouseTo.x - this.mouseFrom.x) + (this.mouseTo.y - this.mouseFrom.y) * (this.mouseTo.y - this.mouseFrom.y)) / 2;
|
|
|
+ return new fabric.Circle({
|
|
|
+ left: this.mouseFrom.x,
|
|
|
+ top: this.mouseFrom.y,
|
|
|
+ stroke: this.drawColor,
|
|
|
+ fill: "rgba(255, 255, 255, 0)",
|
|
|
+ radius: radius,
|
|
|
+ strokeWidth: this.drawWidth
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // triangle
|
|
|
+ drawTriangle() {
|
|
|
+ let height = this.mouseTo.y - this.mouseFrom.y
|
|
|
+ return new fabric.Triangle({
|
|
|
+ top: this.mouseFrom.y,
|
|
|
+ left: this.mouseFrom.x,
|
|
|
+ width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2.0, 2)),
|
|
|
+ height: height,
|
|
|
+ stroke: this.drawColor,
|
|
|
+ strokeWidth: this.drawWidth,
|
|
|
+ fill: "rgba(255,255,255,0)"
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // ellipse
|
|
|
+ drawEllipse() {
|
|
|
+ let left = this.mouseFrom.x
|
|
|
+ let top = this.mouseFrom.y
|
|
|
+ // let ellipse = Math.sqrt((this.mouseTo.x - left) * (this.mouseTo.x - left) + (this.mouseTo.y - top) * (this.mouseTo.y - top)) / 2;
|
|
|
+ return new fabric.Ellipse({
|
|
|
+ left: left,
|
|
|
+ top: top,
|
|
|
+ stroke: this.drawColor,
|
|
|
+ fill: "rgba(255, 255, 255, 0)",
|
|
|
+ originX: "center",
|
|
|
+ originY: "center",
|
|
|
+ rx: Math.abs(left - this.mouseTo.x),
|
|
|
+ ry: Math.abs(top - this.mouseTo.y),
|
|
|
+ strokeWidth: this.drawWidth
|
|
|
+ });
|
|
|
+ },
|
|
|
+ },
|
|
|
+ created(){
|
|
|
+ this.title = this.$route.query.title;
|
|
|
+ this.parm.task_id = this.$route.query.id;
|
|
|
+ this.getData()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+
|
|
|
+ .yj_area{
|
|
|
+ display: flex;
|
|
|
+ min-height: 80vh;
|
|
|
+ justify-content: space-between;
|
|
|
+ .left{
|
|
|
+ width: 200px;
|
|
|
+ background-color: #fff;
|
|
|
+ &>p{
|
|
|
+ padding: 10px;
|
|
|
+ font-size: 12px;
|
|
|
+ span{
|
|
|
+ float: right;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ b{
|
|
|
+ color: #0a9dff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ul{
|
|
|
+ height: 100%;
|
|
|
+ overflow: auto;
|
|
|
+ li{
|
|
|
+ list-style: none;
|
|
|
+ cursor: pointer;
|
|
|
+ padding: 10px 15px;
|
|
|
+ transition: .3s;
|
|
|
+ font-size: 12px;
|
|
|
+ span{
|
|
|
+ float: right;
|
|
|
+ }
|
|
|
+ img{
|
|
|
+ width: 100%;
|
|
|
+ height: 70px;
|
|
|
+ display: block;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+ &.act{
|
|
|
+ background-color: #ffe8ec;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #FA0A2F;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .progress{
|
|
|
+ width: 300px;
|
|
|
+ /* margin-top: 20px; */
|
|
|
+ background-color: #fff;
|
|
|
+ padding: 15px;
|
|
|
+ position: relative;
|
|
|
+ p{
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ ul{
|
|
|
+ /* height: 450px; */
|
|
|
+ /* overflow: auto; */
|
|
|
+ }
|
|
|
+ li{
|
|
|
+ list-style: none;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding: 10px;
|
|
|
+ margin: 5px 0;
|
|
|
+ font-size: 13px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: .3s;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ &.act{
|
|
|
+ background-color: #ffe8ec;
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ .el-progress{
|
|
|
+ width: 60% !important;
|
|
|
+ top: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .mark_df{
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ height: 270px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ .df_title{
|
|
|
+ padding: 10px;
|
|
|
+ height: 60px;
|
|
|
+ background-image: linear-gradient(180deg, #9ac7ff, #ffffff);
|
|
|
+ position: relative;
|
|
|
+ input{
|
|
|
+ position: absolute;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ height: 40px;
|
|
|
+ width: 70px;
|
|
|
+ top: 10px;
|
|
|
+ right: 10px;
|
|
|
+ text-align: center;
|
|
|
+ outline: none;
|
|
|
+ }
|
|
|
+ b{
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ color: #0a9dff;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .df_pane{
|
|
|
+ display: flex;
|
|
|
+ /* justify-content: space-between; */
|
|
|
+ border: 1px solid #DCDFE6;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ .df_num{
|
|
|
+ width: 65%;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ div{
|
|
|
+ width: 33.33%;
|
|
|
+ height: 50px;
|
|
|
+ border: .5px solid #DCDFE6;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 40px;
|
|
|
+ font-size: 13px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .df_score{
|
|
|
+ width: 35%;
|
|
|
+ .button{
|
|
|
+ background-color: #0a9dff;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ div{
|
|
|
+ height: 33.33%;
|
|
|
+ border: .5px solid #DCDFE6;
|
|
|
+ text-align: center;
|
|
|
+ line-height: 61px;
|
|
|
+ font-size: 14px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .papers{
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ li{
|
|
|
+ width: 47%;
|
|
|
+ height: 110px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .mark_area{
|
|
|
+ background-color: #dfeeff;
|
|
|
+ width: 70%;
|
|
|
+ /* height: 100%; */
|
|
|
+ position: relative;
|
|
|
+ .canvas-wraper{
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ canvas{
|
|
|
+ cursor: crosshair;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .tool_bar{
|
|
|
+ width: 98%;
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ background: #fff;
|
|
|
+ -webkit-box-shadow: 0px 4px 4px 0px #d0dae5;
|
|
|
+ box-shadow: 0px 4px 4px 0px #d0dae5;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-bottom: 15px;
|
|
|
+ padding: 0 15px;
|
|
|
+ position: absolute;
|
|
|
+ top: 10px;
|
|
|
+ left: 1%;
|
|
|
+ i{
|
|
|
+ margin: 0 10px;
|
|
|
+ color: #333;
|
|
|
+ font-size: 15px;
|
|
|
+ }
|
|
|
+ span{
|
|
|
+ float: right;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .tab{
|
|
|
+ padding:5px 10px;
|
|
|
+ background-color: #fff;
|
|
|
+ /* box-shadow: 0 1px 3px 0px rgba(0,0,0,.1); */
|
|
|
+ margin:0 0 10px;
|
|
|
+ /* border: 1px solid #d9d9d9; */
|
|
|
+ .el-tabs__nav-wrap::after{
|
|
|
+ background: none;
|
|
|
+ }
|
|
|
+ .el-tabs__item.is-active{
|
|
|
+ color: #FA0A2F;
|
|
|
+ }
|
|
|
+ .el-tabs__active-bar{
|
|
|
+ background-color: #FA0A2F;
|
|
|
+ }
|
|
|
+ button{
|
|
|
+ float: right;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+</style>
|