From 5f8ea627d09b001025eca6cd202398c0f8826741 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=99=BD=E4=BA=86=E4=B8=AA=E7=99=BD?= <543593352@qq.com>
Date: Tue, 24 Sep 2024 11:02:04 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E4=B8=9A=E8=AE=BE=E8=AE=A1-=E8=AF=BE?=
=?UTF-8?q?=E5=A0=82=E5=B1=95=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 5 +-
.../whiteboard/components/ColorPicker.vue | 130 +++
.../whiteboard/components/Contextmenu.vue | 213 ++++
.../src/components/whiteboard/constants.js | 120 +++
.../src/components/whiteboard/libs/icons.svg | 1 +
.../components/whiteboard/libs/jsonTree.css | 107 ++
.../components/whiteboard/libs/jsonTree.js | 822 ++++++++++++++++
.../src/components/whiteboard/whiteboard.vue | 913 ++++++++++++++++++
.../container/newTask/taskTypeView.vue | 366 +++----
9 files changed, 2504 insertions(+), 173 deletions(-)
create mode 100644 src/renderer/src/components/whiteboard/components/ColorPicker.vue
create mode 100644 src/renderer/src/components/whiteboard/components/Contextmenu.vue
create mode 100644 src/renderer/src/components/whiteboard/constants.js
create mode 100644 src/renderer/src/components/whiteboard/libs/icons.svg
create mode 100644 src/renderer/src/components/whiteboard/libs/jsonTree.css
create mode 100644 src/renderer/src/components/whiteboard/libs/jsonTree.js
create mode 100644 src/renderer/src/components/whiteboard/whiteboard.vue
diff --git a/package.json b/package.json
index 9f245d7..bd68669 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,10 @@
"vue-qr": "^4.0.9",
"vue-router": "^4.4.0",
"xgplayer": "^3.0.19",
- "xlsx": "^0.18.5"
+ "xlsx": "^0.18.5",
+ "less": "^4.2.0",
+ "less-loader": "^7.3.0",
+ "whiteboard_lyc": "^0.0.8"
},
"devDependencies": {
"@electron-toolkit/eslint-config": "^1.0.2",
diff --git a/src/renderer/src/components/whiteboard/components/ColorPicker.vue b/src/renderer/src/components/whiteboard/components/ColorPicker.vue
new file mode 100644
index 0000000..a819480
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/components/ColorPicker.vue
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
diff --git a/src/renderer/src/components/whiteboard/components/Contextmenu.vue b/src/renderer/src/components/whiteboard/components/Contextmenu.vue
new file mode 100644
index 0000000..691f0bd
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/components/Contextmenu.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
diff --git a/src/renderer/src/components/whiteboard/constants.js b/src/renderer/src/components/whiteboard/constants.js
new file mode 100644
index 0000000..5209a6e
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/constants.js
@@ -0,0 +1,120 @@
+// 描边颜色
+export const strokeColorList = [
+ '#000000',
+ '#343a40',
+ '#495057',
+ '#c92a2a',
+ '#a61e4d',
+ '#862e9c',
+ '#5f3dc4',
+ '#364fc7',
+ '#1864ab',
+ '#0b7285',
+ '#087f5b',
+ '#2b8a3e',
+ '#5c940d',
+ '#e67700',
+ '#d9480f'
+]
+
+// 填充颜色
+export const fillColorList = [
+ 'transparent',
+ '#ced4da',
+ '#868e96',
+ '#fa5252',
+ '#e64980',
+ '#be4bdb',
+ '#7950f2',
+ '#4c6ef5',
+ '#228be6',
+ '#15aabf',
+ '#12b886',
+ '#40c057',
+ '#82c91e',
+ '#fab005',
+ '#fd7e14'
+]
+
+// 背景颜色
+export const backgroundColorList = [
+ '#ffffff',
+ '#f8f9fa',
+ '#f1f3f5',
+ '#fff5f5',
+ '#fff0f6',
+ '#f8f0fc',
+ '#f3f0ff',
+ '#edf2ff',
+ '#e7f5ff',
+ '#e3fafc',
+ '#e6fcf5',
+ '#ebfbee',
+ '#f4fce3',
+ '#fff9db',
+ '#fff4e6'
+]
+
+// 字体列表
+export const fontFamilyList = [
+ {
+ name: '微软雅黑',
+ value: '微软雅黑, Microsoft YaHei'
+ },
+ {
+ name: '宋体',
+ value: '宋体, SimSun, Songti SC'
+ },
+ {
+ name: '楷体',
+ value: '楷体, 楷体_GB2312, SimKai, STKaiti'
+ },
+ {
+ name: '黑体',
+ value: '黑体, SimHei, Heiti SC'
+ },
+ {
+ name: '隶书',
+ value: '隶书, SimLi'
+ },
+ {
+ name: 'Andale Mono',
+ value: 'andale mono'
+ },
+ {
+ name: 'Arial',
+ value: 'arial, helvetica, sans-serif'
+ },
+ {
+ name: 'arialBlack',
+ value: 'arial black, avant garde'
+ },
+ {
+ name: 'Comic Sans Ms',
+ value: 'comic sans ms'
+ },
+ {
+ name: 'Impact',
+ value: 'impact, chicago'
+ },
+ {
+ name: 'Times New Roman',
+ value: 'times new roman'
+ },
+ {
+ name: 'Sans-Serif',
+ value: 'sans-serif'
+ },
+ {
+ name: 'serif',
+ value: 'serif'
+ }
+]
+
+// 字号
+export const fontSizeList = [10, 12, 16, 18, 24, 32, 48].map(item => {
+ return {
+ name: item,
+ value: item
+ }
+})
diff --git a/src/renderer/src/components/whiteboard/libs/icons.svg b/src/renderer/src/components/whiteboard/libs/icons.svg
new file mode 100644
index 0000000..cc8298a
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/libs/icons.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/src/components/whiteboard/libs/jsonTree.css b/src/renderer/src/components/whiteboard/libs/jsonTree.css
new file mode 100644
index 0000000..3812440
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/libs/jsonTree.css
@@ -0,0 +1,107 @@
+/*
+ * JSON Tree Viewer
+ * http://github.com/summerstyle/jsonTreeViewer
+ *
+ * Copyright 2017 Vera Lobacheva (http://iamvera.com)
+ * Released under the MIT license (LICENSE.txt)
+ */
+
+/* Background for the tree. May use for
element */
+.jsontree_bg {
+ background: #FFF;
+}
+
+/* Styles for the container of the tree (e.g. fonts, margins etc.) */
+.jsontree_tree {
+ margin-left: 30px;
+ font-family: 'PT Mono', monospace;
+ font-size: 14px;
+}
+
+/* Styles for a list of child nodes */
+.jsontree_child-nodes {
+ display: none;
+ margin-left: 35px;
+ margin-bottom: 5px;
+ line-height: 2;
+}
+.jsontree_node_expanded > .jsontree_value-wrapper > .jsontree_value > .jsontree_child-nodes {
+ display: block;
+}
+
+/* Styles for labels */
+.jsontree_label-wrapper {
+ float: left;
+ margin-right: 8px;
+}
+.jsontree_label {
+ font-weight: normal;
+ vertical-align: top;
+ color: #000;
+ position: relative;
+ padding: 1px;
+ border-radius: 4px;
+ cursor: default;
+}
+.jsontree_node_marked > .jsontree_label-wrapper > .jsontree_label {
+ background: #fff2aa;
+}
+
+/* Styles for values */
+.jsontree_value-wrapper {
+ display: block;
+ overflow: hidden;
+}
+.jsontree_node_complex > .jsontree_value-wrapper {
+ overflow: inherit;
+}
+.jsontree_value {
+ vertical-align: top;
+ display: inline;
+}
+.jsontree_value_null {
+ color: #777;
+ font-weight: bold;
+}
+.jsontree_value_string {
+ color: #025900;
+ font-weight: bold;
+}
+.jsontree_value_number {
+ color: #000E59;
+ font-weight: bold;
+}
+.jsontree_value_boolean {
+ color: #600100;
+ font-weight: bold;
+}
+
+/* Styles for active elements */
+.jsontree_expand-button {
+ position: absolute;
+ top: 3px;
+ left: -15px;
+ display: block;
+ width: 11px;
+ height: 11px;
+ background-image: url('icons.svg');
+}
+.jsontree_node_expanded > .jsontree_label-wrapper > .jsontree_label > .jsontree_expand-button {
+ background-position: 0 -11px;
+}
+.jsontree_show-more {
+ cursor: pointer;
+}
+.jsontree_node_expanded > .jsontree_value-wrapper > .jsontree_value > .jsontree_show-more {
+ display: none;
+}
+.jsontree_node_empty > .jsontree_label-wrapper > .jsontree_label > .jsontree_expand-button,
+.jsontree_node_empty > .jsontree_value-wrapper > .jsontree_value > .jsontree_show-more {
+ display: none !important;
+}
+.jsontree_node_complex > .jsontree_label-wrapper > .jsontree_label {
+ cursor: pointer;
+}
+.jsontree_node_empty > .jsontree_label-wrapper > .jsontree_label {
+ cursor: default !important;
+}
diff --git a/src/renderer/src/components/whiteboard/libs/jsonTree.js b/src/renderer/src/components/whiteboard/libs/jsonTree.js
new file mode 100644
index 0000000..b2de406
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/libs/jsonTree.js
@@ -0,0 +1,822 @@
+/**
+ * JSON Tree library (a part of jsonTreeViewer)
+ * http://github.com/summerstyle/jsonTreeViewer
+ *
+ * Copyright 2017 Vera Lobacheva (http://iamvera.com)
+ * Released under the MIT license (LICENSE.txt)
+ */
+
+var jsonTree = (function() {
+
+ /* ---------- Utilities ---------- */
+ var utils = {
+
+ /*
+ * Returns js-"class" of value
+ *
+ * @param val {any type} - value
+ * @returns {string} - for example, "[object Function]"
+ */
+ getClass : function(val) {
+ return Object.prototype.toString.call(val);
+ },
+
+ /**
+ * Checks for a type of value (for valid JSON data types).
+ * In other cases - throws an exception
+ *
+ * @param val {any type} - the value for new node
+ * @returns {string} ("object" | "array" | "null" | "boolean" | "number" | "string")
+ */
+ getType : function(val) {
+ if (val === null) {
+ return 'null';
+ }
+
+ switch (typeof val) {
+ case 'number':
+ return 'number';
+
+ case 'string':
+ return 'string';
+
+ case 'boolean':
+ return 'boolean';
+ }
+
+ switch(utils.getClass(val)) {
+ case '[object Array]':
+ return 'array';
+
+ case '[object Object]':
+ return 'object';
+ }
+
+ throw new Error('Bad type: ' + utils.getClass(val));
+ },
+
+ /**
+ * Applies for each item of list some function
+ * and checks for last element of the list
+ *
+ * @param obj {Object | Array} - a list or a dict with child nodes
+ * @param func {Function} - the function for each item
+ */
+ forEachNode : function(obj, func) {
+ var type = utils.getType(obj),
+ isLast;
+
+ switch (type) {
+ case 'array':
+ isLast = obj.length - 1;
+
+ obj.forEach(function(item, i) {
+ func(i, item, i === isLast);
+ });
+
+ break;
+
+ case 'object':
+ var keys = Object.keys(obj).sort();
+
+ isLast = keys.length - 1;
+
+ keys.forEach(function(item, i) {
+ func(item, obj[item], i === isLast);
+ });
+
+ break;
+ }
+
+ },
+
+ /**
+ * Implements the kind of an inheritance by
+ * using parent prototype and
+ * creating intermediate constructor
+ *
+ * @param Child {Function} - a child constructor
+ * @param Parent {Function} - a parent constructor
+ */
+ inherits : (function() {
+ var F = function() {};
+
+ return function(Child, Parent) {
+ F.prototype = Parent.prototype;
+ Child.prototype = new F();
+ Child.prototype.constructor = Child;
+ };
+ })(),
+
+ /*
+ * Checks for a valid type of root node*
+ *
+ * @param {any type} jsonObj - a value for root node
+ * @returns {boolean} - true for an object or an array, false otherwise
+ */
+ isValidRoot : function(jsonObj) {
+ switch (utils.getType(jsonObj)) {
+ case 'object':
+ case 'array':
+ return true;
+ default:
+ return false;
+ }
+ },
+
+ /**
+ * Extends some object
+ */
+ extend : function(targetObj, sourceObj) {
+ for (var prop in sourceObj) {
+ if (sourceObj.hasOwnProperty(prop)) {
+ targetObj[prop] = sourceObj[prop];
+ }
+ }
+ }
+ };
+
+
+ /* ---------- Node constructors ---------- */
+
+ /**
+ * The factory for creating nodes of defined type.
+ *
+ * ~~~ Node ~~~ is a structure element of an onject or an array
+ * with own label (a key of an object or an index of an array)
+ * and value of any json data type. The root object or array
+ * is a node without label.
+ * {...
+ * [+] "label": value,
+ * ...}
+ *
+ * Markup:
+ *
+ *
+ *
+ *
+ * "label"
+ *
+ * :
+ *
+ * <(div|span) class="jsontree_value jsontree_value_(object|array|boolean|null|number|string)">
+ * ...
+ * (div|span)>
+ *
+ *
+ * @param label {string} - key name
+ * @param val {Object | Array | string | number | boolean | null} - a value of node
+ * @param isLast {boolean} - true if node is last in list of siblings
+ *
+ * @return {Node}
+ */
+ function Node(label, val, isLast) {
+ var nodeType = utils.getType(val);
+
+ if (nodeType in Node.CONSTRUCTORS) {
+ return new Node.CONSTRUCTORS[nodeType](label, val, isLast);
+ } else {
+ throw new Error('Bad type: ' + utils.getClass(val));
+ }
+ }
+
+ Node.CONSTRUCTORS = {
+ 'boolean' : NodeBoolean,
+ 'number' : NodeNumber,
+ 'string' : NodeString,
+ 'null' : NodeNull,
+ 'object' : NodeObject,
+ 'array' : NodeArray
+ };
+
+
+ /*
+ * The constructor for simple types (string, number, boolean, null)
+ * {...
+ * [+] "label": value,
+ * ...}
+ * value = string || number || boolean || null
+ *
+ * Markup:
+ *
+ *
+ * "age"
+ * :
+ *
+ * 25
+ * ,
+ *
+ *
+ * @abstract
+ * @param label {string} - key name
+ * @param val {string | number | boolean | null} - a value of simple types
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function _NodeSimple(label, val, isLast) {
+ if (this.constructor === _NodeSimple) {
+ throw new Error('This is abstract class');
+ }
+
+ var self = this,
+ el = document.createElement('li'),
+ labelEl,
+ template = function(label, val) {
+ var str = '\
+ \
+ "' +
+ label +
+ '" : \
+ \
+ \
+ ' +
+ val +
+ '' +
+ (!isLast ? ',' : '') +
+ '';
+
+ return str;
+ };
+
+ self.label = label;
+ self.isComplex = false;
+
+ el.classList.add('jsontree_node');
+ el.innerHTML = template(label, val);
+
+ self.el = el;
+
+ labelEl = el.querySelector('.jsontree_label');
+
+ labelEl.addEventListener('click', function(e) {
+ if (e.altKey) {
+ self.toggleMarked();
+ return;
+ }
+
+ if (e.shiftKey) {
+ document.getSelection().removeAllRanges();
+ alert(self.getJSONPath());
+ return;
+ }
+ }, false);
+ }
+
+ _NodeSimple.prototype = {
+ constructor : _NodeSimple,
+
+ /**
+ * Mark node
+ */
+ mark : function() {
+ this.el.classList.add('jsontree_node_marked');
+ },
+
+ /**
+ * Unmark node
+ */
+ unmark : function() {
+ this.el.classList.remove('jsontree_node_marked');
+ },
+
+ /**
+ * Mark or unmark node
+ */
+ toggleMarked : function() {
+ this.el.classList.toggle('jsontree_node_marked');
+ },
+
+ /**
+ * Expands parent node of this node
+ *
+ * @param isRecursive {boolean} - if true, expands all parent nodes
+ * (from node to root)
+ */
+ expandParent : function(isRecursive) {
+ if (!this.parent) {
+ return;
+ }
+
+ this.parent.expand();
+ this.parent.expandParent(isRecursive);
+ },
+
+ /**
+ * Returns JSON-path of this
+ *
+ * @param isInDotNotation {boolean} - kind of notation for returned json-path
+ * (by default, in bracket notation)
+ * @returns {string}
+ */
+ getJSONPath : function(isInDotNotation) {
+ if (this.isRoot) {
+ return "$";
+ }
+
+ var currentPath;
+
+ if (this.parent.type === 'array') {
+ currentPath = "[" + this.label + "]";
+ } else {
+ currentPath = isInDotNotation ? "." + this.label : "['" + this.label + "']";
+ }
+
+ return this.parent.getJSONPath(isInDotNotation) + currentPath;
+ }
+ };
+
+
+ /*
+ * The constructor for boolean values
+ * {...
+ * [+] "label": boolean,
+ * ...}
+ * boolean = true || false
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {boolean} - value of boolean type, true or false
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function NodeBoolean(label, val, isLast) {
+ this.type = "boolean";
+
+ _NodeSimple.call(this, label, val, isLast);
+ }
+ utils.inherits(NodeBoolean,_NodeSimple);
+
+
+ /*
+ * The constructor for number values
+ * {...
+ * [+] "label": number,
+ * ...}
+ * number = 123
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {number} - value of number type, for example 123
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function NodeNumber(label, val, isLast) {
+ this.type = "number";
+
+ _NodeSimple.call(this, label, val, isLast);
+ }
+ utils.inherits(NodeNumber,_NodeSimple);
+
+
+ /*
+ * The constructor for string values
+ * {...
+ * [+] "label": string,
+ * ...}
+ * string = "abc"
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {string} - value of string type, for example "abc"
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function NodeString(label, val, isLast) {
+ this.type = "string";
+
+ _NodeSimple.call(this, label, '"' + val + '"', isLast);
+ }
+ utils.inherits(NodeString,_NodeSimple);
+
+
+ /*
+ * The constructor for null values
+ * {...
+ * [+] "label": null,
+ * ...}
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {null} - value (only null)
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function NodeNull(label, val, isLast) {
+ this.type = "null";
+
+ _NodeSimple.call(this, label, val, isLast);
+ }
+ utils.inherits(NodeNull,_NodeSimple);
+
+
+ /*
+ * The constructor for complex types (object, array)
+ * {...
+ * [+] "label": value,
+ * ...}
+ * value = object || array
+ *
+ * Markup:
+ *
+ *
+ *
+ *
+ * "label"
+ *
+ * :
+ *
+ *
+ *
{
+ *
+ *
}
+ * ,
+ *
+ *
+ *
+ * @abstract
+ * @param label {string} - key name
+ * @param val {Object | Array} - a value of complex types, object or array
+ * @param isLast {boolean} - true if node is last in list of parent childNodes
+ */
+ function _NodeComplex(label, val, isLast) {
+ if (this.constructor === _NodeComplex) {
+ throw new Error('This is abstract class');
+ }
+
+ var self = this,
+ el = document.createElement('li'),
+ template = function(label, sym) {
+ var comma = (!isLast) ? ',' : '',
+ str = '\
+ \
+
\
+
' + sym[0] + '\
+
…\
+
\
+
' + sym[1] + '' +
+ '
' + comma +
+ '
';
+
+ if (label !== null) {
+ str = '\
+ \
+ ' +
+ '' +
+ '"' + label +
+ '" : \
+ ' + str;
+ }
+
+ return str;
+ },
+ childNodesUl,
+ labelEl,
+ moreContentEl,
+ childNodes = [];
+
+ self.label = label;
+ self.isComplex = true;
+
+ el.classList.add('jsontree_node');
+ el.classList.add('jsontree_node_complex');
+ el.innerHTML = template(label, self.sym);
+
+ childNodesUl = el.querySelector('.jsontree_child-nodes');
+
+ if (label !== null) {
+ labelEl = el.querySelector('.jsontree_label');
+ moreContentEl = el.querySelector('.jsontree_show-more');
+
+ labelEl.addEventListener('click', function(e) {
+ if (e.altKey) {
+ self.toggleMarked();
+ return;
+ }
+
+ if (e.shiftKey) {
+ document.getSelection().removeAllRanges();
+ alert(self.getJSONPath());
+ return;
+ }
+
+ self.toggle(e.ctrlKey || e.metaKey);
+ }, false);
+
+ moreContentEl.addEventListener('click', function(e) {
+ self.toggle(e.ctrlKey || e.metaKey);
+ }, false);
+
+ self.isRoot = false;
+ } else {
+ self.isRoot = true;
+ self.parent = null;
+
+ el.classList.add('jsontree_node_expanded');
+ }
+
+ self.el = el;
+ self.childNodes = childNodes;
+ self.childNodesUl = childNodesUl;
+
+ utils.forEachNode(val, function(label, node, isLast) {
+ self.addChild(new Node(label, node, isLast));
+ });
+
+ self.isEmpty = !Boolean(childNodes.length);
+ if (self.isEmpty) {
+ el.classList.add('jsontree_node_empty');
+ }
+ }
+
+ utils.inherits(_NodeComplex, _NodeSimple);
+
+ utils.extend(_NodeComplex.prototype, {
+ constructor : _NodeComplex,
+
+ /*
+ * Add child node to list of child nodes
+ *
+ * @param child {Node} - child node
+ */
+ addChild : function(child) {
+ this.childNodes.push(child);
+ this.childNodesUl.appendChild(child.el);
+ child.parent = this;
+ },
+
+ /*
+ * Expands this list of node child nodes
+ *
+ * @param isRecursive {boolean} - if true, expands all child nodes
+ */
+ expand : function(isRecursive){
+ if (this.isEmpty) {
+ return;
+ }
+
+ if (!this.isRoot) {
+ this.el.classList.add('jsontree_node_expanded');
+ }
+
+ if (isRecursive) {
+ this.childNodes.forEach(function(item, i) {
+ if (item.isComplex) {
+ item.expand(isRecursive);
+ }
+ });
+ }
+ },
+
+ /*
+ * Collapses this list of node child nodes
+ *
+ * @param isRecursive {boolean} - if true, collapses all child nodes
+ */
+ collapse : function(isRecursive) {
+ if (this.isEmpty) {
+ return;
+ }
+
+ if (!this.isRoot) {
+ this.el.classList.remove('jsontree_node_expanded');
+ }
+
+ if (isRecursive) {
+ this.childNodes.forEach(function(item, i) {
+ if (item.isComplex) {
+ item.collapse(isRecursive);
+ }
+ });
+ }
+ },
+
+ /*
+ * Expands collapsed or collapses expanded node
+ *
+ * @param {boolean} isRecursive - Expand all child nodes if this node is expanded
+ * and collapse it otherwise
+ */
+ toggle : function(isRecursive) {
+ if (this.isEmpty) {
+ return;
+ }
+
+ this.el.classList.toggle('jsontree_node_expanded');
+
+ if (isRecursive) {
+ var isExpanded = this.el.classList.contains('jsontree_node_expanded');
+
+ this.childNodes.forEach(function(item, i) {
+ if (item.isComplex) {
+ item[isExpanded ? 'expand' : 'collapse'](isRecursive);
+ }
+ });
+ }
+ },
+
+ /**
+ * Find child nodes that match some conditions and handle it
+ *
+ * @param {Function} matcher
+ * @param {Function} handler
+ * @param {boolean} isRecursive
+ */
+ findChildren : function(matcher, handler, isRecursive) {
+ if (this.isEmpty) {
+ return;
+ }
+
+ this.childNodes.forEach(function(item, i) {
+ if (matcher(item)) {
+ handler(item);
+ }
+
+ if (item.isComplex && isRecursive) {
+ item.findChildren(matcher, handler, isRecursive);
+ }
+ });
+ }
+ });
+
+
+ /*
+ * The constructor for object values
+ * {...
+ * [+] "label": object,
+ * ...}
+ * object = {"abc": "def"}
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {Object} - value of object type, {"abc": "def"}
+ * @param isLast {boolean} - true if node is last in list of siblings
+ */
+ function NodeObject(label, val, isLast) {
+ this.sym = ['{', '}'];
+ this.type = "object";
+
+ _NodeComplex.call(this, label, val, isLast);
+ }
+ utils.inherits(NodeObject,_NodeComplex);
+
+
+ /*
+ * The constructor for array values
+ * {...
+ * [+] "label": array,
+ * ...}
+ * array = [1,2,3]
+ *
+ * @constructor
+ * @param label {string} - key name
+ * @param val {Array} - value of array type, [1,2,3]
+ * @param isLast {boolean} - true if node is last in list of siblings
+ */
+ function NodeArray(label, val, isLast) {
+ this.sym = ['[', ']'];
+ this.type = "array";
+
+ _NodeComplex.call(this, label, val, isLast);
+ }
+ utils.inherits(NodeArray, _NodeComplex);
+
+
+ /* ---------- The tree constructor ---------- */
+
+ /*
+ * The constructor for json tree.
+ * It contains only one Node (Array or Object), without property name.
+ * CSS-styles of .tree define main tree styles like font-family,
+ * font-size and own margins.
+ *
+ * Markup:
+ *
+ *
+ * @constructor
+ * @param jsonObj {Object | Array} - data for tree
+ * @param domEl {DOMElement} - DOM-element, wrapper for tree
+ */
+ function Tree(jsonObj, domEl) {
+ this.wrapper = document.createElement('ul');
+ this.wrapper.className = 'jsontree_tree clearfix';
+
+ this.rootNode = null;
+
+ this.sourceJSONObj = jsonObj;
+
+ this.loadData(jsonObj);
+ this.appendTo(domEl);
+ }
+
+ Tree.prototype = {
+ constructor : Tree,
+
+ /**
+ * Fill new data in current json tree
+ *
+ * @param {Object | Array} jsonObj - json-data
+ */
+ loadData : function(jsonObj) {
+ if (!utils.isValidRoot(jsonObj)) {
+ alert('The root should be an object or an array');
+ return;
+ }
+
+ this.sourceJSONObj = jsonObj;
+
+ this.rootNode = new Node(null, jsonObj, 'last');
+ this.wrapper.innerHTML = '';
+ this.wrapper.appendChild(this.rootNode.el);
+ },
+
+ /**
+ * Appends tree to DOM-element (or move it to new place)
+ *
+ * @param {DOMElement} domEl
+ */
+ appendTo : function(domEl) {
+ domEl.appendChild(this.wrapper);
+ },
+
+ /**
+ * Expands all tree nodes (objects or arrays) recursively
+ *
+ * @param {Function} filterFunc - 'true' if this node should be expanded
+ */
+ expand : function(filterFunc) {
+ if (this.rootNode.isComplex) {
+ if (typeof filterFunc == 'function') {
+ this.rootNode.childNodes.forEach(function(item, i) {
+ if (item.isComplex && filterFunc(item)) {
+ item.expand();
+ }
+ });
+ } else {
+ this.rootNode.expand('recursive');
+ }
+ }
+ },
+
+ /**
+ * Collapses all tree nodes (objects or arrays) recursively
+ */
+ collapse : function() {
+ if (typeof this.rootNode.collapse === 'function') {
+ this.rootNode.collapse('recursive');
+ }
+ },
+
+ /**
+ * Returns the source json-string (pretty-printed)
+ *
+ * @param {boolean} isPrettyPrinted - 'true' for pretty-printed string
+ * @returns {string} - for exemple, '{"a":2,"b":3}'
+ */
+ toSourceJSON : function(isPrettyPrinted) {
+ if (!isPrettyPrinted) {
+ return JSON.stringify(this.sourceJSONObj);
+ }
+
+ var DELIMETER = "[%^$#$%^%]",
+ jsonStr = JSON.stringify(this.sourceJSONObj, null, DELIMETER);
+
+ jsonStr = jsonStr.split("\n").join("
");
+ jsonStr = jsonStr.split(DELIMETER).join(" ");
+
+ return jsonStr;
+ },
+
+ /**
+ * Find all nodes that match some conditions and handle it
+ */
+ findAndHandle : function(matcher, handler) {
+ this.rootNode.findChildren(matcher, handler, 'isRecursive');
+ },
+
+ /**
+ * Unmark all nodes
+ */
+ unmarkAll : function() {
+ this.rootNode.findChildren(function(node) {
+ return true;
+ }, function(node) {
+ node.unmark();
+ }, 'isRecursive');
+ }
+ };
+
+
+ /* ---------- Public methods ---------- */
+ return {
+ /**
+ * Creates new tree by data and appends it to the DOM-element
+ *
+ * @param jsonObj {Object | Array} - json-data
+ * @param domEl {DOMElement} - the wrapper element
+ * @returns {Tree}
+ */
+ create : function(jsonObj, domEl) {
+ return new Tree(jsonObj, domEl);
+ }
+ };
+})();
+export default {
+ jsonTree
+}
\ No newline at end of file
diff --git a/src/renderer/src/components/whiteboard/whiteboard.vue b/src/renderer/src/components/whiteboard/whiteboard.vue
new file mode 100644
index 0000000..16dfc93
--- /dev/null
+++ b/src/renderer/src/components/whiteboard/whiteboard.vue
@@ -0,0 +1,913 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 下载
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue b/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
index d9f8af7..abef714 100644
--- a/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
+++ b/src/renderer/src/views/classTask/container/newTask/taskTypeView.vue
@@ -18,184 +18,197 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 查找
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ scope.row.entpname }} {{ scope.row.editusername }}
- {{ scope.row.worktag }}
-
-
-
-
-
-
- 添加
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查找
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.entpname }} {{ scope.row.editusername }}
+ {{ scope.row.worktag }}
+
+
+
+
+
+
+ 添加
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
{{ item.worktype }}
-
-
-
-
-
{{ item.username }} 来自{{ item.parententpname }} {{ item.userentpname }}
-
{{ item.timestamp }}
+
+
+
+
+
+
+
+
{{ item.worktype }}
+
+
+
+
+
{{ item.username }} 来自{{ item.parententpname }} {{ item.userentpname }}
+
{{ item.timestamp }}
+
+
+
+
+
+ 预览
+ 添加到作业
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
{{ item.worktype }}
-
-
-
-
-
-
-
+
+
+
-
+
@@ -246,6 +259,7 @@ import { processList } from '@/hooks/useProcessList'
import { getCurrentTime } from '@/utils/date'
import FlowChart from "@/components/Flowchart/index.vue";
import FileUpload from "@/components/FileUpload/index.vue";
+import whiteboard from '@/components/whiteboard/whiteboard.vue'
@@ -350,7 +364,8 @@ const chooseWorkLists = ref([]); // 框架梳理、?课堂展示
const whiteboardObj = ref(''); // 作业资源 - 课堂展示 白板
// 课堂展示-------
const boardLoading = ref(false);
-const question = ref(''); // 课堂展示
+const isShowBoard = ref(false); // 是否展示白板
+const question = ref(''); // 课堂展示 --问题说明
const prevReadMsg = reactive({
visible: false,
type: ""
@@ -809,17 +824,18 @@ const handleClassWorkSave = async () => {
if (classWorkForm.worktype === "课堂展示") {
boardLoading.value = true
- let canvasJson = this.$refs.boardref.getCanvasJson()
- let canvasBase64 = await this.$refs.boardref.getCanvasBase64()
+ let canvasJson = proxy.$refs.boardref.getCanvasJson()
+ let canvasBase64 = await proxy.$refs.boardref.getCanvasBase64()
// 课堂展示提交内容
- formObj.worktag = question.value;
- formObj.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
- formObj.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
+ // cform.worktag = question.value;
+ cform.title = question.value;
+ cform.workcodes = JSON.stringify({json: canvasJson, base64: canvasBase64});
+ cform.entpcourseworklist = JSON.stringify([{'id':-1, 'score': '10'}]);
try {
- addClassworkReturnId(formObj).then(() => {
+ addClassworkReturnId(cform).then(() => {
ElMessage({ type: 'success', message: '作业设计成功!'});
// 重置提交表单
- classWorkForm.worktype = "习题训练";
+ classWorkForm.worktype = "课堂展示";
classWorkForm.uniquekey = props.uniquekey, // 作业唯一标识 作业名称
classWorkForm.title = "";
classWorkForm.quizlist = [], // 作业习题列表内容
@@ -1024,5 +1040,11 @@ watch(() => props.bookobj.levelSecondId, (newVal) => {
box-sizing: border-box;
}
+ .board-wrap {
+ padding: 10px;
+ box-sizing: border-box;
+ background-color: rgb(231, 231, 231)
+ }
+
}